CruiseControl 2.x has two configuration files.
General Information
The main configuration file is for your build loop and is commonly refered to by its default name of config.xml (you can use any name you like, but then you'll need to specify that name as a parameter when you start CC).
The secondary configuration file is the web.xml file for the JSP. In the web.xml you specify the location of the log files generated by the main CC process at the end of each build attempt and the location of the CurrentBuildStatusFile which is updated both before and after a build attempt.
Build Loop reference
SourceForge has the definitive reference for the build configuration file at:
http://cruisecontrol.sourceforge.net/main/configxml.html
Understanding the plugins mechanism also helps understanding the build loop config.
http://cruisecontrol.sourceforge.net/main/plugins.html
One Helpful Tip on Writing Config Files:
Almost everything in the config file (every element, if you want to think about them as elements) has a plugin associated with it (with the exception of the <property> element). The plugin specifically references the class that handles the element. While ANT lets you call core and optional tasks without explicitly specifying the classname that does the work, cruisecontrol forces you to make these explicit definitions. If you're messing up by declaring a configuration element, and not supplying the plugin that is associated with it, cruise control will let you know by saying "unknown plugin". Maybe someday, this explicity will go away, but for now, it's in there, and the user has to handle it.
--AldenAlmagro
Example of a Working build loop config file.
<cruisecontrol>
<project name="cmic_project6" dateformat="yyyy-MMMM-dd HH:mm:ss">
<bootstrappers>
<currentbuildstatusbootstrapper file="project6_currentbuild.txt" />
<cvsbootstrapper cvsroot=":pserver:awick@k2:/cvsroot"
file="project6/build.xml" />
</bootstrappers>
<modificationset quietperiod="180">
<cvs cvsroot=":pserver:awick@k2:/cvsroot"
localworkingcopy="project6"/>
</modificationset>
<schedule interval="600" intervaltype="relative">
<ant buildfile="project6/build.xml" target="integration.clean" multiple="5" />
<ant buildfile="project6/build.xml" target="integration" multiple="1" />
</schedule>
<log dir="project6_logs">
<merge dir="project6/junit"/>
</log>
<publishers>
<currentbuildstatuspublisher file="project6_currentbuild.txt" />
<email mailhost="our-mail-host"
returnaddress="awick@spiderlogic.com"
defaultsuffix="@spiderlogic.com"
buildresultsurl="http://k2:8080/project6/buildresults">
<always address="buildmasters" />
<failure address="developers" />
<map alias="developer1" address="developer1@othercompany.com" />
<map alias="developer2" address="developer2@othercompany.com" />
<map alias="buildmasters" address="awick" />
<map alias="developers" address="awick, localdeveloper, developer1, developer2" />
</email>
</publishers>
</project>
</cruisecontrol>
By default, CC rebuilds after the quiet period if the last build failed, even if there have been no modifications during the quiet period. To change this, include the following in the config file.
<project name="sampleProjectName" buildafterfailed="false">
- MattMunz
Looking at the sample configuration given above, is there a typo in the dateformat attribute...? It looks like there's an extra M for month (its "yyyy-MMM-dd HH:mm:ss"). Shouldn't it really be "yyyy-MM-dd HH:mm:ss".
- Lance Hankins
You are correct for CVS compatibility, as CVS does not accept MMM month formats in dates (e.g. Feb) only MM (e.g. 02)
- Tony Cook
Where do we specify which project to check out from CVS? - VJ
Set the localworkingcopy attribute
Q: I am wondering if the "intervaltype" tag is still supported in the schedule section, as the docs on sourceforge don't seem to reflect this option. --James Seigel
A: Nope. intervaltype hasn't been supported since 1.0.
Reducing Duplication Using Properties and Plugin Preconfigure
Ant style properties were introduced to CruiseControl in version 2.3. This property support, in combination with plugin preconfiguration, is a very powerfull tool with which you can eliminate much of the duplication often found in a CruiseControl config file.
Plugin preconfiguration was improved in 2.3.1 with the addition of support for preconfiguration of nested plugin elements. (To be released anytime soon)
A Quick Introduction to Properties
For the most part, properties in CruiseControl follow the familiar Ant syntax and rules. There are a few exceptions, however, which I'll run through here:
- It's not entirely first come, first set. Properties set a the global level can be eclipsed within the scope of a project by simply reseting the property.
- The property "${project.name}" is automatically defined and will always refer to the current project being serviced - even outside the scope of the project's definition.
To set a property using a name/value pair:
To load the system's environment into a collection of CC properties which will be prefixed with "env." (Note: The "toupper" attribute forces all environment variable names to be converted to upper case):
To load properties from a file:
Just as in Ant, once a property is defined, it can be used to define other properties:
You can even nest properties within other properties to create complex data structures (Note: For experts only!)
Eclipsing properties:
Combining Properties with Plugin Preconfigure
While properties are great on their own, they're even better when used in conjunction with plugin preconfiguration. Remember that automatic ${project.name} variable? Let's see if we can't get our project definitions down to the bare minimum:
<cruisecontrol>
<!-- Load environment variables -->
<property environment="env" toupper="true"/>
<!-- Commonly used directories -->
<property name="reportdir" value="${env.CCDIR}/report"/>
<property name="projectdir" value="${env.CCDIR}/checkout/${project.name}"/>
<property name="testdir" value="${projectdir}/build/junit-reports"/>
<property name="logdir" value="${env.CCDIR}/logs/${project.name}"/>
<!-- Defaults for email -->
<property name="buildmaster.email" value="buildmaster@example.com"/>
<property name="buildmaster.name" value="Buildmaster"/>
<!-- Preconfigure our plugins -->
<plugin name="log"
dir="${logdir}"/>
<plugin name="currentbuildstatuslistener"
file="${logdir}/buildstatus.html"/>
<plugin name="cvs"
localworkingcopy="${projectdir}"/>
<plugin name="ant"
antscript="${env.ANT_HOME}/bin/ant"
antWorkingDir="${projectdir}"
target="cruise"/>
<plugin name="htmlemail"
buildresultsurl="http:
mailhost="smtp.example.com"
returnaddress="${buildmaster.email}"
returnname="${buildmaster.name}"
subjectprefix="[BUILD ${project.name}]"
xsldir="${reportdir}/jsp/webcontent/xsl"
css="${reportdir}/jsp/webcontent/css/cruisecontrol.css"/>
<project name="project1">
<listeners>
<currentbuildstatuslistener/>
</listeners>
<log>
<merge dir="${testdir}"/>
</log>
<modificationset>
<cvs/>
</modificationset>
<schedule>
<ant/>
</schedule>
<publishers>
<htmlemail>
<always address="${buildmaster.email}"/>
<failure address="proj1dev@example.com"/>
</htmlemail>
</publishers>
</project>
<project name="project2">
<listeners>
<currentbuildstatuslistener/>
</listeners>
<log>
<merge dir="${testdir}"/>
</log>
<modificationset>
<cvs/>
</modificationset>
<schedule>
<ant/>
</schedule>
<publishers>
<htmlemail>
<always address="${buildmaster.email}"/>
<failure address="proj2dev@example.com"/>
</htmlemail>
</publishers>
</project>
</cruisecontrol>
Using Plugin Preconfigure for Projects
Since 2.4.0 it is even possible to pre-configure the project plugin. Doing this you can write templates for similar structured projects thus reducing duplication to an even greater extent. You could preconfigure the project plugin, but then you would have only one template for all your projects. In order to create different templates for different kinds of projects, it's possible to register a new plugin re-using the existing class which handles projects.
I've used the example from above:
<cruisecontrol>
<!-- Load environment variables -->
...
<!-- Commonly used directories -->
...
<!-- Defaults for email -->
...
<!-- Preconfigure our plugins -->
....
<!-- Preconfiguration for projects of kind x -->
<!-- choose your plugin's name, but the classname is fixed -->
<plugin name="project.kind.x" classname="net.sourceforge.cruisecontrol.ProjectConfig">
<!--
you can also use the ${project.name} property here - it will be
resolved when using the template
-->
<listeners>
<currentbuildstatuslistener/>
</listeners>
<log>
<merge dir="${testdir}"/>
</log>
<modificationset>
<cvs/>
</modificationset>
<schedule>
<ant/>
</schedule>
<publishers>
<htmlemail>
<always address="${buildmaster.email}"/>
<failure address="${parameter.failure.email}"/>
</htmlemail>
</publishers>
</plugin>
<!-- using the created template -->
<project.kind.x name="project1">
<property name="parameter.failure.email" value="proj1dev@example.com"/>
</project.kind.x>
<project.kind.x name="project2">
<property name="parameter.failure.email" value="proj2dev@example.com"/>
</project.kind.x>
</cruisecontrol>
Configure mailadresses per project
You probably want to configure the mailadresses per project and only a few within the template.
- Within the project template (or plugin) "call" <htmlemail> and extend it by common addresses if necessary:
<htmlemail>
<failure address="admin@host.com" reportwhenfixed="true"/>
</htmlemail>
- In the config, where the project template (or plugin) is used, add the addresses specific to the current project:
<project.kind.build.standard name="some-project">
...
<publishers>
<htmlemail>
<always address="developer1@host.com"/>
<always address="developer2@host.com"/>
...
</htmlemail>
<publishers>
...
- You can even use the plugin preconfiguration for the htmlemail plugin in addition to generalize html email settings applicable for different project templates (or plugins).