How to get the next build number in Gradle
Asked Answered
T

5

26

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'
Tierratiersten answered 19/11, 2017 at 7:32 Comment(3)
How can plugin understand what should be the next version? In your case it might be 3.0.2 or 3.1.0 or 4.0.0. Some libs might have completely different versioning standards, for instance latest hibernate version is 5.2.12.Final.Olney
@OleksandrShpota ant's ivy:buildnumber task does this pretty good look at thisNevsa
Maybe if you use your build number differently. For example, if my version is 1.2.4 my build number could be 010204. I guess you could write your own plugin which would by default do 1.2.4 -> 1.2.5 and 010204 -> 010205. I haven't written Gradle plugins so far so I can't help you with that.Reimer
T
4

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)

Tierratiersten answered 20/1, 2018 at 11:59 Comment(0)
C
10

I don't think there is support in Gradle, but you can try to use the Ant task. https://docs.gradle.org/current/userguide/ant.html#sec:import_ant_build

Another way to do this is to use some sort of plugin, or customized task for managing the version.

Congdon answered 21/11, 2017 at 0:29 Comment(0)
D
9

Yes, you can access ivy tasks from the ant script by importing ant's build.xml file to gradle's build.gradle file. Following is the syntax to do so.

ant.importBuild 'build.xml'

Please refer : https://docs.gradle.org/current/userguide/ant.html#sec:import_ant_build

Distiller answered 27/11, 2017 at 8:31 Comment(0)
T
6

I recommend you to use ResearchGate release plugin https://github.com/researchgate/gradle-release It has a pretty documentation. Easy to read. Also, check out how I used it in my personal project. https://github.com/vatolinrp/bitcoin-esb/blob/master/build.gradle It would be a nice example for you.

Teriann answered 27/11, 2017 at 9:18 Comment(0)
T
4

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)

Tierratiersten answered 20/1, 2018 at 11:59 Comment(0)
S
4
  • 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)

Sensitivity answered 26/1, 2018 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.