Skip to content

[12.x] Ensure make:migration generates unique timestamp prefixes#60769

Closed
pushpak1300 wants to merge 1 commit into
laravel:12.xfrom
pushpak1300:fix/migration-unique-timestamp
Closed

[12.x] Ensure make:migration generates unique timestamp prefixes#60769
pushpak1300 wants to merge 1 commit into
laravel:12.xfrom
pushpak1300:fix/migration-unique-timestamp

Conversation

@pushpak1300

Copy link
Copy Markdown
Member

The papercut

Coding agents routinely scaffold models by chaining generator commands:

php artisan make:model ABC -m && php artisan make:model XYZ -m

These run within the same second, so both migrations get an identical Y_m_d_His timestamp prefix.

Migrations are ordered by that prefix, which only has one-second resolution. When prefixes tie, execution order falls back to the file name (alphabetical), which is not the creation order. This is harmless on SQLite — so test suites pass and the problem stays hidden — but on MySQL and Postgres it's a real bug: if XYZ's migration depends on a table created by ABC's migration, the alphabetical fallback can run them in the wrong order and the migration fails.

Anonymous migration classes (#37598) fixed the class name collision, but not the ordering collision — two anonymous migrations can still share a prefix.

Why fix it in the framework

Laravel Boost already instructs agents to avoid generating migrations this way, but that's guidance, not a guarantee — any tool or script that scaffolds two migrations in one second reintroduces it. Handling it directly in the framework closes the papercut for good, regardless of how the migrations are generated.

Fix

MigrationCreator::getDatePrefix() now checks the target migration directory for an existing file using the computed prefix. If one exists, it nudges the timestamp forward one second at a time until it finds a free prefix, guaranteeing a deterministic order on every driver.

Because A && B runs as two sequential processes, the first migration is written to disk before the second globs, so the collision is reliably detected. A test covers the bump.

Migrations are ordered by their Y_m_d_His timestamp prefix, which only has
one-second resolution. Chained generator calls such as
`make:model ABC -m && make:model XYZ -m` run within the same second, so both
migrations receive an identical prefix. When prefixes tie, execution order
falls back to the file name, which is harmless on SQLite but can run
dependent migrations out of order on MySQL and Postgres.

MigrationCreator now bumps the timestamp forward one second at a time until it
finds a prefix that is not already used in the target directory, guaranteeing a
deterministic order on every driver.
@pushpak1300

Copy link
Copy Markdown
Member Author

Superseded by the 13.x-targeted PR.

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.

1 participant