Skip to content

Group migration sets that share a migration history - #1116

Merged
markstory merged 3 commits into
5.xfrom
fix-migrator-multi-source
Sep 19, 2026
Merged

markstory merged 3 commits into
5.xfrom
fix-migrator-multi-source

Conversation

@dereuromark

@dereuromark dereuromark commented Sep 14, 2026 •

Copy link
Copy Markdown
Member

Fixes #1115.

Migrator::runMany() evaluates shouldDropTables() once per migration set, but a migration history is keyed by connection and plugin only. ManagerFactory::createConfig() derives the log table from Util::tableName($plugin), and the unified cake_migrations table filters on its plugin column. The source folder never enters either.

Two sets that differ only in source therefore share one history while each sees only its own directory on disk. Manager::printStatus() compares the whole log against one source's files and flags everything belonging to the sibling source as applied but missing. shouldDropTables() then returns true, and the connection is dropped and its history truncated on every run, even when the test database is current. Legacy phinxlog tables are affected in the same way.

The fix groups sets by their shared history, using the connection and plugin, and collects the migration IDs present on disk across the group. A logged migration found in any source of the group no longer counts as missing. Sets with distinct histories retain their previous behavior.

The sibling migration IDs are passed as an optional third parameter to shouldDropTables(). This keeps the data flow explicit, but changes the signature of a protected method. Existing subclasses that override the two-parameter method would need to accept the new optional parameter.

testRunManyMultipleSkip was passing because of the unwanted drop, so it now forgets one applied migration to give the second run a valid reason to drop. That also allows it to run against the unified table, so its skipIf is gone.

Both new tests fail on 5.x and pass with the fix in legacy and unified mode.

Migrator::runMany() decided whether to drop tables once per migration
set. A migration history is keyed by connection and plugin only, never
by source, so two sets differing only in their source write to one
history while each of them sees just its own directory on disk. Every
set therefore reported its siblings' applied migrations as missing, and
the connection was wiped on every run even when the database was
already up to date.

Sets are now grouped by the history they share, and a logged migration
found on disk in any set of the group no longer counts as missing.

testRunManyMultipleSkip relied on that spurious drop to trigger its
failure, so it now forgets an applied migration to give the second run
a genuine reason to drop. It no longer has to be skipped when the
unified table is in use.
Comment thread src/TestSuite/Migrator.php Outdated
@markstory
markstory merged commit 2354f82 into 5.x Sep 19, 2026
14 checks passed
@markstory
markstory deleted the fix-migrator-multi-source branch September 19, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support multiple sources per migration-set in test suite Migrator

2 participants