Skip to content

Make migration planning deterministic and dry runs read-only - #173

Merged
jogibear9988 merged 6 commits into
masterfrom
codex/migrator-runner-safety
Sep 22, 2026
Merged

jogibear9988 merged 6 commits into
masterfrom
codex/migrator-runner-safety

Conversation

@jogibear9988

Copy link
Copy Markdown
Member

Compute deterministic migration plans, isolate scopes, and make DryRun read-only through an additive history contract. Preserve legacy history-property behavior. Improve rollback, cache invalidation, caller connection ownership, and SQLite foreign-key restoration/integrity validation. Post-commit callbacks no longer trigger a misleading rollback. Validation: 68 unit tests and 141 SQLite tests passed; existing issue #139 test remains skipped. Server-backed CI is required before merge. First PR in the upgrade series; please review and merge manually.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved critical scope, history-initialization, and transaction-recovery issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 4 High severity

Open (4)
What changed in this PR

This PR makes migration planning deterministic and dry runs read-only, while adding scoped history support and safer transaction/SQLite handling.

Changes:

  • Adds deterministic plans and optional read-only history inspection.
  • Refactors execution, rollback, callbacks, caching, and connection ownership.
  • Adds SQLite integrity handling and runner-safety tests.
File Review summary
src/​Migrator/​Providers/​TransformationProvider.cs Critical (1 vote): retain transactions until completion succeeds. Moderate (1 vote): clean up internally owned connections.
src/​Migrator/​Providers/​Impl/​SQLite/​SQLiteTransformationProvider.cs Adjusts SQLite foreign-key handling and integrity validation.
src/​Migrator/​Migrator.cs Critical (1 vote): preserve history initialization for real executions. Nit (1 vote): correct the Plan XML documentation.
src/​Migrator/​MigrationPlan.cs Defines deterministic migration steps.
src/​Migrator/​MigrationLoader.cs Critical (3 votes): support scoped migrations without IMigrationHistory. Nit (1 vote): document or make automatic scope filtering opt-in.
src/​Migrator/​MigrationExecution.cs Critical (2 votes): pass each migration’s declared scope at all execution points.
src/​Migrator/​MigrateAnywhere.cs Moderate (1 vote): preserve dry-run preview logging or route through the planner.
src/​Migrator/​Framework/​IMigrationHistory.cs Adds the optional read-only history contract.
src/​Migrator.Tests/​RunnerSafetyTests.cs Adds safety and dry-run coverage.
src/​Migrator.Tests/​MigratorTest.cs Updates migration and rollback tests.
src/​Migrator.Tests/​MigrationLoaderTest.cs Updates migration-loader test setup.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Migrator/MigrationExecution.cs Outdated
Comment thread src/Migrator/MigrationLoader.cs Outdated
Comment thread src/Migrator/Migrator.cs Outdated
Comment thread src/Migrator/Providers/TransformationProvider.cs Outdated
Copilot AI review requested due to automatic review settings September 22, 2026 12:38
jogibear9988 added a commit that referenced this pull request Sep 22, 2026
Include legacy scope compatibility, pre-transaction history initialization, failed-commit recovery, and stacked PR CI coverage from #173. Keep provider corrections layered on the corrected runner.
jogibear9988 added a commit that referenced this pull request Sep 22, 2026
Carry the runner test-provider implementation from #173 into the provider-fix stack. The 31 targeted runner tests now compile and pass.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved critical scope-filtering and additional execution, dry-run, logging, and callback issues require fixes.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity

Open (2)
Resolved since last review (3)
Previously missed (3)

In code that hasn't changed since last review

Medium severity Dry-run path writes schema metadata before DryRun is set

src/​Migrator/​MigrateAnywhere.cs:67

This early return does not make the public MigrateAnywhere dry-run path read-only: BaseMigrate and its constructor read provider.AppliedMigrations before a caller can set DryRun, and the legacy property creates/upgrades SchemaInfo. The main Migrator no longer uses this class, but direct callers still get database writes during dry runs; move initial history access behind IMigrationHistory or remove this path from the supported dry-run surface.

Medium severity Post-commit callback failures bypass migration error logging

