我相信计算机是做重复性任务的最佳选择。我当然不是,我要么忘记,要么(大多数时候)不以一致的方式做事 - 这不是我想要的。
我可能要做的一件事是在发布新版Android应用时忘记清单中的版本信息。在过去,我使用过具有自动版本编号功能的已配置构建系统,并且我已经习惯了(或者我可能很懒)。
我发现这个Stackoverflow post在提出解决方案时非常有用,但我花了一段时间对其进行微调,以便它能够按照我想要的方式工作。早期的尝试有时会导致继续建设,这是一个痛苦。所以我想我会在这里发布我的解决方案,希望别人能发现它有用。
答案 0 :(得分:14)
此解决方案是在Linux上开发的。我确信熟练的Windows& Mac开发人员可以将其适应他们的平台,但我不是这样的开发人员。 Linux是我的技能所在。
Git在git describe --dirty
命令中有一个很好的功能。它会向下扫描提交日志并找到标记,然后从那里构建一个版本字符串。如果这是一个“生产构建”,其中最后一次提交已被标记,并且所有文件都已签入,那么这就是您的版本字符串。如果这是一个开发版本,那么最后一个标记附加了额外提交的数量和缩写的哈希码。 --dirty
标志只是锦上添花的结果:如果尚未提交任何已修改的文件,它会附加单词dirty
。这非常适合清单文件中的android:versionName
属性。
对于android:versionCode
,需要一个号码。这需要为发布而不是开发构建计时,并且因为每个发行版将都有一个带有版本字符串的标记,我只需要计算这些。我始终以v<major>.<minor>[.<patch>]
格式标记我的版本,其中<major>
,<minor>
和<patch>
只是数字。因此计算以小写“v”开头,后跟数字的计数标记就是这里真正需要的。
在跟踪模板清单文件后,我发现最好的方法是在项目库中使用AndroidManifest.xml文件,使用流编辑器sed
进行编辑,并将结果存入bin / AndroidManifest.xml
所以我开发了下面的脚本,将它放在与我的项目相同级别的脚本文件夹中(以便它们可以共享相同的脚本),然后在Eclipse中配置自定义构建器。
有一个我称之为version.sh
的脚本:
#/bin/bash
echo "Auto Version: `pwd`"
CODE=`git tag | grep -c ^v[0-9]`
NAME=`git describe --dirty | sed -e 's/^v//'`
COMMITS=`echo ${NAME} | sed -e 's/[0-9\.]*//'`
if [ "x${COMMITS}x" = "xx" ] ; then
VERSION="${NAME}"
else
BRANCH=" (`git branch | grep "^\*" | sed -e 's/^..//'`)"
VERSION="${NAME}${BRANCH}"
fi
echo " Code: ${CODE}"
echo " Ver: ${VERSION}"
cat AndroidManifest.xml | \
sed -e "s/android:versionCode=\"[0-9][0-9]*\"/android:versionCode=\"${CODE}\"/" \
-e "s/android:versionName=\".*\"/android:versionName=\"${VERSION}\"/" \
> bin/AndroidManifest.xml
exit 0
要在此处配置构建器,请执行以下步骤:
1)。右键单击项目库并选择“属性”,然后选择“构建器”。
2)。点击“新建”按钮,然后选择“程序”选项。
3)。将您的版本命名为“&lt; project&gt; Auto Version”。这个字符串在所有项目中都必须是唯一的。
4)。按如下方式配置“Main”选项卡:
4A)。在“位置”部分中,使用“浏览文件系统”并导航并选择脚本文件。
4B)。在“工作目录”部分中,使用“浏览工作区”选择项目。
5)。在“刷新”选项卡中取消选中“完成后刷新资源”。
6)。不要在“环境”选项卡中设置任何变量。
7)。在“构建选项”选项卡中:
7A)。确保勾选“手动构建期间”,并
7B)。 “自动构建期间”也会被勾选。
7C)。我现在还有其他一切未被选中。我甚至没有为它分配一个控制台。老鹰目瞪口呆可能已经发现脚本确实输出了一些信息,但现在我已经开始工作了,我只是希望这个东西能够安静地运行而不会打扰我。
8)。好的是构建设置,然后将构建器放在“Android Pre-Compile”和“Java Builder”之间。
返回开发应用程序,确保它们的版本正确,并查看应用程序的信息。不是那个版本号很酷。 : - )
史蒂夫
答案 1 :(得分:12)
用于计算version.code
:
git rev-list master --first-parent --count
这跟随versioning guideline。因为它有效地从初始提交(包括)中找到提交的数量,该提交总是从先前版本递增。
用于计算version.name
:
git describe --tags --dirty --abbrev=7
build.xml
通常会导入名为custom_rules.xml
所以将脚本的内容设为:
<?xml version="1.0" encoding="UTF-8"?>
<project name="application-custom">
<macrodef name="git" taskname="@{taskname}">
<attribute name="command" />
<attribute name="dir" default="" />
<attribute name="property" default="" />
<attribute name="taskname" default="" />
<attribute name="failonerror" default="on" />
<element name="args" optional="true" />
<sequential>
<exec executable="git" dir="@{dir}" outputproperty="@{property}"
failifexecutionfails="@{failonerror}" failonerror="@{failonerror}">
<arg value="@{command}" />
<args/>
</exec>
</sequential>
</macrodef>
<target name="-pre-build">
<git command="rev-list" property="versioning.code" taskname="versioning">
<args>
<arg value="master" />
<arg value="--first-parent" />
<arg value="--count" />
</args>
</git>
<git command="describe" property="versioning.name" taskname="versioning">
<args>
<arg value="--tags" />
<arg value="--dirty" />
<arg value="--abbrev=7" />
</args>
</git>
<echo level="info" taskname="versioning">${versioning.code}, ${versioning.name}</echo>
<replaceregexp file="AndroidManifest.xml" match='android:versionCode=".*"' replace='android:versionCode="${versioning.code}"' />
<replaceregexp file="AndroidManifest.xml" match='android:versionName=".*"' replace='android:versionName="${versioning.name}"' />
</target>
<target name="-post-build" >
<replaceregexp file="AndroidManifest.xml" match='android:versionCode=".*"' replace='android:versionCode="0"' />
<replaceregexp file="AndroidManifest.xml" match='android:versionName=".*"' replace='android:versionName="0"' />
</target>
就是这么做的。
在坚果shell中,它只是用当前版本代码和名称替换android.versionCode
和android.versionName
,存储在git中。
-post-build
目标中的零,或者(尽管我非常怀疑你会需要它)你可以将它配置为一些属性(文件或嵌入式;你的选择)享受。
HEAD
计算内部版本号;在开发期间进行构建时以及稍后在安装稳定版本时(或者在进行主要版本转换的测试时)导致版本降级问题。使用master
(或用于生产构建的分支)ref代替。PS:与AS用户相关:Automatically versioning Android project from git describe with Android Studio/Gradle
答案 2 :(得分:8)
使用Android Studio(Gradle):
android {
defaultConfig {
...
// Fetch the version according to git latest tag and "how far are we from last tag"
def longVersionName = "git -C ${rootDir} describe --tags --long".execute().text.trim()
def (fullVersionTag, versionBuild, gitSha) = longVersionName.tokenize('-')
def(versionMajor, versionMinor, versionPatch) = fullVersionTag.tokenize('.')
// Set the version name
versionName "$versionMajor.$versionMinor.$versionPatch($versionBuild)"
// Turn the version name into a version code
versionCode versionMajor.toInteger() * 100000 +
versionMinor.toInteger() * 10000 +
versionPatch.toInteger() * 1000 +
versionBuild.toInteger()
// Friendly print the version output to the Gradle console
printf("\n--------" + "VERSION DATA--------" + "\n" + "- CODE: " + versionCode + "\n" +
"- NAME: " + versionName + "\n----------------------------\n")
...
}
}
答案 3 :(得分:0)
' for windows
' preBuildMy.cmd include repVer.vbs
' repVer.vbs :
Dim objFileSystem, objOutputFile
Dim objInputFile
Dim sText,gitFile
FileName = "./bin/AndroidManifest.xml"
' gitFile = ".\..\.git\refs\heads\master"
gitFile = ".\..\.git\refs\remotes\origin\master"
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
set objInputFile= objFileSystem.OpenTextFile(FileName)
sText= objInputFile.ReadAll
set objOutputFile = objFileSystem.CreateTextFile(FileName , TRUE)
set objInputFile= objFileSystem.OpenTextFile(gitFile)
refText= objInputFile.ReadAll
sText = Replace(sText,"v1.0","v 1.0 " & Now & " ref=" & mid(refText,1,7))
objOutputFile.WriteLine(sText)
objOutputFile.Close
Set objFileSystem = Nothing
WScript.Quit(0)