Ant Power, Cruise under Control and Selenium Fuel (part 4) - Managing dependencies in Cruise Control

On my last post I mentioned about how to configure Cruise Control to build projects that depends on another project's artifacts. But I described only the configuration and how to find the latest artifact built. Now is time to show the build files of the projects and how they know what artifact to include. This can be simple as add one more classpath to Ant. But I have one more issue to solve, branches.

The problem here is, as many of you already know branches are used to split the development tree so you can have all sort of things developed in parallel, like new features, bug fixes and so on. In my case we usually have a main development tree and a bug fix tree. Of course I wanted that both trees were subject to Cruise Control, so the solution was call the bug fix project "project-release" and the main project just "project".

When you have such structure you have to merge both trees from time to time, the problem was if my Ant build file in the release points to a release artifact and the trunk points to a trunk artifact, when they get to merge we always will have to take care of the difference. Not a good thing to do. This was extremely easy to solve because Cruise Control has a build call layout very good.

Let's see how Cruise Control starts a build. First it sits and wait for a trigger, usually a commit on the SVN tree. After that if decides (it can subject to Queuing and Veto) to build the project, it calls a build file which has the name build-project.xml and inside that file another Ant call is made to actually run Ant on the project's build file. The key thing is, you should put the differences on a trunk build or branch build inside this first build file. There, in my case, I define which artifact will be included in the path. Let's see for one project the Cruise Control configuration file and both build files.

Here for the trunk project:

    <schedule interval="60">
    <ant anthome="/usr/local/cruisecontrol/apache-ant-1.7.0"
    buildfile="build-project.xml"
    target="build"
    uselogger="true"
    usedebug="false"/>
  </schedule>

And now for the branch project:

<schedule interval="60">
    <ant anthome="/usr/local/cruisecontrol/apache-ant-1.7.0"
    buildfile="build-project-release.xml"
    target="build"
    uselogger="true"
    usedebug="false"/>
  </schedule>

The only difference if that Cruise Control calls build on different files for the branch project and for the trunk project. In these files I configure properties suited for each project. Here is the example of both files:


<!-- build-project.xml -->
<!-- for the project (trunk) -->
<target name="build">
<svn>
  <checkout url="http://localhost/svn/project/trunk" revision="HEAD" destPath="." />
</svn>
<ant antfile="build.xml" target="build-all">
  <property name="moduleA.dir"    value="/var/cc-sandbox/artifacts/moduleA/latest" />
  <property name="moduleB.dir"   value="/var/cc-sandbox/artifacts/moduleB/latest" />
</ant>
</target>

<!-- build-project-release.xml -->
<!-- for the project-release (branch)-->
<target name="build">
<svn>
  <checkout url="http://localhost/svn/project/branches/release_1_0" revision="HEAD" destPath="." />
</svn>
<ant antfile="build.xml" target="build-all">
  <property name="moduleA.dir"    value="/var/cc-sandbox/artifacts/moduleA-release/latest" />
  <property name="moduleB.dir"   value="/var/cc-sandbox/artifacts/moduleB-release/latest" />
</ant>
</target>

Now, since Ant inherits this properties I have to just create one single build file which is the same for branch and trunk. For example:

<path id="internal-dep-classpath">
   <!-- depends on moduleA project -->
   <fileset dir="${moduleA.dir}" >
     <include name="*.jar" />
   </fileset>
   <!-- depends on module B libraries -->
   <fileset dir="${moduleB.dir}" >
     <include name="*.jar" />
   </fileset>
 </path>

That's it.

Published in Nov 20, 2008