Common
-
Build (CI parity):
bun turbo:local run build --filter=@tuturuuu/<app> --concurrency=2, thennode scripts/ci/wave1-native-artifact.mjs prepare <app> production <sha> <workers-subdomain>,node scripts/ci/wave1-native-runtime.mjs <app> production <sha>(needsCI=true) andnode scripts/ci/wave1-native-publish.mjs dry-run <app> production <sha>. -
The production publication profile (
scripts/ci/wave1-native-profiles.json) uploads a route-free Worker (workers_dev: false,routes: []). Binding the canonical host is a separate provider step, so uploading never moves traffic. -
Production publication is gated by
productionPublicationPolicyintuturuuu.ci.tsand thewave1-native-production.yamldispatch, which listscalendar,mailandapps. All three are admitted. Each run uses the protected GitHub environmentwave1-<app>-production(publishonly succeeds whenPUBLICATION_ENVIRONMENTequals that exact name) and must be dispatched from theproductionref. -
Environments the release owner creates (restrict each to the
productionbranch and add a required reviewer):wave1-calendar-production,wave1-mail-production,wave1-apps-production. Each holds the same four secrets, by name:PRODUCTION_SUPABASE_URL,PRODUCTION_SUPABASE_PUBLISHABLE_KEY(public build inputs),WAVE1_PRODUCTION_CLOUDFLARE_READ_TOKEN(read-only topology, used by the preflight and verify steps) andWAVE1_PRODUCTION_CLOUDFLARE_API_TOKEN(upload only, used by the upload step). The per-app Worker secrets listed below are set on the Worker, not in GitHub. -
Legacy
vercel-production-mail.yamlandvercel-production-apps.yamlare disabled intuturuuu.ci.ts, like Calendar and Meet: Vercel can no longer build either app. -
Tasks and Track are not wave-1 profile apps. Their
mail-calendar-tasks-builds.yaml(tasks-cutover-artifact) andtrack-cloudflare.yaml(track-cutover-artifact) jobs already rewrite the emitted config to the production Worker namestuturuuu-tasksandtuturuuu-track(route-free,workers_devandpreview_urlsoff) and upload the artifact for an operatorwrangler deploy. They need no environment and have no production publisher job. -
Rollback: Vercel can no longer redeploy
calendar,mailorappsfrommain. Their build command now emits a native Worker and Vercel fails withNEXT_OUTPUT_DIR_MISSING, so the rollback target is the retained READY deployment below, restored by moving the alias. Never delete these deployments until a full release cycle has run on the Worker. -
Smoke, after the flip, per host
<host>:A passing smoke showsserver: cloudflareand nox-vercel-idheader.
Verified at 506c1ea9
The full production-profile sequence (build, seal, original-bytes workerd acceptance,
upload-limit dry-run, final seal) passes on an isolated checkout for these apps:
Every size is inside the recorded paid-plan limits (64 MiB script). Mail and Apps runtime
acceptance returns
200 for GET/HEAD /api/build-info, 405 for POST, and 307 for the
unauthenticated workspace route. Meet and Roadmap use their own workflows and are covered above.
Calendar
Apps
Meet
meet.tuturuuu.com is already served by the tuturuuu-meet Worker (server: cloudflare,
anonymous / answers 307 to the Web login). Source carries the custom-domain route in
apps/meet/void.config.ts. Bindings: ASSETS, WORKER_SELF_REFERENCE, ABUSE_GUARD
(service tuturuuu-abuse-guard), R2 cache bucket tuturuuu-meet-cache,
IMAGES, and the MEET_LIVE Durable Object (migration tag meet-live-v1). Required secret
names: MEET_REALTIME_TOKEN_SECRET, NEXT_PUBLIC_SUPABASE_URL,
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEY, GOOGLE_GENERATIVE_AI_API_KEY.
Meet is not part of the wave-1 profile set: meet-cloudflare.yaml validates it on every
change (native build, emitted-config receipt, restored-artifact acceptance) and its deploy
job publishes from the production ref with a deployment marker. Meet AI stays contained (MEET_AI_DISABLED=true). Migration changes follow the Meet
migration serialization and are not part of this packet. Vercel holds no READY production
deployment for Meet (all recent ones are canceled), so rollback for a Meet regression is the
previous Worker version, not Vercel.
Roadmap
tuturuuu.com/roadmap is served by the tuturuuu-roadmap Worker through Web’s proxy
(apps/web/src/lib/roadmap-public-proxy.ts), which fetches the non-redirecting worker origin
and never forwards cookies or authorization. The Worker also owns the routes
tuturuuu.com/roadmap and tuturuuu.com/roadmap/* in apps/roadmap/void.config.ts.
- Rollback: remove the
isRoadmapPublicPathbranch inproxy.ts(Web then serves its own page) or pointROADMAP_UPSTREAM_ORIGINelsewhere; no Worker deletion is needed. - Smoke:
curl -sS -L --max-redirs 3 -o /dev/null -w '%{http_code}\n' https://tuturuuu.com/roadmapexpects200;https://tuturuuu.com/vi/roadmapexpects one redirect to/roadmap.