'Version increment using gradle task

I want to increase the version number of my project from 1.0.0. to 1.0.1 automatically whenever a new build is made through bash command. I only need to increase path number and others i will be increasing manually during manual build.

i want to change

this :

version=1.0.0

to This:

version=1.0.1

using gradle task. any help that how can i do this . Is there any way to update this using regex or using substring function.



Solution 1:[1]

Here is an example task:

version='1.0.0'  //version we need to change

task increment<<{
    def v=buildFile.getText().find(version) //get this build file's text and extract the version value
    String minor=v.substring(v.lastIndexOf('.')+1) //get last digit
    int m=minor.toInteger()+1                      //increment
    String major=v.substring(0,v.length()-1)       //get the beginning
    //println m
    String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+m+"'")
    //println s
    buildFile.setText(s) //replace the build file's text
}

Run this task several times and you should see the version change.

A variant:

version='1.0.0'

task incrementVersion<<{
    String minor=version.substring(version.lastIndexOf('.')+1)
    int m=minor.toInteger()+1
    String major=version.substring(0,version.length()-1)
    String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+m+"'")
    buildFile.setText(s)
}

Solution 2:[2]

Here's a custom task for version bumps in Gradle (Android project):

class Version {

    private int major
    private int minor
    private int patch
    private int code

    Version(int code, String version) {
        this.code = code

        def (major, minor, patch) = version.tokenize('.')
        this.major = major.toInteger()
        this.minor = minor.toInteger()
        this.patch = patch.toInteger()
    }

    @SuppressWarnings("unused")
    void bumpMajor() {
        major += 1
        minor = 0
        patch = 0

        code += 1
    }

    @SuppressWarnings("unused")
    void bumpMinor() {
        minor += 1
        patch = 0

        code += 1
    }

    @SuppressWarnings("unused")
    void bumpPatch() {
        patch += 1
        code += 1
    }

    String getName() { "$major.$minor.$patch" }

    int getCode() { code }
}

tasks.addRule("Pattern: bump<TYPE>Version") { String taskName ->
    if (taskName.matches("bump(Major|Minor|Patch)Version")) {
        task(taskName) {
            doLast {
                String type = (taskName - 'bump' - 'Version')

                println "Bumping ${type.toLowerCase()} version…"

                int oldVersionCode = android.defaultConfig.versionCode
                String oldVersionName = android.defaultConfig.versionName

                version = new Version(oldVersionCode, oldVersionName)
                version."bump$type"()

                String newVersionName = version.getName()
                String newVersionCode = version.getCode()

                println "$oldVersionName ($oldVersionCode) ? $newVersionName ($newVersionCode)"

                def updated = buildFile.getText()
                updated = updated.replaceFirst("versionName '$oldVersionName'", "versionName '$newVersionName'")
                updated = updated.replaceFirst("versionCode $oldVersionCode", "versionCode $newVersionCode")

                buildFile.setText(updated)
            }
        }
    }
}

See this Kanji learning Android app for completeness.

Prerequisites

Following format required (note the single quotes):

android {
    defaultConfig {
        versionCode 3
        versionName '0.3.13'
    }
}

Usage

$ ./gradlew bumpPatchVersion

> Task :app:bumpPatchVersion
Bumping patch version…
0.3.13 (3) ? 0.3.14 (4)

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

$ ./gradlew bumpMinorVersion

> Task :app:bumpMinorVersion
Bumping minor version…
0.3.14 (4) ? 0.4.0 (5)

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

$ ./gradlew bumpMajorVersion             

> Task :app:bumpMajorVersion
Bumping major version…
0.4.0 (5) ? 1.0.0 (6)

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

Solution 3:[3]

You could also use split with a increment-matrix, that could be changed depending on the amount of changes:

def version = '1.0.0'
def incstep = '0.0.1'.split(/\./).collect{it.toInteger()}

def indexedVersionList = version.split(/\./).toList().withIndex()
def updatedVersionList = indexedVersionList.collect{num, idx -> num.toInteger()+incstep[idx]}
def updatedVersion = updatedVersionList.join(".")

Solution 4:[4]

This is how I did it with Kotlin DSL (build.gradle.kts):

