Android 在 Git 中构建版本自动化
Android build version automation in Git
我曾经使用以下 Gradle 脚本在 Subversion 中自动构建版本:
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()
}
}
这个脚本的本质是从 SVN repo 获取当前修订 # 并将其用作生成的版本 # AndroidManifest.xml
,例如:
<!--
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" >
它让我的生活变得更加轻松,例如当我收到错误报告时,我可以轻松找到有问题的修订版。这真的很重要,尤其是在有多个 testers/distribution 点上传不同版本的情况下。
现在问题:
如何制作与 Git 类似的东西?在 Git 中没有单一的修订 #,只有分支的散列 - 但它是字母数字 - Android 只允许使用整数作为版本代码。
最后我想出了怎么做。这是代码:
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
}
我使用了shell脚本来生成版本,并将其作为环境变量注入:
# the build command (bash) in CI server
# versionCode: number of commits that are reachable from here
# *supposedly* monotonically increasing for each release build
export ANDROID_VERSION_CODE="$(git rev-list HEAD --count)"
# versionName: first 8 chars in commit SHA1
export ANDROID_VERSION_NAME="${GIT_COMMIT:0:8}"
// build.gradle
// read env variable as string or integer
def env = { System.getenv it }
def envInt = { Integer.parseInt(env(it)) }
android {
defaultConfig {
if (env("ANDROID_VERSION_CODE")) {
versionCode envInt("ANDROID_VERSION_CODE")
versionName env("ANDROID_VERSION_NAME")
} else {
// fallback
versionCode 1
versionName "1.0"
}
}
}
我曾经使用以下 Gradle 脚本在 Subversion 中自动构建版本:
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()
}
}
这个脚本的本质是从 SVN repo 获取当前修订 # 并将其用作生成的版本 # AndroidManifest.xml
,例如:
<!--
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" >
它让我的生活变得更加轻松,例如当我收到错误报告时,我可以轻松找到有问题的修订版。这真的很重要,尤其是在有多个 testers/distribution 点上传不同版本的情况下。
现在问题:
如何制作与 Git 类似的东西?在 Git 中没有单一的修订 #,只有分支的散列 - 但它是字母数字 - Android 只允许使用整数作为版本代码。
最后我想出了怎么做。这是代码:
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
}
我使用了shell脚本来生成版本,并将其作为环境变量注入:
# the build command (bash) in CI server
# versionCode: number of commits that are reachable from here
# *supposedly* monotonically increasing for each release build
export ANDROID_VERSION_CODE="$(git rev-list HEAD --count)"
# versionName: first 8 chars in commit SHA1
export ANDROID_VERSION_NAME="${GIT_COMMIT:0:8}"
// build.gradle
// read env variable as string or integer
def env = { System.getenv it }
def envInt = { Integer.parseInt(env(it)) }
android {
defaultConfig {
if (env("ANDROID_VERSION_CODE")) {
versionCode envInt("ANDROID_VERSION_CODE")
versionName env("ANDROID_VERSION_NAME")
} else {
// fallback
versionCode 1
versionName "1.0"
}
}
}