Guías / Convención de PRs y Commits (v2)
Referencia
7 de julio de 2026
prcommitsconvencionworkflowgit

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, usar infra o no-ticket (nunca vacío).
  • tipo: uno del set fijo feat | 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). Acepta infra y no-ticket como 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

TipoCuándo usarlo
featNueva funcionalidad o capacidad visible para el usuario
fixCorrección de un bug o comportamiento incorrecto
hotfixCorrección urgente directo a producción
choreMantenimiento que no cambia comportamiento (dependencias, tooling)
refactorReestructuración interna sin cambio de comportamiento
testAgrega o modifica tests únicamente
docsCambios de documentación únicamente
styleFormato, espacios en blanco, cambios cosméticos
perfMejora de performance
ciCambios en pipelines de CI/CD y workflows de GitHub Actions
buildCambios en el sistema de build (Makefile, buf, toolchain)
revertRevierte un commit previo

refactor es 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

TokenPaísBandera
ar-discoArgentinaDisco
ar-jumboArgentinaJumbo
ar-veaArgentinaVea
br-prezunicBrasilPrezunic
co-jumboColombiaJumbo
pe-metroPerúMetro
us-tfmUSATFM

Tokens especiales (válidos tanto en título de PR como en scope de commit, salvo aclaración):

TokenUso
sharedCódigo común / cambio que afecta a varias banderas
coreLógica de negocio transversal, no atada a un tenant (solo scope de commit)
commonUtilidades/helpers/config compartida entre tenants (solo scope de commit)
infraPR o commit de infra/CI sin ticket Jira (va en el slot de ticket)
no-ticketCualquier 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-jumbo vs co-jumbo).
  • US: el token canónico es us-tfm. En EKS el namespace/banner real es freshmarket; un agente debe saber mapear us-tfm <-> freshmarket.

5. Casos borde

  • Código compartido / varios tenants -> [shared] (PR) o scope shared (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 con make setup-hooks) bloquea commits no conformes en la máquina del developer.
    • CI — job commit-msg-validator en 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 con Merge).
    • Sin make setup-hooks, el CI sigue siendo el backstop.