checksum drift detection and repeatable migrations - #35
Merged
Merged
Conversation
Drift detection: an up run verifies that every already-applied migration still matches its recorded checksum before applying anything, aborting with `Error::ChecksumMismatch`. Opt out with `Migrator::allow_checksum_mismatch` / `--allow-checksum-mismatch`. Repeatable migrations: a migration declared with `repeatable()` or a `-- migrant:repeatable` directive re-runs whenever its up-SQL checksum changes instead of applying once. They run after the pending versioned migrations, at most once per run, keep a single bookkeeping row updated in place, and are exempt from the drift, unknown-tag, and out-of-order checks. They are forward-only: a down run never selects them, and declaring one with no checksum or with a down direction is rejected at registration. `Migrator::rerun_repeatable` / `--rerun-repeatable` re-runs them regardless of checksum, and `redo` warns when it will not revert one. The bookkeeping table gains an `is_repeatable` column, and `down.sql` is now optional for file-discovered migrations. See the changelogs for the on-disk schema upgrade note.
The test ran in the repo root against `db/migrant.db`, which persists between runs. A change to the bookkeeping schema then breaks the next run against that stale file, which CI never reproduces because it starts from a fresh checkout. It now copies the repo's `Migrant.toml` and `migrations/` into a tempdir and runs there, like the other CLI tests, so every run starts from an empty database and nothing is written to the working tree.
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.
Checksum drift detection and repeatable migrations
Two related features built on the
checksumbookkeeping column: enforcing that an appliedmigration's SQL has not changed, and its inverse, migrations that re-run when it does.
Drift detection
run applies anything, aborting with
Error::ChecksumMismatch. The check runs even whennothing is pending, and skips rows where either side is null (programmatic or legacy rows).
--allow-checksum-mismatch(Migrator::allow_checksum_mismatch), independentof the existing
--allow-unknown-tags/--allow-out-of-order.Repeatable migrations
-- migrant:repeatabledirective in the up-SQL or therepeatable()builder method;
Migratable::is_repeatable()reports it.migrations are skipped.
preserved.
is authoritative on kind for a tag it still defines; the
is_repeatablecolumn decides onlyfor tags no longer in the set.
down direction is an
Error::Migration.--rerun-repeatable(Migrator::rerun_repeatable) to re-run them regardless ofchecksum, since editing the file is otherwise the only trigger.
redonaming the repeatable migrations it will not revert, since it targets themost recent versioned migration instead.
migrant new --repeatable, reportrepeatable/stalefromstatusandlist, and addReport::repeatable_tags().Breaking changes
__migrant_migrationsgains anis_repeatablecolumn. This folds into the existingunreleased bookkeeping schema change; see the CHANGELOG for the upgrade SQL.
down.sqlis now optional for file-discovered migrations. A migration with no down file is ano-op in that direction.
NewMigration::down_path()returnsOption<&Path>.Coverage
Unit and integration tests for both features, run against sqlite plus postgres and mysql via
migrant_lib/test.sh. Specs inspec/checksum-drift-detection.mdandspec/repeatable-migrations.md; guide pages and both changelogs updated.