Search code examples
androidgitsvnversion-controlgradle

Android build version automation in Git


I used to automate build version in Subversion using following Gradle script:

import org.tmatesoft.svn.core.wc.*

buildscript {
    dependencies {
         classpath 'com.neenbedankt.gradle.plugins:android-apt:1.2+'
        classpath 'com.android.tools.build:gradle:1.0.0'
        classpath group: 'org.tmatesoft.svnkit', name: 'svnkit', version: '1.7.11'
    }
}

def getSvnRevision() { //getting SVN revision #
    ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
    SVNClientManager clientManager = SVNClientManager.newInstance(options);
    SVNStatusClient statusClient = clientManager.getStatusClient();
    SVNStatus status = statusClient.doStatus(projectDir, false);
    SVNRevision revision = status.getRevision();
    return revision.getNumber();
}

android {
    compileSdkVersion 21
    buildToolsVersion '21.1.2'

    defaultConfig {
        versionName = "1.0." + getSvnRevision()
        versionCode = 1000000 + getSvnRevision()
    }
}

Essense of this script is to get from SVN repo current revision # and use it as version # to generated AndroidManifest.xml, like:

<!--
 Version number encoding: XXYYZZZ
    XX 2 digits - major version
    YY 2 digits - minor version
    ZZZ 3 digits - build (SVN revision)
    Example: 0123456 is version 1.23.456
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="my.package"
    android:versionCode="1000650"
    android:versionName="1.0.650" >

It makes my life significantly easier, e.g. when I receive bug report I can easily locate revision with issue. It really matters especially in case when one has several testers/distribution points where different versions are uploaded.

Now question:

How can I make something similar with Git? In Git there's no single revision #, instead there's only hash of branch - but it's alphanumeric - Android permits usage only of integers as version code.


Solution

  • In the end I've figured how to do it. Here's code:

    def getGitRevision = { ->
        try {
            def stdout = new ByteArrayOutputStream()
            exec {
                standardOutput = stdout
                commandLine 'git', 'rev-list', '--first-parent', '--count', 'master'
            }
            println("Building revision #"+stdout)
            return asInteger(stdout.toString("ASCII").trim())
        }
        catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    
    android {
        /*
        Version number encoding: XXYYZZZB
        XX 2 digits - major version
        YY 2 digits - minor version
        ZZZ 3 digits - build (VCS revision)
        B 1 digit - build variation/patch
        Example: 01234561 is version 1.23.456a
        */
    
        def char[] patches='abcdefghijklmnopqrstuwxyz'.toCharArray()
        def majorVersion=1
        def minorVersion=3
        def revision=getGitRevision()
        def patch=0
        defaultConfig {
            applicationId "com.my.package"
            versionName = majorVersion + '.' + minorVersion + '.' + revision + patches[patch]
            versionCode = 10000000*majorVersion+10000*minorVersion + 10*revision+patch
        }