Skip to content

Deploy

nowyourlink ships from main. There is one production environment (nowyourlink.com) and one preview environment (*.preview.nowyourlink.com) per spec 13 §8.

  1. Open a PR against main. Branch from origin/main; CI runs the spec-13 gate suite on every push. main is protected — no direct pushes.
  2. Pass the gates. All required checks must be green. Branch protection currently requires one approving review (required_approving_review_count = 1 in infra/terraform/github.tf). Spec 13 §7 targets two on the high-risk CODEOWNERS paths (apps/api/auction-*, apps/api/saga-*, apps/api/payment-*, packages/saga/**, packages/auction-engine/**, packages/legal/**, infra/terraform/**); the count bumps to 2 once a second human is on the rotation. The terraform comment is the single source of truth.
  3. Get an approval. Code-owner review is mandatory; stale reviews are dismissed when the diff changes.
  4. Merge with a linear-history squash. Tag-protection prevents force-push or deletion of v* tags (see infra/terraform/github.tf).
  5. Trigger deploy. Today the Deploy workflow is workflow_dispatch only (issue #16 wires it to the push-on-main gate). Run it from the Actions tab against main. The workflow applies Terraform’s app resources, deploys every Worker in dependency order via wrangler deploy --env production, then re-applies Terraform.

main requires every one of these to be green on the head SHA (canonical list in local.required_status_checks in infra/terraform/github.tf — that resource is the single source of truth):

  • ci — lint, typecheck, test, build (Turbo orchestrates)
  • lint-seo — Astro SEO regression suite
  • spec-check — spec front-matter linter
  • security-scan / audit — pnpm audit --audit-level=moderate
  • security-scan / gitleaks — secret scanner
  • security-scan / codeql — static analysis

Spec 13 §7 also lists lighthouse-ci / perf-budget (gated to PRs touching apps/web), but it is not enforced today — the workflow exists but the context is not in required_status_checks. It will join the gate once perf-budget assertions stabilise. Until then, treat a red lighthouse-ci as advisory.

apps/web ships first because its service_name is referenced by sibling Workers via script_name bindings. Each wrangler deploy is wrapped in a 3-attempt retry — Cloudflare’s API occasionally 5xxs.

web → api → admin → queue → cron → webhook

If a deploy step fails after three attempts the workflow stops; later steps are skipped. Re-run the job; check the worker’s Cloudflare deployment logs for the underlying error before retrying a third time.

  • Custom-domain TLS verification — minutes after the first apply of a cloudflare_pages_domain. Not blocking but the docs site can serve Issuing certificate for the first window after a docs domain change. See PR #65 carry-forward.
  • Stripe webhook secret rotation — manual via Stripe dashboard + wrangler secret put STRIPE_WEBHOOK_SECRET --env production.
  • Terraform state migrations — apply locally with terraform -chdir=infra/terraform apply after a terraform init to refresh the lock.

PRs that touch apps/**, packages/**, or infra/terraform/** trigger the Preview workflow. It applies preview-environment Terraform targets, then deploys every Worker to *.preview.nowyourlink.com. No production verification — preview URLs vary per PR and are not part of the public domain contract.