Chapter 6. Setting Up a Continuous Integration Server with CruiseControl

An Introduction to CruiseControl

CruiseControl is a widely used and widely regarded open source continuous integration tool written in Java. CruiseControl is backed by ThoughtWorks, a leading proponent of agile methodologies and open source technologies. One of the first open source Continuous Integration tools, it benefits from a large user base and a number of third-party tools. ThoughtWorks now also offers CruiseControl Enterprise, a supported version of the product.

For those who skipped the introduction to this part of the book, Continuous Integration is a powerful technique used to keep development teams in phase and reduce the risks and complexities involved in combining code written by a number of individual developers into a unified working product. It basically involves automatically building and testing the latest source code at frequent intervals. At the same time, team members test and commit their changes frequently into the source code repository. It can considerably reduce the costs and risks traditionally involved in the integration phase of a project.

CruiseControl falls into the same category of tools as Continuum (Chapter 5), LuntBuild (Chapter 7), and Hudson (Chapter 8). CruiseControl is the oldest of the three tools. Up until recently, configuration was still entirely done via an Extensible Markup Language (XML) configuration file. As of version 2.7, a basic administration console was added, similar to the ones found in the other tools we look at. CruiseControl supports an extensive range of software configuration management tools and notification mechanisms.

In this chapter, we will talk about CruiseControl 2.7.1, the latest release at the time of this writing.

CruiseControl runs as a process on the Continuous Integration server (known as the “Build Loop”) that periodically checks for updates in the source code repository. Whenever updates are detected in a project’s source code, CruiseControl runs the corresponding build process and notifies a configurable list of listener modules. These listener modules let you notify team members about build results via email, IM, RSS, or using other methods.

CruiseControl also runs a web site containing a summary of build results and generated artifacts.

Installing CruiseControl

This section will show you how to get CruiseControl up and running on your machine.

I recommend creating a dedicated user account for CruiseControl. On a Linux machine, you can create a new user, as follows:

# useradd cruisecontrol
# su - cruisecontrol
cruisecontrol@linux-gxu0:~>

