fix(ci): skip the snapshot and apply when no migrations are pending - #295
Merged
Conversation
The migrate job runs whenever a push touches db/migrations/** and on every manual dispatch (a dispatch has no diff, so detect-changes assumes migrate=true). Neither means anything is actually pending -- CI can't know that until it connects. With nothing pending the apply was already a harmless no-op, but the job still took an RDS snapshot and waited for it: 1-2 minutes per deploy, and junk churning through the 5-snapshot retention. The migrate:status preflight already knows the count, so parse it and gate the snapshot and the apply on it. Unparseable output falls through as "1" so the safe path (snapshot first) is taken. Pruning now only runs when a snapshot was actually created. `up` being skipped is a success as far as the deploy is concerned, so the result artifact and the Slack step report success rather than the raw 'skipped' -- otherwise slack-deploy's finalize would mark the whole run failed. The Slack step and the job summary say "nothing pending" instead of claiming migrations were applied. The baseline tripwire still runs unconditionally. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nourshoreibah
marked this pull request as ready for review
July 29, 2026 05:14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The
migratejob fires whenever a push touchesdb/migrations/**and on every manual dispatch — a dispatch has no diff, sodetect-changesassumesmigrate=true:Neither condition means anything is actually pending; CI can't know that until it connects to the database.
With nothing pending the apply was already a harmless no-op (
database is already up to date), but the job still took an RDS snapshot and waited for it — 1-2 minutes per deploy, and junk churning through the 5-snapshot retention window. Both of the manual dispatches on566ffa4hit exactly this path.What
migrate:statusalready runs as a read-only preflight and already prints the count, so parse it and gate on it:pending == 01, so the safe path (snapshot first) is takenReporting
upbeing skipped is a success as far as the deploy is concerned, so the result artifact and the Slack step reportsuccessrather than the rawskipped— otherwiseslack-deploy'sfinalizewould mark the whole run failed, since it fails on any.metathat isn'tsuccess. The Slack step name and the job summary say "nothing pending" instead of claiming migrations were applied.A missing
migrate.logis fine: the result step falls back tostatus.log, andslack-deployalready wraps itsdetails-fileread in a try/catch.Verification
The count parser, against real
migrate:statusoutput:1 applied, 0 pending0→ skips1 applied, 1 pending1→ runs3 applied, 12 pending12→ runs1→ runs (safe default)Resulting step conditions:
Production was adopted separately (ledger now holds
0000_baseline_schema,1 applied, 0 pending), so on currentmainthis job takes thepending == 0path — which is what this PR makes cheap.🤖 Generated with Claude Code