Maven-publish and dynamically setting the version results in build-failure

It is not possible to dynamically set the version and deploy the version using the new incubating maven-publish plugin in the same step.

If I use the following build.gradle file:

apply plugin: 'java'
apply plugin: 'gradlecm'
apply plugin: 'maven-publish'
  group = 'test'
  buildscript {
    repositories {
        mavenCentral()
        maven {
            name 'kercheval'
            url 'http://kercheval.org/mvn-repo/releases'
        }
    }
    dependencies {
        classpath 'org.kercheval:GradleCMPlugin:+'
    }
}
  buildvcs {
    type = 'none'
}
  publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
}

running “gradle clean publishToMavenLocal” results in an error, because the publish task tries to upload the file build/libs/${project.name}.jar, but the file is named build/libs/${project.name}-0.1-${timestamp}.jar

When I use the old maven plugin instead, everything works perfectly.

Please see https://github.com/kercheval/GradleCMPlugin/issues/28 for more details.

Is this a bug in the maven-publish plugin?

It looks like we headed into the same problem some days ago. Actually, you are able to set/change the version but you have to touch multiple locations:

project.tasks.withType(PublishToMavenRepository) { publishTask ->
     publishTask.publication.version = project.version
        ...

Furthermore, replace the version in the pom.

project.tasks.withType(GenerateMavenPom).each { generateMavenPomTask ->
        generateMavenPomTask.pom.getProjectIdentity().version = project.version
        ...

Unfortunately it is a little bit trickier for dependencies, since there is no public api for updating the version over there. Therefore we seemingly currently have to use reflection (!) for changing the version for these dependencies…

Ideally, however, we think that these manipulations should not be necessary at all?

This really does seem to be a gradle behavioral problem (a bug). The maven project identity object in the gradle sources appears to be created at plugin apply (MavenPublishPlugin.java@71). This appears true as well for other publish plugins. This is way too early in the lifecycle for gradle init.

Version is very dynamic and should never be used by plugins prior to initial completion of the task graph. In most scenarios, the project version should be used only at task execution (with only modifiers executing at graph completion). The gradle publish plugins explicitly violate this expectation.

While plugin order dependency is likely unavoidable in some circumstances, in this particular case version assignment must be made prior to the apply plugin line in the gradle file or the project version according to the publish plugins will be out of date.

I am uncertain of the design considerations around this decision, but perhaps the publish plugin is trying to allow a version assignment for the POM that differs from the project version. This could be handled in a better manner if so.

I think we are going to need a gradle dev/qa response in this thread.

Same problem with our semantic versioning plugin. The maven-publish plugin tries to read the version too early resulting in a build failure.

Can this behavior be changed?

I have ran into this issue when trying to write a plugin. I managed to fixed it by using the ModelRule API

If you have a plugin is setting the version using afterEvaluate (for example because it needs to read some configuration from the build script in apply), then it will likly fail. There is a solution, which is incubating…

The ModelRule API enables you to say. I need to modify some configuration once other configuration has been finalised, and thefore build dependencies between various types of configuration. Thus it’s possible to modify the publication configuration, before it’s finalised once you have the input you need.

Perhpahs a gradle dev could verify this, but it’s working for me. (Documentation for this API is pretty incomplete, but I figured it out from the code.) Check out org.gradle.model.ModelRule and see an look at the source code for the maven-publish and publish plugins.

If I get a chance I could post an example…

Hey Tim,

I’m also hitting this issue with a custom plugin that needs to modify the project version, and have had a poke around in the ModelRule code, but it is pretty sparsely-documented. It’d be great if you could post an example of how you used it to do this. I imagine this must be a not-entirely-uncommon problem.

Is there an issue for this or has it been fixed?

The issue tracker asks users to raise issue via the forums, so is it possible to have this added as an issue? Here are 3 issues in downstream projects that would benefit from a definitive way of dealing with this…

https://github.com/townsfolk/gradle-release/issues/82 https://github.com/foo4u/gradle-semver-plugin/issues/3 https://github.com/kercheval/GradleCMPlugin/issues/28