Gradle 自动版本控制脚本并在 Android 中包含提交哈希
Gradle script to autoversion and include the commit hash in Android
我需要编写一个 gradle 脚本来在每次提交时自动对我的应用程序进行版本控制。我还需要将提交哈希作为测试人员应用程序中的参考。
我很困惑自动版本控制通常是如何工作的。有人可以解释自动版本控制过程吗?
一个理想的解决方案是从项目的 git 状态中获取版本。这样,版本控制不依赖于您记住增加变量,或更改 gradle 或配置文件中的任何文本。另一个优点是版本名称和代码可以追溯到一个特定的代码状态。
您可以在 http://ryanharter.com/blog/2013/07/30/automatic-versioning-with-git-and-gradle/
中找到一个描述性示例
想法是使用 getVersionName 函数获取 git 信息,并在 gradle 脚本中使用该函数:
/*
* Gets the version name from the latest Git tag
*/
def getVersionName = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags'
standardOutput = stdout
}
return stdout.toString().trim()
}
节:
val gitDescribe: String by lazy {
val stdout = ByteArrayOutputStream()
rootProject.exec {
commandLine("git", "describe", "--tags")
standardOutput = stdout
}
stdout.toString().trim()
/* 'g' doesn't belong to the commit id and stands for 'git'
v0.1.9-1-g3a259e0 -> v0.1.9-1-3a259e0
if you like this to be removed then */
//.replace("-g", "-")
}
当然,你需要有可用的命令行git(因为将执行命令git describe --tags
来生成信息)。
另一种方法(也基于从 git 获取版本信息)可以将该逻辑外化到 gradle 插件 - 例如:
- https://github.com/moallemi/gradle-advanced-build-version
- https://github.com/infusionsoft/gradle-build-version-plugin
- https://github.com/nemerosa/versioning
使用哪种取决于您要应用哪种版本控制策略。
我遇到了类似的问题,但不想修改 versionName 以包含 git 哈希。我们希望将其保留为 1.2.2 之类的东西,但仍有可能在 UI 中显示 git 散列。
我修改了 中的代码,以使用 buildConfigField 任务生成一个 BuildConfig.GitHash 值,该值可以在 Java 代码中引用。
将此添加到模块 build.gradle 文件的 android
部分上方:
def getGitHash = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
}
然后将以下行添加到 build.gradle 的 android
部分的 defaultConfig
部分,即下面的 versionName
:
buildConfigField "String", "GitHash", "\"${getGitHash()}\""
这会在 auto-generated BuildConfig.java 文件中生成以下行:
// Fields from default config.
public static final String GitHash = "e61af97";
现在您可以使用 BuildConfig.GitHash
在 Java 代码中获取 git 哈希值。
也值得一看 grgit - Groovy/Gradle Git,它可以帮助简化信息提取,包括 Git 提交哈希,在 Gradle 脚本中。
我创建了一个 Gradle 插件来为您完成这项工作。项目和完整说明位于 https://github.com/lessthanoptimal/gversion-plugin
要使用它,请将以下内容添加到您的 build.gradle 文件
plugins {
id "com.peterabeles.gversion" version "1.2.4"
}
gversion {
srcDir = "src/main/java/"
classPackage = "com.your.package"
className = "MyVersion" // optional. If not specified GVersion is used
dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" // optional. This is the default
timeZone = "UTC" // optional. UTC is default
}
现在您只需要 运行 gradle 任务 'createVersionFile' 来创建文件。您可能需要考虑将以下行添加到您的 gradle 项目 project.compileJava.dependsOn(createVersionFile)
这将导致它在每次 Gradle 构建项目时生成文件。有关 Android 说明,请参阅上面的网站。
文件如下所示
/**
* Automatically generated file containing build version information.
*/
public class MyVersion {
public static final String MAVEN_GROUP = "com.your";
public static final String MAVEN_NAME = "project_name";
public static final String VERSION = "1.0-SNAPSHOT";
public static final int GIT_REVISION = 56;
public static final String GIT_SHA = "a0e41dd1a068d184009227083fa6ae276ef1846a";
public static final String BUILD_DATE = "2018-04-11T12:19:03Z";
public static final long BUILD_UNIX_TIME = 1523449143116L;
}
您可能还想将版本文件添加到您的 .gitignore 中,因为它是自动生成的,您不希望它出现在 git.
中
将以下代码添加到您的 build.gradle
def gitCommitHash = 'git rev-parse --verify --short HEAD'.execute().text.trim()
defaultConfig{
... otherConfigs
buildConfigField("String", "GIT_HASH", "\"${gitCommitHash}\"")
}
现在您可以通过 BuildConfig.GIT_HASH
获得 git 哈希
玩得开心
这是 Kotlin DSL (build.gradle.kts) derived from 的解决方案:
task<Exec>("MyTask") {
doLast {
commandLine("git")
.args("rev-parse", "--verify", "--short", "HEAD")
.workingDir(rootProject.projectDir)
}
}
另一种使用 Java 标准的方法 ProcessBuilder API:
tasks.create("MyTask") {
val command = "git rev-parse --verify --short HEAD"
doLast {
val process = ProcessBuilder()
.command(command.split(" "))
.directory(rootProject.projectDir)
.redirectOutput(Redirect.INHERIT)
.redirectError(Redirect.INHERIT)
.start()
process.waitFor(60, TimeUnit.SECONDS)
val result = process.inputStream.bufferedReader().readText()
println(result)
}
}
有关详细信息,请参阅:
- How to invoke external command from within Kotlin code?
我需要编写一个 gradle 脚本来在每次提交时自动对我的应用程序进行版本控制。我还需要将提交哈希作为测试人员应用程序中的参考。
我很困惑自动版本控制通常是如何工作的。有人可以解释自动版本控制过程吗?
一个理想的解决方案是从项目的 git 状态中获取版本。这样,版本控制不依赖于您记住增加变量,或更改 gradle 或配置文件中的任何文本。另一个优点是版本名称和代码可以追溯到一个特定的代码状态。
您可以在 http://ryanharter.com/blog/2013/07/30/automatic-versioning-with-git-and-gradle/
中找到一个描述性示例想法是使用 getVersionName 函数获取 git 信息,并在 gradle 脚本中使用该函数:
/*
* Gets the version name from the latest Git tag
*/
def getVersionName = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--tags'
standardOutput = stdout
}
return stdout.toString().trim()
}
节:
val gitDescribe: String by lazy {
val stdout = ByteArrayOutputStream()
rootProject.exec {
commandLine("git", "describe", "--tags")
standardOutput = stdout
}
stdout.toString().trim()
/* 'g' doesn't belong to the commit id and stands for 'git'
v0.1.9-1-g3a259e0 -> v0.1.9-1-3a259e0
if you like this to be removed then */
//.replace("-g", "-")
}
当然,你需要有可用的命令行git(因为将执行命令git describe --tags
来生成信息)。
另一种方法(也基于从 git 获取版本信息)可以将该逻辑外化到 gradle 插件 - 例如:
- https://github.com/moallemi/gradle-advanced-build-version
- https://github.com/infusionsoft/gradle-build-version-plugin
- https://github.com/nemerosa/versioning
使用哪种取决于您要应用哪种版本控制策略。
我遇到了类似的问题,但不想修改 versionName 以包含 git 哈希。我们希望将其保留为 1.2.2 之类的东西,但仍有可能在 UI 中显示 git 散列。
我修改了
将此添加到模块 build.gradle 文件的 android
部分上方:
def getGitHash = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim()
}
然后将以下行添加到 build.gradle 的 android
部分的 defaultConfig
部分,即下面的 versionName
:
buildConfigField "String", "GitHash", "\"${getGitHash()}\""
这会在 auto-generated BuildConfig.java 文件中生成以下行:
// Fields from default config.
public static final String GitHash = "e61af97";
现在您可以使用 BuildConfig.GitHash
在 Java 代码中获取 git 哈希值。
也值得一看 grgit - Groovy/Gradle Git,它可以帮助简化信息提取,包括 Git 提交哈希,在 Gradle 脚本中。
我创建了一个 Gradle 插件来为您完成这项工作。项目和完整说明位于 https://github.com/lessthanoptimal/gversion-plugin
要使用它,请将以下内容添加到您的 build.gradle 文件
plugins {
id "com.peterabeles.gversion" version "1.2.4"
}
gversion {
srcDir = "src/main/java/"
classPackage = "com.your.package"
className = "MyVersion" // optional. If not specified GVersion is used
dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" // optional. This is the default
timeZone = "UTC" // optional. UTC is default
}
现在您只需要 运行 gradle 任务 'createVersionFile' 来创建文件。您可能需要考虑将以下行添加到您的 gradle 项目 project.compileJava.dependsOn(createVersionFile)
这将导致它在每次 Gradle 构建项目时生成文件。有关 Android 说明,请参阅上面的网站。
文件如下所示
/**
* Automatically generated file containing build version information.
*/
public class MyVersion {
public static final String MAVEN_GROUP = "com.your";
public static final String MAVEN_NAME = "project_name";
public static final String VERSION = "1.0-SNAPSHOT";
public static final int GIT_REVISION = 56;
public static final String GIT_SHA = "a0e41dd1a068d184009227083fa6ae276ef1846a";
public static final String BUILD_DATE = "2018-04-11T12:19:03Z";
public static final long BUILD_UNIX_TIME = 1523449143116L;
}
您可能还想将版本文件添加到您的 .gitignore 中,因为它是自动生成的,您不希望它出现在 git.
中将以下代码添加到您的 build.gradle
def gitCommitHash = 'git rev-parse --verify --short HEAD'.execute().text.trim()
defaultConfig{
... otherConfigs
buildConfigField("String", "GIT_HASH", "\"${gitCommitHash}\"")
}
现在您可以通过 BuildConfig.GIT_HASH
玩得开心
这是 Kotlin DSL (build.gradle.kts) derived from
task<Exec>("MyTask") {
doLast {
commandLine("git")
.args("rev-parse", "--verify", "--short", "HEAD")
.workingDir(rootProject.projectDir)
}
}
另一种使用 Java 标准的方法 ProcessBuilder API:
tasks.create("MyTask") {
val command = "git rev-parse --verify --short HEAD"
doLast {
val process = ProcessBuilder()
.command(command.split(" "))
.directory(rootProject.projectDir)
.redirectOutput(Redirect.INHERIT)
.redirectError(Redirect.INHERIT)
.start()
process.waitFor(60, TimeUnit.SECONDS)
val result = process.inputStream.bufferedReader().readText()
println(result)
}
}
有关详细信息,请参阅:
- How to invoke external command from within Kotlin code?