website_sale_disable_cart removes the cart from every website once installed, which breaks website_membership_signup_required when CI installs everything together. The repo is shared by clients that never install them together: run_tests.py now tests each ISOLATE addon in its own database, after the rest, and ci.yml isolates website_sale_disable_cart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| bot.py | ||
| prompt.md | ||
| README.md | ||
Bot de incidencias
Atiende con Claude las incidencias de CriptoMart/addons-cm en Forgejo: responde
las preguntas funcionales o de configuración y abre un PR cuando hace falta código.
- bot.py: orquestador. Habla con la API de Forgejo, prepara un clon
limpio, lanza
claude -py publica el resultado. - prompt.md: instrucciones del bot (criterios y tono), comunes a todos los repos.
- ../../.gitea/issue-bot.md: qué es este repo (compartido entre clientes) y sus convenciones. Se añade a las instrucciones; es lo único que cambia de un repo a otro.
- ../../.gitea/workflows/issue-bot.yml: disparo por Actions al abrir o comentar una incidencia.
Qué hace con cada incidencia
Actúa cuando el último mensaje de una incidencia abierta es de una persona:
| Decisión | Acción |
|---|---|
answer |
Comenta la respuesta |
needs_info |
Comenta pidiendo los datos que faltan |
code |
Commit en bot/issue-N, push, PR contra 18.0 y comentario |
none |
Nada |
No actúa sobre PR, incidencias cerradas ni las que llevan la etiqueta no-bot, y
deja de responder tras BOT_MAX_REPLIES respuestas en la misma incidencia. Nunca
fusiona ni cierra nada.
Claude trabaja sin el token de Forgejo y sin herramientas web: solo lee el repo y
las fuentes de Odoo, edita ficheros y pasa pre-commit. Un cambio que toque
.gitea/, tools/ci/, tools/issue_bot/ o tools/pr_bot/ se rechaza.
Los PR que abre los revisa después el bot de revisión, que comparte con este la imagen del runner, la cuenta y los secretos.
Puesta en marcha
En Forgejo, una vez:
- Dar a la cuenta del bot (
claudia_eco) permiso de escritura en código, incidencias y PR: como colaborador con rol de escritura o desde un equipo propio, no desde el equipo de las personas del cliente. - Proteger la rama
18.0exigiendo aprobación, para que solo se fusione tras revisión. - Crear la etiqueta
no-bot.
Con Actions
Los jobs corren en la máquina del runner de ecocentral, con su imagen (Claude
Code, pre-commit, dependencias de Odoo 18 y Chromium) y sus montajes: las
fuentes de Odoo/OCA en /odoo-src y la caché issue-bot-cache. Cómo se monta
y se mantiene (Dockerfile, update.sh, sources.txt, runner-config.yml,
cron semanal) está documentado en el tools/issue_bot/README.md de ecocentral,
y sus ficheros viven allí: aquí no hay copia, para no tener dos listas de
fuentes para una misma máquina.
Un runner de Forgejo solo atiende el ámbito en el que se registra, y este repo
(organización CriptoMart) y el de ecocentral (Ecocentral) están en
organizaciones distintas. Por eso en esa máquina hay un segundo registro,
hecho en la organización CriptoMart, que comparte imagen, montajes y caché
con el de ecocentral:
-
Con el usuario
runner, una carpeta propia para el segundo daemon, con una copia delrunner-config.ymlde ecocentral (misma etiqueta,network: host, montajes,valid_volumes,force_pull: false,capacity: 1):mkdir ~/runner-criptomart && cd ~/runner-criptomart cp ~/<carpeta del runner de ecocentral>/runner-config.yml . forgejo-runner register --config runner-config.yml \ --instance http://localhost:3000 --token <token> \ --name criptomart --labels issue-bot:docker://eco-issue-bot:latestEl token sale de los ajustes de Actions de la organización
CriptoMart(Ajustes → Actions → Runners → Crear nuevo runner). -
Un servicio aparte para este daemon (copia de la unidad de systemd del de ecocentral con
WorkingDirectory=en~/runner-criptomartyforgejo-runner daemon --config runner-config.yml), y arrancarlo. -
Activar Actions en el repo.
-
Secretos del repo:
BOT_FORGEJO_TOKEN(token declaudia_eco) y uno deANTHROPIC_API_KEYoCLAUDE_CODE_OAUTH_TOKEN(lo generaclaude setup-token). Son secretos por repo: no se heredan de ecocentral.
Cada daemon tiene su capacity: 1, así que un job de cada repo puede correr a
la vez. Por eso el PostgreSQL del job test de aquí escucha en el 54330 y no
en el 54329 de ecocentral. Los dos comparten la caché issue-bot-cache
(entornos de pre-commit y los .pot del bot de revisión, que van por commit).
Tests del CI
En cada PR contra 18.0, y en cada push a esa rama, el job test de
ci.yml lanza
../ci/run_tests.py con el esquema del CI de la OCA: crea
una base de datos con las dependencias de los addons y después instala los
addons con --test-enable, de modo que solo corren los tests del repo.
PostgreSQL es un servicio del job, en el puerto 54330 de 127.0.0.1.
Los addons de ISOLATE (en ci.yml) se prueban cada uno en su propia base de
datos, después del resto: son los que con solo estar instalados cambian el
comportamiento de otros addons del repo, que es compartido por clientes que no
los instalan juntos. Por ejemplo, website_sale_disable_cart quita el carrito
a todos los sitios web.
Odoo arranca desde las fuentes montadas en /odoo-src/18.0, así que:
- Todo repo del que dependa un addon de aquí tiene que estar en la parte
18.0delsources.txtdel runner (en ecocentral). Si falta, el job falla diciendo qué módulo no encuentra, en lugar de dejar el addon sin probar. - Una dependencia Python nueva (
external_dependencies) pide añadirla alDockerfiledel runner (en ecocentral). - Ambas cosas llegan al runner al ejecutar
update.sh, no al fusionar.
/odoo-src/18.0 trae también un clon de este repo, porque ecocentral depende
de él. El job lo salta (ODOO_SRC_SKIP: addons-cm en ci.yml) y prueba el
checkout del PR.
Los tests corren contra la OCB y la OCA de la última actualización semanal, no contra commits fijados.
Sin Actions (poll)
En una máquina con claude autenticado, pre-commit y el token en
~/.config/gitea-addons-cm.token:
*/5 * * * * flock -n /tmp/addons-cm-issue-bot.lock python3 /ruta/al/repo/tools/issue_bot/bot.py poll
El primer poll solo anota la hora: el histórico no se atiende. Para pasar el
bot por incidencias ya abiertas:
python3 tools/issue_bot/bot.py run 12 15 --dry-run # enseña lo que publicaría
python3 tools/issue_bot/bot.py run 12 15
Configuración
| Variable | Por defecto |
|---|---|
BOT_FORGEJO_URL |
https://git.criptomart.net |
BOT_FORGEJO_REPO |
CriptoMart/addons-cm |
BOT_FORGEJO_TOKEN / ..._TOKEN_FILE |
~/.config/gitea-addons-cm.token |
BOT_REPO_DIR (clon propio del bot) |
~/.cache/eco-issue-bot/addons-cm |
BOT_BASE_BRANCH (18.0 en los workflows) |
rama por defecto del repo (16.0) |
BOT_ODOO_SRC (carpetas separadas por :) |
/media/snt/data/odoo |
BOT_MODEL (pide Claude Code ≥ 2.1.280) |
claude-opus-5-5 |
BOT_MAX_BUDGET_USD (por incidencia) |
5 |
BOT_TIMEOUT (segundos) |
2400 |
BOT_MAX_REPLIES |
8 |
BOT_STATE_FILE |
~/.local/state/eco-issue-bot/addons-cm/since |
bot.py, prompt.md y los ficheros de ../pr_bot/ son copia de
los de ecocentral; solo cambian los valores por defecto de esta tabla, el de
BOT_I18N_LANGS, las referencias al sources.txt del runner y el mensaje
del commit de traducciones del bot de revisión ([I18N] …). Un arreglo en
uno de los dos repos se copia tal cual al otro.