CruiseControl is a popular open source tool for implementing Continuous Integration (CI) of Java applications. The idea behind CI is simple. Build, regression test, and deploy your software application to a test environment every time a code change is committed to version control. If the code change causes the build to break, the regression test to fail, or a problem with the deployment, identify and correct the problem promptly.
CruiseControl is ideally suited for CI. It is a reliable tool that provides real value to Java development teams of any size. While CruiseControl is easy to install, it takes some effort to configure. Fortunately, this challenge can be overcome by understanding the structure and content of the CruiseControl configuration file. After reading the discussion below, you should be able to configure CruiseControl to implement a CI build.
Downloading and Installing CruiseControl
Before configuring CruiseControl, take a few minutes to download and install the software. CruiseControl is available in source and binary distributions from the CruiseControl downloads page. Installing the binary distribution is the quickest way to get started since this distribution contains everything needed to run CruiseControl.
Since CruiseControl is a Java application, it will run on any platform where a JDK is installed Simply select a directory to install CruiseControl then extract the zip file containing the binary distribution to that directory. The top-level CruiseControl directory will be named cruisecontrol-bin-<release>. This directory contains the UNIX shell script, cruisecontrol.sh, and the Windows batch file, cruisecontrol.bat. These files are used to start CruiseControl on UNIX and Windows platforms, respectively. The top-level CruiseControl directory also contains the CruiseControl configuration file, config.xml.
Understanding the Design of CruiseControl
Before attempting to configure CruiseControl, it is important to understand the design of this CI framework. Written in Java, CruiseControl is composed of three main modules: the build loop, the dashboard, and the build results JSP.
The build loop is the core of CruiseControl. It is the daemon process that wakes up at a user defined time interval to trigger a build. The build loop contains the logic to check your version control system for changes since the last build. If changes are detected, the build loop triggers the build and publishes the results.
The build loop relies on a system of plugins to implement the logic for all supported version control systems. The plugin architecture is one of the strengths of CruiseControl because it isolates the implementation details of the build loop for each supported version control tool.
The dashboard is the web-based GUI for viewing build results, manually triggering builds, and editing the CruiseControl configuration file. The dashboard reports the status of CruiseControl builds by project. Each project is defined in the CruiseControl configuration file.
The build results JSP displays the results of the build loop for a project. The page lists links to completed builds along the left side. The details of the selected build are displayed along the right side of the page.
Configuring CruiseControl
A project is the unit of work that CruiseControl uses to implement the build loop. Each project is defined in the CruiseControl configuration file, config.xml. (By the way, you can rename config.xml if you prefer to use another name for the CruiseControl configuration file. If you rename config.xml you will need to modify cruisecontrol.sh or cruisecontrol.bat to reference the new name.)
In addition to the project, config.xml defines all other configuration settings. However, the project is the only element that you need to configure to get started with CruiseControl.
After installing CruiseControl, edit config.xml in the top-level CruiseControl directory. Notice that config.xml starts with the XML tag <cruisecontrol> and ends with the XML tag </cruisecontrol>. The simplest configuration file defines a single project, using the XML element <project>, nested between the XML tags <cruisecontrol> and </cruisecontrol>. However, multiple projects can be defined in config.xml by using a separate <project> element for each project definition. Once additional projects are defined, CruiseControl can be configured to run more multiple projects simultaneously.
Below is a template for config.xml that includes the <project> element nested inside the <cruisecontrol> element.
<cruisecontrol>
<project name=myProject
.
.
.
</project>
</cruisecontrol>
Configuring a <project> in the config.xml File
Each CruiseControl project is defined by several XML elements that are nested inside a <project> element. The <project> element must define a unique name for the project by assigning a value to the name attribute.
Each XML element nested inside the <project> element maps to a plugin that is executed during the build loop. The elements listed below are typically used to define a project.
- <listeners>
- <bootstrappers>
- <modificationset>
- <schedule>
- <log>
- <publishers>
When configured with these elements, the config.xml file has the following structure.
<cruisecontrol>
<project name=myProject
<listeners>
.
.
.
</listeners>
<bootstrappers>
.
.
.
</bootstrappers>
<schedule>
.
.
.
</schedule>
<log />
<publishers>
.
.
.
</publishers>
</project>
</cruisecontrol>
Once these XML elements are nested inside the <project> element they can be configured as described below to complete the definition of a CruiseControl project.
Configuring <listeners> inside the <project> Element
<listeners> is the element that serves as a container for instances of the Listeners plugin. Typically, <listeners> contains the child element <currentbuildstatuslistener>. <currentbuildstatuslistener> can be configured to update the file status.txt for each CruiseControl project. status.txt contains status information that is displayed on the left side of the build results JSP. The information in status.txt also tells the build results JSP when CruiseControl is building a project.
The example below shows that the <currentbuildstatuslistener> is configured to write status.txt to the logs directory for the CruiseControl project. ${project.name} is a property that is automatically set by CruiseControl to the name of the project defined by the <project> element in the config.xml file.
<listeners>
<currentbuildstatuslistener
file="logs/${project.name}/status.txt"/>
</listeners>
Configuring <bootstrappers> inside the <project> Element
<bootstrappers> is a container for instances of the Bootstrappers plugin. <bootstrappers> contains the child element of <bootstrappers> for the version control system that you are using. Depending on the version control system that you are using, the Bootstrapper may configure the appropriate settings so that CruiseControl can retrieve source code files from version control. For some version control systems, such as AccuRev, the Bootstrapper actually retrieves the files from the version control system repository.
The example below shows the <accurevbootstrapper> configured to update the AccuRev workspace which has the same name as the CruiseControl project. The name of the CruiseControl project, and AccuRev workspace, is stored in the CruiseControl property ${project.name}.
<bootstrappers>
<accurevbootstrapper
workspace="/home/accurev_user/workspaces/${project.name}"
verbose="true"/>
</bootstrappers>
Configuring <modificationset> inside the <project> Element
Like <bootstrapper>, <modificationset> is a container for a child element that corresponds to the version control system that you are using. The function of the child element of <modificationset> is to check for changes committed to the version control system since the last build.
The example below shows the <accurev> element that checks for changes in an AccuRev stream since the last CruiseControl build from that stream. The attribute quietperiod specifies the minimum time, in seconds, that must pass between a commit to the version control system and the start of a CruiseControl build. Use of the quiet period attribute ensures that a CruiseControl build does not start if a developer is currently committing changes to the version control system.
<modificationset quietperiod="30">
<accurev stream="AccuRev_stream"
verbose="true"/>
</modificationset>
Configuring <schedule> inside the <project> Element
<schedule> controls the frequency of the build loop. The attribute interval specifies the period, in seconds, between scheduled builds. The child element of <schedule> specifies a builder, the element that maps to the Java class that executes the build. CruiseControl implements builders that invoke the Java build tools Ant, Maven, and Maven2. Additionally, CruiseControl implements an ExecBuilder, which can invoke any shell script. Builders can be nested inside the CompositeBuilder to permit more than one builder to execute during the build loop.
The example below illustrates the use of the CompositeBuilder to execute Ant to build the application followed by a shell script to deploy the build to a test environment.
<schedule interval="300">
<composite>
<ant antscript="/opt/cruisecontrol/build.sh"
antworkingdir="/opt/cruisecontrol/projects/"
buildfile="/opt/cruisecontrol/project/${project.name}" />
<exec workingdir="/opt/cruisecontrol/projects/${project.name}"
command="/opt/cruisecontrol/projects/${project.name}/deploy.sh"/>
</composite>
Configuring <log> inside the <project> Element
<log> is an optional element that specifies where log files generated by CruiseControl are stored. The example below shows the <log> element configured to store log files created by CruiseControl in a directory that corresponds to the name of the CruiseControl project.
<log dir="/opt/cruisecontrol/logs/${project.name}" />
Configuring <publishers> inside the <project> Element
<publishers> run after the build completes to publish the build results. The example below shows the <publishers> configured with the nested element <htmlemail> to define the mail server to use to send email notifications following successful and unsuccessful builds.
<publishers>
<htmlemail
mailhost="mail.cmcrossroads.com"
returnaddress="[email protected]"buildresultsurl="http://127.0.0.1:8080/buildresults/${project.name}"
xsldir="webapps/cruisecontrol/xsl"
css="webapps/cruisecontrol/css/cruisecontrol.css"
spamwhilebroken="true">
<success address="[email protected]"/>
<failure address="[email protected]"
reportWhenFixed="true"/>
</htmlemail>
</publishers>
Running CruiseControl
You are ready to start CruiseControl after configuring the config.xml file as described above. Before starting CruiseContol ensure that the JAVA_HOME environment variable is set to the path to the JDK. Start CruiseControl by executing cruisecontrol.sh on a UNIX platform or cruisecontrol.bat on a Windows platform. The CruiseControl start script will read config.xml and execute the build loop for the project defined in that file. The results of the build will be displayed on the dashboard and on the build results JSP.