Saltar al contenido principal

Flujo de ramas y paso a producción

A producción se llega por funcionalidad: cada rama aprobada por QA entra a main con su propio PR. dev es solo el entorno de QA y nunca se fusiona en main. El porqué está en el ADR 0005.

RamaEntornoQué recibe
mainProducción (app.xenpia.com)Solo PRs de ramas aprobadas por QA, y los hotfix
devTest (test.xenpia.com)PRs de ramas en QA y el sync automático desde main
feat/*, fix/*—Salen siempre de main

Las reglas​

  1. La rama sale de origin/main, escrito siempre de forma explícita. La rama por defecto del repo es dev y se queda así a propósito. Por eso GitHub, git switch -c x sin base y los worktrees de Claude Code y Cursor parten de dev. Una rama que sale de dev lleva dentro trabajo ajeno sin aprobar y ya no puede subir sola. Antes de cada push, git log --oneline origin/main..HEAD tiene que listar solo tus commits.
  2. Nunca fusiones dev en tu rama. Para ponerla al día, fusiona main.
  3. Nunca abras un PR de dev a main. Tampoco desde una rama qa/*, que ya lleva dev fusionado. El check «Rama permitida hacia main» del CI marca esos PR en rojo. El 2026-09-25 un PR dev → main subió 159 archivos sin QA y dejó producción en 500.
  4. QA aprueba y entonces se fusiona a main. La aprobación queda en el PR (una revisión o un comentario de QA). El botón de merge es la puerta: GitHub no lo impone en el plan gratuito.
  5. Fusiona con merge commit, no con squash. Así el commit de la rama es el mismo en dev y en main, el sync no choca y git-cliff ve cada commit convencional.

Paso a paso​

1. Empezar​

git fetch origin
git switch -c feat/mi-funcionalidad origin/main

2. Mandarla a QA​

Push y PR con base dev. Al fusionarlo, "Deploy Test" la despliega en Test.

Si el PR a dev choca, no fusiones dev en tu rama. Resuélvelo en una rama desechable:

git switch -c qa/mi-funcionalidad feat/mi-funcionalidad
git merge origin/dev # resolver aquí los conflictos
git push -u origin qa/mi-funcionalidad
# PR de qa/mi-funcionalidad a dev

Las correcciones que pida QA van en feat/mi-funcionalidad y se vuelven a mandar a dev igual.

3. QA aprueba: a producción​

git switch feat/mi-funcionalidad
git fetch origin && git merge origin/main
cd docs && yarn gen && cd .. # los artefactos tienen que cuadrar con main
git commit -am "docs: regenerar artefactos sobre main" # solo si yarn gen cambió algo
git push

PR de feat/mi-funcionalidad con base main. Con el CI en verde y la aprobación de QA, fusiona. Después, solo:

  • Deploy Production: backup de la base, migraciones y deploy.
  • Sync main into dev: lleva el merge a dev y redespliega Test.

4. Cortar la versión​

Cuando haya un conjunto de cambios que anunciar: Actions → Promote to Production → Run workflow. Genera las notas en docs/blog/ con lo fusionado en main desde la última etiqueta, etiqueta vX.Y.Z y relanza el deploy para publicar las notas. No mueve código.

Hotfix​

Es el mismo camino, más corto: fix/x desde main, PR a main y el sync lo lleva a dev. No hace falta pasarlo por dev antes si la urgencia no lo permite.

El atajo es solo para algo roto en producción. Antes de elegirlo, mira qué entorno falla:

Lo rotoA dónde va el PR
Producción (app.xenpia.com, deploy-prod.yml, datos de PROD)Hotfix: PR a main
Solo Test (test.xenpia.com, pipeline.yml, algo que solo está en dev)PR a dev, como cualquier rama
Los dosPR a dev; cuando Test lo confirme, la misma rama a main

GitHub ejecuta un workflow de push con el archivo tal como está en el commit empujado. Un arreglo de Deploy Test mandado a main no protege Test hasta que el sync lo lleve a dev, y de paso despliega producción sin necesidad. Pasó el 2026-09-28 con #145.

Migraciones​

  • supabase db push --include-all aplica las pendientes aunque lleguen fuera de orden de fecha. Por eso una rama puede subir antes que otra más antigua.
  • Una migración no puede depender de otra que viva en una rama sin aprobar. Si depende, las dos ramas suben juntas o se fusionan en una.
  • DEV tendrá migraciones que PROD aún no tiene. Es normal: son las ramas en QA.

Ver qué falta por subir​

# Trabajo en dev que todavía no está en producción (sin los merges del sync)
git log --oneline --no-merges origin/main..origin/dev

# ¿Está ya en producción esta rama?
git branch -r --contains feat/mi-funcionalidad | grep origin/main

Si el sync choca​

Cuando el merge de main en dev choca en código, "Sync main into dev" abre un PR desde sync/main-a-dev. Se resuelve en esa rama, nunca en main:

git fetch origin
git switch -c sync/main-a-dev origin/sync/main-a-dev
git merge origin/dev # resolver; docs/generated se arregla con yarn gen
git push

Y se fusiona el PR a dev.

Transición (2026-09)​

Hasta el cambio, dev se promovía entero, así que tiene trabajo sin separar por rama. Para cada funcionalidad que QA apruebe, crea una rama desde main, trae sus commits con cherry-pick y abre el PR a main:

git switch -c feat/x origin/main
git cherry-pick <sha1> <sha2> # los de esa funcionalidad, de git log origin/main..origin/dev

Se hace una sola vez. Desde ahí, cada rama nueva sale de main.