This solution was developed on Linux. I'm sure skilled Windows & Mac developers can adapt it to their platforms, but I am not such a developer. Linux is where my skill set lives.
Git has a nice feature in the git describe --dirty
command. It scans back down the commit log and finds the tag and then builds a version string from there. If this is a "production build" where the last commit has been tagged and all files have been checked in then that is your version string. If this is a development build then the last tag is appended with the number of additional commits and an abbreviated hash code. The --dirty
flag is just the cherry on the icing on the cake: it appends the word dirty
if there are any modified files not committed yet. This is perfect for your android:versionName
attribute in the manifest file.
For the android:versionCode
a number is required. This needs to clock for releases but not for development build, and as every release will have a tag with a version string I simply count these. I always tag my versions in the form v<major>.<minor>[.<patch>]
where <major>
, <minor>
and <patch>
are just numbers. So counting tags that start with a lower case 'v' followed with a digit are counted is all thats really needed here.
After trailing with a template manifest file I discovered that the best way was to simply use the AndroidManifest.xml file in the project base, edited using the stream editor sed
and deposit the result in bin/AndroidManifest.xml.
So I developed the script below, placed it in a scripts folder at the same level as my projects (so that they can all share the same script) and then configured a custom builder in Eclipse.
There is the script which I called 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
To configure the builder here are the steps:
1). Right click the project base and select "Properties" and then "Builders".
2). Hit the "New" button and select the "Program" option.
3). Name your version something like "<project> Auto Version". This string needs to be unique across all projects.
4). Configure the "Main" tab as follows:
4a). In the "Location" section use "Browse File System" and navigate and select the script file.
4b). In the "Working directory" section use "Browse Workspace" to select the project.
5). Leave the "Refresh resources upon completion" unchecked in the "Refresh" tab.
6). Don't set any variables up in the "Environment" tab.
7). In the "Build Options" tab:
7a). Make sure that "During manual builds" is ticked, and
7b). That "During auto builds" is also ticked.
7c). I now have everything else left unselected. I don't even allocate a console to it. The eagle eyed out there may have spotted that the script does output some information, but now I've got it working I just want the thing to run silently without bothering me.
8). Okay the build settings and then position your builder between "Android Pre-Compile" and "Java Builder".
Go back to developing your apps safe in the knowledge that they are being properly versioned, and check out your app's info. Isn't that version number cool. :-)
Steve