Current runtime policy: Docker setup and Docker-backed E2E/image CI are paused;
the Docker cron runner is retired. Rust and TanStack Start are not in use and
must not be run, tested, or updated until further notice. Retained Docker and
migration sections below are historical procedures. Current hosted Next.js,
package, Worker, database, and mobile workflows retain their own gates. See the
active runtime map.
Generated Release Formatting
Release Please initially pushes generated manifests, then amends that commit with Biome formatting before approval. Biome cancels superseded runs per Git ref so the intermediate unformatted commit cannot keep running beside its replacement. Inspect the run for the current release PR head when diagnosing a failure. Cancelled or skipped runs do not publish PR reports. Generated release branches use the release workflow’s formatter rather than separate automatic formatting PRs; their final commits still receive the normal format and lint checks. After formatting,scripts/ci/normalize-release-description.js also consolidates
identical bullets in each component section of the generated PR description. It
preserves source references, distinct wording, component summaries, and review
bot content. This runs even when generated files need no formatting changes.
Before formatting, scripts/ci/normalize-release-notes.js combines repeated
descriptions within each new release section, retaining every distinct commit
and PR link. It excludes narrowly identified integration-only merge commits.
The existing production release heading marks the immutable published boundary;
if that boundary is missing, normalization fails instead of rewriting history.
The generated release commit is amended using the existing exact-SHA lease.
No package version, dependency resolution or published changelog is rewritten.
Branch-to-Environment Map
Hosted Web Release Flow
Preview
- Preview workflows are named
vercel-preview-<app>.yaml. - Most preview workflows are manual-only from
mainwith a requiredpreview_ref;vercel-preview-platform.yamlalso triggers on protectedmainpushes so the staging database workflow receives a same-SHA platform build signal. e2e-tests.yamlalso runs only on non-productionpushes; production promotion relies on the already-green validation before the branch is promoted plus the production build-validation gates below.- Production workflows cancel superseded per-app runs only when a newer
productionpush arrives;maincommits and manual recovery runs leave an active production deployment untouched. - Each deploy job is bound to a
vercel-preview-<app>GitHub Environment and introduces Vercel credentials only after dependency installation. - Platform preview is build validation only; on-premise machines own the actual
apps/webruntime deployment. - Satellite preview deploys remain the normal Vercel validation surface for
branch work and merged
mainchanges. - Platform preview can reuse a successful same-SHA production platform build marker to avoid redundant preview builds. Production does not reuse preview markers because it must build and deploy the prebuilt production artifacts.
Staging Database
supabase-staging.yamlis tied to theVercel Platform Preview Deploymentworkflow onmain.- The staging migration runs only when the triggering platform preview build concludes successfully, or when manually dispatched.
- The staging deploy step runs
supabase db push --include-allafter linking the staging Supabase project, so staging can converge aftermainmigration history changes. - This means
mainis where app preview and staging schema advancement are meant to stay aligned. - If a production commit was promoted before the same-SHA staging migration run
existed, manually dispatch
supabase-staging.yamlfrommain; production migration re-evaluates after that staging run succeeds.
Production
- Satellite production web deploys run through
vercel-production-<app>.yaml. - A production push first runs
vercel-production.yaml, which computes affected Vercel and Cloudflare apps in one runner and calls only the necessary per-app workflows. Each target uses its own last successful deployment marker, so an app skipped on an earlier commit still receives any undeployed changes. - Hosted
apps/webproduction deploys run throughvercel-production-platform.yaml; self-hosted machines still use the Docker release flow below for their own runtime deployment. apps/appsproduction deploys are handled byvercel-production-apps.yaml.apps/qrproduction deploys are handled byvercel-production-qr.yaml.- Each production app uses a workflow-and-branch concurrency group whose
cancel-in-progresspredicate matches onlyproductionpush events, so the newest production SHA remains deployable without lettingmaincommits or manual recovery runs cancel it. - Production deploy jobs are bound to
vercel-production-<app>GitHub Environments and reject manual dispatches unless the selected branch isproduction.
Hosted Calendar schedules
Infrastructure owns the hosted Calendar provider-sync (every 15 minutes) and smart-scheduling (every six hours) schedules in itsvercel.json and
cron.config.json. Requests enter /api/cron/calendar/:job, authenticate with
CRON_SECRET, and use the encrypted gateway credential to reach Calendar.
Calendar must not keep a second direct Vercel schedule: direct scheduler requests
do not carry the private hosting header.
The retired Docker configuration retains these jobs in
apps/web/cron.config.json with vercel: false. That flag excludes them from
generated Web Vercel schedules; it does not activate a Docker runner. The
Infrastructure hosted schedules are the active Calendar owners. After deployment, verify a fresh provider sync timestamp
with all Calendar clients closed; a READY deployment alone is insufficient.
Browser App Version Metadata
- Browser apps share one platform version from
packages/utils/src/platform-release.ts; do not read visible app versions from individual apppackage.jsonfiles. - The shared browser app version is the
TUTURUUU_PLATFORM_VERSIONconstant exported frompackages/utils/src/platform-release.ts. Release Please owns that value (it carries thex-release-please-versionannotation), so do not pin a literal version in docs or bump it by hand. Read the constant directly when you need the current value. - Every Vercel browser app workflow runs
bun run --silent scripts/ci/generate-build-metadata.tsbeforevercel build. The generated metadata includes the commit hash, short hash, commit message, ref, environment, deployment URL, deployment stamp, and build timestamp. - The account-scoped version badge uses
public.user_configskeySHOW_VERSION_BADGE. It is hidden by default and only exact@tuturuuu.comaccounts may enable a truthy value. - Exact-domain enforcement happens on the server through
isExactTuturuuuDotComEmail; subdomains such as@xwf.tuturuuu.comare not eligible, and client cookies cannot make the badge render for ineligible users.
Production Database
supabase-production.yaml is stricter than staging:
- It re-evaluates automatically after either
Vercel Production Deployment Plannercompletes its selected production deploys onproductionorSupabase Staging Migrationcompletes onmain. - The production planner for the target commit must have concluded
successfully on
production, and the selected platform deployment must have recorded the successfulvercel-production-platformdeployment marker for the same SHA. A workflow run that skipped because package releases were still publishing is not enough. - The
mainstaging migration for the same target commit must have completed with asuccessconclusion. - A manual dispatch can still be used when an operator explicitly wants to run
it, but the dispatch must select the
productionbranch and still satisfy the same production-deployment and staging-migration SHA checks.
supabase db push --include-all. This keeps production schema changes
behind application deployment, staging validation, and branch promotion
for the same commit.
Self-Hosted Web Release Flow
If a server receives code throughgit pull, use the Docker production commands from
the checked-out commit:
bun serve:web:dockerfor in-place replacementbun serve:web:docker:bgfor blue/green rebuild-before-cutover deployment
Inactive migration and retained Docker tooling
apps/tanstack-web and apps/backend are not in use. Their source and runbooks
are retained for a possible future resumption; they are not release dependencies
for the live Next.js apps. Migration-specific builds, workers, Docker comparisons,
and cutover gates must not be required for ordinary Next.js delivery. Keep source
tracking required by repository policy without claiming a runtime cutover.
Docker setup is also outside the current supported path, and the Docker cron
runner is retired. The earlier self-hosted commands in this page are retained
reference procedures. Hosted Vercel/Cloudflare delivery and the owning scheduler
configuration establish active release behavior. See the
active runtime map.
Team Release Checklist
- Merge the change set with green CI.
- Docker setup is inactive; do not require or run
docker-setup-check.yamluntil explicitly resumed. - If database migrations changed, confirm the
main-driven staging path first. Check that app code remains usable against the old production schema: the production Vercel planner deploys apps before the production migration job runs, and the job may wait in the Actions queue. - Promote to
productiononly after preview and staging behavior is understood. - Confirm that the follow-up Supabase workflow’s Migrate production database job actually ran and applied the expected migration. A successful prerequisite job can leave the migration job skipped.
- For schema-dependent app releases, test the new deployment’s authenticated read path against production after the migration and confirm the public alias points to that tested deployment.
- For self-hosted rollout, deploy from the intended commit and prefer
bun serve:web:docker:bg.
Rollback Guidance
- Vercel-hosted rollback: for satellite apps, redeploy the previous known-good commit or use Vercel rollback tooling.
- If an app reads a production column that has not migrated yet, roll back only that app to a tested deployment. Keep the migration workflow running, then test the newer deployment directly against the migrated database before promoting its alias again. Verify the public URL after both changes.
- Supabase rollback: use a corrective migration instead of editing applied migration history.
- Self-hosted Docker rollback: checkout the previous known-good commit and rerun
bun serve:web:docker:bg.
What Not To Do
- Do not push production schema changes directly from a laptop as the normal path.
- Do not assume staging and production migrations are interchangeable; they are gated differently.
- Do not manually dispatch production Supabase migration from
main; the only validmainpath is the automatic staging-migration re-evaluation, and the production gate still requires the same commit to have both a successful production platform deployment and a completed successfulmainstaging migration. - Do not use the in-place Docker path when you specifically need rebuild-before-restart semantics.
Migrated Supabase CI baseline
E2E jobs share a pristine database-volume snapshot, in addition to the existing Supabase service image cache. The exact fingerprint includes migration contents, seed files, local configuration, setup code, CLI/service versions, and runner architecture. A UTC-day seed epoch bounds time-relative fixture staleness and stays fixed throughout a job. There are no partial restore keys. Only trustedmain runs publish
a snapshot, before tests create users or other mutable fixtures.
The setup action refuses an existing database volume. It verifies archive integrity,
the Postgres image digest, and migration history before using a restored database;
a mismatch or corrupt snapshot rebuilds from migrations. Snapshots are copied only
after PostgreSQL stops cleanly. Each job gets its own volume. Gateway model metadata
is refreshed after restoring, so it is not frozen into the baseline. Production and
staging database deployments do not use these local test snapshots.
Keep an uncached migration run in validation when changing migrations or the cache
format. Compare cold and warm setup times before claiming a performance gain. The
helper refuses execution outside a fresh Linux GitHub Actions runner and must never
be used to archive a developer or production database.
The Supabase baseline fingerprint includes the configured image registry as well
as the image version. CI honors SUPABASE_INTERNAL_IMAGE_REGISTRY for restore
integrity checks. Its contract also transfers the pristine snapshot to a separate
runner and requires a verified restore, so a safe cold fallback cannot hide a
broken cross-runner cache. Restore failures report only their phase, without
printing credential-bearing child-process output.