tasks.create("incrementVersion") {
    group = "my tasks"
    description = "Increments the version in this build file everywhere it is used."
    fun generateVersion(): String {
        val updateMode = properties["mode"] ?: "minor" // By default, update the minor
        val (oldMajor, oldMinor, oldPatch) = version.split(".").map(String::toInt)
        var (newMajor, newMinor, newPatch) = arrayOf(oldMajor, oldMinor, 0)
        when (updateMode) {
            "major" -> newMajor = (oldMajor + 1).also { newMinor = 0 }
            "minor" -> newMinor = oldMinor + 1
            else -> newPatch = oldPatch + 1
        }
        return "$newMajor.$newMinor.$newPatch"
    }
    doLast {
        val newVersion = properties["overrideVersion"] as String? ?: generateVersion()
        val oldContent = buildFile.readText()
        val newContent = oldContent.replace("""= "$version"""", """= "$newVersion"""")
        buildFile.writeText(newContent)
    }
}

Usage:

./gradlew incrementVersion [-P[mode=major|minor|patch]|[overrideVersion=x]]

Examples:

./gradlew incrementVersion -Pmode=minor
./gradlew incrementVersion -PoverrideVersion=2.5.11

That is given that you have something like this in your build script:

version = "1.2.3"

... and the patch part of the version is just a number (not containing letters like alpha, rc, etc.).

Solution 5:[5]

Below solution will not create an issue evern last number exceed from 9-10 and so on

   version='1.0.11.1001'


    task incrementrevsion{
        def v = version
        println v
        String minor=v.substring(v.lastIndexOf('.')+1) //get last digit
        int m=minor.toInteger()+1                      //increment
        println m
        String major=v.substring(0,v.lastIndexOf("."));       //get the beginning
        println major
        String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+ "." +m+"'")
        //println s
        buildFile.setText(s) //replace the build file's text
    }

Solution 6:[6]

def patch = version.substring(version.lastIndexOf('.') + 1)
def p = patch.toInteger() + 1
def major = version.substring(0, version.length() - p.toString().length())
def s = buildFile.getText().replaceFirst("version = '$version'", "version = '" + major + p + "'")
buildFile.setText(s)

The only difference with Alexiy's answer that line 3 contains m.toString().length() as if minor version > 10, i.e 1.0.12 and you will use that approach it will change it to 1.0.113. We need to calculate the length of minor version instead of chopping off only 1 symbol.

And one more thing, usually the last number is called patch, minor is a middle one :)

Solution 7:[7]

My Solution where the version will be set by a Parameter.

version = '4.0.0' // I have whitespaces between the equals-sign
task setVersion << {
group = 'Versioning'
description = "Sets the version to the new number specified with -PnewVersion=\'x.x.x\'"
println version
if(project.hasProperty('newVersion')) {
    println 'Set Project to new Version '+newVersion
    String s=buildFile.getText().replaceFirst("version = '$version'","version = '"+newVersion+"'")
    buildFile.setText(s)
}

}

Call Gradle Task with:

gradle setVersion -PnewVersion='5.1.1'

Solution 8:[8]

As for me work this solution. You need add this code into build.gradle file:

version='1.0.1'

tasks.register("incrementVersion") {
doLast {
    def ver = version
    println ver
    String lastNumber = ver.substring(ver.lastIndexOf('.') + 1)
    int increment = lastNumber.toInteger() + 1
    println increment

    String firstNumber = ver.substring(0, ver.lastIndexOf("."))
    println firstNumber
    String result = buildFile.getText().replaceFirst("version='$version'","version='" + firstNumber + "." + increment + "'")
    buildFile.setText(result)
}

}

Solution 9:[9]

I know I am posting this quite late, but the answers mentioned above work well upto '1.0.99'. After which it starts misbehaving.

If any one is still interested, I found a different approach.

 task increment {

    def v = buildFile.getText().find(version)
    def (major, minor, patch) = v.tokenize('.')
    int newPatch = patch.toInteger() + 1
    String newVersion = major + "." + minor + "." + newPatch
    String updatedVersion = buildFile.getText().replaceFirst("version='"+v+"'","version='"+newVersion+"'")
    buildFile.setText(updatedVersion)
 }

Solution 10:[10]

This is an example of same think but with KTS(Kotlin Script).

val newVersion: String? by project
tasks.register("bumpVersion") {
    this.doFirst {
        println("Old version $version")
        val newVersion = takeIf { newVersion.isNullOrBlank() }?.let {
            val versionArray = version.toString().split(".")
            "${versionArray[0]}.${versionArray[1]}.${versionArray.last().toInt().plus(1)}"
        } ?: newVersion

        buildFile.readText().apply {
            println("Bump to $newVersion")
            val content = this.replaceFirst("version = \"$version\"", "version = \"$newVersion\"")
            buildFile.writeText(content)
        }
    }
}

Increment automatic the patch or it is possible to send new version as property.

./gradlew bumpVersion -PnewVersion=0.2.0

Solution 11:[11]

Kotlin dsl:

tasks.create("incrementPatch") {
    group = "version"
    description = "????????????? ??????? ???? ?????? ? ????? VERSION"
    doFirst {
        incrementVersion("patch")
    }
}
tasks.create("incrementMinor") {
    group = "version"
    description = "????????????? ??????? ????? ?????? ? ????? VERSION"
    doFirst {
        incrementVersion("minor")
    }
}
tasks.create("incrementMajor") {
    group = "version"
    description = "????????????? ??????? ????? ?????? ? ????? VERSION"
    doFirst {
        incrementVersion("major")
    }
}

tasks.named("compileKotlin") {
    dependsOn(":incrementPatch")
}

fun incrementVersion(updateMode: String){
    val versions = file("version").readText().trim()
    println("read version = $versions")
    val (oldMajor, oldMinor, oldPatch) = versions.substringBefore("-").split(".").map(String::toInt)
    var (newMajor, newMinor, newPatch) = arrayOf(oldMajor, oldMinor, 0)
    when (updateMode) {
        "major" -> newMajor = (oldMajor + 1).also { newMinor = 0 }
        "minor" -> newMinor = oldMinor + 1
        else -> newPatch = oldPatch + 1
    }
    val newVersion ="$newMajor.$newMinor.$newPatch-SNAPSHOT"
        println("new version = $newVersion")
    file("version").writeText(newVersion)
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 MushyPeas
Solution 4
Solution 5 unknown
Solution 6 Bogdan Nechyporenko
Solution 7
Solution 8
Solution 9 Aryan Raj
Solution 10 Rudge
Solution 11 Vovan