Skip to content

Commit cb1a248

Browse files
committed
feat: deploy production database migrations
1 parent dab9b83 commit cb1a248

3 files changed

Lines changed: 62 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,47 @@ jobs:
203203
apps/web/playwright-report
204204
apps/web/test-results
205205
retention-days: 7
206+
207+
production-database:
208+
name: Apply production migrations
209+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
210+
needs:
211+
- quality
212+
- routes
213+
- database
214+
- browser
215+
runs-on: ubuntu-latest
216+
timeout-minutes: 10
217+
environment: Production
218+
env:
219+
SUPABASE_POOLER_URL: postgresql://postgres.mogdmhkqkpvksvtvwdgl@aws-0-ap-southeast-2.pooler.supabase.com:5432/postgres
220+
221+
steps:
222+
- name: Check out repository
223+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
224+
225+
- name: Set up Node.js
226+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
227+
with:
228+
node-version-file: .node-version
229+
230+
- name: Set up Supabase CLI
231+
uses: supabase/setup-cli@46f7f98c7f948ad727d22c1e67fab04c223a0520 # v3.0.0
232+
with:
233+
version: 2.114.0
234+
235+
- name: Prepare production database connection
236+
env:
237+
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DB_PASSWORD }}
238+
run: >-
239+
node -e 'const fs = require("node:fs"); const url = new
240+
URL(process.env.SUPABASE_POOLER_URL); url.password =
241+
process.env.SUPABASE_DB_PASSWORD;
242+
fs.appendFileSync(process.env.GITHUB_ENV,
243+
`SUPABASE_DB_URL=${url.href}\n`);'
244+
245+
- name: Preview production migrations
246+
run: supabase db push --db-url "$SUPABASE_DB_URL" --dry-run
247+
248+
- name: Apply production migrations
249+
run: supabase db push --db-url "$SUPABASE_DB_URL" --yes

docs/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ official calendar; importing calendar events does not itself reconcile them.
214214

215215
## Delivery
216216

217-
Changes move through focused branches and pull requests. GitHub Actions checks formatting, linting, types, tests and the production build. Vercel creates preview deployments and promotes `main` after checks. Supabase schema changes remain forward-only migrations in the same pull request as their application code.
217+
Changes move through focused branches and pull requests. GitHub Actions checks formatting, linting, types, tests and the production build. Vercel creates preview deployments and promotes `main` after checks. Supabase schema changes remain forward-only migrations in the same pull request as their application code. Pull requests exercise the complete migration history locally. After every gate passes on `main`, the production database job previews and applies pending migrations through the protected GitHub `Production` environment.
218218

219219
`supabase/migrations/` is an eight-part baseline that states the schema as it
220220
is rather than the ninety-five migrations that reached it. The hosted project

supabase/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ Edit a baseline part only to correct something that has never been deployed.
3636
Once the hosted project has applied a file, changing it puts the two out of
3737
step, and a forward migration is the only way back.
3838

39+
## Production delivery
40+
41+
Pull requests rebuild and test the complete migration history against local
42+
Supabase. They never receive production credentials and cannot change the
43+
hosted database.
44+
45+
After a commit reaches `main`, GitHub Actions waits for the quality, route,
46+
database and browser gates. The `Apply production migrations` job then enters
47+
the `Production` environment, previews the pending migration plan and applies
48+
it to project `mogdmhkqkpvksvtvwdgl` with `supabase db push`. The environment
49+
must provide `SUPABASE_DB_PASSWORD` as a secret. The job constructs the
50+
percent-encoded session-pooler URL at runtime, so it does not require a broad
51+
Supabase Management API token.
52+
53+
Production migrations are forward-only. Do not edit, rename or remove a
54+
migration after it has been applied. Add a new migration to correct it.
55+
3956
`seed.sql` intentionally contains no catalogue or user fixtures. `pnpm db:reset` performs an explicitly local reset, then applies the separate preview
4057
fixture through a database client that refuses every non-loopback connection.
4158
Reapply it to an already running local stack with `pnpm db:seed:preview`.

0 commit comments

Comments
 (0)