Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,47 @@ jobs:
apps/web/playwright-report
apps/web/test-results
retention-days: 7

production-database:
name: Apply production migrations
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs:
- quality
- routes
- database
- browser
runs-on: ubuntu-latest
timeout-minutes: 10
environment: Production
env:
SUPABASE_POOLER_URL: postgresql://postgres.mogdmhkqkpvksvtvwdgl@aws-0-ap-southeast-2.pooler.supabase.com:5432/postgres

steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .node-version

- name: Set up Supabase CLI
uses: supabase/setup-cli@46f7f98c7f948ad727d22c1e67fab04c223a0520 # v3.0.0
with:
version: 2.114.0

- name: Prepare production database connection
env:
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DB_PASSWORD }}
run: >-
node -e 'const fs = require("node:fs"); const url = new
URL(process.env.SUPABASE_POOLER_URL); url.password =
process.env.SUPABASE_DB_PASSWORD;
fs.appendFileSync(process.env.GITHUB_ENV,
`SUPABASE_DB_URL=${url.href}\n`);'

- name: Preview production migrations
run: supabase db push --db-url "$SUPABASE_DB_URL" --dry-run

- name: Apply production migrations
run: supabase db push --db-url "$SUPABASE_DB_URL" --yes
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ official calendar; importing calendar events does not itself reconcile them.

## Delivery

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.
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.

`supabase/migrations/` is an eight-part baseline that states the schema as it
is rather than the ninety-five migrations that reached it. The hosted project
Expand Down
17 changes: 17 additions & 0 deletions supabase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ Edit a baseline part only to correct something that has never been deployed.
Once the hosted project has applied a file, changing it puts the two out of
step, and a forward migration is the only way back.

## Production delivery

Pull requests rebuild and test the complete migration history against local
Supabase. They never receive production credentials and cannot change the
hosted database.

After a commit reaches `main`, GitHub Actions waits for the quality, route,
database and browser gates. The `Apply production migrations` job then enters
the `Production` environment, previews the pending migration plan and applies
it to project `mogdmhkqkpvksvtvwdgl` with `supabase db push`. The environment
must provide `SUPABASE_DB_PASSWORD` as a secret. The job constructs the
percent-encoded session-pooler URL at runtime, so it does not require a broad
Supabase Management API token.

Production migrations are forward-only. Do not edit, rename or remove a
migration after it has been applied. Add a new migration to correct it.

`seed.sql` intentionally contains no catalogue or user fixtures. `pnpm db:reset` performs an explicitly local reset, then applies the separate preview
fixture through a database client that refuses every non-loopback connection.
Reapply it to an already running local stack with `pnpm db:seed:preview`.
Expand Down
Loading