Auto increment version code in Android app

39,619

Solution 1

So, I see it like this:

Depending on article that you present, use ant for this tasks (targets?).

  1. parse Manifest (parse XML)
  2. get old version form manifest and increase it/get version from repo
  3. store new version in manifest
  4. build android app.

But im my case I usually fill this field by value based on Tag's revision when I deploy or distribute application.

Solution 2

I accomplished this. And here's how I did it for the next guy (using Eclipse):

1) Create an external console executable that is going to write a new version code to the AndroidManifest.xml: (mine is in C#)

using System.IO;
using System.Text.RegularExpressions;

namespace AndroidAutoIncrementVersionCode
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string FILE = @"AndroidManifest.xml";
                string text = File.ReadAllText(FILE);
                Regex regex = new Regex(@"(?<A>android:versionCode="")(?<VER>\d+)(?<B>"")", RegexOptions.IgnoreCase);
                Match match = regex.Match(text);
                int verCode = int.Parse(match.Groups["VER"].Value) + 1;
                string newText = regex.Replace(text, "${A}" + verCode + "${B}", 1);

                File.WriteAllText(FILE, newText);
            }
            catch { }
        }
    }
}

aside: any c-sharp compiler can build this app, you don't need Visual Studio or even Windows

  1. if you don't have it already, install .NET runtime (Mono will work, link) (link to MS's .NET framework 2.0, 2.0 is the smallest download, any version >= 2.0 is fine)
  2. copy this code to a *.cs file (i named mine: AndroidAutoIncrementVersionCode.cs)
  3. open a command prompt and navigate over to where you made your *.cs file
  4. build the file using this command (on Windows, similar for Mono but change path to compiler): c:\Windows\Microsoft.NET\Framework\v2.0.50727\csc AndroidAutoIncrementVersionCode.cs (see: .NET or Mono for more info)
  5. congrats, you just built a C# app without any tools, it should have generated AndroidAutoIncrementVersionCode.exe in the same directory automatically

    **mileage may vary, paths might be different, no purchase required, void where prohibited, i added this because C# is awesome, and people mistakenly think it has MS lock-in, you could just as easily translate this to another language (but i'm not going to do that for you ;). incidentally any version of any .NET compiler will work, i adapted the code for the least common denominator...*

end aside

2) Run the executable during the build process: a) Go to the project properties

go to project properties

b) In the properties, Go to "Builders" -> "New..."

Eclipse properties screen

c) Choose "Program"

choose program

d) In the "Main" tab select the program location (I also set the working directory to be safe) and give it a name if you wish.

edit configuration - main

e) In the "Refresh" tab select the "Refresh resources upon completion" and "The selected resource" option - this will refresh the manifest after we write it.

edit configuration - refresh

f) In the "Build Options" tab you can turn off "Allocate Console" as you have no input and output and then select only "During manual builds" and "During auto builds" deselect "After a Clean" if it is checked. Then select "Specify a working set of relevant resources" and click the "Specify Resources..." button. In the "Edit Working Set" dialog, locate your "AndroidManifest.xml" file in the dialog and check it, then hit "Finish"

edit configuration - build options edit working set

f) Now hit "OK" inside the "Edit Configuration Dialog" and in the properties for your App, select the newly created builder, and keep clicking "Up" until it is at the top of the list, this way the auto increment runs first, and doesn't trigger accidental out-of-sync states or rebuilds. Once the new builder you made is at the top of the list, click "OK" and you're finished.

edit configuration - hit ok enter image description here

Solution 3

This shell script, suitable for *nix systems, sets the versionCode and the last component of versionName to the current subversion revision. I'm using Netbeans with NBAndroid and I call this script from the target -pre-compile in custom_rules.xml.

Save this script in a file called incVersion in the same directory as AndroidManifest.xml, make it executable: chmod +x incVersion

