Fluentmigrator: Migrate runner fails if no matching migrations are found

Created on 17 Apr 2019  路  8Comments  路  Source: fluentmigrator/fluentmigrator

We are noticing a new behavior with FluentMigrator 3.2.1 when upgrading from 1.6. The issue is if no matching migrations are found the runner is returning a non-zero exit code. I believe the original behavior was correct - there may not be matching migrations but that doesn't mean the runner should return an error. A good use case would be part of a continuous deployment environment where many migrations are present in the assembly but none match the tag / profile requirements to run for this environment. In this case the deployment fails - when it should have succeeded.

bug

Most helpful comment

This behaviour tries to protect angainst the following cases:

  • Wrong assembly specified
  • Misspelled tag names

When you have a baseline database and no (matching) migrations, then the application shouldn't even try to execute migrations. We cannot check for a namespace alone, only for types within given namespaces.

I guess my thought is, can we rework how we do sanity checks? --sanity-check=off would be the simplest behavior, and it can be an enum flags:

[Flags]
public enum SanityCheckFlags
{
  Off = 0,
  MigrationsMustExistInSpecifiedAssembly = 1,
  MigrationsMustExistInSpecifiedNamespace = 2,
  MigrationsMustExistInSpecifiedTag = 4
}

Following possible calling conventions:
--sanity-check=off
--sanity-check=assembly
--sanity-check=namespace
--sanity-check=tag
--sanity-check=all : Default. Special AND combination of all flags. Equivalent to:
--sanity-check=assembly,namespace,tag

All 8 comments

This would require updating the FAQ: https://fluentmigrator.github.io/articles/faq.html#why-does-the-migrateexe-tool-say-no-migrations-found

Note, also, in testing: If you have a Maintenance migration but no matching Migrations for a --tag=MyTag option, it returns No migrations found.

There are a couple of ways to solve this:

  1. Add a new command line switch --fail-if-no-migrations
  2. Provide sample workflow that sidesteps the issue, possibly by calling --preview - does preview throw if no migrations?

Related: https://github.com/fluentmigrator/fluentmigrator/issues/976#issuecomment-451876925
^ the comments here by @fubar-coder should be added to the FAQ

What is the use case to allow a migrator to succeed when the filter returns no migrations? This looks like wrong tags given at the command line - or the wrong assembly.

EDIT: Just to clarify, this was an intentional change to catch wrong parameters given to the runners, which seems to be exactly the problem you're facing in your example.

  1. Why not verify the --namespace parameter exists? This would catch most refactoring bugs where someone changes project structure and the namespace of Migration classes.
  2. The use case is continuous testing. @mmiller678 has a UnitTest tag and he creates a new database every time and then runs all migrations. However, he also creates a "baseline" CreateDatabase.sql periodically and archives migrations. In this scenario, he had archived all DDL Migrations, but had a bunch of DML Migrations without a UnitTest tag, because inserting/updating/deleting data in UnitTest migrations doesn't make a whole lot of sense.

My understanding is, that the migrations will always be there, but will not executed, because the database has the migrations already applied. In this case, no error should be thrown.

In other words: When a namespace was specified and/or a tag, but no migrations could be found (before filtering by its version), then this is usually an error. This behaviour tries to protect angainst the following cases:

  • Wrong assembly specified
  • Misspelled tag names

When you have a baseline database and no (matching) migrations, then the application shouldn't even try to execute migrations. We cannot check for a namespace alone, only for types within given namespaces.

This assumes you never archive or remove all the migrations. We have 1000s of migrations so periodically we remove them all from the project after they have been executed. The work around is to have a default migration that doesn鈥檛 do anything but never gets archived. I think the runner is trying to be too clever - at least give me a way to turn off this new behavior as not having any matching migrations to run is a valid use case.

This behaviour tries to protect angainst the following cases:

  • Wrong assembly specified
  • Misspelled tag names

When you have a baseline database and no (matching) migrations, then the application shouldn't even try to execute migrations. We cannot check for a namespace alone, only for types within given namespaces.

I guess my thought is, can we rework how we do sanity checks? --sanity-check=off would be the simplest behavior, and it can be an enum flags:

[Flags]
public enum SanityCheckFlags
{
  Off = 0,
  MigrationsMustExistInSpecifiedAssembly = 1,
  MigrationsMustExistInSpecifiedNamespace = 2,
  MigrationsMustExistInSpecifiedTag = 4
}

Following possible calling conventions:
--sanity-check=off
--sanity-check=assembly
--sanity-check=namespace
--sanity-check=tag
--sanity-check=all : Default. Special AND combination of all flags. Equivalent to:
--sanity-check=assembly,namespace,tag

TBH: I'd just implement all and off with all being -1. This would allow us to just return 0 in the runner.

I agree wtih @mmiller678 when he says

at least give me a way to turn off this new behavior as not having any matching migrations to run is a valid use case

I have two main branches of my application. One of these branches will be the future definitive (master) branch, but right now it has to keep all changes from the current master branch plus some differences which will only exist in the new version (2.0) of our project.

I got here in this issue exactly because what @mmiller678 has explained in his comments. In my case, I set up migration support on both branches, but I only need an actual migration on branch 2.0. Then, all worked fine on branch 2.0, but on master branch I got the "no migrations are found" error, even though I've implemented it purpusefully to have no migrations. It should just have the migration structure support, so that when the need comes I'll be able to just add my migrations classes to it.

I don't see creating a default empty migration as a proper solution. It's confusing and useless. I'd much rather set a flag to tell FM if it should throw errors when not finding migrations. The workaround here, besides creating the empty migration, will be to comment the code and add TODO: uncomment it!

Do you have a way to turn this behavior off programatically (via C#)?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brooklynDev picture brooklynDev  路  3Comments

tgharold picture tgharold  路  6Comments

ondravondra picture ondravondra  路  8Comments

biju-ps picture biju-ps  路  9Comments

jzabroski picture jzabroski  路  6Comments