Same system as ecocentral-18 (see its docs/CI-CD.md): - ci.yml: lint (pre-commit), test (tools/ci/run_tests.py, OCA-style two-phase install) and review (PR bot, after lint and test). - issue-bot.yml: the issue bot answers issues or opens a PR on bot/issue-N. - pr-bot.yml: review when WIP is removed or the i18n label is added. - .gitea/issue-bot.md: context for the bots; this repo is shared by several clients. The bot scripts are copies of ecocentral's. Only the defaults differ (repo, token and state files, i18n languages es,eu,ca,gl) along with the [I18N] commit message and the references to the runner's sources.txt. The jobs run on a second forgejo-runner registration (CriptoMart org) on ecocentral's runner machine, sharing its image, mounts and cache. The runner files (Dockerfile, update.sh, sources.txt) live in ecocentral. Specific to this repo: - ODOO_SRC_SKIP: the runner's /odoo-src/18.0 holds a clone of addons-cm, so test skips it and checks the PR checkout instead. - BOT_BASE_BRANCH "18.0": the repo's default branch is 16.0. - test PostgreSQL on port 54330: ecocentral's runs on 54329 and a test job from each repo can run at the same time. The lint job fails until the repo is cleaned up with pre-commit run --all-files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| i18n.py | ||
| prompt.md | ||
| README.md | ||
| review.py | ||
Bot de revisión de PR
Revisa con Claude los pull requests de CriptoMart/addons-cm en Forgejo cuando
ya han pasado el linter y los tests, y deja un comentario con lo que encuentra.
No aprueba, no bloquea y no fusiona: la decisión sigue siendo de quien revisa.
- review.py: orquestador. Decide si toca revisar, prepara la
cabeza del PR, lanza
claude -py publica el comentario. Reutiliza la API de Forgejo, el clon y la llamada a Claude del bot de incidencias. - prompt.md: instrucciones de la revisión, comunes a todos los repos.
- i18n.py: prepara y repasa los
.po. - ../../.gitea/issue-bot.md: qué es este repo y sus convenciones, entre ellas la de idiomas. Es el mismo fichero que usa el bot de incidencias.
Qué revisa
| Parte | Qué busca |
|---|---|
| Seguridad y permisos | ACL que faltan o sobran, reglas de registro, sudo(), métodos públicos, controladores, SQL a mano |
| Idiomas y traducciones | Textos en un idioma que no es el del addon o que Odoo no puede traducir (_() mal usado) |
| Flujos de Odoo | Sobrescrituras, otras entradas al mismo modelo, otros addons que tocan lo mismo, datos que ya hay en producción |
Cada hallazgo lleva gravedad (alta, media, baja), fichero y línea, el caso concreto y un arreglo propuesto. Estilo, formato y lo que cubren los tests no entran: de eso ya se han ocupado el linter y el CI.
Cuándo actúa
| Disparo | Dónde |
|---|---|
| El CI de un PR pasa lint y test | job review de ci.yml (needs) |
Se quita la marca WIP o se pone i18n |
pr-bot.yml, si el CI ya había pasado |
Se salta los PR cerrados, los marcados como WIP (WIP: o [WIP] en el
título), los que no van contra 18.0 y los que llevan la etiqueta no-bot.
Revisa cada commit una sola vez y deja de hacerlo tras BOT_MAX_REVIEWS
revisiones del mismo PR. Cada revisión nueva sustituye a la anterior: repite lo
que sigue vigente y deja fuera lo arreglado.
Traducciones (etiqueta i18n)
Por defecto el bot solo revisa los textos. Con la etiqueta i18n en el PR,
además:
- Recoge el
.potde cada addon que toca el PR. Lo exporta Odoo en el jobtest, cuando los tests pasan, y lo deja en la caché del runner (BOT_POT_DIR/<commit>/). - Pone al día
i18n/<addon>.poty prepara un.popor idioma deBOT_I18N_LANGS(es,eu,ca,gl) con los términos de todo el addon. - Claude rellena los
msgstrvacíos. Un.ponuevo que se quede sin ninguna traducción no se crea. - Se descartan las traducciones que no conservan los marcadores (
%s,%(nombre)s) del original. - El bot sube el resultado a la rama del PR en un commit
[I18N] <addons>: …. Ese commit pasa el CI como cualquier otro, pero no se vuelve a revisar.
Poner la etiqueta en un PR ya revisado lanza otra pasada, esta vez con las
traducciones. Los addons que el CI no instala (EXCLUDE en ci.yml) no tienen
.pot y se quedan como están.
Riesgo aceptado: el .pot sale de una caché en la que el job test, que
ejecuta el código del PR, puede escribir. Un test malicioso podría dejar un
.pot falso para el commit de otro PR, y si ese PR lleva la etiqueta, el bot
subiría a su rama términos que no salen de su código. Solo afecta a ficheros
i18n/, solo con la etiqueta y solo con acceso de escritura al repo, que es
privado. Lo de fondo es que todos los jobs comparten issue-bot-cache; si
algún día entra código menos fiable, el job test debería tener su propia
caché.
Puesta en marcha
Usa la misma imagen, la misma cuenta (claudia_eco) y los mismos secretos que
el bot de incidencias: ver su README, que a su vez
remite al de ecocentral para el runner. Solo hay que añadir:
- La etiqueta
i18nen el repo de Forgejo. - La caché que comparten los jobs. Ya está si el runner monta
issue-bot-cache:/root/.cachecomo dice el README del runner; los.potvan en/root/.cache/eco-pr-bot/poty se borran solos a los 14 días.
El job review corre con el review.py de la propia rama del PR, así que los
PR abiertos antes de fusionar este bot no se revisan hasta que incorporen
18.0.
A mano
En una máquina con claude autenticado, python3-polib y el token en
~/.config/gitea-addons-cm.token:
python3 tools/pr_bot/review.py run 217 --dry-run # enseña lo que publicaría
python3 tools/pr_bot/review.py run 217 --force # repite un commit ya revisado
Sin --ci-passed comprueba en Forgejo que el commit tiene lint y test en
verde. Fuera del runner no hay .pot del CI, así que las traducciones no se
tocan aunque el PR lleve la etiqueta.
Configuración
Las variables del bot de incidencias (BOT_FORGEJO_*, BOT_REPO_DIR,
BOT_ODOO_SRC, BOT_MODEL, BOT_MAX_BUDGET_USD, BOT_TIMEOUT) valen igual
aquí. Propias de este bot:
| Variable | Por defecto |
|---|---|
BOT_MAX_REVIEWS (por PR) |
6 |
BOT_CI_CONTEXTS (separados por ,) |
CI / lint (pull_request),CI / test (pull_request) |
BOT_I18N_LABEL |
i18n |
BOT_I18N_LANGS |
es,eu,ca,gl |
BOT_POT_DIR |
~/.cache/eco-pr-bot/pot |