Skip to main content

Deploy to production

Push code → CI runs → Worker is live.

Drafted from planning · v0.1

The deploy unit

One shop = one deploy. Each shop has its own branch (shops/{slug}), its own Worker, its own D1, its own R2. See deployment topology.

Branch model

main ← canonical code; tagged releases
shops/swicked ← Swicked's branch
shops/{N} ← one per shop

Branches deviate from main by wrangler.jsonc shop-specific bindings and (rarely) shop-overrides/{slug}/ files. Code in src/ should be identical.

Deploy a code change to all shops

Most code changes go to all shops:

# 1. Land the change on main via PR
git switch main
git pull
# review CI green

# 2. Rebase each shop branch onto main
git switch shops/swicked
git rebase main
git push --force-with-lease origin shops/swicked

# 3. CI auto-deploys on push to shops/* (deploy-shop.yml workflow)
# Watch: https://github.com/{org}/{repo}/actions

Repeat step 2-3 for each shop. A planned scripts/deploy-all-shops.ps1 will fan this out.

Deploy a shop-specific change

Rare, but happens (custom branding, shop-only feature flag):

git switch shops/swicked
# edit shop-overrides/swicked/...
git commit -am "Swicked: custom logo on receipts"
git push origin shops/swicked
# CI deploys

The change does NOT propagate to main; it stays on the shop branch.

Apply a database migration

When migrations/*.sql has new files:

# Verify locally first
wrangler d1 migrations apply helm-dev --local

# Then apply to production for each shop
wrangler d1 migrations apply helm-swicked-db --remote

CI's deploy-shop.yml runs wrangler d1 migrations apply automatically as part of the deploy.

Smoke test after deploy

CI doesn't replace human verification on prod. After a deploy:

  1. Open https://helm-swicked.kvick.bike in a browser
  2. Sign in with your PIN
  3. Click through Today, Customers, Service, Sales (whichever is built)
  4. Check Settings → Audit (when slice 1 is done) for the deploy event
  5. Watch logs for 5 minutes via wrangler tail --env swicked

If anything looks wrong, roll back (next section).

Roll back a deploy

# List recent deployments
wrangler deployments list --env swicked

# Roll back to a specific version
wrangler rollback <deployment-id> --env swicked

Rollback is ~30 seconds. The previous Worker version starts serving traffic immediately.

D1 migrations are NOT rolled back automatically — schema changes are forward-only. If a deploy includes a destructive migration, plan a hand-rolled "down migration" before pushing.

Restore D1 from backup

If something corrupted the database:

# Daily backups are in helm-swicked-assets R2 bucket under backups/db/
wrangler r2 object get helm-swicked-assets backups/db/2026-05-09.sql --file backup.sql

# Apply to a fresh DB or replace
wrangler d1 import helm-swicked-db backup.sql

For a full disaster scenario, see disaster recovery.

Onboarding a new shop

# 1. Create resources
wrangler d1 create helm-{slug}-db
wrangler r2 bucket create helm-{slug}-assets
wrangler kv:namespace create "helm-{slug}-kv" # optional

# 2. Create the shop branch
git switch -c shops/{slug} main
# edit wrangler.jsonc to add env.{slug} block with the new IDs
git commit -am "Onboard {slug}"
git push origin shops/{slug}
# CI deploys

# 3. Apply migrations + seeds (CI does this; verify)
wrangler d1 migrations apply helm-{slug}-db --remote
wrangler d1 execute helm-{slug}-db --remote --file=seed_permissions.sql

# 4. Configure Stripe + Twilio sub-accounts (manual; per-vendor flow)

# 5. Verify with the shop owner

A planned scripts/onboard-shop.sh will templatize this. Target: 2 minutes.

See also