# Deployment and rollback

GitHub Actions deploy isolated previews and the production Worker with reviewed migrations.

## Production [#production]

A push to `main` triggers `deploy-prod.yml`. Its concurrency group serializes production deployment without cancelling an in-flight run. The workflow checks out the revision, installs the frozen lockfile, applies pending database migrations, builds the Worker and deploys it with Wrangler.

`pnpm deploy` is the explicit local deployment path. It uses configured credentials and can change production state. Routine development and bundle measurement should use a build and `wrangler deploy --dry-run` instead.

## Pull request previews [#pull-request-previews]

The preview workflow uses `scripts/preview.mjs` to derive and validate an isolated Worker/database target. It ensures the preview branch/configuration, applies migrations through the named preview migration URL, builds and uploads the preview, then checks the runtime. Closing the PR cleans up the isolated resources from trusted default-branch code.

Preview isolation is a correctness boundary: a preview must never silently reuse production auth, storage or database resources. Read the workflow and isolation tests before changing naming, credentials or teardown.

## Configuration and secrets [#configuration-and-secrets]

Cloudflare API credentials authorize the workflow; Worker runtime secrets are separate. Database access, Better Auth, R2/files and optional providers must be configured for the target environment. `VITE_SITE_URL` is a public build value, not a secret. Setup and the deployment skill describe the concrete secret names and provider steps.

Hyperdrive points to Postgres with query caching disabled. R2 uses the environment’s intended bucket. The Worker owns fetch and scheduled entry points; cron runs the existing job program. Adding a feature does not require another Worker by default.

## Migrations and rollback [#migrations-and-rollback]

Migrations run before the new code is deployed. Review compatibility with the previous Worker because that version can still serve traffic while the database changes. Prefer additive changes and staged removal over a destructive migration coupled to one deploy.

To roll back code, identify the known-good Worker deployment/version in Cloudflare and use the supported Wrangler rollback command for the exact target. Verify runtime routes and scheduled behavior afterward. A Worker rollback does **not** reverse Postgres migrations, restore deleted records or undo external deliveries. Database recovery requires its own reviewed plan and backup/restore procedure.

## Verification [#verification]

Build and run the produced Worker locally, then validate the preview URL and its discovery/auth behavior before merging. Check workflow logs for migration and target selection, and production traces for job execution after deployment. Never treat a green Node dev server as workerd compatibility evidence.


## Key files [#key-files]

- [`.github/workflows/deploy-prod.yml`](https://github.com/CarlosZiegler/doro/blob/main/.github/workflows/deploy-prod.yml)
- [`.github/workflows/pr-preview.yml`](https://github.com/CarlosZiegler/doro/blob/main/.github/workflows/pr-preview.yml)
- [`scripts/preview.mjs`](https://github.com/CarlosZiegler/doro/blob/main/scripts/preview.mjs)
- [`.agents/skills/deploy-cloudflare/SKILL.md`](https://github.com/CarlosZiegler/doro/blob/main/.agents/skills/deploy-cloudflare/SKILL.md)

