Flyway · PostgreSQL 13+ · GitHub Actions

Test Flyway migrations against production before you merge

A green flyway migrate in CI proves your scripts run on an empty database. DbProof runs it on a copy of production's schema, with its row statistics, on every pull request, and says what would fail or lock in production.

How it works with Flyway

Real flyway migrate, against production's shape

Connect a repository and DbProof finds your V…__…sql folder, in src/main/resources/db/migration or anywhere else, and opens a pull request with the workflow.

Restore production's shape

The check starts a throwaway Postgres on production's major version in your runner and restores the latest snapshot of production's schema and flyway_schema_history.

Apply one version at a time

Flyway runs with -target for each new version in turn, so a finding names the script that caused it.

Weigh it against production

DbProof compares the result with production's statistics and reports on the pull request as a check and a comment, with the script, the line and a suggested fix.

The setup pull request runs Flyway's own Docker image, so the check needs no Java build:

- uses: dbproof/check-action@v1
  with:
    project: your-org/billing
    migrations-dir: db/migration
    migrate-command: >-
      docker run --rm --network host -v "$PWD/db/migration:/flyway/sql"
      flyway/flyway:11-alpine -url="$DBPROOF_CHECK_JDBC_URL"
      -user="$DBPROOF_CHECK_USER" -password="$DBPROOF_CHECK_PASSWORD"
      -locations=filesystem:/flyway/sql migrate
Findings

What the check reports

Each finding names the migration file and line, says what production would do, and suggests a fix. Errors fail the check; warnings don’t.

error

NOT NULL on a column with nulls

Production's statistics show nulls, so SET NOT NULL fails mid-deploy. DbProof suggests a backfill and a V145_1__enforce_… script that follows it.

error

Migration fails to apply

A hotfix already added the column in production. DbProof shows Postgres's error from Flyway's output, on the pull request.

warning

Index built without CONCURRENTLY

Writes to a large table blocked while the index builds. The fix builds it concurrently, in a script Flyway runs outside a transaction (executeInTransaction=false).

warning

Table rewrite on a table over 1M rows

A type change that rewrites the whole table while holding its lock.

warning

Version used by another open pull request

Two pull requests both add V145. Whichever merges second fails on deploy.

error

An applied script edited

Someone changed a script production already ran, which Flyway's validation rejects on the next deploy.

warning

Foreign key without an index

Every delete from the parent scans the child table.

drift

Production changed outside migrations

DbProof opens a pull request with a V…__adopt_… script on the next free version, so history catches up with production.

What leaves production

Structure and statistics, never rows

A capture step in your deploy job reads production with the connection string your migrations already use, and uploads a snapshot.

What capture reads

  • The catalog: tables, columns, indexes, constraints, views and functions
  • Planner estimates: row counts, and each column's share of nulls, distinct values and width
  • flyway_schema_history, with installed_by, the database user, replaced before upload

What it never reads

  • Rows from any of your tables
  • Sample values: no most-common values, no histograms
  • Your connection string: it stays in your GitHub secrets
FAQ

Flyway questions

Spring Boot runs Flyway at startup. Does that work?

Checks do: they only need the migrations folder. Capture runs on a schedule every six hours, and in your deploy job if you add its two steps; capturing from application startup is coming later.

Repeatable migrations?

Yes. DbProof tracks R__ scripts in production's history, so a deploy that only changes a view isn't mistaken for drift.

Java-based migrations?

Not yet. The check applies SQL scripts; a Java migration isn't run.

Does DbProof connect to my database?

No. Capture runs in your deploy job, and checks run against a throwaway Postgres in your runner. DbProof only receives the snapshot.

Find out what your next Flyway migration does to production

Connect a repository in a few minutes. Free during the beta.