Now download the CruiseControl binaries from the CruiseControl web site (http://cruisecontrol.sourceforge.net/download.html). CruiseControl comes packaged as either a Windows executable installer or as a simple ZIP file. Here we will use the ZIP file, as this will work in any environment. If you are installing CruiseControl on a remote server, you can download the latest version from the CruiseControl web site using a command-line tool like wget, as shown here:

$ wget http://prdownloads.sourceforge.net/cruisecontrol/cruisecontrol
-bin-2.7.1.zip?download
...
13:46:56 (30.21 KB/s) - 'cruisecontrol-bin-2.7.1.zip?download' saved [14487]

Now unzip the package into the home directory:

$ unzip cruisecontrol-bin-2.7.1.zip
Archive:  ../cruisecontrol-bin-2.7.1.zip
   creating: cruisecontrol-bin-2.7.1/
   creating: cruisecontrol-bin-2.7.1/lib/
   creating: cruisecontrol-bin-2.7.1/logs/
   creating: cruisecontrol-bin-2.7.1/logs/connectfour/
  inflating: cruisecontrol-bin-2.7.1/cruisecontrol.bat
  inflating: cruisecontrol-bin-2.7.1/lib/commons-el.jar
  inflating: cruisecontrol-bin-2.7.1/lib/commons-logging.jar
  inflating: cruisecontrol-bin-2.7.1/lib/jasper-compiler.jar
  ...
$ cd cruisecontrol-bin-2.7.1
$ ls
apache-ant-1.7.0  cruisecontrol.bat  dashboard-config.xml  lib   projects   
webapps
config.xml        cruisecontrol.sh   docs                  logs  README.txt  
widgets.cfg

And that’s it as far as installing things goes. Now we can test the installation. CruiseControl comes with its own bundled Jetty web server, so you don’t have to worry about configuring (yet) another web server to monitor builds. Starting up CruiseControl is simple: just run the cruisecontrol.sh script (or cruisecontrol.bat for Windows installations):

$ cd ~/cruisecontrol-bin-2.7.1
$ ./cruisecontrol.sh
[cc]Sep-19 01:08:29 Main          - CruiseControl Version 2.7.1 Compiled on 
                                    September 4 2007 1821
...
[cc]Jun-18 14:09:38 ontrollerAgent- Starting HttpAdaptor with CC-Stylesheets
[cc]Jun-18 14:09:38 ontrollerAgent- starting httpAdaptor
[cc]Jun-18 14:09:38 BuildQueue    - BuildQueue started
HttpAdaptor version 3.0.1 started on port 8000
[cc]Jun-18 14:09:38 Container     - Started org.mortbay.jetty.servlet.
                                    WebApplicationHandler@e2cb55
[cc]Jun-18 14:09:38 Container     - Started WebApplicationContext
                                    [/,CruiseControl Reporting App]
[cc]Jun-18 14:09:39 Container     - Started org.mortbay.jetty.servlet.
                                    WebApplicationHandler@29e357
[cc]Jun-18 14:09:39 Container     - Started WebApplicationContext[/cruisecontrol,
                                    CruiseControl Reporting App]
[cc]Jun-18 14:09:39 SocketListener- Started SocketListener on 0.0.0.0:8080
[cc]Jun-18 14:09:39 Container     - Started org.mortbay.jetty.Server@b4d3d5

This script initializes the continuous build process and starts up a Jetty web server.

By default, it will use port for the web site and port 8000 for Java Management Extensions (JMX) administration. As these are pretty common ports, you may need to modify them on your own server (especially if you are experimenting on a machine with other tools already installed). To do this, you provide webport and webport and jmxport command-line options, as follows:

$ ./cruisecontrol.sh -webport 8888 -jmxport 8880

CruiseControl comes with a small demonstration project you can use to make sure everything is running correctly. If you open http://localhost:8080 (for a standard configuration) or http://localhost:8888 (if you ran the above command), you will get the rather spartan console shown in Figure 6-1.

A CruiseControl web site
Figure 6-1. A CruiseControl web site

Configuring an Ant Project

Now that the server is installed, we’ll look at how to add a simple project to CruiseControl. CruiseControl works best with Ant, so we’ll look at this configuration first.

When it builds a project, CruiseControl uses a dedicated work directory for each project, where it checks out the source code and runs its builds. However, CruiseControl will not create this directory by itself, even if you tell it where to find the SCM tool. You have to do it yourself. So the first thing to do is to create a working directory for your project. These directories live (by convention) in the $CC_HOME/projects directory, where $CC_HOME is your CruiseControl installation directory. So before you start, you need to manually create the project and check out an initial copy of the source code. In this example, we will be working with a sample project called library-loans, an imaginary API designed to interface to a library loans database. First, we check out our project from the SCM repository into the projects directory (in this example, we use Subversion [Chapter 4], but CruiseControl supports a wide range of SCM tools):

$ su - cruisecontrol
Password:
$ cd cruisecontrol-bin-2.7.1/projects/
$ svn co svn://localhost/library-loans/trunk library-loans
A    library-loans/test
...
A    library-loans/build.xml
Checked out revision 31.
$ ls 
connectfour/  library-loans/

It’s also wise to verify that the build works properly in this environment. A lot of time-wasting errors come from badly configured Continuous Integration user accounts. In this sample project, we use some fairly standard ant targets: clean, to delete all generated artifacts; compile, to compile the main classes; build, to package the compiled classes into a jar called library-loans.jar; and test, to run the unit tests against this jar. Our continuous build process will go as far as running the unit tests:

$ cd library-loads
$ ant test
Buildfile: build.xml

init:
...
    [junit] Testcase: testSetName took 0.004 sec
    [junit] Testcase: testSetSymbol took 0 sec

BUILD SUCCESSFUL
Total time: 2 seconds

Now that we have a working project, we need to tell CruiseControl how to update the source code from the repository before each build. CruiseControl supports a large number of SCM tools, both open source and commercial. The current version (2.5) supports CVS, Subversion, BitKeeper, ClearCase, MKS, Perforce, PVCS, StarTeam, Visual SourceSafe, and more. However, there’s a catch. When you configure CruiseControl to talk to a particular SCM tool, you are actually just telling it where to check for updates. If it detects updates, it will start a build. Period. It won’t actually update your project source code from the repository before it does so: it leaves that minor detail to you.

As a rule, you don’t usually integrate this task into your normal build.xml file. For one thing, your build.xml file is usually in the source code repository, so you have to update this file manually before updating the rest of the project through CruiseControl.

One common solution, of which several variations are described on the CruiseControl wiki, is to use a “wrapper” build file, which updates from the source code repository and then invokes the ordinary build file. This avoids cluttering up the ordinary build file with details about your source code repository. In our example, this file is simply called build-cc.xml, and it looks like this:

<project name="library-loans-cc">
    <target name="svn-update" description="Update from Subversion">
        <exec executable="svn">
            <arg line="update"/>
        </exec>
    </target>
    
    <target name="clean">
        <ant target="clean"/>
    </target>
    
    <target name="build" depends="svn-update">
        <ant target="build"/>
    </target>
    
    <target name="test" depends="build">
        <ant target="test"/>
    </target>

    <target name="load-tests" depends="build">
        <ant target="load-tests"/>
    </target>
</project>

So, now we can update the source code from the repository and build the project. Now you can add this project to the CruiseControl configuration file. Sure, CruiseControl has a web site where you can monitor builds, but all the serious configuration takes place in a file called config.xml. This makes CruiseControl less convenient to manage when compared to other similar tools such as Continuum (Chapter 5), LuntBuild (Chapter 7), and Hudson (Chapter 8). However, as we will see, the configuration file is relatively short and isn’t too hard to master.

A basic CruiseControl configuration file goes something like this:

<cruisecontrol>
    <property name="build" value="projects/${project.name}/build"/>

    <project name="library-loans">

        <listeners>
            <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
        </listeners>
        
        <bootstrappers>
                <svnbootstrapper file="projects/${project.name}/build-cc.xml" 
                                 localWorkingCopy="projects/${project.name}" />
        </bootstrappers>

        <modificationset quietperiod="0">
            <svn localWorkingCopy="projects/${project.name}"/>
        </modificationset>
        
        <schedule interval="600">
            <ant anthome="apache-ant-1.6.5" 
                  buildfile="projects/${project.name}/build-cc.xml"
                  target="clean test"/>
            <ant anthome="apache-ant-1.6.5" 
                  buildfile="projects/${project.name}/build-cc.xml"
                  time="0200"
                  target="clean load-tests"/>
        </schedule>
        
        <log>
             <merge dir="${build}/test-results"/>
        </log>
        
        <publishers>
            <onsuccess>
                <artifactspublisher dest="artifacts/${project.name}" 
                                    file="${build}/${project.name}.jar"/>
            </onsuccess>
        </publishers>
        
    </project>
    
</cruisecontrol>

The CruiseControl configuration file contains a list of project entries. Properties like ${project.name} and ${build} are used to improve readability and reduce duplication. This is an example of how Ant-style properties can be used in CruiseControl configuration files. The ${project.name} property is automatically set by CruiseControl, but you can also define and use your own just as you would in an Ant build file, as shown here with the ${build} property.

You can configure each project using a number of elements, which are described briefly here. Some of the more interesting ones are treated in more detail in other articles.

<listeners>

Listeners are used to perform actions when various project events occur. The currentbuildstatuslistener listener is the only one you really need from the word go, as it is used to display the build status of each project on the CruiseControl web site (see Figure 6-1).

<bootstrappers>

Bootstrappers are tasks that are executed just before a build starts. One useful strategy, described by Lasse Koskela[6] is to use a bootstrapper task to update the cruise control build file (build-cc.xml) before performing the full build.

<modificationset>

The modification set tells CruiseControl where and how to check for updates in the source repository. Here we are using Subversion, so we use the <svn> task. The localWorkingCopy attribute points to the local directory in which the Subversion project has been checked out: it is almost always the project directory. This task basically runs svn log to determine the modifications, which have occurred since the last build.

We could also have used CVS, StarTeam, ClearCase, or one of the many other SCM tools supported by CruiseControl. We could even use a directory on the file system, using the <filesystem> element.

If you are using an SCM tool, which doesn’t support atomic commits, such as CVS, ClearCase, or Visual SourceSafe, you may need to use the quietperiod attribute. This value corresponds to the number of seconds that must have passed without any repository modifications. It is designed to avoid builds being started when someone is in the middle of committing her changes. You can set it to “0,” as shown here, for SCM tools that support atomic commits and therefore don’t need to wait until all the changes files have been committed.

Another useful attribute is “requiredmodification.” Normally, CruiseControl will only start a build if it detects modifications in the source code repository. However, in some situations, you may want to run a build systematically, even if no modifications have been detected. For example, you may want a full nightly build to be run systematically at midnight every night; just set “requiredmodification” to “false.”

<schedule>

The schedule element is where you schedule your builds. CruiseControl supports two scheduling models. In the first approach, CruiseControl periodically polls the source code repository for changes and runs a build whenever a change is detected. You define the number of seconds between these queries in the “interval” attribute. In the following example, the source code repository will be polled every 60 seconds. If any changes are detected, CruiseControl will run the build specified in the embedded build task:

        <schedule interval="60">
            <ant anthome="apache-ant-1.6.5" 
                  buildfile="projects/${project.name}/build-cc.xml"
                  target="test"/>
        </schedule>

As shown here, you define the actual build tasks within the schedule element. CruiseControl 2.5 supports Ant, NAnt, Maven, and Maven 2 builds, via the <ant>, <nant>, <maven>, and <maven2> build tasks. The build task shown here runs the standard unit tests by invoking the test target in the build-cc.xml build file, which is the equivalent of the following:

$ cd projects/library-loans
$ ant -f build-cc.xml test

The second scheduling approach is to specify the actual times at which you want the builds to be run. This is useful if you want to set up a nightly integration build, for example. Suppose that you want to add a task to regularly run load tests. As load tests are expected to put the server under some stress, they are only performed once a day at 1 a.m. To run a task at a particular time, you use the time attribute, as shown in this example (“time="0100"”). If you define a time for a build, the schedule frequency is ignored:

        <schedule interval="60">
            <ant anthome="apache-ant-1.6.5" 
                  buildfile="projects/${project.name}/build-cc.xml"
                  target="load-tests"
                  time="0100"/>
        </schedule>

A third scheduling possibility is to use the multiple attribute, which lets you run a task only every Nth build. For example, you may want to do incremental builds (“ant test”) and do a full build (“ant clean test”) only every 10th build. You could do this as follows:

        <schedule interval="60">
            <ant anthome="apache-ant-1.6.5" 
                  buildfile="projects/${project.name}/build-cc.xml"
                  multiple=10
                  target="clean test"/>
        </schedule>

In some cases, you need to stop build tasks over a certain period of time. Suppose your database goes down every night from 2 a.m. to 4 a.m. for backups. If you run any builds during this period, it will create unnecessary build failures. To get around this, you can temporarily suspend builds during a certain period using the <pause> element, as shown here:

        <schedule interval="60">
            <ant anthome="apache-ant-1.6.5" 
                  buildfile="projects/${project.name}/build-cc.xml"
                  target="test"/>
            <pause starttime="0200" endtime="0400"/> 
        </schedule>

<log>

Here we merge the JUnit test results into the CruiseControl logfile. This lets CruiseControl correctly display the unit test results on the web site.

<publishers>

Publisher entries are run at the end of each build, successful or not. They are typically used to notify developers of build results in some way, shape, or form. The most common method is old-fashioned email, but CruiseControl supports many other methods, and you can be quite imaginative if you put your mind to it. Another common use is to deploy generated files somewhere useful. In this example we place a copy of the generated JAR file into the artifacts directory, where it can be accessed from the CruiseControl web site. We look at publishers in more detail in Keeping People Notified with Publishers.

Now restart CruiseControl and open the CruiseControl web site. You should see your new project, which has been added to the list of projects.

We saw earlier how the build status screen gives you an overview of all your projects. From this page, you can drill down to see the details for each project (see Figure 6-2). Here you will find the results of the last build and a list of the files modified since the previous successful build. The Test Results page provides a list of unit test results. There’s also a “Metrics” page (see Figure 6-3), which gives you some nice graphs about the number of successful builds over time.

Build results for a project are displayed on the CruiseControl web site
Figure 6-2. Build results for a project are displayed on the CruiseControl web site

Keeping People Notified with Publishers

It’s a good thing to have your builds running regularly, but it’s even better to let everyone know how they’re going. Developers will not, as a rule, spend their time glued to the CruiseControl web console waiting for the next build results to come up: they have better things to do with their time.

Publishing notification is one of the areas in which CruiseControl excels. Out-of-the-box, CruiseControl supports eMail, Jabber IM, RSS feeds, and even blogs. You can also perform various tasks such as ftp or scp file transfers, invoking an Ant target, running command-line tasks, or even using an X10 interface to hook up a lava lamp.

The CruiseControl web site displays metrics concerning build history for a project
Figure 6-3. The CruiseControl web site displays metrics concerning build history for a project

Publishers are usually called after every build, whether the build succeeds or fails. If you need to run a publisher task only when a build succeeds or only when it fails, you can place it inside either a <onsuccess> or <onfailure> block, respectively. So, in the following example, the JAR file is deployed to the artifacts directory only if the build is successful:

        <publishers>
            <onsuccess>
                <artifactspublisher dest="artifacts/${project.name}" 
                                    file="${build}/${project.name}.jar"/>
            </onsuccess>
        </publishers>

The most common notification method is by email. CruiseControl supports both plain text email and HyperText Markup Language (HTML) email. The plain text email (<email>) simply sends a lightweight text message containing a link to the build results (see Figure 6-4). Configuring the email publisher is relatively straightforward. A typical example is shown here:

        <property name="web.server.url" value="http://localhost:8080"/>
        ...
        <publishers>
            ....
            <email mailhost="localhost"
                   returnaddress="cruisecontrol"
                   defaultsuffix="mycompany.com"
                   subjectprefix="Build report:"
                   reportsuccess="fixes"
                   spamwhilebroken="false"
                   buildresultsurl="${web.server.url}/buildresults/${project.name}">
                <always address="build-archives" />
                <failure address="developers" reportWhenFixed="true"/ />
                <map alias="john" address="[email protected]" />
                <map alias="mike" address="[email protected]" />
                <map alias="developers" address="john, mike, harry" />
            </email>
            ....
        </publishers>

Most of the attributes are fairly self-explanatory:

mailhost

This attribute points to your mail server. If you’re on a Unix machine, you can use the local machine, of course.

returnaddress

The mail address to which errors are sent if the notification mail did not get through.

defaultsuffix

This suffix is used to build email addresses. For instance, here, “build-archives” in the <always> element will map to “[email protected].”

subjectprefix

The prefix added to the start of email titles.

reportsuccess

This determines when mail is to be sent, and can be either “always,” “fixes,” or “failures.” The first option sends mail for every successful build, whereas “fixes” only sends mail for the first successful build and the first successful build after a failure. The “failures” option only sends mail for failed builds.

spamwhilebroken

If this is set to “true” (which is the default value), CruiseControl will send a mail each time the build fails, until the problem is fixed. If this seems overkill, set this attribute to “false” and CruiseControl will just send one message when the build breaks, and then another (if requested) when the problem is fixed.

buildresultsurl

This is the base Uniform Resource Locator (URL) used to build the link to the build page. You shouldn’t need to change this.

always

This element contains an address, or an address list, to which a message is sent after each build, whatever its outcome.

failure

This element contains an address, or an address list, to which a message is sent whenever a build fails. (There is also the <success> element, which does the opposite, but its utility is not particularly obvious.) A useful attribute of the <failure> element is the reportWhenFixed attribute: if this is set to “true,” a message will be sent to report when the problem has been fixed.

map

The <map> element defines aliases between SCM tool user accounts and email addresses. This is quite useful, as very often they don’t match. You can also define lists of addresses, which in practice lets you set up team mailing lists.

A plain-text email notification
Figure 6-4. A plain-text email notification

The other way to send mail is as a self-contained HTML document. The HTML email task (<htmlemail>) sends a summary of the build in HTML (see Figure 6-5). It is very similar to the <email> element that we just looked at:

        ...
        <htmlemail mailhost="localhost"
                   returnaddress="cruisecontrol"
                   defaultsuffix="mycompany.com"
                   subjectprefix="Build report:"
                   reportsuccess="fixes"
                   spamwhilebroken="false"
                   buildresultsurl="${web.server.url}/buildresults/${project.name}"
                   css="webapps/cruisecontrol/css/cruisecontrol.css"
                   xsldir="webapps/cruisecontrol/xsl" 
                   buildresultsurl="${web.server.url}/buildresults/${project.name}">            
                <always address="build-archives" />
                <failure address="developers" reportWhenFixed="true"/ />
                <map alias="john" address="[email protected]" />
                <map alias="mike" address="[email protected]" />
                <map alias="developers" address="john, mike, harry" />
        </htmlemail>        
        ...

In fact, it is identical, with a few extra attributes. None are mandatory, but in many cases CruiseControl will have a hard time finding the correct files if you don’t give it a bit of a hand with the following two:

css

The path to cruisecontrol.css, which is the stylesheet used to generate the mail. You could substitute your own, of course, if you really wanted to.

xsldir

The path to the CruiseControl XSL directory, where CruiseControl keeps its XSL files (strangely enough).

An HTML email notification
Figure 6-5. An HTML email notification

Using the HTML mail format in this context can sometimes have some practical advantages. If the build server is an internal machine hidden behind a firewall (which is often the case), external users may not have access to the build web site. The HTML notification messages in CruiseControl contain full details of the build results, whereas the text mail just contains a link to the build server. So, for external users who are unable to access the build server, the text notification may not provide enough details. Developers often appreciate the HTML notification format in the case of build failures, since they can immediately see details of the error that has occurred and the modifications since the last build, without having to go to the build site (see Figure 6-6).

An HTML email notification for a failed build
Figure 6-6. An HTML email notification for a failed build

As we have seen earlier, you can use reportsuccess and reportWhenFixed attributes to let you keep track of when integration errors are fixed. As soon as the problem has been fixed, a mail will be published to let everyone know about it (see Figure 6-7).

An HTML email notification for a fixed build
Figure 6-7. An HTML email notification for a fixed build

CruiseControl supports many other types of notification.

The <jabber> task lets you notify users via an IM client, which can have the advantage of being more eye-catching than a simple mail. The <weblog> task lets you publish to a weblog, and the <rss> to an RSS channel.

The <x10> task can be used to control lava lamps and other similar electronic devices. The principle of lava lamps is well known in Agile circles: you have two lava lamps hooked up to the build server, one green and one red. When the builds are successful, the green one bubbles. If a build fails, the red one bubbles. The nature of lava lamps is that the longer they stay on, the more agitated they get, so the longer the build stays broken, the more red bubbles you get. Another property of lava lamps is that they tend to take 10 to 15 minutes to warm up. If the developer is quick, she may be able to fix the failure before the lamp starts bubbling and the rest of the team notices.[*]

The <socket> task lets you write your build results directly to a socket. And if that isn’t enough, the <execute> task lets you run an external program.

Setting Up a Maven 2 Project in CruiseControl

CruiseControl isn’t as well integrated with Maven as it is with Ant. However, you can actually use the SCM features of Maven to make life easier. In this section, we’ll go through the steps involved in configuring a Maven 2 project under CruiseControl.

For this example, we’ll use a project called “tasker.”

First of all, check out the source code in a working directory for CruiseControl:

$ cd projects
$ svn co svn://localhost/tasker/trunk tasker
A    tasker/src
...
Checked out revision 24.
$ ls
connectfour  library-loans  tasker

Now add the Maven project to the CruiseControl configuration file.

Next you need to set up version control. In CruiseControl, this is easier to do for a Maven 2 project than for an Ant project, mainly because of Maven’s integrated lifecycle support. In Maven 2, you specify the source code repository using the <scm> tag in your pom.xml file. A simple <scm> entry might look like this:

  <scm>
      <connection>scm:svn:svn://subversion.mycompany.com/tasker/trunk</connection>
      <developerConnection>scm:svn:svn://subversion.mycompany.com/tasker/trunk
      </developerConnection>
  </scm>  

If this is correctly set up, you can update your project using the Maven scm plugin, as shown here:

$ mvn svn:update

In other words, you don’t have to worry about the build wrapper we saw in the Ant project configuration. You just have to add the project to the CruiseControl configuration file. Here is an example:

    <project name="tasker">
        
        <listeners>
            <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
        </listeners>
        
        <modificationset quietperiod="0">
            <svn localWorkingCopy="projects/${project.name}"/>
        </modificationset>
        
        <schedule interval="10">
            <maven2 
                mvnscript="/usr/local/bin/mvn"
                pomfile="projects/${project.name}/pom.xml"
                goal="scm:update package"
            />
        </schedule>
        
        <log>
            <merge dir="projects/${project.name}/target/surefire-reports"/>
        </log>
        <publishers>
            <onsuccess>
                <artifactspublisher dest="artifacts/${project.name}" 
                        file="projects/${project.name}/target/${project.name}-1.0.jar"/>
                </onsuccess>        
        </publishers>
        
    </project>

The major change here is that we replaced the <ant> schedule task with a <maven2> task. The <maven2> task is relatively simple: you provide a mvnscript attribute (to tell CruiseControl where to find the mvn executable), the project pom.xml, and the goals to be executed. The first goal must be scm:update, which updates your project from the source repository. The next goal here is package, which compiles the source code, runs the unit tests, and generates a JAR file.

There are a few tricks that you should be aware of here. First of all, make sure you set the <merge> element in <logs> to point to your /target/surefire-reports directory. This tells CruiseControl where to find Maven’s unit test results.

Second, we have to tell CruiseControl about the generated artifact (the JAR file). For Maven users, one of the big weaknesses in CruiseControl is its poor support for Maven artifact versions. CruiseControl expects an artifact with a constant name, such as “tasker.jar.” Maven, by contrast, generates versioned artifacts, such as “tasker-1.0.jar.” And CruiseControl doesn’t know how to talk to Maven to know what the current version is. So, the simplest solution is to make sure that the “file” attribute in the <artifactspublisher> tag matches the current version in Maven. Unfortunately, this requires you to manually update your CruiseControl script whenever you update your Maven artifact version number.

Now you’re done! Your Maven 2 project is now correctly integrated into CruiseControl (see Figure 6-8).

A Maven 2 build in CruiseControl
Figure 6-8. A Maven 2 build in CruiseControl

The CruiseControl Dashboard

For a long time, the CruiseControl user interface was somewhat basic, to say the least. In the more recent releases, however, there is a new and revamped graphical dashboard that gives you a convenient overview of the status of your projects, as shown in Figure 6-9. This dashboard gives you a color-coded summary of the status of your builds: tones of green for success, tones of red for failure, yellow for a build in progress, and gray for inactive projects.

The CruiseControl dashboard
Figure 6-9. The CruiseControl dashboard

You can also drill down to view the details of a particular build, or view a summary of all the latest build results in the Builds tab. From here, you can also force a build to run manually. The dashboard also lets you add a project to the CruiseControl configuration file (although in general you still need to go and tailor the configuration file manually to suite your needs), and provides access to RSS feeds for server build results.

Third-Party Tools

CruiseControl boasts a rich collection of third-party tools. In this section, I describe a few of the more useful of them. Many, if not most, are listed on the CruiseControl wiki.

CruiseControl Configuration Tool

The CruiseControl Configuration UI[*] is a Java client application that can help you write and maintain CruiseControl configuration files using a Swing interface (see Figure 6-10). The CruiseControl configuration file is presented in the form of a tree, in which you can add, delete, or modify elements. One nice piece of functionality is the help panel, which displays contextual help for the current element and can be a useful learning aid or memory-jogger.

The CruiseControl Configuration UI in action
Figure 6-10. The CruiseControl Configuration UI in action

Firefox and Thunderbird Integration

Dmitri Maximovich[*] has written a neat little CruiseControl plug-in for Firefox and Thunderbird. You configure the plug-in by specifying a name and the JMX URL for the server (or servers) you want to monitor. CruiseControl runs JMX by default on port 8000, so your JMX URL will probably look like http://cruisecontrol.mycompany.com:8000. Once you’ve configured your server, you will see a panel in the lower right corner of the Firefox window, which summarizes the current build status (see Figure 6-11).

A CruiseControl plug-in for Firefox
Figure 6-11. A CruiseControl plug-in for Firefox

Conclusion

CruiseControl is a powerful and flexible continuous integration tool, albeit with a nontrivial learning curve. It is a pure CI tool, with little in the way of interproject dependency or build artifact management. However, its flexibility and sophisticated notification techniques can make it an excellent choice for experienced Continuous Integration practitioners.



[6] In “Driving On CruiseControl—Part 1,” appearing on http://www.javaranch.com in September 2004.

[*] This technique is well documented on the CruiseControl wiki and also by Mike Clark (visit http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Devices/BubbleBubbleBuildsInTrouble.rdoc*).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.174.191