-
Notifications
You must be signed in to change notification settings - Fork 11.4k
Add an optional shouldRun
method to migrations.
#55011
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an optional shouldRun
method to migrations.
#55011
Conversation
Thanks for submitting a PR! Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface. Pull requests that are abandoned in draft may be closed due to inactivity. |
shouldRun
method to the migration classes.shouldRun
method to migrations.
One thing I'm curious about is we are not instantiating the migration a bit earlier, and we're not using the |
@taylorotwell ah, i see what you're getting at.
The alternative option is to move this out of a collection filter method in |
We currently workaround this limitation in our app with custom migration code/commands, so having this built into Laravel would be fantastic. If there's anything I can do to help here let me know. |
Another option is to wait till class ConditionalMigrator extends Migrator
{
protected function runUp($file, $batch, $pretend): void
{
// First we will resolve a "real" instance of the migration class from this
// migration file name. Once we have the instances we can run the actual
// command such as "up" or "down", or we can just simulate the action.
$migration = $this->resolvePath($file);
$name = $this->getMigrationName($file);
if ($pretend) {
$this->pretendToRun($migration, 'up');
return;
}
// check here if migration should run
if (! $migration->shouldRun()) {
$this->write(Info::class, "Skipped migrating {$name}");
return;
}
$this->write(Task::class, $name, fn () => $this->runMigration($migration, 'up'));
// Once we have run a migrations class, we will log that it was run in this
// repository so that we don't try to run it next time we do a migration
// in the application. A migration repository keeps the migrate order.
$this->repository->log($name, $batch);
}
} Incidentally, in another project I'm currently placing feature or environment dependent migrations at a separate path and running them with a custom command (similar need, different type of solution). |
@inmanturbo nice, thanks! I think i was avoiding that because it had the possibility to fire migration events before then being skipped, but i'll take another look on my lunch today! Another thing i'd love some feedback on is having the migration show as "SKIPPED" when running the command in the same way we show RAN and FAILED results. |
You cannot require_once the same file twice that returns a value (in this case anonymous class) instead of defining a global class etc. as the second time you Also, I'm for the SKIPPED status to be visible, would be nice if it could show a "string" reason too instead of just a bool value. |
A string reason would be cool, but not sure it would fit within the two column layout of the current migration status run. Maybe we could a |
- Refactored where the skip check is done - Added in a 'SKIPPED' status message for skipped migrations - Added in a new MigrationResult backed enum to store the new third 'state' of a migration ran.
…/laravel-framework into feature/should-run-migration
Showing
Showing skipped is a good idea. As to showing a reason for skipping, yet another option still is to use an exception that will be caught by the migrator, similar to how validation works. This would allow you to But I think simply skipping without providing a reason is enough for the scope of this PR. In any case it's a usefull feature to have in the framework and I appreciate you working on it. |
Alright:
Only thing left might be that the migration still shows as "Pending" in |
@taylorotwell this is ready to merge as is, but i'd love your opinion on:
|
Looks like CI run fails are to do with Docker issues, not actual test fails 🤞🏻 |
@@ -241,12 +254,16 @@ protected function runUp($file, $batch, $pretend) | |||
return $this->pretendToRun($migration, 'up'); | |||
} | |||
|
|||
$this->write(Task::class, $name, fn () => $this->runMigration($migration, 'up')); | |||
if ($this->shouldSkipMigration($migration)) { | |||
$this->write(Task::class, $name, fn () => MigrationResult::Skipped); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
What's this?
I've added the ability to declare a
shouldRun
function in your migration files to determine wether or not a migration should run whenphp artisan migrate
orphp artisan rollback
is called.Why?
This adds the ability to selectively run migrations that you may have shipped to various environments based on:
etc.
This allows you to ship code to environments without running potentially damaging migrations before you're ready.
Backwards compatibility.
The
shouldRun
function is added as an implemented function on the abstractMigration
class and returns true by default, so ALL migration classes should work as usual, with no need to adjust thestub
file either.