I believe that computers are the best things for doing repetitive tasks. I certainly am not, I either forget, or (mostly) don't do things in a consistent way - which isn't what I want.
One of the things I am likely to do is forget to up the version information in the manifest when I publish a new version of an Android app. In the past I've worked with configured build systems that have a auto version numbering feature and I got use to it (or maybe I got lazy).
I found this Stackoverflow post very useful in coming up with a solution, but it took me a while to fine tune it so it works just they way I want it. Earlier attempts would sometime cause continues building, which was a pain. So I thought I would publish my solution here in the hope that someone else will find it useful.
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
Idea (using ant and git executable)
ok, here's a novel way of doing it:
for calculating version.code:
git rev-list master --first-parent --count
this follows the versioning guideline. As it effectively finds the number of commits from the initial commit (inclusive) which is always incrementing from the previous version.
for calculating the version.name:
git describe --tags --dirty --abbrev=7
Implementation:
build.xml usually imports a custom ant script called custom_rules.xml
so making the content of the script as:
<?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>
would just do.
In a nut shell, it just replaces the android.versionCode and android.versionName with the current version code and name, stored in git.
Caveats
initial version code and name is set to 0 upon the completion of build. If you require it, replace the zero in the -post-build target, or (though I highly doubt you would require it) you could make it configurable and place it in some property (file or embedded; your choice)
if the build is failed, or aborted, the version will remain as it is. (though i highly doubt it is of any concern, just revert the file!)
Enjoy.
Refs
Best way to integrate Git with Ant?
macrodef for git improvised from Ant Tasks for Git | tlrobinson.net blog
Important Edit
prevent using HEAD to calculate the build number; causes version downgrade issue when doing a build during development, and later when installing the stable version (or when doing a beta to main release transition). using the master (or the branch which is used for production builds) ref instead.
PS: relevant for AS users: Automatically versioning Android project from git describe with Android Studio/Gradle
Using 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)
Related
We have a unique situation where we are deploying a Xamarin.Android app to China to 33 app stores. Hence, our solution has 33 application projects, and we setup Jenkins (running on Windows) to package and sign all our apks (otherwise it would be crazy to make builds).
We also need to modify android:versionCode and android:versionName in the manifest file, by using the ${SVN_REVISION} value from Jenkins. Is there a way to pass these values command line to MSBuild?
Normally we would hand edit this value, but it's not possible because of so many application projects.
Our build parameters right now look like this in Jenkins:
/p:Configuration=Release;AndroidKeyStore=True;AndroidSigningKeyStore=ourkeystore.keystore;AndroidSigningStorePass=ourpassword;AndroidSigningKeyAlias=ouralias;AndroidSigningKeyPass=ourpassword /t:SignAndroidPackage
Add this to the end of your *.csproj file, before the ending </Project> tag:
<Target Name="BeforeBuild" Condition=" '$(JENKINS)' == '1' ">
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml" Namespaces="<Namespace Prefix='android' Uri='http://schemas.android.com/apk/res/android' />" Query="manifest/#android:versionCode" Value="$(SVN_REVISION)" />
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml" Namespaces="<Namespace Prefix='android' Uri='http://schemas.android.com/apk/res/android' />" Query="manifest/#android:versionName" Value="2.0.$(SVN_REVISION)" />
</Target>
I have Jenkins configured to pass JENKINS=1 and SVN_REVISION. When it goes to build, it modifies AndroidManifest.xml before the build.
I don't know if this will work on xbuild on a Mac or not, depends on if XmlPoke is implemented. I should do a blog post on this.
No. You'll have to manipulate the android:versionCode and android:versionName yourself. Personally, I use a rake task to handle this particular detail.
I want to auto-increment the versionCode and versionName of the manifest file of the android app when I click on Export (to export a new version of the app)
I found the second answer here (Auto increment version code in Android app) extremely useful (comment include .exe programs to auto increment Android versionCode) , however, they made it run on Build, I want it to run when I click on File -> Export , see image please
You might consider modifying the File -> Export button to execute a builder to increment the version code (as shown in the post you mentioned) in addition to that button's usual functionality. The org.eclipse.ui.menus extension point seems like a good starting point. (Disclaimer: I haven't tried this.)
However, it might be good to keep the following xkcd in mind here:
I have done this with a ton of custom ant steps.
First, you need to extract the build number into a properties file. Let's call it version.properties
Then, the step to increment the version code is:
<target name="increment-version-code">
<propertyfile file="version.properties">
<entry key="versionCode" type="int" default="0" operation="+" value="1" />
</propertyfile>
</target>
This will read the entry versionCode, increment it and save it back to version.properties.
So far, so good. The last step is to get that versionCode into the AndroidManifest.xml file and unfortunately now it gets messy.
The way I solved it was to regenerate the manifest from a template on every build using the filtering functionality in ant.
<target name="generate-manifest">
<filter filtersfile="version.properties"/>
<copy todir="${source.dir}" overwrite="true" verbose="true" filtering="true">
<fileset dir="${source.dir}" casesensitive="false">
<include name="**/*.base"/>
</fileset>
<mapper type="glob" from="*.base" to="*" />
</copy>
</target>
Then, all you have left to do is move your AndroidManifest.xml to AndroidManifest.xml.base and replace your versionCode attribute to read android:versionCode="#versionCode#" . You can then run the increment-version-code target to bump the versionCode in version.properties and the generate-manifest target to convert the .base template into the final manifest.
These can then be easily added as build steps to your Eclipse project or as dependencies to exported ant builds. Unfortunately, there's no easy hook for the Export functionality (though, there is for "After Clean", which I find good enough).
Of course, with Gradle on the horizon, all of this would have to be rewritten soon. :(
So far I have been focusing on my application's programming and paid little attention to making the build process smarter. Thus I have been doing things pretty much manually (the "dumb way"), including updating by hand android:versionCode and android:versionName in AndroidManifest.xml.
I would like now to automatically (i.e. upon Build or upon Export):
Fetch from git the latest tag/branch containing build and version codes.
Parse them so that I can assign them to the respective fields in AndroidManifest.xml.
Modify AndroidManifest.xml accordingly.
Proceed with the normal build process (Eclipse+ADT, no Ant whatsoever), as if I did 1-2-3 by hand...
I found a few clues about a "pre-build step", builders and build.xml, but I have no idea where to find those and where to start.
Any tips or pointers on where I could find more information on the subject? (a step-by-step tutorial would be ideal)
Update 1: I found this thread to be suggesting that I:
Right-click on the project, Properties > Builders
Add a builder that points to the project's Ant build file.
Order that builder to be invoked before the Java builder
Fine, but where is the project's Ant build file? Where do I find it?
Update 2: Apparently, it's possible to export the entire project into an Ant file. But I am not sure that's I want. Must a pre-build step always include an Ant build file?
Update 3: Is building an Ant file, only for the pre-build step, the right approach?
Here's what I use to dynamically assign a versionCode and versionName to AndroidManifest.xml. It works only when building with ant, so you'll have to install it first. Then go to the project directory in your command line and execute "android update project -p .", which will create the necessary files for building with ant, like local.properties and build.xml.
Then open build.xml and place this inside:
<target name="-pre-build" depends="-custom-git-version,-custom-manifest-version">
</target>
<!-- Packages the application. -->
<target name="-post-build">
<antcall target="-custom-restore-manifest"/>
<property name="suffix" value="${git.commits}-${git.version}.apk" />
<exec executable="sed" inputstring="${out.final.file}" outputproperty="out.final.renamedfile">
<arg value="s/\.apk/-${suffix}/" />
</exec>
<copy file="${out.final.file}" tofile="${out.final.renamedfile}" />
<echo>Final file copied to: ${out.final.renamedfile}</echo>
</target>
<!-- Custom targets -->
<target name="-custom-git-version">
<exec executable="sh" outputproperty="git.commits">
<arg value="-c" />
<arg value="git log --pretty=format:'' | wc -l" />
</exec>
<echo>git.commits: ${git.commits}</echo>
<exec executable="git" outputproperty="git.version">
<arg value="describe" />
<arg value="--tags" />
<arg value="--long" />
</exec>
<echo>git.version: ${git.version}</echo>
</target>
<target name="-custom-manifest-version">
<echo>Creating backup of AndroidManifest.xml</echo>
<copy file="AndroidManifest.xml" tofile="AndroidManifest.xml.antbak" preservelastmodified="true" />
<replaceregexp
file="AndroidManifest.xml"
match='android:versionCode="(\d+)"'
replace='android:versionCode="${git.commits}"' />
<replaceregexp
file="AndroidManifest.xml"
match='android:versionName="(\d+\.\d+)\.\d+"'
replace='android:versionName="\1.${git.commits}"' />
</target>
<target name="-custom-restore-manifest">
<echo>Restoring backup of AndroidManifest.xml</echo>
<move file="AndroidManifest.xml.antbak"
tofile="AndroidManifest.xml"
preservelastmodified="true"
overwrite="true" />
</target>
The output of this is not exactly what you want, but it is a start - feel free to modify it :) The result is something like "yourapp--.apk
Using this you'll build your application with executing "ant clean debug", or "ant clean release", depending on what you want. You can also create "ant.properties" file with this content:
key.store=keystore_file
key.store.password=some_password
key.alias=some_alias
key.alias.password=some_other_password
to enable automatic signing of your app.
You should also read this: http://developer.android.com/tools/building/building-cmdline.html
You are on the right track with setting up a pre-build step, but the ant build file is something you'll create yourself from scratch. Eclipse has some ant scripts that it uses externally that handle the automated compilation, packaging and stuff, but you want to create a separate one that just does these extra steps you want.
So, you're going to have to learn a bit about ant scripting to get this done. Some of those links you found give you the basic idea of how to create a simple ant file. To add to that, some of the ant tasks you will probably need to use are:
Exec - You will need this to execute your git command that gets your version info. It has an argument called resultProperty you can use to store the output of the command into a property that ant can access. (or you can just have the command output to a file and ant can access that.)
ReplaceRegExp - You will need this to replace tokens (maybe #VERSIONCODE# and #VERSIONNAME# ) you place in your AndroidManifest.xml where the values should eventually go, with the values returned by the exec.
You will probably also want to execute an exec task at the beginning to restore your AndroidManifest.xml file to it's original state (with the tokens in place) so it's repeatable without manual cleanup. I would provide more info on the git commands you need to run within these exec tasks, but I'm afraid all my experience is with Subversion, so you'll have to fill in the gaps there.
You should consider building with maven-android. Once you have your project building cleanly, use the version-update plugin to automatically increment your version number.
Writing a build script with maven-android can't be described as easy - but the payoff is worth the effort and you should consider this avenue.
Also, this tutorial might come in handy (I use a variant of the technique described here for my own builds)
EDIT (2014):
Consider migrating to Android Studio and using Gradle. See: How to autoincrement versionCode in Android Gradle
The way I managed to achieve this: build > execute shell (we needed some php code to receive some info from a db) and the string replacement happens in php:
#!/usr/bin/php
<?php
$filename = $WORKSPACE."/src/com/me/myapp/MyActivity.java";
$file = #file_get_contents($filename);
if($file) {
$repl = preg_replace("OriginalString", "NewString", $file);
file_put_contents($filename, $repl);
echo "\n\nReplaced some stuff in $filename";
}
?>
My Android app is targeted to 20+ market, each with several different properties in the Manifest.xml.
To release 20+ apk one after another is really time-consuming, and I tried to use the windows batch file to do the release job in a single click.
For now, I use the solution provided by the tutorial here to change the field in the Manifest.xml, but I don't know ant well, so I use a very hack method to do the job in batch file like below:
start cmd.exe /c "ant config-google-play release_mine"
REM the line below is for waiting for the former task to finish
ping 1.1.1.1 -n 1 -w 90000 > nul
start cmd.exe /c "ant config-eoemarket release_mine"
ping 1.1.1.1 -n 1 -w 90000 > nul
....
Is there some elegant way to accomplish this? like just editing targets in build.xml to do it in ant, etc.
First off, why are you always starting a new cmd process? If you just called Ant 20x+ times in your build script it would start building the next build right after the current one would be finished.
Secondly I would advise you to have 20x+ different AndroidManifest.xml files (have a prefix or suffix for each file, so that none of them are named exactly "AndroidManifest.xml") and then you just rename them to AndroidManifest.xml before each build. You can do that with the custom_rules.xml Ant build file (put it next to your build.xml) like this:
<project name="custom_rules">
<target name="config-google-play">
<property name="version" value="google_play" />
</target>
<target name="-pre-build">
<copy tofile="${basedir}/AndroidManifest.xml" overwrite="true">
<fileset file="${basedir}/AndroidManifest.xml.${version}" />
</copy>
</target>
</project>
Here I assumed you renamed your manifests as AndroidManifest.xml.xxxxx. Note also the "-pre-build" target which is invoked before the actual build of the apk starts.
Then just add other "config-" targets and set it's values to whatever you renamed your AndroidManifest.xml(s) to. Then write your build script with 20x+ lines of Ant with "ant config-xxxxx release" where xxxxx is the appropriate config of your build.
My final solution:
Define task:
<target name="modify_manifest">
<property
name="version.market"
value="${channel}"/>
<property
name="out.final.file"
location="${out.absolute.dir}/${ant.project.name}_${channel}_${project.version.name}.apk"/>
<antcalltarget="release"/>
</target>
Then include ant-contrib*.jar as the answer here so that I can use loop in ant. Then define a new task below
<target name="deploy" >
<foreach
delimiter=","
list="${market_channels}"
param="channel"
target="modify_manifest" >
</foreach>
</target>
Use “ant deploy” to do the task.
market_channels should be defined in ant.property as follow:
market_channels=google-play,other,...
Getting an IDE to automatically increment build numbers is a long discussed issue - I'm always surprised that something that seems so basic (to me) is so much work.
The highest scored question and answer (by quite a bit) for this topic are here:
https://stackoverflow.com/a/8156809/150016
My problem is that the solution depends on .net and I'd prefer to avoid a .net dependency for Eclipse solution. I also want to avoid any dependency on VCS.
So, I'm looking for a solution that is portable and 'Eclipse-ish'. I think the best candidates are an Ant solution (which I will post) or a Java app similar to the dotNet app in the linked answer above.
(I didn't add my answer to that question because it has an accepted answer and is already a very long post. If the moderators prefer I will delete this question and add my answer to the question above.)
I was hoping for something comparatively simple but I don't think any solution to this problem really is simple.
In the project's properties dialog, under Builders, you can configure a script to run prior to building your apk.
In the properties dialog, select Builders from the list on the left. Click New to add a new script. On the dialog that pops up, select Program. On the ensuing dialog, call your Builder Program what you like in the Name field. Put the path to the script in the Location field. Give it a working directory in the Working Directory field. Note that you can specify variables in these fields (e.g., we use ${build_project:/libs/update_version.sh} to reference a script in the project's lib directory).
You'll want this to run before any of the other builders, so move it to the top of the list using the Up button.
On the Build Options tab of the Dialog (it's right under the Name field towards the top), you can select options for when you want this program to run.
I'm assuming something like Linux, Unix, or MacOS here. In those systems you can use grep or its variants to get the current versionCode, increment it, and then awk or similar to modify the file accordingly. Or, you could write a Ruby, Python, Perl, etc. script to replace the versionCode in the AndroidManifest.xml file. I suppose there are equivalent tools on Windows, but I'm not very familiar with that environment.
Have you tried to 'Maven-ise' your android project build ?
If you use the "maven-android-plugin", you can keep track of your project build with pom.xml's "version" tag.
In pom.xml you can increment the build version by using "versions-maven-plugin"
To reflect the incremented build number to to your AndroidManifest.xml you can use the Synchronizing Version technique within your pom file.
This way you can auto-increment the android project build number by running the "versions-maven-plugin" every time the app builds. The solution is also portable in the same way the Ant solution is.
I hope this can also solve the problem you have mentioned (and what I have understand). Please correct me if something is missing.
Here is a solution that uses Ant. I must admit that getting Ant setup was a bit of a hassle, but it seems to be a widely used and powerful adjunct to Eclipse, so I believe it will turn out to be valuable for me in other ways.
Ant is the preferred solution for building Android SDK apps without Eclipse (as described here), but is not part of the ADT so you probably won't have it if you have just been using Eclipse.
So, the first step is to download and install Ant from here.
Next add Ant to your path and make sure that your path also points to the JDK (rather then the JRE). On Windows I found that I also had to create JAVA_HOME and point it to the root of the JDK.
We only need Ant for the auto-increment step - the intention is not to replace Eclipse and use it for the whole build - but it is useful to do a few steps in that direction to ensure that Ant is working. So, go to the root of your project and type
> android update project --path .
This creates a build.xml for your project. Once I had done that I was able to do
> ant release
and Ant built my project. If you want to keep going in that direction I found this article useful.
Next, I edited my project's new build.xml and added the following task (it can go anywhere, just not in the middle of another task/target)
<target name="update.buildnum">
<buildnumber/>
<!-- this task creates (and increments) Ant property 'build.number' which I use below -->
<echo>Current build number:${build.number}</echo>
<echoxml file="res/values/buildnum.xml">
<resources>
<string name="buildnum">${build.number}</string>
</resources>
</echoxml>
</target>
The task used above auto-increments a build number in a file (which it will create) called 'build.number' in your project's root. The rest of the task above puts the current build number into a resource string so that your application can retrieve it with this code:
String build = context.getString( com.your.app.R.string. buildnum );
int appBuild = ( int ) Integer.parseInt( build );
Some people will prefer a solution that writes the build number to the application code in the AndroidManifest.xml. Here is an answer that includes a task to do that, but it requires a 3rd party Ant task (xmltask), and I'm a bit hesitant to have a 3rd party task modifying my manifest (which is now pretty huge) on every build. If you do decide to use that task then the corresponding Android code to get the build number would be:
String packageName = ctx.getPackageName();
PackageInfo pInfo = ctx.getPackageManager().getPackageInfo( packageName, 0);
int appVer = pInfo.versionCode;
Finally, you need to get Eclipse to run this Ant task every time you do a build.
Go to your project's properties, find the Builders, and click the button to add a new Builder. There are tons of options here but you only need to specify a few.
Give the builder some name by setting the Name: field.
Select the Buildfile:. I used the 'browse workspace' option to select it, and then it filled the field with "${workspace_loc:/appname/build.xml}"
Select targets from a list on the targets tab. In my case I had to remove the 'help' task (the default task in the build.mxl generated above), and then add the 'build.number' task. I suggest you only set a target for Manual Build:.
I moved the new Builder to be the first build step.
One issue with this solution is that every time you get Eclipse to deploy (run) your application it is considered to be a new manual build, even if the project hasn't changed. So, if you deploy your application to several devices, each device will have a different build with its own build number. One thing that will ameliorate this problem a bit is that Google says that a future ADT will allow for mutiple deployments in one operation.
This (above) was tested with Ant 1.8.4, Eclipse Indigo SR2 (3.7.2), ADT 20 preview 2 and SDK Tools 20, on Win7 32bit.
My solution is based on using Ant (without XMLTask)
<property name="version.file" value="version.properties"/>
<property name="manifest.file" value="AndroidManifest.xml"/>
<!--build.slot: 0.1.2.3.4.5-->
<property name="build.slot" value="2"/>
<target name="all">
<antcall target="increment.build"/>
<antcall target="update.manifest"/>
</target>
<target name="increment.build">
<propertyfile file="${version.file}">
<entry key="build.no" type="int" default="0" operation="+" value="1" />
</propertyfile>
</target>
<scriptdef name="setBuildNo" language="javascript">
<attribute name="verName" />
<attribute name="buildNo" />
<attribute name="buildSlot" />
<attribute name="property" />
<![CDATA[
var verNums = attributes.get("vername").split(".");
var buildNo = attributes.get("buildno");
var buildSlot = attributes.get("buildslot");
if (!(buildSlot > 1 && buildSlot < 10))
buildSlot = 2;
var newVer = "";
for (var i = 0; i < Math.min(verNums.length, buildSlot); i++)
newVer += (verNums[i].trim() || "0") + ".";
for (var i = verNums.length; i < buildSlot; i++)
newVer += "0" + ".";
project.setProperty(attributes.get("property"), newVer + buildNo);
]]>
</scriptdef>
<target name="debug">
<setBuildNo verName="1" buildNo="999" property="a"/>
<setBuildNo verName="2." buildNo="999" property="b"/>
<setBuildNo verName="3.3" buildNo="999" property="c"/>
<setBuildNo verName="4.4." buildNo="999" property="d"/>
<setBuildNo verName="5.5.5" buildNo="999" property="e"/>
<setBuildNo verName="6.6.6." buildNo="999" property="f"/>
<setBuildNo verName="7.7.7.7" buildNo="999" property="g"/>
<echo>1 => ${a}</echo>
<echo>2. => ${b}</echo>
<echo>3.3 => ${c}</echo>
<echo>4.4. => ${d}</echo>
<echo>5.5.5 => ${e}</echo>
<echo>6.6.6. => ${f}</echo>
<echo>7.7.7.7 => ${g}</echo>
</target>
<target name="update.manifest">
<fail message="File not found: "${manifest.file}"" status="1">
<condition>
<not>
<available file="${manifest.file}" />
</not>
</condition>
</fail>
<!-- Reads build version -->
<loadproperties srcfile="${version.file}">
<filterchain>
<linecontains>
<contains value="build.no="/>
</linecontains>
</filterchain>
</loadproperties>
<!-- Reads versionName from AndroidManifest -->
<xmlproperty file="${manifest.file}" collapseAttributes="true"/>
<fail unless="manifest.android:versionName" message="Attribute "android:versionName" undefined into "${manifest.file}"" status="1"/>
<property name="version.name" value="${manifest.android:versionName}"/>
<!-- Create a new version -->
<setBuildNo verName="${version.name}" buildNo="${build.no}" buildSlot="${build.slot}" property="new.version.name"/>
<!-- Replaces using regexp -->
<replaceregexp
file="${manifest.file}"
match="android:versionName.*=.*".*${version.name}.*""
replace="android:versionName="${new.version.name}""/>
<!-- Replaces for check and generates a exception (if not found version) -->
<replace
file="${manifest.file}"
token="android:versionName="${new.version.name}""
value="android:versionName="${new.version.name}""
failOnNoReplacements="true"/>
<!--<echo>${version.file}</echo>
<echo>${manifest.file}</echo>-->
<echo>Auto Increment Build: ${version.name} => ${new.version.name}</echo>
</target>
Using
ant [-Dmanifest.file=<file>] [-Dversion.file=<file>] [-Dbuild.slot=<number>]
-Dmanifest.file - path and filename AndroidManifest.xml. Default: AndroidManifest.xml in a folder with build.xml
-Dversion.file - path and file name in which to store the number Build version. Default: version.properties folder with build.xml
-Dbuild.slot - position of build number in version array. Default: 2, ie X.X.build.
Auto Increment Build in Eclipse
Project | Properties | Builders | New | Ant Build
Main
Build file
<path>/build.xml
Arguments
-Dmanifest.file=${workspace_loc://AndroidManifest.xml} -Dversion.file=${workspace_loc://version.properties}
Refresh
[x] Refresh resources upon completion
(*) Specify resources
[Specify resources]
<Project>
[x] AndroidManifest.xml
Build Options
[x] Specify working set of relevant resources
[Specify resources]
<Project>
[x] res
[x] src
[x] AndroidManifest.xml
My solution used some of the code found in other answers, XMLTask, and Groovy to automatically increment the build number. I also included a rule to do a git commit and tag to link the build number to a specific point in the version control - useful for bug tracking.
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask"/>
<path id="groovy.classpath">
<fileset dir="/Users/deepwinter1/.gvm/groovy/current/lib/">
<include name="*.jar"/>
</fileset>
</path>
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
<classpath refid="groovy.classpath"/>
</taskdef>
<target name="update.build.number">
<xmltask source="AndroidManifest.xml">
<copy path="manifest/#android:versionCode" property="buildNum"/>
</xmltask>
<groovy>
buildNum = Integer.valueOf(properties["buildNum"])
properties["buildNum"] = buildNum + 1
</groovy>
<xmltask source="AndroidManifest.xml" dest="AndroidManifest.xml">
<replace path="manifest/#android:versionCode"
withText="${buildNum}"/>
</xmltask>
<antcall target="commit.and.tag.build">
<param name="buildNum" value="${buildNum}"/>
</antcall>
</target>
<target name="commit.and.tag.build">
<exec executable="git">
<arg value="commit"/>
<arg value="-a"/>
<arg value="-m"/>
<arg value="Build Number ${buildNum}"/>
</exec>
<exec executable="git">
<arg value="tag"/>
<arg value="b${buildNum}"/>
</exec>
</target>
a "bit" better workaround answer you can find here...
https://stackoverflow.com/a/8156809/304270
Tiny c# tool which will execute before everynew new build and increase appropriate value in manifest file..