fix(migrations): adopt sqlx reversible up/down format and revert tooling (#58) - #63
Open
heymide wants to merge 1 commit into
Open
fix(migrations): adopt sqlx reversible up/down format and revert tooling (#58)#63heymide wants to merge 1 commit into
heymide wants to merge 1 commit into
Conversation
Author
|
Note on CI: the new \migrations.yml\ workflow won't report a check on this PR itself — GitHub only executes workflows that already exist on the default branch, and this is a new file coming from a fork. It will run on \main\ after merge (\on: push). The smoke test has been run and passed locally against PostgreSQL 17 in the meantime (see Verification above). |
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.
Summary
Fixes #58 — adopts sqlx's reversible migration format for the whole
migrations/directory, adds a.down.sqlfor every migration, documents the one intentionally-irreversible piece (migration 010's enumADD VALUE) with an operator runbook, and wiressqlx migrate revertinto the developer tooling with a CI smoke test that proves it works.What changed
Migrations — reversible format, backward-compatible retrofit
NNN_name.sql→NNN_name.up.sqlfor all 11 migrations. The SQL payload is byte-for-byte unchanged (git reports 100% similarity renames, 0 insertions/deletions).NNN_name.down.sqlfor all 11 migrations. 001–009 and 011 are clean, unconditional reversals (drop table/index/column/type in correct dependency order). Two index-name collisions across migrations (002/005idx_users_stellar_address, 002/010idx_transactions_stellar_tx_hash) are handled by ownership: the later migrations' statements were runtime no-ops, so their down scripts do not drop those indexes (documented inline).ALTER TYPE transaction_status ADD VALUE 'submitted_unconfirmed'is irreversible — Postgres has noALTER TYPE … DROP VALUE. Its.down.sqlreverses the reversible parts (dropsbatch_submissions, restores the UNIQUE constraint — which intentionally fails loudly if batch legs share a hash, aborting the revert transaction safely) and carries a full operator runbook for removing the orphan enum value (create-new-type → migrate columns viastatus::textcast → swap → drop old type). The runbook lives in the.down.sqlheader because editing the.up.sqlwould change its content checksum and break live databases (see below).Why the retrofit is safe on already-applied databases
sqlx checksums a reversible migration over its
.up.sqlfile alone (Migration::new→sha384(sql)insqlx-core/src/migrate/migration.rs), and records that checksum on apply. Since the up payload is byte-identical to the old minimal.sqlfile, the checksums sqlx recorded before this change are preserved. Verified against a real database: after applying all migrations with the old format, runningsqlx migrate runagainst the same DB with the new files is a clean no-op (noVersionMismatch).Tooling
scripts/migrate-revert-smoke.sh— applies all migrations to a fresh disposable DB, reverts011 → 010 → 009, asserts the schema matches the pre-migration state at each step (via psql), re-applies (idempotency), and tears down..github/workflows/migrations.yml— runs the smoke test against a disposable Postgres 16 service container on every PR/push tomain(scoped to migrations only; general CI remains issue No CI workflow configured (missing .github/workflows) #6).README.md— documents the.up.sql/.down.sqlconvention,sqlx migrate add -r, the run/revert/info commands, the migration-010 caveat, and the smoke test.Verification (run locally against PostgreSQL 17)
Before (baseline):
sqlx migrate revert→No migrations available to revert.After:
sqlx migrate runon a fresh DB: all 11 applied.sqlx migrate runon the already-applied (old-format) DB: clean no-op — checksums preserved.sqlx migrate revert× 3 (011 → 010 → 009): each reverts,sqlx migrate infoflips the version topending, and psql asserts the schema returned to the pre-migration state — including the documented behavior that 010's enum value survives its revert.011 → 001then re-apply: all 11 down scripts execute, then all 11 re-apply cleanly (idempotent).scripts/migrate-revert-smoke.sh: PASS (full output in the branch).Acceptance criteria
.up.sql/.down.sqlpair format (repo-wide now;sqlx migrate add -rdocumented)..down.sqlscripts.sqlx migrate revertdemonstrated against a fresh test database (smoke script, CI workflow).Notes / out of scope
sqlx::migrate!("./migrations")insrc/db.rsalready supports reversible migrations for forward application..down.sqlfor already-applied environments is safe because checksums are preserved (verified above); no_sqlx_migrationsreconciliation is required.