Publishing plugin and dynamically set project version


(Alexej Kubarev) #1

Hi,

I’m trying to create a release process with Gradle for our Java-based projects. Most of the things are working properly now but I’m having a problem that I cannot yet resolve. This is mainly around the new Maven Publishing plugin (yes, i’m very well aware it’s incubating still) and the dynamic version of the project.

What I’m trying to achieve is that we never add ‘-SNAPSHOT’ or ‘-RC<0-9>’ to the version but it’s always set to something like ‘3.2.1’ or ‘3.2.2’, then when a taskGraph is ready I am checking if the release task is in the graph and change ‘project.version’ property accordingly, then the project is built and a few other tasks are triggered (such as Git tagging, commiting etc…). Now the only thing that is behaving incorrectly for me is the ‘publish’ task.

I would like to trigger the publish task from either within my ‘release’ task (This would be best, but for some reason ‘tasks[“publish”].execute()’ doesn’t work) or to put it as dependency to my release task (which i can do and it gets triggered) but for ‘publish’ to understand the modified version. I have a feeling that it reads and saves the ‘project.version’ as soon as the publishing extension is configured via

publishing {
        publications {
            java(MavenPublication) {
                from components.java
            }
        }
            repositories {
            maven {
                if(project.version.endsWith('-SNAPSHOT')) {
                    name = 'nexus.snapshots'
                    url 'http://mynexus/nexus/content/repositories/snapshots'
                } else {
                    name = 'nexus.releases'
                    url 'http://mynexus/nexus/content/repositories/releases'
                }
            }
        }
    }

To make it simpler to understand my flow would be like this: When script is initialised, it validates if it’s a release or a dev build, changes versions accordingly and runs publish. After the publish task, if this is a release build - Go through the tagging and version bumping processes and push it all. So basically the only part that is giving me problem is making publish aware and accept the version changes. If my gradle.properties contains ‘version=3.2.1’ and I run a dev build, publication plugin still thinks it’s 3.2.1 and looks for ‘artefact-3.2.1.jar’ even though I’ve changed version in the ‘gradle.taskGraph.whenReady’ to be 3.2.1-SNAPSHOT.

Is there a good way to achieve what I’m trying to do - make publishing aware of my new version without breaking anything else?


#2

You likely need to update the ‘MavenPublication’ with the new version at the same time you set the project version.
Try something like ‘publishing.publications.java.version = ‘3.2.1-SNAPSHOT’’. I can’t recall if you need to update the various artifacts inside the publication as well.


(Alexej Kubarev) #3

Thanks, I was actually able to get it to work, somewhat but it was pretty “hacky” to say the least. It does feel like this is something that should be simplified before it’s time for maven-publish plugin to go out of incubation.

My solution involved doing the following when gradle.taskGraph.whenReady is called and correct version (snapshot or release) is determined:

project.tasks.withType(PublishToMavenRepository) { publishTask ->
        def oldArtifacts = publishTask.publication.artifacts.toArray()
        publishTask.publication.artifacts.clear()
                  oldArtifacts.each({ artifact ->
            publishTask.publication.artifacts.artifact(
                source:
     artifact.file.getAbsolutePath().replaceAll(publishTask.publication.version, project.version),
                 classifier:
 artifact.classifier,
                 extension:
artifact.extension
            )
        })
                  if(project.version.endsWith('-SNAPSHOT')) {
            publishTask.repository.url 'http://mynexus/nexus/content/repositories/snapshots'
        } else {
            publishTask.repository.url 'http://mynexus/nexus/content/repositories/releases'
        }
                  publishTask.publication.version = project.version
    }
          project.tasks.withType(GenerateMavenPom).each { generateMavenPomTask ->
        generateMavenPomTask.pom.getProjectIdentity().version = project.version
    }

Basically it involves modifying all of the artifacts, publications and also the pom generation. Thank you for confirming that this seemed to be the right, even though quite cumbersome way to do it. Are there any plans on simplifying all this in the next releases?


#4

The publishing plugins are early-adopters of the new Gradle configuration model. This is in very early stages of development, but I expect it to gain some momentum in the coming releases.

You can read more about it here: https://github.com/gradle/gradle/blob/master/design-docs/unified-configuration-and-task-model.md


(Justin Ryan) #5

I dealt with this by lazily refreshing the version and groupId. My implementation is hidden in a “publishing” plugins I’m working on that deals with this pretty generically and tries to hide some of the rought-edges that exist with the maven-publish plugin:

https://github.com/nebula-plugins/nebula-publishing-plugin/blob/1.9.0/src/main/groovy/nebula/plugin/publishing/NebulaMavenPublishingPlugin.groovy#L79