manf=AndroidManifest.xml
newverfull=`svnversion`
newvers=`echo $newverfull | sed 's/[^0-9].*$//'`
vers=`sed -n '/versionCode=/s/.*"\([0-9][0-9]*\)".*/\1/p' $manf`
vername=`sed -n '/versionName=/s/.*"\([^"]*\)".*/\1/p' $manf`
verbase=`echo $vername | sed 's/\(.*\.\)\([0-9][0-9]*\).*$/\1/'`
newvername=$verbase$newverfull
sed /versionCode=/s/'"'$vers'"'/'"'$newvers'"'/ $manf | sed /versionName=/s/'"'$vername'"'/'"'$newvername'"'/  >new$manf && cp new$manf $manf && rm -f new$manf
echo versionCode=$newvers versionName=$newvername

Create or edit custom_rules.xml and add this:

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules">
    <xmlproperty file="AndroidManifest.xml" prefix="mymanifest" collapseAttributes="true"/>
    <target name="-pre-compile">
        <exec executable="./incVersion" failonerror="true"/>
    </target>
</project>

So if my current svn revision is 82, I end up with this in AndroidManifest.xml:

android:versionCode="82"
android:versionName="2.1.82">

When I want to release a new version I'll typically update the first parts of versionName, but even if I forget, the last part of versionName (which is exposed in my About activity) will always tell me what svn revision it was built from. Also, if I have not checked in changes, the revision number will be 82M and versionName will be something like 2.1.82M.

The advantage over simply incrementing the version number each time a build is done is that the number stays under control, and can be directly related to a specific svn revision. Very helpful when investigating bugs in other than the latest release.

Solution 4

Building on Charles' answer, the following increments the existing build version:

#!/usr/bin/python
from xml.dom.minidom import parse

dom1 = parse("AndroidManifest.xml")
oldVersion = dom1.documentElement.getAttribute("android:versionName")
versionNumbers = oldVersion.split('.')

versionNumbers[-1] = unicode(int(versionNumbers[-1]) + 1)
dom1.documentElement.setAttribute("android:versionName", u'.'.join(versionNumbers))

with open("AndroidManifest.xml", 'wb') as f:
    for line in dom1.toxml("utf-8"):
        f.write(line)

Solution 5

Receipe:

To automatically have the android:versionCode attribute of manifest element in AndroidManifest.xml set to the current time (from epoch in seconds, obtained from unix shell) everytime you run a build, add this to your -pre-build target in custom_rules.xml Android file.

<target name="-pre-build">
  <exec executable="date" outputproperty="CURRENT_TIMESTAMP">
    <arg value="+%s"/>
  </exec>
  <replaceregex file="AndroidMainfest.xml" match="android:versionCode=.*"
    replace='android:versionCode="${CURRENT_TIMESTAMP}"' />
</target>

Confirmation Test:

Obtain the versionCode attribute of the generated apk file, using the following shell command from your Android project directory :

$ANDROID_SDK/build-tools/20.0.0/aapt dump badging bin/<YourProjectName>.apk | grep versionCode

and compare it to the current date returned from the shell command: date +%s The difference should equal the period of time in seconds between the two confirmation steps above.

Advantages of this approach:

  1. Regardless of whether the build is started from command line or Eclipse, it will update the versionCode.
  2. The versionCode is guaranteed to be unique and increasing for each build
  3. The versionCode can be reverse-engineered into an approximate build time if you need it
  4. The above script replaces any present value of versionCode, even 0 and doesn't require a macro place holder (such as -build_id-).
  5. Because the value is updated in the AndroidManifest.xml file, you can check it in to version control and it will retain the actual value, not some macro (such as -build_id-).
Share:
39,619
iseeall
Author by

iseeall

Updated on July 08, 2022

