Docs/Integrate/Gate a PR in CI
OSS

Gate a PR in CI

On GitHub, start with the official DBLift Action (uses: dblift/action@v1). It installs the pip package and runs migrate, validate, or info. Other runners stay pip install plus a DBLift command.

The Action does not start a database. Every command needs a reachable one — these recipes supply an ephemeral Postgres service and pass the connection through DBLIFT_DB_URL.

oss · migrate · validate · info

GitHub Actions

dblift/action — command is migrate, validate, or info (ignored when args is set). args is raw CLI passthrough and overrides command. extras defaults to postgresql. Python defaults to 3.11.

.github/workflows/dblift.yml

yaml
name: Database migrations on: pull_request jobs: migrate: runs-on: ubuntu-latest env: DBLIFT_DB_URL: postgresql+psycopg://dblift:dblift@localhost:5432/dblift services: postgres: image: postgres:16 env: POSTGRES_USER: dblift POSTGRES_PASSWORD: dblift POSTGRES_DB: dblift ports: - 5432:5432 options: >- --health-cmd "pg_isready -U dblift -d dblift" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v5 - uses: dblift/action@v1 with: command: migrate extras: postgresql

Applying the migrations to the ephemeral Postgres service above is the check: dblift's migrate validates before it applies, so a bad checksum or a broken ordering fails the job rather than being written to the database.

Set pr-comment: true to post the pending migration plan as a pull request comment. That needs permissions: pull-requests: write on the workflow or job. On fork PRs the token is read-only, so the Action falls back to the job's step summary. The plan is rendered before the command runs, so command: migrate with pr-comment: true comments the pending set at job start, then applies it. args suppresses the pr-comment plan render.

sql is populated only when pr-comment: true and args is empty. pending-count is empty when args is set or the pending probe fails. Reading exit-code from a later step requires continue-on-error: true on the Action step; otherwise a non-zero dblift status fails the job immediately and later steps never see the output.

Validate on pull requests that touch migrations

yaml
on: pull_request: paths: - 'migrations/**' jobs: validate: runs-on: ubuntu-latest env: DBLIFT_DB_URL: postgresql+psycopg://dblift:dblift@localhost:5432/dblift services: postgres: image: postgres:16 env: POSTGRES_USER: dblift POSTGRES_PASSWORD: dblift POSTGRES_DB: dblift ports: - 5432:5432 options: >- --health-cmd "pg_isready -U dblift -d dblift" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v5 - uses: dblift/action@v1 with: command: validate

validate still needs a reachable database. The Action does not start one.

Without the Action

Pip-install on the runner when you are not using the Action:

yaml
name: dblift on: pull_request: paths: ["migrations/**"] jobs: validate: runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_USER: dblift POSTGRES_PASSWORD: dblift POSTGRES_DB: dblift ports: ["5432:5432"] options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 env: DBLIFT_DB_URL: postgresql+psycopg://dblift:dblift@localhost:5432/dblift steps: - uses: actions/checkout@v5 - uses: actions/setup-python@v5 with: python-version: "3.11" cache: pip - run: pip install "dblift[postgresql]" - run: dblift migrate - run: dblift validate - run: dblift info

GitLab CI

.gitlab-ci.yml

yaml
stages: [validate] validate-migrations: stage: validate image: python:3.11 services: - name: postgres:16 alias: postgres variables: POSTGRES_USER: dblift POSTGRES_PASSWORD: dblift POSTGRES_DB: dblift DBLIFT_DB_URL: "postgresql+psycopg://dblift:dblift@postgres:5432/dblift" rules: - changes: [migrations/**/*] script: - pip install "dblift[postgresql]" - dblift migrate - dblift validate - dblift info

One config, many stages

Rather than exporting a different DBLIFT_DB_URL per stage, declare the stages once under environments: in dblift.yaml and select with --env, DBLIFT_ENV, or a branch mapping under resolve.branch_map.

Pre-commit

.pre-commit-config.yaml

yaml
repos: - repo: https://github.com/dblift/dblift rev: v3.8.0 # pin to a released tag hooks: - id: dblift-validate additional_dependencies: ["dblift[postgresql]"] - id: dblift-info additional_dependencies: ["dblift[postgresql]"]

Because the hooks use language: python, pre-commit builds an isolated environment holding only the base package. Name the driver extra in additional_dependencies for the database you connect to, or the hook will have no driver. The same applies to pre-commit try-repo, locally and in CI.

No database-free lint in OSS

The hooks need a configured dblift.yaml or DBLIFT_DB_URL and a reachable database — typically the local dev database from your docker-compose.yml. Offline SQL linting is validate-sql, which is Pro.

On this page