diff --git a/.github/workflows/release-email.yml b/.github/workflows/release-email.yml index 267e2aae..e2d4cdbd 100644 --- a/.github/workflows/release-email.yml +++ b/.github/workflows/release-email.yml @@ -81,12 +81,6 @@ jobs: echo "reason=$(node -e "console.log(JSON.parse(process.argv[1]).reason)" "$BUMP")" >> "$GITHUB_OUTPUT" echo "Bump decision: $BUMP" - - name: Apply database migrations - if: steps.bump.outputs.should_send == 'true' - run: pnpm --filter api exec prisma migrate deploy - env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - - name: Send product update email if: steps.bump.outputs.should_send == 'true' working-directory: apps/api diff --git a/docs/MARKETING-EMAIL.md b/docs/MARKETING-EMAIL.md index 1343cc22..69651793 100644 --- a/docs/MARKETING-EMAIL.md +++ b/docs/MARKETING-EMAIL.md @@ -56,19 +56,20 @@ Delivery is recorded in `MarketingReleaseEmailSend` (one row per subscriber per Pushing a semver tag `vX.Y.Z` to GitHub triggers **Release product email** when **X** (major) or **Y** (minor) increases vs the previous tag; **Z**-only (patch/hotfix) tags are skipped: 1. Resolves the previous semver tag and compares **X** and **Y** (Z-only → skip). -2. Runs `prisma migrate deploy` against production (applies pending migrations from the tagged commit, including `MarketingReleaseEmailSend`). -3. Runs `send-release-email.ts --version=X.Y.Z --previous-version=…` with repository secrets. +2. Runs `send-release-email.ts --version=X.Y.Z --previous-version=…` with repository secrets. -Required GitHub repository secrets (production): +Apply production migrations **before tagging** ([RELEASE.md](./RELEASE.md#3-database-migrations-production)); this workflow does not run `prisma migrate deploy` (GitHub Actions cannot reach Railway private `*.railway.internal` URLs). + +Required GitHub secrets in the **`production`** environment: | Secret | Purpose | |--------|---------| -| `DATABASE_URL` | Production Postgres (`MarketingSubscriber`) | +| `DATABASE_URL` | Production Postgres **public** URL (Railway TCP proxy / public host — not `postgres.railway.internal`) | | `RESEND_API_KEY` | Resend API | | `TELEMETRY_EMAIL_FROM` | From address | | `TELEMETRY_DASHBOARD_ORIGIN` | Unsubscribe / docs links (e.g. `https://telemetry-tracker.com`) | -Store these in the GitHub **`production`** environment (the workflow job uses `environment: production`). To retry a send without re-tagging, use **Actions → Release product email → Run workflow** with `version` and `previous_version`. +Store these in the GitHub **`production`** environment. To retry a send without re-tagging, use **Actions → Release product email → Run workflow** with `version` and `previous_version`. The workflow runs **after** the tag is pushed — finalize `CHANGELOG.md` on `main` **before** tagging so the email body matches the release. diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 6bf97661..f8b4fbd8 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -138,7 +138,7 @@ Always document **migrations**, **new env vars**, and **breaking changes** in CH 1. **Finalize CHANGELOG** — rename `[Unreleased]` to `[X.Y.Z] - YYYY-MM-DD`. Prefer doing this in the **`develop` → `main`** release PR so `develop` and `main` stay aligned; if you commit on `main` after promotion, you **must** sync `develop` in step 9. 2. **Deploy** — Railway rebuilds `main` automatically when the release PR merges; see [Deploy runbook](#deploy-runbook-railway). -3. **Production DB** — run [migrations](#3-database-migrations-production) **before tagging** on MINOR (Y) / MAJOR (X) releases (the [Release product email](../.github/workflows/release-email.yml) workflow also runs `prisma migrate deploy` immediately before send, but apply migrations here as part of the normal release gate). +3. **Production DB** — run [migrations](#3-database-migrations-production) **before tagging** on MINOR (Y) / MAJOR (X) releases. The release email workflow reads production Postgres but does not migrate (use the public `DATABASE_URL` in GitHub secrets — see [MARKETING-EMAIL.md](./MARKETING-EMAIL.md#automated-send-minor--major-tags)). 4. **Post-deploy** — [verification](#post-deploy-verification). 5. **Tag** — after deploy and migrations are green (tag push triggers the product update email workflow for MINOR/MAJOR — **X** or **Y** bump, not Z-only hotfixes): ```bash @@ -198,7 +198,7 @@ On push and pull requests to **`develop`** and **`main`**, CI runs ([`.github/wo ### 3. Database migrations (production) -CI does **not** migrate your production database during normal builds. Apply migrations after API deploy and **before pushing a MINOR (Y) / MAJOR (X) tag** (see [On `main` after promotion](#on-main-after-promotion)). The [Release product email](../.github/workflows/release-email.yml) workflow also runs `prisma migrate deploy` immediately before sending so delivery records can be written. +CI does **not** migrate your production database during normal builds. Apply migrations after API deploy and **before pushing a MINOR (Y) / MAJOR (X) tag** (see [On `main` after promotion](#on-main-after-promotion)). The [Release product email](../.github/workflows/release-email.yml) workflow connects to production Postgres for the send ledger only — use Railway’s **public** database URL in GitHub secrets, not `postgres.railway.internal`. ```bash DATABASE_URL="postgresql://..." pnpm --filter api exec prisma migrate deploy