Comments

  • iseeall
    iseeall almost 2 years

    is there a way to auto-increment the version code each time you build an Android application in Eclipse?

    According to http://developer.android.com/guide/publishing/versioning.html, you have to manually increment your version code in AndroidManifest.xml.

    I understand, you have to run a script before each build which would, e.g. parse AndroidManifest.xml file, find the version number, increment it and save the file before the build itself starts. However, i couldn't find out how and if Eclipse supports runnings scripts before/after builds.

    I have found this article about configuring ant builder, but this is not exactly about Android and I fear this will mess up too much the predefined building steps for Android?

    Should be a common problem, how did you solve it?

    Well, one can do this manually, but as soon as you forget to do this chore, you get different versions with the same number and the whole versioning makes little sense.

  • iseeall
    iseeall almost 13 years
    Yes, those are the steps the script should be. Unfortunately I can't find out where the script call should be. Building Android app from Eclipse doesn't use build.xml file. So, my question boils down to: where (in what file? in what Eclipse project setting?) to place the call of the script
  • iseeall
    iseeall almost 13 years
    Actually, if one uses CVS, such a script won't make versioning automatic. CVS doesn't support project-wide revision numers, that's why you used italic on Tag. But you then first have to create a CVS tag manually. Which means, if you forget to create a CVS tag, you end up with incorrect build number. This is essentially the same as just manually updating versionCode in AndroidManifest.xml, with the only advantage that the build number is also in synch with tag visible to other developers (well, it's in code anyway). Looks like real automation is not achievable if CVS is used.
  • aeracode
    aeracode almost 13 years
    Sorry, I don't directly use ant for build android apps. But that what I saw had a lot of code. Look at this link.
  • aeracode
    aeracode almost 13 years
    You are right about CVS. Similar question
  • aeracode
    aeracode almost 13 years
  • thedrs
    thedrs over 12 years
    great answer ! Works great for me. I enhanced it to also increase the "android:versionName" and also uploaded the executable itself for those less versed in C#.
  • thedrs
    thedrs over 12 years
    Note the version name must be in the form of X.Y.Z, and Z is increased each time. Put the exe in the same location as the manifest.
  • Rick Barrette
    Rick Barrette almost 12 years
    Thanks, I was able to get this working on my Linux box using mono
  • Jim Geurts
    Jim Geurts almost 12 years
    Like @thedrs, I tweaked this example to also update the versionName value (in the form of X.Y.Z). Source available at: gist.github.com/3131675
  • sulai
    sulai over 11 years
    This is great, thank you so much! If running as a shell script, don't forget to add #!/usr/bin/python as the first line and make it executable: chmod +x buildincrease.py.
  • m0skit0
    m0skit0 almost 11 years
    The answer that should've been accepted. And I wonder why Google doesn't add this to the SDK...
  • Tine M.
    Tine M. over 10 years
    That is great answer, HOWEVER I have a problem on Eclipse 4.2.2. Looks like every time the AndroidManifest.xml is changed, the project gets rebuilt. Because of auto increment program that causes an infinitive loop... I solved it by unchecking "during auto build"....
  • PurkkaKoodari
    PurkkaKoodari over 10 years
    Great answer, however the program is only run when the manifest is changed.
  • Ahmad Kayyali
    Ahmad Kayyali over 10 years
    @ckozl: I keep recieving File is Out of sync is there any way to auto refresh the AndroidManifest.xml? thanks
  • ckozl
    ckozl over 10 years
    @AhmadKayyali it seems that almost every time they update the android tools or you upgrade eclipse it results in a slightly different build ordering, theoretically "refresh selected resources upon completion" should do the job, but it would seem that at times, it doesn't... try playing with the options, i'm sorry that i don't have a better answer, but I've literally updated this process about 7 times because every version acts a little different... happy hunting!
  • Ahmad Kayyali
    Ahmad Kayyali over 10 years
    that did the trick refresh selected resources upon completion by selecting specific resources and I picked the AndroidManifest file. thanks
  • Lukasz 'Severiaan' Grela
    Lukasz 'Severiaan' Grela over 9 years
    Never mind, I had to restart eclipse to have it working.
  • O__O
    O__O about 9 years
    I use eclipse juno on windows for android development. I have copied the script shared above in a ".bat" file in my project folder and followed the steps mentioned to create a builder. Also created a AndroidManifest.template.xml with android:versionCode="CODE" android:versionName="VERSION" I change some value in my manifest and run the app, but i dont see any change in the version number/version code in my manifest; Please help me in understanding the problem :( Also, i use Sourcetree for GIT operations.
  • Dmitry Gusarov
    Dmitry Gusarov almost 9 years
    "C# is awesome, and people mistakenly think it has MS lock-in" +1