Skip to content

Instantly share code, notes, and snippets.

@orip
Created October 7, 2013 17:52
Show Gist options
  • Save orip/6872109 to your computer and use it in GitHub Desktop.
Save orip/6872109 to your computer and use it in GitHub Desktop.
Define an Android app's versionName and versionCode from git tags. http://orip.org/2013/10/versioning-android-apps-with-git-tags.html
android {
def gitTag = {
def tagMatchOptions
try {
tagMatchOptions = "--match ${tagToBuildFrom}"
} catch (MissingPropertyException) {
tagMatchOptions = ""
}
"git describe --exact HEAD ${tagMatchOptions}".execute().text.trim()
}()
def gitHash = "git rev-parse --short HEAD".execute().text.trim()
def hasModifiedDeletedOrOtherFiles = !"git ls-files -mdo --exclude-standard".execute().text.trim().isEmpty()
def hasStagedFiles = !"git diff-index --no-ext-diff --name-only --cached HEAD".execute().text.trim().isEmpty()
def dirtyWorkingCopy = hasModifiedDeletedOrOtherFiles || hasStagedFiles
def gitDescription = dirtyWorkingCopy ? "${gitHash}-dirty" : gitHash
// Version name: ignore leading non-digits and everything after the first underscore
// Version code: take digits after the first underscore
// e.g. tag xxx1.2.3.foo-bar_15_baz will yield versionName 1.2.3.foo-bar and versionCode 15
def versionMatcher = gitTag =~ /^[^0-9]*([^_]*)(_([0-9]*))?/
// TODO: die if building a public release with no tag instead of having defaults
def versionNameFromTag = versionMatcher[0][1]
def versionCodeFromTag = versionMatcher[0][3]?.toInteger()
defaultConfig {
minSdkVersion 10
targetSdkVersion 18
// TODO: die if building a public release with no tag instead of having defaults
versionName versionNameFromTag ?: "dev"
versionCode versionCodeFromTag ?: 1
buildConfig += "public static final String GIT_DESCRIPTION = \"${gitDescription}\";"
// Show this in the 'about' dialog
buildConfig += "public static final String VERSION = \"${versionName} ${gitDescription}\";"
}
applicationVariants.all { variant ->
def apkSuffix = "-${variant.mergedFlavor.versionName}-${gitDescription}"
def originalApkFile = variant.outputFile
variant.outputFile = file(originalApkFile.name.replace(".apk", "${apkSuffix}.apk"))
// print the APK path after assemble is done
variant.assemble.doLast {
println variant.outputFile
}
// print the APK path as the last step before install, at which point the apk is complete
variant.install?.doFirst { // the install task can be null
println variant.outputFile
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment