laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

Skippable Migrations #2557

Open liamkeily opened 3 years ago

liamkeily commented 3 years ago

If an app uses feature flag's then sometimes it would be nice to skip a migration until the feature flag is enabled. AFAIK there is currently no way of doing this.

For example, it would be good if inside the migration you could do something like this:

<?php

if (! THE_FEATURE_FLAG) {
    $this->skip();
}

// The rest of the migration

Could this work, or is there a nicer way of achieving this?

ahinkle commented 3 years ago

Can you provide an example where you would withhold a migration from code that already is in place for a feature?

In my opinion, this would hide obscure bugs.

liamkeily commented 3 years ago

A feature flag may look like define('THE_FEATURE_FLAG', env('APP_ENV') === 'staging'); and all related code would sit behind if (THE_FEATURE_FLAG) {. This allows a feature code to be merged and deployed but not enabled on production until the feature has been fully tested on staging and approved. It definately requires more thought, but is useful in some cases. We currently use a custom migration runner for this project so I was just wondering whether we could use Laravel migrations in a similar way.

brunogaspar commented 3 years ago

Personally, never had the need for such functionality, since we usually do controlled deployments and when new features are being developed and if we need to QA on staging, we deploy that branch on staging until we're happy with it, without merging the entire thing into master/main.

The idea is although interesting, just unsure it would be accepted in the core to be honest, very small chance of being useful to a lot more people.

An external package extending the default migrator is probably the way to go.

How i would approach it is, on the migrations you don't want to be ran (migrated) it could have a function that would return a boolean. Inside that function, you could apply the logic you need and if you want to skip, just ensure it returns false for example.

The migrate:status command would also need to list those skipped migrations and what not.

itainathaniel commented 3 years ago

How i would approach it is, on the migrations you don't want to be ran (migrated) it could have a function that would return a boolean. Inside that function, you could apply the logic you need and if you want to skip, just ensure it returns false for example.

Yup, extending Illuminate\Database\Migrations\Migration allow skip(): boolean function is probably the right way.

And you don't have to change migrate:status since the migration won't run and IMHO you don't need to mark it differently in the Ran? column.