Android Studio Gradle 自动版本控制

Author Avatar
Omico Yuwen 2月 03, 2017
  • 在其它设备中阅读本文章

这篇文章缘起在酷安上,neoFelhz 与我的对话。

经过了我的这个 APP 第三次 Release 之后,我突然觉得,自动版本控制还是很重要的,但是我觉得 SemVer 对于我的小项目过于繁琐,因此有了这篇文章。

git diff 的盆友,可以直接看这条 commit 快速 GET 这项技能。

https://github.com/Omico/CurrentActivity/commit/96af43e2b8b4cff53020889a6a91f40b0ceb32fe

自动版本号(versionCode)

关于自动版本号,我就像图片里说的,我认为用 commit id 的个数就能很好表达。

通过参考 git 文档,我得出以下命令:

1
2
3
4
def getVersionCode() {
def cmd = 'git rev-list HEAD --count'
return cmd.execute().text.trim().toInteger()
}

这样能通过统计所有 commit id 的个数来确定版本号。

自动版本名(versionName)

关于自动版本名,这个灵感来自一次无意间的思考,在我编译 Android 系统的时候,内核的版本号的生成让我比较好奇。

因此我翻阅了 kernel 的源码,在 <内核根目录>/scripts/setlocalversion 这个文件中,我发现了我要的,看到是由 git describe 这个命令实现的,于是我翻阅了 git 文档,经过一番探索,我得出了以下命令:

1
2
3
4
def getVersionName() {
def cmd = 'git describe --tags --dirty'
return cmd.execute().text.trim()
}

这样得到的版本名就是你的 Tag 名。

当你的工作区最后一次 commit id 与你的最新 Tag 的 commit id 相同时,你的版本名就会是<最后一个 Tag 名>

例如:

v1.0.8

当你的工作区最后一次 commit id 与你的最新 Tag 的 commit id 相同,但修改了项目工程时,你的版本名就会是<最后一个 Tag 名>-dirty

例如:

v1.0.8-dirty

当你的工作区没有提交新的 Tag ,但有新的 commit 时,你的版本名就会是<最后一个 Tag 名>-<在最后一个 Tag 之后,提交 commit 的个数>-g<commit id 的前七位>

例如:

v1.0.8-1-g96af43e

当你的工作区没有提交新的 Tag ,也没有新的 commit ,但修改了项目工程时,你的版本名就会是<最后一个 Tag 名>-<在最后一个 Tag 之后,提交 commit 的个数>-g<commit id 的前七位>-dirty

例如:

v1.0.8-1-g96af43e-dirty

在工程里应用

修改前:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "me.omico.currentactivity"
minSdkVersion 19
targetSdkVersion 25
versionCode 4
versionName "1.0.3"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.android.support:design:25.1.1'
}

修改后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "me.omico.currentactivity"
minSdkVersion 19
targetSdkVersion 25
versionCode getVersionCode()
versionName getVersionName()
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:25.1.1'
compile 'com.android.support:design:25.1.1'
}

def getVersionCode() {
def cmd = 'git rev-list HEAD --first-parent --count'
return cmd.execute().text.trim().toInteger()
}

def getVersionName() {
def cmd = 'git describe --tags --dirty'
return cmd.execute().text.trim()
}

参考链接:
https://git-scm.com/docs/git-rev-list
https://git-scm.com/docs/git-describe

This blog is under a CC BY-NC-SA 3.0 CN License
本文链接:https://blog.omico.me/android-studio-gradle-auto-version-control/