Skip to content

Pre-cutover staging environment and per-PR preview deployments

  • Status: Accepted
  • Date: 2026-06-09
  • Relates to: ADR-0014 (D1 data tier), ADR-0006 (Cloudflare hosting), ADR-0009 (CI/CD)

The original go-live plan was a big-bang cutover: nothing deployed anywhere until launch day, when the Worker would be published and apex/www DNS flipped in one step. That concentrates all deployment risk — first-ever production deploy, first real form submission, first edge-rule contact — into the launch window.

The quarry.team zone already lives on Cloudflare (Terraform looks it up; apex/www currently point at the legacy host). Workers supports multiple environments per config, custom-domain routes on any zone hostname, and version preview URLs (wrangler versions upload publishes a version without promoting traffic, served at an ephemeral hash-prefixed URL). All the pieces for a pre-cutover soak exist — only the apex/www routes actually need to wait for launch.

  1. A staging Worker environment ([env.staging] in wrangler.toml) deploys as quarry-web-staging on staging.quarry.team with its own D1 database (marketing-site-form-submissions-staging) and sessions KV, so test submissions never touch production data. Every push to main deploys staging once the repo variable STAGING_DEPLOY_ENABLED=true is set — independent of (and well before) the production DEPLOY_ENABLED gate.
  2. Per-PR previews upload a Worker version of the staging environment (wrangler versions upload; preview_urls = true) and post the ephemeral preview URL as a sticky PR comment. No traffic promotion, no routes.
  3. Environment selection happens at build time. The @astrojs/cloudflare adapter resolves wrangler.toml for the environment named by CLOUDFLARE_ENV and emits the deployable config to dist/server/wrangler.json; all wrangler commands target that emitted file. (Plain wrangler deploy against the source toml does not work — it has no main/assets.)
  4. Staging is noindexed at the edge — a zone response-header-transform rule sets X-Robots-Tag: noindex, nofollow for http.host eq staging.quarry.team (Terraform-owned), keeping the build artifact identical across environments.
  5. The D1 store is named marketing-site-form-submissions (staging: …-staging), table form_submissions — named for what it holds, not the marketing concept around it.
  • The DNS cutover stops being a launch event: by launch day the same Worker, D1 schema, WAF/cache rules, Turnstile, and email dispatch have been serving staging traffic; go-live is enabling the apex/www routes (DEPLOY_ENABLED=truewrangler deploy) and retiring the legacy host.
  • Rollback paths shrink: wrangler rollback (versions) or re-pointing two DNS records.
  • Reviewers get a clickable preview per PR instead of building locally.
  • Costs: a second (tiny) D1 + KV; preview versions are free. Turnstile’s widget must list the staging hostname (Terraform).
  • Preview URLs live on workers.dev and skip the zone’s WAF/cache rules — acceptable for ephemeral, unguessable-hash review URLs; the staging hostname is the parity target.