pgsafe
Static safety linter for PostgreSQL DDL migrations. pgsafe parses SQL and flags schema
changes likely to lock or break production — no database connection, no network.
📖 Full documentation, the rules reference, and an in-browser playground: pgsafe.fixedwidth.tech
Install
Install from crates.io with a Rust toolchain:
Or download a prebuilt binary from the latest release
(static Linux and macOS), or build from source with cargo build --release (binary at
target/release/pgsafe).
Quickstart
Applying fixes
Findings that have an unambiguous mechanical rewrite carry a fix. Preview them:
The output is a standard unified diff, so it pipes straight into git apply:
|
Apply them in place (or to stdout when reading stdin):
--fix and --diff are human-output only and cannot be combined with each other
or with --format json/--format github/--format sarif. A -- pgsafe:ignore finding is never
auto-fixed. After --fix, the exit code reflects re-linting the fixed file.
Run it in CI with the GitHub Action:
- uses: fixed-width/pgsafe@v0.8.6
with:
files: "db/migrate/*.sql"
SARIF output (GitHub code scanning)
--format sarif emits SARIF 2.1.0, for upload to GitHub code scanning:
- run: pgsafe --format sarif db/migrate/*.sql > pgsafe.sarif
- uses: github/codeql-action/upload-sarif@v3
# pgsafe exits non-zero when findings gate, so upload the results regardless:
if: always()
with:
sarif_file: pgsafe.sarif
Findings (including -- pgsafe:ignore-suppressed ones, marked dismissed) become SARIF
results; a file that fails to parse becomes a tool-execution notification.
A findings run (exit 1) and a parse error (exit 2) both still write valid SARIF, so
if: always() uploads the results in the common cases. A configuration or I/O error
(e.g. an unreadable path) exits 2 without writing SARIF — the resulting 0-byte file
then (correctly) fails the upload. Pass repo-relative migration paths: absolute paths and
stdin don't map back to files GitHub can annotate as code-scanning alerts.
See pgsafe.fixedwidth.tech/docs for configuration, output formats, and the full rules reference.
Changelog
Notable changes for each release are in CHANGELOG.md.
License
Apache-2.0. See LICENSE.