Convención de PRs y Commits (v2)
Fuente de verdad para nombrar Pull Requests y commits en los servicios del rancho WL.
Fuente de verdad para nombrar Pull Requests y commits en los servicios del rancho Catálogo (y extensible al resto).
Decisión de base: los repos del rancho mergean con squash. El título del PR ES el commit que queda en
main, esa es la unidad autoritativa para el changelog de un RC. Los commits de la rama son material de review y ahora también están enforced (ver sección 7), pero su función principal es dar detalle de qué módulo cambió.
1. Título de PR
Formato:
[<pais-bandera>] [<ticket>] <tipo>: <descripcion>
Ejemplos:
[co-jumbo] [WR-2902] fix: timeout en search VIS
[br-prezunic] [WR-2841] feat: cashback en checkout
[us-tfm] [WR-3010] chore: bump shared-pkg a v1.4.0
[ar-jumbo] [WR-3055] refactor: cliente core-auth propio
[pe-metro] [WR-3200] feat: onboarding de nuevo tenant
[shared] [WR-3100] refactor: extraer validador de sesion
[co-jumbo] [infra] chore: deshabilitar auto-deploy en push a main
Reglas
pais-bandera: token en minúscula de la lista canónica (sección 4). Siempre país + bandera juntos, nunca la bandera sola.ticket: cualquier clave Jira válida (PROYECTO-NUMERO, ej.WR-2902). Si no hay ticket, usarinfraono-ticket(nunca vacío).tipo: uno del set fijofeat | fix | chore | refactor | docs | hotfix.descripcion: imperativa, corta, sin punto final.
2. Commits de la rama
Formato:
<tipo>(<ticket>): <scope> [<modulo>] <descripcion>
El [<modulo>] es opcional: se agrega solo cuando el cambio toca un paquete puntual (search, cmedia, otel, deps…) dentro del scope.
Ejemplos:
feat(WR-4653): br-prezunic add search fallback for unavailable products
fix(WR-3468): shared [search] conditional Cmedia client
fix(WR-2841): pe-metro [checkout] hide installments con una sola cuota
chore(infra): shared deshabilitar auto-deploy en push a main
Reglas
ticket: obligatorio en el header (no como footer). Aceptainfrayno-ticketcomo valores válidos cuando no hay clave Jira.scope: siempre tenant o dominio transversal (tabla de la sección 4), nunca un módulo.modulo: opcional, entre corchetes al inicio de la descripción, solo cuando el cambio es puntual a un paquete.descripcion: imperativa, corta (subject ≤ 72 caracteres), sin punto final, inglés o español neutro.
Tipos válidos
| Tipo | Cuándo usarlo |
|---|---|
feat | Nueva funcionalidad o capacidad visible para el usuario |
fix | Corrección de un bug o comportamiento incorrecto |
hotfix | Corrección urgente directo a producción |
chore | Mantenimiento que no cambia comportamiento (dependencias, tooling) |
refactor | Reestructuración interna sin cambio de comportamiento |
test | Agrega o modifica tests únicamente |
docs | Cambios de documentación únicamente |
style | Formato, espacios en blanco, cambios cosméticos |
perf | Mejora de performance |
ci | Cambios en pipelines de CI/CD y workflows de GitHub Actions |
build | Cambios en el sistema de build (Makefile, buf, toolchain) |
revert | Revierte un commit previo |
refactores un tipo, no un scope.
Footers
BREAKING CHANGE: <descripcion>cuando aplica, para que el RC lo marque.- No se usa
Refs:(el ticket ya vive en el header, es redundante).
3. Parseo (para agentes / scripts)
Título de PR (= commit de main con squash):
^\[(?<tenant>[a-z-]+)\] \[(?<ticket>[A-Z]{2,}-\d+|infra|no-ticket)\] (?<tipo>feat|fix|chore|refactor|docs|hotfix): (?<desc>.+)$
Header de commit de rama:
^(?<type>feat|fix|hotfix|chore|refactor|test|docs|style|perf|ci|build|revert)\((?<ticket>[A-Z]{2,}-\d+|infra|no-ticket)\): (?<scope>[a-z-]+) (\[(?<modulo>[a-z0-9-]+)\] )?(?<description>.+)$
Con esos grupos, el changelog de un RC se arma agrupando por tenant y tipo del título de PR; los commits aportan el detalle de modulo para auditoría fina.
4. Lista canónica de tokens
| Token | País | Bandera |
|---|---|---|
ar-disco | Argentina | Disco |
ar-jumbo | Argentina | Jumbo |
ar-vea | Argentina | Vea |
br-prezunic | Brasil | Prezunic |
co-jumbo | Colombia | Jumbo |
pe-metro | Perú | Metro |
us-tfm | USA | TFM |
Tokens especiales (válidos tanto en título de PR como en scope de commit, salvo aclaración):
| Token | Uso |
|---|---|
shared | Código común / cambio que afecta a varias banderas |
core | Lógica de negocio transversal, no atada a un tenant (solo scope de commit) |
common | Utilidades/helpers/config compartida entre tenants (solo scope de commit) |
infra | PR o commit de infra/CI sin ticket Jira (va en el slot de ticket) |
no-ticket | Cualquier otro PR o commit sin ticket (va en el slot de ticket) |
Notas:
- El prefijo de país es obligatorio porque hay banderas repetidas entre países (
ar-jumbovsco-jumbo). - US: el token canónico es
us-tfm. En EKS el namespace/banner real esfreshmarket; un agente debe saber mapearus-tfm<->freshmarket.
5. Casos borde
- Código compartido / varios tenants ->
[shared](PR) o scopeshared(commit). - Sin ticket ->
[infra]/infra(CI/infra) o[no-ticket]/no-ticket(otros). Nunca vacío. - Hotfix -> tipo
hotfix, para que salte a la vista en el armado del RC. - Breaking change -> footer
BREAKING CHANGE:en el commit.
6. Por qué esto da el RC “gratis”
El título del PR sigue siendo la unidad autoritativa del changelog, se lee directo del git log entre dos tags:
## RC v1.5.0-RC1 - co-jumbo
### Features
- WR-2902 timeout en search VIS (#412)
### Fixes
- WR-2950 corregir precio tachado (#418)
Esto alimenta los flujos de qa-release y prod-release.
7. Enforcement
- Título de PR: GitHub Action que valida el título contra el regex de la sección 3. Una sola Action por repo, imposible de saltear, y con squash es lo único que llega a
main. - Commits de rama: ahora también enforced en dos puntos:
- Local — hook
commit-msg(instalado conmake setup-hooks) bloquea commits no conformes en la máquina del developer. - CI — job
commit-msg-validatoren GitHub Actions valida cada commit del PR contra el regex de la sección 3 antes de que pueda mergearse. Omite merge commits (subjects que empiezan conMerge). - Sin
make setup-hooks, el CI sigue siendo el backstop.
- Local — hook