-
Notifications
You must be signed in to change notification settings - Fork 2.9k
docs: add pgfence migration safety check to CI/CD workflow #10813
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| --- | ||
| description: Add migration safety checks to your Hasura CI/CD pipeline with pgfence | ||
| keywords: | ||
| - hasura | ||
| - docs | ||
| - ci-cd | ||
| - migrations | ||
| - safety | ||
| - postgres | ||
| - locks | ||
| - pgfence | ||
| sidebar_label: Migration safety checks | ||
| sidebar_position: 50 | ||
| --- | ||
|
|
||
| import ProductBadge from '@site/src/components/ProductBadge'; | ||
|
|
||
| # Migration Safety Checks | ||
|
|
||
| <ProductBadge free pro ee /> | ||
|
|
||
| ## Introduction | ||
|
|
||
| When deploying Hasura Migrations to production, certain SQL statements can acquire aggressive Postgres locks that block | ||
| reads and writes for the duration of the operation. On large tables, this can cause downtime or cascading lock queue | ||
| failures. | ||
|
|
||
| [pgfence](https://pgfence.com) is an open-source CLI that analyzes your migration SQL files **before deployment** and | ||
| reports which lock modes each statement acquires, the associated risk level, and safe rewrite alternatives when a | ||
| dangerous pattern is detected. | ||
|
|
||
| Adding pgfence to your CI/CD pipeline catches problems like non-concurrent index creation, unsafe column type changes, | ||
| and missing `lock_timeout` settings before they reach production. | ||
|
|
||
| ## What pgfence detects | ||
|
|
||
| pgfence checks for common Postgres migration footguns, including: | ||
|
|
||
| | Pattern | Risk | Why it's dangerous | | ||
| |---------|------|--------------------| | ||
| | `CREATE INDEX` (non-concurrent) | Medium | Acquires a `SHARE` lock, blocking all writes | | ||
| | `ALTER COLUMN TYPE` | High | Requires `ACCESS EXCLUSIVE` lock and full table rewrite | | ||
| | `ADD COLUMN ... NOT NULL` without `DEFAULT` | High | `ACCESS EXCLUSIVE` lock on the entire table | | ||
| | `ADD CONSTRAINT ... FOREIGN KEY` (inline) | High | Locks both tables with `ACCESS EXCLUSIVE` | | ||
| | `DROP TABLE` / `TRUNCATE` | Critical | `ACCESS EXCLUSIVE` lock, irreversible | | ||
| | Missing `SET lock_timeout` | Policy | No timeout means unbounded lock waits | | ||
|
|
||
| For each issue found, pgfence provides the safe alternative — for example, `CREATE INDEX CONCURRENTLY` instead of | ||
| `CREATE INDEX`, or the `NOT VALID` + `VALIDATE CONSTRAINT` pattern for foreign keys. | ||
|
|
||
| ## Add pgfence to a GitHub Actions workflow | ||
|
|
||
| If you use [GitHub Actions](https://github.com/features/actions) to deploy Hasura Migrations (as recommended for | ||
| production in the | ||
| [GitHub integration docs](/cloud-ci-cd/github-integration.mdx)), you can add pgfence as a step that runs before | ||
| applying migrations. | ||
|
|
||
| ### Basic workflow | ||
|
|
||
| Add the following step to your existing workflow file (e.g., `.github/workflows/hasura-deploy.yml`) **before** the step | ||
| that applies migrations: | ||
|
|
||
| ```yaml | ||
| - name: Check migration safety | ||
| run: npx --yes @flvmnt/pgfence@0.2.3 analyze --ci hasura/migrations/**/*.sql | ||
| ``` | ||
|
Comment on lines
+64
to
+66
|
||
|
|
||
| The `--ci` flag causes pgfence to exit with code 1 if any check exceeds the default risk threshold, which will fail the | ||
| workflow and prevent the deployment. | ||
|
|
||
| ### Full example workflow | ||
|
|
||
| ```yaml | ||
| name: Hasura Deploy | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - 'hasura/migrations/**' | ||
| - 'hasura/metadata/**' | ||
|
|
||
| jobs: | ||
| deploy: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Check migration safety | ||
| run: npx --yes @flvmnt/pgfence@0.2.3 analyze --ci hasura/migrations/**/*.sql | ||
|
|
||
|
Comment on lines
+89
to
+91
|
||
| - name: Apply migrations | ||
| run: hasura migrate apply --endpoint ${{ secrets.HASURA_ENDPOINT }} --admin-secret ${{ secrets.HASURA_ADMIN_SECRET }} | ||
|
|
||
| - name: Apply metadata | ||
| run: hasura metadata apply --endpoint ${{ secrets.HASURA_ENDPOINT }} --admin-secret ${{ secrets.HASURA_ADMIN_SECRET }} | ||
| ``` | ||
|
|
||
| ### Controlling the risk threshold | ||
|
|
||
| By default, `--ci` fails the build on `HIGH` risk or above. You can adjust this with `--max-risk`: | ||
|
|
||
| ```yaml | ||
| - name: Check migration safety | ||
| run: npx --yes @flvmnt/pgfence@0.2.3 analyze --ci --max-risk medium hasura/migrations/**/*.sql | ||
| ``` | ||
|
Comment on lines
+104
to
+106
|
||
|
|
||
| This will fail the build on `MEDIUM` risk or above, catching issues like non-concurrent index creation. | ||
|
|
||
| ### JSON output for further processing | ||
|
|
||
| To integrate pgfence results into other tools or dashboards, use the `--output json` flag: | ||
|
|
||
| ```yaml | ||
| - name: Check migration safety | ||
| run: npx --yes @flvmnt/pgfence@0.2.3 analyze --output json hasura/migrations/**/*.sql > pgfence-report.json | ||
| ``` | ||
|
Comment on lines
+115
to
+117
|
||
|
|
||
| ## Adjusting migration paths | ||
|
|
||
| Hasura stores migrations under `hasura/migrations/<source-name>/<timestamp>_<name>/up.sql` by default. Adjust the glob | ||
| pattern to match your project structure: | ||
|
|
||
| ```yaml | ||
| # Single data source named "default" | ||
| run: npx --yes @flvmnt/pgfence@0.2.3 analyze --ci hasura/migrations/default/**/up.sql | ||
|
|
||
| # All data sources | ||
| run: npx --yes @flvmnt/pgfence@0.2.3 analyze --ci hasura/migrations/**/up.sql | ||
| ``` | ||
|
|
||
| ## Further resources | ||
|
|
||
| - [pgfence documentation](https://pgfence.com) | ||
| - [pgfence on npm](https://www.npmjs.com/package/@flvmnt/pgfence) | ||
| - [pgfence on GitHub](https://github.com/flvmnt/pgfence) | ||
| - [PostgreSQL explicit locking documentation](https://www.postgresql.org/docs/current/explicit-locking.html) | ||
| - [Hasura Migrations Best Practices](/migrations-metadata-seeds/migration-best-practices.mdx) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This documentation page is missing the ProductBadge component that is consistently included in all other pages in the cloud-ci-cd section. Add the import statement and ProductBadge component after the main heading to match the pattern used in other files like github-integration.mdx, preview-apps.mdx, and regression-tests.mdx.