Ir al contenido

CI/CD

CÉNIT corre en Cloudflare Workers vía @opennextjs/cloudflare (no Vercel). El pipeline está repartido en seis workflows de GitHub Actions, cada uno con un rol acotado: build + bundle budget, deploy a Workers, migraciones de Supabase, deploy del sitio de docs, validación de la línea Docs: en PRs, y tests + lint.

Corre en cada PR que toca paths de build (app/**, lib/**, package.json, wrangler.toml, open-next.config.ts, etc.) y en push a main.

  • Ejecuta opennextjs-cloudflare build + wrangler deploy --dry-run contra cenit-dev.
  • Mide el tamaño gzip del bundle y falla si excede el budget de .github/cloudflare-build-baseline.json.
  • Valida que las versiones de @opennextjs/cloudflare y wrangler pineadas en el lockfile matcheen el baseline.
  • No deploya — solo gate de PR.

Tres targets:

  • PR previews → Worker cenit-pr-${PR_NUM}. Auto-deploy en opened/synchronize/reopened. Auto-cleanup en closed.
  • Staging → Worker cenit-staging. Auto en cada push a main.
  • Producción → Worker cenit-prod. Trigger: push de tag v*. Gated por el GitHub Environment cf-production (reviewer + timer de 5 min).

Sentry releases se taggean con el nombre del tag en producción y con el SHA en staging.

Aplica migraciones de Supabase via scripts/db-migrate.sh. Idempotente — cada archivo queda registrado con su sha256 en _cenit_meta.schema_migrations.

  • Staging (db-staging env) → push a main.
  • Producción (db-production env, con reviewer) → push de tag v*.

Trigger paths: supabase/migration-*.sql, scripts/db-migrate.sh y el propio workflow.

Sitio Astro Starlight → Cloudflare Pages.

  • Producción → proyecto cenit-docs, dominio docs.cenitams.com. Auto en push a main con cambios en docs-site/**.
  • Staging → proyecto cenit-docs-staging, dominio docs-staging.cenitams.com. Auto en push a staging.

Token separado (CLOUDFLARE_DOCS_API_TOKEN) con scope Pages:Edit — least privilege respecto del token de la app.

Valida que cada PR tenga una línea Docs: en el body con uno de: updated, n/a, o follow-up #ISSUE. Sin docs declarados → CI falla. La regla vive en DOCUMENTATION_PLAN.md § 6 y la plantilla en .github/PULL_REQUEST_TEMPLATE.md.

Lint + unit tests + integration (Vitest + Playwright + Postgres matrix). Path-filter ignora cambios doc-only (**.md, .llm/**, docs/**). Nightly cron a las 06:00 UTC corre la matrix completa PG15+PG17 si hubo actividad en main en las últimas 24h.

1. PR mergeado a main → staging auto-deploy (app + docs + migrations)
2. Verificación manual en staging
3. git tag v1.2.3 -m "release notes" && git push origin v1.2.3
4. Reviewer aprueba cf-production y db-production
5. Producción deploya (app + migrations)

El docs site no participa del tag flow — se deploya con cada push a main directamente.

  • App: cenitams.com (legacy cenitapp.com redirige 302).
  • Docs: docs.cenitams.com (staging: docs-staging.cenitams.com).
Ventana de terminal
# Workers (app)
CLOUDFLARE_API_TOKEN # Workers:Edit
CLOUDFLARE_ACCOUNT_ID
CLOUDFLARE_HYPERDRIVE_LOCAL_* # stubs para emulación local en deploy
# Pages (docs)
CLOUDFLARE_DOCS_API_TOKEN # Pages:Edit + User:Read
# DB
STAGING_DATABASE_URL # session-pooler (port 6543, sslmode=require)
PRODUCTION_DATABASE_URL
  • Sentry — el SHA del build se exporta como release.
  • Multi-tenant — migraciones que cambian RLS pasan por el flow de migrations gateado.
  • Path filter middleware.ts hardcodeadocloudflare-build.yml lista middleware.ts en su paths: filter. Si el archivo se renombra a proxy.ts (la convención que Next.js 16 documenta como sucesor), el workflow dejará de dispararse en cambios a ese archivo y los builds quedarán mudos. Actualizar el filter en el mismo PR que el rename.
  • Sin rollback automático de migrationsdb-migrate.sh aplica forward-only. Rollback requiere migration nueva que revierta.
  • Concurrency en migrationsconcurrency: cancel-in-progress: false evita cancelar una migración en vuelo, pero si dos tags pushean en sucesión cercana, la cola puede crecer.
  • PR preview workers no comparten DB con la app real — apuntan al mismo Supabase staging. Cuidado al testear destructive ops.