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.
| Rama | Entorno | Qué recibe |
|---|---|---|
main | Producción (app.xenpia.com) | Solo PRs de ramas aprobadas por QA, y los hotfix |
dev | Test (test.xenpia.com) | PRs de ramas en QA y el sync automático desde main |
feat/*, fix/* | — | Salen siempre de main |
Las reglas
- La rama sale de
origin/main, escrito siempre de forma explícita. La rama por defecto del repo esdevy se queda así a propósito. Por eso GitHub,git switch -c xsin base y los worktrees de Claude Code y Cursor parten dedev. Una rama que sale dedevlleva dentro trabajo ajeno sin aprobar y ya no puede subir sola. Antes de cada push,git log --oneline origin/main..HEADtiene que listar solo tus commits. - Nunca fusiones
deven tu rama. Para ponerla al día, fusionamain. - Nunca abras un PR de
devamain. Tampoco desde una ramaqa/*, que ya llevadevfusionado. El check «Rama permitida hacia main» del CI marca esos PR en rojo. El 2026-09-25 un PRdev→mainsubió 159 archivos sin QA y dejó producción en 500. - 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. - Fusiona con merge commit, no con squash. Así el commit de la rama es el mismo en
devy enmain, 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
devy 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 roto | A 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 dos | PR 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-allaplica 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.