PATTERN Cited by 1 source
PR-bot auto-deploy-request¶
Problem¶
Separating code-deploy from schema-deploy ( decoupled deploy) is architecturally correct but operationally expensive:
- Engineers must remember to create a separate schema-change unit on the database platform for every PR that touches the schema.
- The code PR and the schema change live in different tools; reviewers lose the cross-context when they look at one or the other.
- Every schema change needs a class-of-change analysis to determine deploy order; asking every engineer to internalise this is a high-friction ask.
The pattern's goal is to keep the decoupling while eliminating the operational overhead.
Shape¶
A CI bot watches every pull request and auto-creates the schema-change unit on the database platform when it detects schema-affecting diffs. Five primitives:
- Schema-change detection — the bot watches for
file changes that indicate a schema change (e.g.
Rails migration files under
db/migrate/,atlas.hclupdates,schema.sqlpatches). - Isolated schema-change target — the bot creates a branch on the database platform that mirrors the git branch, so the schema change can be tested without affecting any other work.
- Execute migration — the bot runs the migration against the database branch, surfacing any errors as PR-comment feedback.
- Open deploy-request — the bot creates the platform's first-class schema-change unit (e.g. PlanetScale's deploy request).
- Post link back on PR — so reviewers can jump directly from the code PR to the schema-change unit and review both together.
The skeleton is CI watches diff → detects schema-affecting change → creates isolated schema-change unit → executes migration on that unit → comments link back on PR.
Canonical instance: PlanetScale's internal Rails workflow¶
Mike Coutermarsh's 2024 post canonicalises the pattern in use on PlanetScale's own Rails API:
"We've built a 'pull request bot' with GitHub Actions that will detect any schema changes that need to be made as a part of a pull request. When it sees changes, it will create a PlanetScale branch, run the migrations, open a deploy request (PlanetScale's method for making a schema change) and comment the result in GitHub."
(Source: sources/2026-04-21-planetscale-how-planetscale-makes-schema-changes)
Substrate variables:
- CI — GitHub Actions.
- Database platform — PlanetScale.
- Migration executor —
planetscale_railsgem. - Detection heuristic — files under
db/migrate/(Rails convention).
Second-order value: class-of-change instruction¶
Because the bot has already parsed the migration, it can classify the change and emit the appropriate deploy-order instruction as a PR comment:
"With our bot, we are able to use the PlanetScale API to detect the class of changes being made to the database. The bot then generates comments based on the characteristics of the changes, including instructions for the sequence of steps needed to make the change safely for our application."
Two rules Coutermarsh names explicitly:
- "When removing a column, application code must be deployed before the schema is changed"
- "When adding a column, application code must be deployed after the schema is changed"
The PR reviewer reads the rule in the bot comment rather than having to remember expand-migrate- contract for every diff.
Third-order value: co-located review¶
The two deploy units (code + schema) execute independently but are reviewed together. The PR-bot comment is the link that makes this work: reviewers click from the code-change PR to the schema-change deploy request and back. Without the bot, the two units would live in separate tools with no explicit linkage.
"This allows our team to review both the schema change as well as the code. Giving full context around why and what is being changed."
Substrate independence¶
Coutermarsh's final paragraph generalises the pattern:
"We've implemented our bot using GitHub Actions, however a similar workflow can be achieved with other CI tools as well. On the PlanetScale side, all of the API calls needed are available via the
pscaleCLI."
The pattern works with any combination of:
- CI tools: GitHub Actions, Buildkite, CircleCI, GitLab CI.
- Database platforms: PlanetScale, Atlas-managed databases, any platform with a schema-change API.
- Languages/frameworks: Rails, Django, Node/Prisma, Go migrations, any framework with a conventional migration file layout.
The invariant is the skeleton: detect-diff → isolate-target → execute → report.
Composition¶
- With local MySQL CI — CI runs the migration twice: once against local MySQL (for fast feedback), once against the database-branch (for production-topology verification).
- With schema-change queue — when multiple PRs submit deploy requests concurrently, the queue serialises them + runs combined-lint.
- With patterns/expand-migrate-contract — the bot's deploy-order instruction is a PR-time output of the underlying expand-migrate-contract discipline.
Trade-offs¶
- Bot implementation complexity — the bot must know the migration file layout (framework-specific), call the database platform's API correctly, handle auth, and emit class-of-change comments in the right shape.
- Detection false-negatives — a schema change smuggled into a non-standard file path won't trigger the bot; the bot is as good as its detection heuristic.
- False-positives — renaming a migration file or
touching
db/migrate/for a non-schema reason may trigger spurious deploy requests. - Deploy-order instruction requires API support — the pattern assumes the database platform can classify a change via its API; this is PlanetScale- specific and may not be available on every platform.
- Coupling to the bot as single point of failure — if the bot breaks, engineers fall back to creating deploy requests by hand, which is the pre-bot workflow.
Seen in¶
- sources/2026-04-21-planetscale-how-planetscale-makes-schema-changes
— canonical disclosure, PlanetScale's internal Rails
API. GitHub Actions bot +
planetscale_railsgem + PlanetScale API + PR-comment class-of-change instruction.
Related¶
- systems/github-actions
- systems/planetscale
- systems/vitess
- systems/planetscale-rails-gem
- concepts/deploy-request
- concepts/schema-change-deploy-order
- concepts/schema-change-queue
- concepts/coupled-vs-decoupled-database-schema-app-deploy
- patterns/expand-migrate-contract
- patterns/local-mysql-ci-for-fast-tests
- companies/planetscale