How to get the next build number in Gradle

Viewed 7210

Is there any way to get the next version when publishing to a repository in gradle?

For e.g. if I have the version 3.0.1 in my repository I want the published version to be 3.0.2.

ivy has a task for ant named buildnumber which does exactly that:

<project xmlns:ivy="antlib:org.apache.ivy.ant"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<target name="ivyBuildNumber" description="Use ivy get the next build number">
    <ivy:buildnumber
        resolver="url-chain"
        organisation="${ivy.organisation}"
        module="${ivy.module}"
        revision="${version.base}"/>

    <echoproperties prefix="ivy.new."/>
</target>

Is there a way to do so in gradle? if not how can I access ivy tasks from gradle's ant?

In my build.gradle I calling to the ant

ant.importBuild 'build.xml'
5 Answers

After a long work, I managed to do that.

In my build.gradle I added this following code

ant.importBuild 'build.xml'

task getNextBuild(dependsOn : ivyBuildNumber) {
    doLast{
        def nextVersion = ant.properties['ivy.new.revision']
        println nextVersion
    }
}

I imported my ant build file, and created a task that calls the ivy buildnumber task.

There is my build.xml

<project xmlns:ivy="antlib:org.apache.ivy.ant">

    <target name="ivyBuildNumber">
        <path id="ivy.classpath" path="lib/ivy.jar" />
        <typedef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.classpath" />
        <ivy:buildnumber
            organisation="daniel"
            module="hello"/>
        <echoproperties prefix="ivy.new."/>
    </target>
</project>

Because my IDE (Intellij), didn't have ivy.jar in the content,
I imported the ivy.jar from my root dir (lib/ivy.jar)

  • For this exact behavior, Ivy buildnumber task can be invoked using pure Gradle without importing the Ant build:
configurations {
    antTasks // define a new configuration
}

repositories {
    mavenCentral()
}

dependencies {
    antTasks("org.apache.ivy:ivy:2.4.0") // add Ivy library to it
}

ext {
    // define the Ivy task, using the extra configuration as classpath extension
    ant.taskdef(name: "ivyBuildNumber", 
                classname: "org.apache.ivy.ant.IvyBuildNumber", 
                classpath: configurations.antTasks.asPath) 

    ant.ivyBuildNumber(organisation: "daniel", module: "hello")
    nextVersion = ant.properties["ivy.new.revision"]
}

task demo {
    doLast {
        println nextVersion
    }
}
  • In general, Gradle doesn't have any bundled equivalent to Maven Release Plugin, so one has to rely on plugins. One solid plugin is gradle-release by ResearchGate, the other is axion by Allegro Tech. The former is classic Maven-style versioning, the latter takes SCM itself as the only source of truth, eliminating the versioning in the build files. But neither of these plugins does provide the exact requested behavior.

  • My personal take on the versioning problem was initially to use some plugins. Since I use Bamboo as CI server at work, literally everything I did with release plugins using Gradle crashed on CI server sooner or later. It might have worked for some weeks, but every server update brought some problems. I ended up using SCM-less approach with a simple convention: use branch name as base version, concatenate it with build number (both values are provided by the CI server):

ext {
    branch = System.getProperty("branch", "develop")
    buildNumber = System.getProperty("buildNumber", "latest")
    isRelease = System.getProperty("isRelease", "false").toBoolean()
    artifactVersion = "${branch}${(isRelease ? ".$buildNumber" : "-SNAPSHOT")}"
}

CI server then can be set up for executing the following command

./gradlew -DisRelease=true -Dbranch=${git.branch} -DbuildNumber=${build.number} mavenPublish

when 'Release' button is pushed. For example, build 12 of the 3.0 branch will produce version 3.0.12 in the binary repository.

The advantages are:
+ the version comes for free, assuming the branches are named accordingly
+ the auto-incremented build number also comes for free
+ one can easily publish custom revisions
+ no plugins means no problems with Gradle version updates
+ this approach is dead simple and always works

The downsides are:
- additional script tasks are required for tags
- some build numbers will be skipped, obviously (e.g. next version after 3.5.76 can be 3.5.84)

Related