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.
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:
--fail-if-no-migrations--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.
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:
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#)?
Most helpful comment
I guess my thought is, can we rework how we do sanity checks?
--sanity-check=offwould be the simplest behavior, and it can be an enum flags: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