Gradle-git plugin not working with maven-publish plugin (saying :publish UP-TO-DATE)

I have a multi-module project, and I’m using maven-publish to publish the jar, javadoc jar and source jar for each module to our local Nexus repo. This works fine if all I want to do is:

gradle clean build publish

In this case, all my modules build and all the relevant artifacts are uploaded to the repo. So far, so good. What I’m trying to do, though, is use the gradle-git plugin to perform a release (and ultimately to upload the released artifacts to the repo). I’ve added the gradle-git plugin to my build, and it works fine, in the sense that I can run

gradle clean build releasePatchVersionAsDev

and it will happily figure out the correct version number (which it dumps to the console), build the code, and push all my unpushed changes.

However, what I really want is for the release plugin to upload all the artifacts with the newly-derived version number. Which it apparently supports via a set of releaseTasks:

releaseTasks = [ 'publish' ]

I then run:

gradle clean build releasePatchVersionAsDev

and everything seems to work as expected (it cleans, builds, correctly figures out a version number for the release and prints it to the console), and then it hits the publish task and simply prints:

:publish UP-TO-DATE

Obviously this isn’t what I want. Publish needs to upload the artifacts to the repo, just as it does if I run it explicitly. For some reason when the release task depends on the publish task, it doesn’t seem to see the publications.

Running the release task with debug enabled, this is what it does when it hits the publish task:

10:10:21.262 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':publish'
10:10:21.263 [INFO] [org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter] Skipping task ':publish' as it has no actions.
10:10:21.263 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':publish'
10:10:21.263 [LIFECYCLE] [class org.gradle.TaskExecutionLogger] :publish UP-TO-DATE
10:10:21.263 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :publish (Thread[main,5,main]) completed. Took 0.001 secs.
10:10:21.263 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :validateSinceTags (Thread[main,5,main]) started.

There are some issues getting the release plugin to work with the publishing plugins. What I’ve seen has been this particular error.

I don’t know that I’ve tested the maven-publish plugin on its own, my issues were with the bintray plugin in combination with maven-publish. I still need to post a disclaimer in the documentation, but here’s some more detail on that issue on the gradle-dev list.

I’ll have to do some more testing to see if this is a related issue.

Is this peculiar to the maven-publish plugin, or does this apply more generally?

I noticed that when I tried to switch back to the regular maven plugin (i.e. using the uploadArchives task) that Gradle then starts complaining that the “Version has not been inferred” (i.e. the behaviour seen in the page you linked to) if I have not explicitly configured a project version. If I do explicitly configure a project version (let’s say I set it to some dummy value, expecting the gradle-git plugin to override it with an inferred version during the configuration stage), then I avoid the previous error and I can see gradle-git correctly printing the inferred version in the build log, but my artifacts all end up being built with the dummy version number rather than the semver-inferred version, and uploadArchives fails with what looks like this error: GRADLE-2406 - I can only guess that this is happening because the artifacts are being built using the dummy version number, and then presumably the maven deployer is searching for artifacts with the gradle-git-generated version number, which obviously don’t exist.

This seems to suggest that the maven plugin resolves the version number before gradle-git gets a chance to override it…?

Hope that helps a bit. I really like this plugin, but at this stage I’m having a hard time understanding how anyone might be using it to build or deploy correctly-versioned artifacts :frowning:

Since you can only get that exception when something is trying to use the inferred version, using your workaround is almost definitely going to cause some side effects like that.

Unfortunately, as much as I like the concept, this release plugin hasn’t turned out to have as many practical benefits as I’d hoped, given the behavior of some of the core plugins.

I’ll do some more testing and see if I can figure out why the normal maven plugin causes this issue.

For the benefit of anyone else who reads this, I managed to find a reasonable workaround by splitting the release process up into two separate Gradle build steps (i.e. two distinct Gradle runs). Step 1 is a prepare stage, and its job is simply to infer the release version from the Git repo and write it out to a file. In step 2, we read the contents of the file into the project’s version property, so the desired version is available all the way through the build, then proceed with the release process from there. And yes, this is pretty much what the Maven release plugin does. But it works.

This has the small disadvantage of requiring a 2-step build, but the big advantage of ensuring that the inferred version gets set correctly everywhere that needs it, rather than me having to do crazy rubbish in taskGraph.whenReady to loop over every task searching for version numbers I need to patch, which I decided was one hack too many when I realised that I also needed to patch the versions of my subprojects in the generated poms (i.e. in the dependencies between subprojects). Ugh.

Doing it this way also means that now I’ve got a version file in the build that my code can query at runtime.

I just released gradle-git 0.9.0, which I think will resolve this issue.

Versions will now be inferred as soon as something tries to access them.

The breaking change will be the names of the tasks. Instead of ‘./gradlew releasePatchAsRc’ you would specify ‘./gradlew release -Prelease.scope=patch -Prelease.stage=rc’. Wordier, but it gets around the timing issues.

Let me know if you still have issues.