Ant and Build Version Numbers

11 PM September 26, 2005

Our customer recently found themselves confused about which version of the software they had running. Our response is to modify our ant packaging script to add the version number and time stamp to various parts of the release package. This is how I went about it.

First, requirements. To the customer, the most important piece of information is the build version number. The version number is an alphanumeric string that identifies the phase, milestone and release of the build. The next most important piece of information is when the build was done, and by whom. Finally, I will also include a unique "build number" because ant has a handy feature for that.

I changed the script's init target to gather this information:

01 <target name="init">

02     <description>Prepare for a build tasks</description>

03     <tstamp />

04     <buildnumber file="installation-package/build.number"/>


06     <input message="Please enter the build version number:" addproperty="build.version" />

07     <property name="app.jar.filename" value="app-${build.version}.jar" />

08 </target>

The important pieces are:

Line 03
The tstamp task puts the current date and time into script properties named DSTAMP (a date stamp), TSTAMP (a time stamp) and TODAY (human readable date).
Line 04
The buildnumber task creates a unique number for this build. It does this by storing the build number in a disk file named "build.number", which we check in along with the build script.
Line 06
The script asks the user for the version string interactively, using the input task. I did consider getting the version number from a property file. Unfortunately, I'm likely to forget to update the property file before a release. Fortunately, we don't need to run the packaging script unattended, so asking interactively is fine.
Line 07
Finally, the script includes the build version string sets in the name of the output application JAR file.

Next, we are going to create a readme file to hold the detailed version information. The task looks like this:

01 <target name="make-readme">

02     <echo file="${build.dir}/readme-${build.version}.txt">Version:    ${build.version}

03 Build time: ${TODAY} at ${TSTAMP}

04 Build #:    ${build.number}</echo>

05 </target>

The echo task conveniently expands properties in its input text. We include the version number in the file name too, so that it can be seen without having to open the file. Note that the open and close <echo> tags are hard up against the content, and lines 3 and 4 are hard against the left margin. If we don't do this, then the output file ends up filled with whitespace.

Since we are changing the application JAR file name based on the version number, we need to ensure that the startup scripts use the correct JAR file. We're deploying on Windows, so the simplest thing to do is to modify the startup scripts to use the calculated name.

This ant task copies scripts from the startup-files directory to the build directory, replacing all instances of the string "@jarfile@" with the application jar file name:

01 <target name="copy-run-scripts">

02     <filter token="jarfile" value="${app.jar.filename}" />

03     <copy todir="${build.dir}" filtering="true">

04         <fileset dir="${install.dir}/startup-files" includes="**/*" />

05     </copy>

06 </target>

The filter task defines a filter that is then used by the copy task. To use the filter, the copy task must have filtering="true" in its attribute list.

I also added some other little touches - such as stuffing the build time and number into the jar manifest - but they're just a matter of including the right "${}" references in the right places.

So, with version numbers and timestamps whereever you look, nobody need be confused about what version of the software they have, ever again.

By alang | # | Comments (5)
(Posted to javablogs and Java)
© 2003-2006 Alan Green