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)
Context
Section titled “Context”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.
Decision
Section titled “Decision”- A
stagingWorker environment ([env.staging]inwrangler.toml) deploys asquarry-web-stagingonstaging.quarry.teamwith its own D1 database (marketing-site-form-submissions-staging) and sessions KV, so test submissions never touch production data. Every push tomaindeploys staging once the repo variableSTAGING_DEPLOY_ENABLED=trueis set — independent of (and well before) the productionDEPLOY_ENABLEDgate. - 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. - Environment selection happens at build time. The
@astrojs/cloudflareadapter resolveswrangler.tomlfor the environment named byCLOUDFLARE_ENVand emits the deployable config todist/server/wrangler.json; all wrangler commands target that emitted file. (Plainwrangler deployagainst the source toml does not work — it has nomain/assets.) - Staging is noindexed at the edge — a zone response-header-transform
rule sets
X-Robots-Tag: noindex, nofollowforhttp.host eq staging.quarry.team(Terraform-owned), keeping the build artifact identical across environments. - The D1 store is named
marketing-site-form-submissions(staging:…-staging), tableform_submissions— named for what it holds, not the marketing concept around it.
Consequences
Section titled “Consequences”- 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=true→wrangler 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.devand skip the zone’s WAF/cache rules — acceptable for ephemeral, unguessable-hash review URLs; the staging hostname is the parity target.