· via dev.to (home feed)
Jenkins pipeline gives every pull request its own disposable Postgres branch
A developer built a Jenkins pipeline on Databricks Lakebase that spins up an instant copy-on-write Postgres branch for every pull request, tests migrations against real data, and gates promotion behind DBA approval.

A database branch for every PR
A developer has published a runnable CI setup in which every pull request gets its own disposable Postgres database: an instant, copy-on-write branch of production, created when the PR opens, tested against real rows, and torn down when the build ends. According to a post on dev.to by Harish Shenoy, the pipeline runs on Databricks Lakebase, a managed Postgres service that separates storage from compute and makes the branch a first-class object — a full clone carrying production's data, available in seconds, with an endpoint that scales to zero compute when nobody is using it.
The pain point it targets
The setup attacks a familiar problem: a single shared dev or staging Postgres that the whole team uses concurrently with no isolation. Shenoy describes half-finished migrations and casual experiments leaving the shared instance unusable by late week, while migrations that passed CI had only ever run against an empty schema. That is the deeper flaw he identifies: running migration SQL against tables with zero rows proves nothing about how the same statement behaves at production volume — the article's example is an ADD COLUMN that locked the orders table for nine minutes in production.
How the pipeline works
There are two paths, kept separate by the Jenkinsfile.
When a pull request opens, Jenkins creates a branch named for the PR (ci-pr-42 in the example) directly from production. Because the clone is copy-on-write, the branch exists immediately and carries production's data. The PR's migration is applied to that branch, the test suite runs against the resulting rows, and an always-run cleanup step deletes the branch afterward so nothing lingers and keeps consuming storage.
When code merges to main, the pipeline skips the branch-and-test stages and stops at an approval gate restricted to the DBA team. Only after a human approves does the promote stage apply the migration to production. The reviewer is not judging SQL in the abstract — they are signing off on the exact migration artifact that already survived CI against a copy of production data.
Deliberately, the Jenkinsfile merely orchestrates five shell scripts (create, migrate, test, promote, teardown), so identical commands run on a laptop and in CI. Since the logic lives in shell, the author notes the same flow works under GitHub Actions, GitLab CI, Azure DevOps, CircleCI or any other orchestrator that can execute a script.
The assertion that carries the argument
The demo project is an orders service with a handful of seeded customers. A sample migration adds a fulfillment_status column, NOT NULL with a default, plus an index. The pivotal test checks that pre-existing orders were actually backfilled with the default value. A naive NOT NULL column addition without a default would pass on an empty test schema and then break production; on a data-carrying branch, the same migration fails the test safely before it ships. For locked-down CI agents that cannot install Python dependencies, the repo ships a pure-SQL assertions file, and there is an optional Liquibase path for versioned changelogs with rollback.
Cost, alternatives and access
The article's comparison positions Aurora's fast clone as the closest alternative, with Oracle RMAN restores and SQL Server restores cast as slow — hours, in Oracle's case — and expensive to keep running. Lakebase's claimed advantages are instant copy-on-write branching, usage-based pricing with no license cost, and zero compute cost for idle environments. On the security question of letting developers spin up copies of production, Shenoy stresses that branches are isolated clones rather than access to production itself, and that authentication uses short-lived OAuth tokens from a service principal instead of a static database password in a Jenkins credential store.
Getting it running
Everything is public. The repository (harishshenoy552/lakebase-cicd on GitHub) includes screenshots of a real Jenkins run through all five stages, and the author says the full flow — bootstrap, branch, migrate, test, promote, teardown — takes about three minutes to exercise, given a Databricks workspace with Lakebase on the autoscaling tier plus the Databricks CLI, psql, jq and Python. A nine-minute video walkthrough accompanies the post.
Why it matters
Code branching became instant and essentially free over the past decade; database branching never got the same treatment, so teams papered over the gap with rituals — a staging database nobody trusts, a DBA ticket queue, a nervous Friday deploy. This pipeline replaces those rituals with something testable: migrations run against real data before anyone approves them, developers stop queuing behind a shared instance, and DBAs review a migration that has already executed rather than guessing at its blast radius. The catch is that the approach ties you to one vendor's managed Postgres. But as a working pattern for per-PR database isolation with a human promotion gate, it is a concrete, runnable reference implementation rather than a proposal.
- #postgres
- #ci-cd
- #devops
- #jenkins
- #database-branching