How to publish to two repositories (snapshot and release) with appropriate version number


(Andreas Sahlbach) #1

Ok, I am the build master for some builds here. The build system has to be usable by release manager and developer. Both groups should not be bothered about build details and should not be able to do serious errors. So I have to write a build script with the following requirements:

  • using the build should not require setting system properties or something. usage of “gradle taskname” should be sufficient * I want to publish snapshots to a snapshot repository (ivy or maven compatible) * I want to publish releases to a release repository (maven compatible, because it’s used from outside our project) * snapshots should have versions with a timestamp like 3.5.0-20131211.120012 * releases should have clean versions without timestamp like 3.5.0

Is it possible to make the version of a publication dynamically using some Groovy magic? It looks like, the version of a publishing->publications->MavenPublication is defined during the configuration phase. By the time the gradle script knows, if it is a snapshot or a release build, the version number of the pom is already defined.

Can I use some closures magic to delay the calculating of the version number or can I modify the version number of the MavenPublication somehow? Because of my requirements above I don’t want to force the user to use command line tricks like defining the repository or version via system property or similar stuff. This is too error prone and unconvenient.

Any help will be appreciated,

Andreas


(Peter Niederwieser) #2

How do you decide if it’s a snapshot or release version?


(Andreas Sahlbach) #3

By the task name… gradle snapshot -> snapshot gradle release -> release The base version 3.5.0 is in the gradle.settings checked in and is managed by the release manager.


(Peter Niederwieser) #4

You can check which of the two tasks will get executed using the ‘gradle.taskGraph.whenReady’ callback. At the time the callback occurs (after the task execution graph has been built but before any tasks have been executed), you should still be able to reconfigure things. For API details see the Gradle Build Language Reference. You might also find an example in the Gradle User Guide.

Alternatively, you can base your decision on the task names provided on the command line (‘gradle.startParameter.taskNames’). This is a pragmatic solution which has its limitations, but it is simple and allows you to make a decision at any time.


(Andreas Sahlbach) #5

I was trying to find a solution with gradle.taskGraph.whenReady. But when the taskGraph is ready, the publication object is already created and I couldn’t find a way to get hold of the publication object that was defined during the configuration phase.

All examples of the reference documentation are using the declarative way to set properties for the publication. Is there a generic way to get hold of these build objects you define in your script (I think they are called conventions) so I can modify them within the execution phase?

I will give your second solution a try. It might be sufficient for my case, because they are probably always tasks from the end of the task graph.

Thanks for your help, Peter!


(Peter Niederwieser) #6

Usually, you can get hold of any model object at any time, but should (whenever possible) only mutate it in the configuration phase. The publication objects of the incubating ‘maven-publish’ and ‘ivy-publish’ plugins are different in that they are part of an ongoing experiment to improve Gradle’s configuration mechanism, and as such are created lazily. I can’t tell offhand how to get hold of them, although from what I remember, ‘afterEvaluate {}’ and ‘taskGraph.whenReady {}’ have worked for me in the past.


(Matt Khan) #7

I deal with this by calculating version (and setting it on the relevant projects) in a taskGraph.whenReady callback & by adding a task that configures the upload locations and then making all Upload tasks depend on that

i.e.

def repoConfig = project.task(type: ConfigureUploadRepo, 'configureUploadRepos')
project.tasks.withType(Upload).all { it.dependsOn repoConfig }

the repoConfig task just deals with configuring the uploadArchives and install tasks in the usual manner