src/​Migrator/​MigrationExecution.cs:56

These callbacks are intentionally after commit, but their exceptions now escape outside the catch that calls logger.Exception. A failing AfterUp/AfterDown therefore loses the migration/version error log (while still aborting the runner); catch the callback separately, log it, and rethrow without attempting a rollback.

Low severity Public XML documentation describes outdated migration behavior

src/​Migrator/​Migrator.cs:199

The XML documentation immediately above this signature still describes executing Up()/Down() and honoring DryRun, but Plan only reads history and returns steps; the actual MigrateTo method below is now undocumented. Update the public API docs so callers are not told that planning performs migration work.

Comment thread src/Migrator/MigrationLoader.cs
Copilot AI review requested due to automatic review settings September 22, 2026 12:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved issues remain in dry-run history handling, callback execution and logging, no-op behavior, documentation, and history compatibility.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 4 High severity

Open (4)
Resolved since last review (1)
Previously missed (2)

In code that hasn't changed since last review

Medium severity Log post-commit callback failures before rethrowing

src/​Migrator/​MigrationExecution.cs:56

These post-commit callbacks are outside the catch that calls logger.Exception, so an AfterUp/AfterDown failure is propagated without being recorded. Keep the no-rollback behavior, but wrap the callback in a catch that logs the exception before rethrowing it.

Medium severity Preserve history snapshots passed to lifecycle callbacks

src/​Migrator/​Migrator.cs:215

history is mutated in the loop after being passed directly to Started, so a logger that retains the argument no longer sees the initial applied-version snapshot. The legacy BaseMigrate contract preserves that snapshot for both callbacks (BaseMigrate.cs:19-25), while Finished now also receives the mutated list at line 236; keep a separate pre-run copy for both callbacks.

Comment thread src/Migrator/MigrateAnywhere.cs
Comment thread src/Migrator/MigrationExecution.cs
Comment thread src/Migrator/Migrator.cs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings September 22, 2026 14:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@jogibear9988
jogibear9988 added this pull request to stack #179 September 22, 2026 15:50
The PR matrix exposed Firebird history creation occurring inside the first migration transaction. Initialize history before real execution while keeping planning read-only. Preserve explicitly scoped migrations and their history arguments for custom providers without IMigrationHistory. Retain failed transactions so rollback can recover a failed commit. Add regression tests for legacy scopes and transaction recovery, and enable CI on stacked codex PR bases. Validation: targeted runner tests; full provider matrix reruns on push.
Implement the three abstract metadata members on the isolated transaction test provider. This keeps the failed-commit recovery test independent of live database metadata. Validation: 31 targeted runner, loader and rollback tests passed.
Replace broad try/catch blocks that swallowed Assert.Fail with exact exception assertions, verify the migration's error message and assert Rollback was called immediately after execution. Remove never-triggered Dispose callback assertions from loader setup and date-version fixtures.

Validation: solution build and Unit 68 passed.
…ings

Restore LF endings in the two existing fixtures to avoid whole-file diff noise. Validation correction for 727d132: the completed Unit run had 70 passing tests, not 68; no test behavior changes in this formatting commit.
Defer legacy runner history access until navigation and use IMigrationHistory for read-only reads; constructors and DryRun no longer initialize history. Empty latest-version runs return before history access. Restore migration context around post-commit callbacks and clear it even when a callback fails. Update README scope semantics to match the explicitly requested effective-scope behavior.

Validation: solution build, Unit 70 passed, SQLite 145 passed with one pre-existing default-removal skip handled in the provider layer. New regressions cover legacy navigation, empty assemblies, callback context, durable history and callback failure cleanup. Addresses reviews 4071830715, 4071830792 and 4071830843; documents the deliberate scope policy discussed in 4071742900.
Copilot AI review requested due to automatic review settings September 22, 2026 18:12
@jogibear9988
jogibear9988 force-pushed the codex/migrator-runner-safety branch from 29597a8 to c8619f9 Compare September 22, 2026 18:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@jogibear9988
jogibear9988 merged commit 95cb126 into master Sep 22, 2026
12 checks passed
@jogibear9988
jogibear9988 deleted the codex/migrator-runner-safety branch September 22, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants