CI/CD / DATABASE SCHEMA DRIFT DETECTION

Your code moved on.
Did your database?

Catch unexpected tables, columns, indexes, and constraints before a deployment proceeds. Use dbmt to compare an expected-state database with your target, then review the differences in your CI workflow.

Choose your license
14-DAY TRIAL

Meet your next workflow.

Choose the installer for your computer.

On a Mac, check Apple menu → About This Mac for your chip.

Trial installers are not available here yet. Please check back for the download.

$10.95 monthly or $99 yearly One developer, up to two devices

The branch switchyardWORKFLOW STUDY
The branch switchyardAn expected-state schema and a target schema meet at a CI comparison junction. A difference branches into review before deployment.EXPECTEDschemaTARGETschemadbmt compareDIFFERENCEreview before releaseDEPLOYMENTDECISION

CI / compare against the baseline you choose.

Illustration / example workflow
CI drift check · reference workflow

1. Why Schema Drift Causes Outages

Database schema drift occurs when an environment’s actual schema catalog diverges from the expected state defined in your application codebase. Common culprits include:

  • Emergency Hotfixes: An engineer adds an index or alters a column directly on production during an incident and forgets to backport the change into migration scripts.
  • Out-of-Order Branch Merges: Two feature branches branch off main, apply conflicting DDL, and get deployed in reverse order.
  • Manual DBA Maintenance: Index rebuilds, vacuum tweaks, or table partition adjustments that were not documented in source control.

When your next deployment pipeline runs, application ORMs (like Prisma, Drizzle, Hibernate, or ActiveRecord) attempt to run migrations against unexpected column structures, resulting in failed transactions, locked tables, and customer downtime.

2. Deterministic Exit Codes in dbmt

The dbmt CLI is engineered specifically for non-interactive scripting. Every command returns standard POSIX exit codes so your CI runners can make clear pass/fail decisions:

Exit Code 0 : Clean parity. Schemas are identical (in sync).
Exit Code 1 : Drift detected! Schema differences found between source and target.
Exit Code 2 : Connection error. Database unreachable, bad credentials, or SSL failure.
Exit Code 3 : Safety gate violation. Target schema modified during execution or unconfirmed drop.
PIPELINE RECIPES

Interactive CI/CD Workflow Builder

Adapt these templates for a prepared macOS runner with dbmt installed and an approved same-engine comparison profile. Review flags, exit behavior, credentials, and trigger rules for your installed version.

.github/workflows/db-drift.ymlYAML
name: Database Schema Drift Gate
on:
  pull_request:
    branches: [main]
    paths:
      - 'migrations/**'
      - 'schema/**'

jobs:
  verify-schema:
    runs-on: [self-hosted, macOS]
    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Check prepared dbmt installation
        run: dbmt --version

      - name: Check Schema Drift Against Staging
        env:
          DBMIGRATE_MASTER_KEY: ${{ secrets.DBMIGRATE_MASTER_KEY }}
          TARGET_DB_URL: ${{ secrets.STAGING_DATABASE_URL }}
        run: |
          # Configure branch protection and command exit behavior for your workflow
          dbmt compare --profile staging-sync

3. GitHub Actions Integration

Start with a manually triggered workflow on a prepared macOS runner. Configure your approved profile and review the installed command behavior before adding pull-request or deployment triggers:

name: Database Schema Review

on:
  workflow_dispatch:

jobs:
  compare:
    # Prepare dbmt, database access, and an approved profile on this runner.
    runs-on: [self-hosted, macOS]
    steps:
      - name: Check installed version
        run: dbmt --version
      - name: Compare the approved profile
        run: dbmt compare --profile ci-staging-check

4. GitLab CI Pipeline Example

Use a prepared macOS shell runner tagged macos and dbmt. Adapt the profile, credentials, and job policy before adding this example to .gitlab-ci.yml:

stages: [database-review]

schema_review:
  stage: database-review
  tags: [macos, dbmt]
  # Prepare dbmt, database access, and the comparison profile on this runner.
  script:
    - dbmt --version
    - dbmt compare --profile ci-staging-check
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

5. Automated PR Commenting

When dbmt compare catches differences, you can automatically post the planned synchronization DDL as a comment on the pull request. This lets database administrators and tech leads review the exact ALTER TABLE and CREATE INDEX statements before approving the PR.

6. Production Protection Controls

Even in headless CI environments, dbmt respects connection protection profiles:

  • Pre-Apply Snapshot: On high-protection targets, dbmt apply automatically takes a schema snapshot before executing DDL.
  • Destructive Statement Gates: If a sync plan contains DROP TABLE or DROP COLUMN, execution requires the explicit flag --allow-destructive to prevent accidental data loss.
  • Re-Check Target Parity: Immediately before running the first SQL statement, dbmt re-checks the target schema catalog. If another transaction changed the database, execution aborts with exit code 3.
AUTOMATION QUESTIONS

CI/CD integration FAQs.

How does dbmt detect schema drift in CI/CD workflows?

dbmt inspects the live system catalogs of your source database (for example, an expected-state database built from migration history) and target (e.g. pre-production or production DB). If any table structure, index, foreign key, or column definition differs, dbmt outputs a structured diff and terminates with exit code 1, immediately halting the CI/CD pipeline before bad changes deploy.

What deterministic exit codes does dbmt return?

dbmt returns standardized POSIX exit codes: 0 means schemas are completely in sync; 1 indicates drift was detected (differences found); 2 signifies a connection or authentication failure; and 3 means a safety policy gate failed (e.g., target schema changed during execution or destructive drop detected without override).

Can dbmt generate migration plans headlessly in CI?

Yes. With `dbmt plan --profile pr-check --out ./drift-plan.sql`, dbmt generates the complete, dependency-ordered synchronization DDL. You can attach this SQL file as an artifact or post it as a comment on pull requests for developer review.

How are database credentials secured in CI runners?

You can pass connection strings via standard environment variables (e.g. DBMIGRATE_TARGET_URL) using GitHub Actions Secrets or GitLab CI Masked Variables. Alternatively, you can use pre-configured profiles encrypted with AES-256-GCM unlocked via a single master password secret.