Q37 of 38 · CI/CD & DevOps

How do you test database schema migrations in a CI pipeline without risking production data?

CI/CD & DevOpsSeniorci-cddatabasemigrationsschemapostgrestesting

Short answer

Short answer: Run migrations against a schema-identical ephemeral database in CI. Test forward migration, rollback migration, and idempotency. Use a migration linter to catch destructive operations before they reach any shared environment.

Detail

Database migrations are the highest-risk part of most deployments because some are irreversible. A CI strategy for migrations has three layers.

Pre-merge lint: run a migration linter (Squawk for PostgreSQL, gh-ost dry-run for MySQL) to catch dangerous patterns — adding a NOT NULL column without a default to a large table, dropping a column still referenced in code, or missing an index on a foreign key.

Migration test: spin up a Docker container with the current production schema snapshot, run the new migration, assert the resulting schema matches expectations (snapshot test or explicit column assertions), then run the rollback migration and assert the schema returns to the original state.

Data integrity test: seed a subset of production-like data, run the migration, and verify the data is not silently corrupted. Schema-only tests miss issues like a VARCHAR length reduction that truncates existing values without error.

Migration files must be immutable after merge — only new migrations can fix problems. Enforce this with a CI check that hashes committed migration files and fails if an existing file is modified.

// WHAT INTERVIEWERS LOOK FOR

Three-layer approach: lint, schema test, data integrity test. Rollback testing as a first-class concern. Immutable migration files enforced by CI hash check.