Автоматическая нумерация версий вашего Android-приложения с использованием Git и Eclipse
Я считаю, что компьютеры - лучшая вещь для выполнения повторяющихся задач. Я, конечно, нет, я либо забываю, либо (в основном) не делаю вещи согласованно - а это не то, чего я хочу.
Одна из вещей, которые я могу сделать, - это забыть добавить информацию о версии в манифест, когда я опубликую новую версию приложения для Android. В прошлом я работал с настроенными системами сборки, которые имеют функцию автоматической нумерации версий, и я привык к ней (или, может быть, я стал ленивым).
Я нашел этот пост Stackru очень полезным, чтобы найти решение, но мне потребовалось некоторое время, чтобы настроить его так, чтобы он работал именно так, как я хочу. Более ранние попытки когда-нибудь вызвали бы продолжение строительства, что было болью. Поэтому я подумал, что опубликую свое решение здесь в надежде, что кто-то найдет его полезным.
4 ответа
Это решение было разработано на 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). Назовите вашу версию как-то вроде "
4). Настройте вкладку "Главная" следующим образом:
4а). В разделе "Местоположение" используйте "Обзор файловой системы", перейдите и выберите файл сценария.
4b). В разделе "Рабочий каталог" используйте "Обзор рабочей области", чтобы выбрать проект.
5). Оставьте флажок "Обновить ресурсы по завершении" неактивным на вкладке "Обновить".
6). Не устанавливайте переменные на вкладке "Среда".
7). На вкладке "Параметры сборки":
7а). Убедитесь, что галочка "Во время ручной сборки" отмечена, и
7б). То, что "Во время автоматической сборки" также отмечено.
7c). Теперь у меня все остальное не выбрано. Я даже не выделяю ей консоль. Орел, который там наблюдал, возможно, заметил, что скрипт действительно выводит некоторую информацию, но теперь у меня все получилось, я просто хочу, чтобы эта вещь работала тихо, не беспокоя меня.
8). Ладно, настройки сборки, а затем поместите ваш конструктор между "Android Pre-Compile" и "Java Builder".
Вернитесь к разработке своих приложений в безопасности, зная, что они правильно версионируются, и ознакомьтесь с информацией о вашем приложении. Разве это не номер версии круто?:-)
Стив
Идея (использование исполняемого файла ant и git)
хорошо, вот новый способ сделать это:
для расчета
version.code
:git rev-list master --first-parent --count
это следует руководству по версиям. Поскольку он эффективно находит количество коммитов от начального коммита (включительно), который всегда увеличивается с предыдущей версии.
для расчета
version.name
:git describe --tags --dirty --abbrev=7
Реализация:
build.xml
обычно импортирует пользовательский скрипт ant 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>
бы просто сделать.
В скорлупе ореха он просто заменяет android.versionCode
а также android.versionName
с текущей версией кода и именем, хранящимся в git.
Предостережения
- исходный код и имя версии устанавливаются в 0 после завершения сборки. Если вам это нужно, замените ноль в
-post-build
target, или (хотя я очень сомневаюсь, что вам это понадобится) вы можете сделать его настраиваемым и поместить его в какое-либо свойство (файл или встроенный; ваш выбор) - если сборка не удалась или была прервана, версия останется без изменений. (хотя я очень сомневаюсь, что это имеет какое-либо значение, просто верните файл!)
Наслаждаться.
Refs
- Лучший способ интегрировать Git с Ant?
- macrodef для git, импровизированный от Ant Tasks for Git | блог tlrobinson.net
Важное редактирование
- не использовать
HEAD
рассчитать номер сборки; вызывает проблему понижения версии при выполнении сборки во время разработки, а затем при установке стабильной версии (или при переходе от бета-версии к основному выпуску). с использованиемmaster
(или ветвь, которая используется для производственных сборок) ref вместо.
PS: актуально для пользователей AS: автоматическое управление версиями Android-проекта из git description с помощью Android Studio/Gradle
Использование 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")
...
}
}
' 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)