Three degrees of freedom in ant

I've just finished updating the build process at Handmark (again). This time, the goal was auditability and repeatability. We wanted to have a permanent record of exactly which revision was built when, and the ability to quickly get back to that exact build.

The prior build process had two degrees of freedom. On one axis, we have the set of projects. On the other, we have the set of build steps. We represented these two degrees of freedom with two separate ant scripts. build.xml lists the many different jar and war files and the relationships among them. It calls actions.xml via the <ant> task, which lists the build steps like clean, get, compile, unit test, jar, and war. For details, please see Separation of Concerns in Ant.

The command line to run the build took the branch and revision, like this:

ant -Dbranch=trunk -Drevision=24516 clean,war

It would pull the source code and build the war files. When it was finished, the branch and revision number were embedded within the manifest of the war files, but there was no permanent record that this build occurred. In addition, if we wanted to go back to a previous build, we would have to find the branch and revision number and reissue the command. And to be absolutely safe, we would have to pull the previous versions of the build scripts and properties files to ensure that we got exactly the same results.

Here's my solution
I wrapped this build process within another layer. We now have a build script that loads a file called This file contains two lines:


It then creates a temporary working directory, pulls the build scripts by that branch and revision into that directory, and launches them.

<!-- Load the tag file. --><property prefix="tag" file="${basedir}/" />
<!-- Get the project files. --><svn username="${username}" password="${password}">    <export srcUrl="${svnbase}/${tag.branch}/Projects/MyProject/" revision="${tag.revision}" destPath="${work}" /></svn>

<!-- Build the war files. --><ant dir="${work}" target="war" inheritall="false">    <property name="branch" value="${tag.branch}" />    <property name="revision" value="${tag.revision}" />    <property name="username" value="${username}" />    <property name="password" value="${password}" />    <property name="thirdparty" location="${thirdparty}" /></ant>

Now we can change and check it in. We can go back to any prior build by checking out the file that was current at the time. We can be sure that the build process is repeatable because even the build scripts themselves are pulled by revision. And best of all is the new command line:


Leave a Reply

You must be logged in to post a comment.