Skip to content
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

Prevent compile task being triggered prior to a flyway task being run #10

Open
davidmweber opened this issue Jan 22, 2018 · 10 comments
Open

Comments

@davidmweber
Copy link
Collaborator

SBT insists on compiling sources when running a flyway task. This is problematic for people who use code generators such as Slick and can mean a simple operation like flywayClean being very slow due to the compilation that gets triggered. I am really not sure why SBT is triggering the compile or how to prevent it. Ideas welcome.

@xuwei-k
Copy link
Member

xuwei-k commented Feb 21, 2018

I think fullClasspath triggers compile

https://github.com/flyway/flyway-sbt/blob/71ed19ab6af72f2205a9b43b638dd66575446b93/src/main/scala/org/flywaydb/sbt/FlywayPlugin.scala#L178-L187

@davidmweber
Copy link
Collaborator Author

davidmweber commented Feb 21, 2018

This is a tricky one. If I change it to something like externalDependencyClasspath, no compilation is triggered but this classpath does not include the stuff in src/main/resources/ that contains the actual migration data. Any ideas?

@davidmweber
Copy link
Collaborator Author

The fullClassPath key points to the compiled JAR file which contains the resources containing the migration data which is the reason it needs to compile the project first. Either we just live with this or we find the right resource file for each build and explicitly add it in.

@nafg
Copy link

nafg commented Mar 9, 2018

I think the only solution is to enable flyway on a different project.
If you think about it, the real problem is that there's nothing stopping you from having a "Java" migration (e.g. written in scala) that depends on code generated by slick-codegen. Classpath location means allowing for code migrations. (If there was a way to just get a resources "classpath," that might help if there was a way to switch off code migrations.) And code migrations can do anything code can do. So it's kind of an inherent problem. Again, the only solution I can think of is to put migrations in a different subproject (or configuration, but that's harder to do).

@stevewillcock
Copy link

stevewillcock commented Oct 12, 2018

I had a similar issue and creating a separate sub-project seems to be a good option - e.g.

lazy val flywayrunner = project
  .settings(
    commonSettings,
    libraryDependencies ++= Seq(
      "org.flywaydb" % "flyway-core" % "5.1.4",
      "org.postgresql" % "postgresql" % "9.4.1208"
    ),
    flywayUser := "my_db_user",
    flywayUrl := "jdbc:postgresql://localhost:5432/my_db",
  ).enablePlugins(FlywayPlugin)

Then you can set up a task to run whichever flyway tasks you need in the top level project - this is to run the flyway clean and migrate tasks on compile for example:

lazy val fullMigrate = taskKey[Unit]("Run all migrations")

fullMigrate := Def.sequential(
  flywayClean in flywayrunner,
  flywayMigrate in flywayrunner
).value

compile in Compile := (compile in Compile).dependsOn(fullMigrate).value

@davidmweber
Copy link
Collaborator Author

@nafg has a plan that I have been dreaming about. Check where the actual migration is and select the classpath "mode" accordingly. But after I get some updates done.

@davidmweber
Copy link
Collaborator Author

@stevewillcock has a great interim solution that will work for many use cases. Perhaps I can stick that in the docs?

@nafg
Copy link

nafg commented Oct 15, 2018

Wait what? All I said is that separate subprojects are demonstrably necessary to prevent a logical dependency cycle.

That's what @stevewillcock said too, adding that you can also write a custom task for convenience. Personally I don't bother, it's easy enough to have the root project aggregate it and access the task that way, or else just use the subprojects prefix, for example you can run db/flywayMigrate.

@nafg
Copy link

nafg commented Oct 15, 2018

The cycle is that code migrations can depend on application code, but application code can depend on generated code, which depends on the database, which depends on migrations, which include code migrations.

The only way out of it is that any code migrations have to be upstream of the generated code.

Even SQL migrations are an issue because at runtime they are not read from their source location -- the runtime classpath is elsewhere, and typically resources are copied there as part of the compile step.

The only other option is that during development, it could read SQL migrations from a file location based on the sbt resource directory setting.

@nerdydrew
Copy link
Contributor

How about the solution in #33? I also added a test for it.

DaniRey added a commit to DaniRey/flyway-sbt that referenced this issue Nov 29, 2022
Many flyway users also generate code from the schema. They have to take care to "Prevent compile task being triggered prior to a flyway task being run sbt#10"
Adapted the example in the readme accordingly, so that many can avoid this pitfall.
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

No branches or pull requests

5 participants