You might find CruiseControlInstalled useful as well (if a little out of date).
This guide assumes that you've already got a working project, with an Ant build file and a CVS module for source control. Your ant buildfile should have a single target, say "full-build", which performs all of the build steps for your project, including compiling, building jars, running tests, and generating the full software distribution.
This guide also assumes that there is a single output file from the build, eg a Zip file containing all of your jars, docs etc. Once you've got the simple things working, you'll be able to customize your build exactly how you like it.Note that we're setting up CC to take advantage of the new multi-project support in v2.1. Although this adds a tiny bit of complexity to the process, it will make it heaps easier when you later want to add another project to your continuous integration.
b) You'll see 3 directories under INSTALL_DIR: docs, main, and reporting. The core of CC is contained in "main". "docs" has a copy of the website. "reporting" contains the source for the reporting application, which can build a web application for showing build results, as well as nice HTML emails. The reporting app is covered later.
c) Cruise is distributed as source files, so you'll need to build the binaries. This should be a simple matter of running the appropriate build script (build.sh/build.bat), which will compile the sources, run the tests, and build INSTALL_DIR/main/dist/cruisecontrol.jar.d) Now try running CC (type "java -jar dist/cruisecontrol.jar" or use the scripts (cruisecontrol.bat/cruiscontrol.sh) that are contained in INSTALL_DIR/main/bin); you should get a "No config file" message, along with usage details. This means that CC is installed OK. NOTE: A cruisecontrol.log file will be created in the current directory.
Now you need to set up your CC working directories, and config file. These can/should be placed in a separate directory to INSTALL_DIR, as they contain your data, as opposed to CC binaries.
a) Create a working area for cruise, eg /work/cruise. This will be referred to as WORK_DIR.b) Now create the following subdirectories:
WORK_DIR/checkout | this is where cruise checks out your project from CVS. (ClearCase users do not need this folder - you will check out items from your ClearCase view.) |
WORK_DIR/logs | this is where cruise will write its build reports into. |
WORK_DIR/artifacts | this is where cruise can put any build output files that need to be kept. |
<cruisecontrol> </cruisecontrol>
d) Now try running CC from within WORK_DIR. (You will need to add cruisecontrol.bat or cruisecontrol.sh to the PATH) By default, CC looks for a config file named "config.xml". This should work ok. CC should start up correctly, stating "BuildQueue started". However, to get cruise to actually do anything, you'll need to configure a project.
Alternatively, you can run CC from another location, and specify the path to config.xml using the - configfile commandline option. (Be warned: the paths in your config file are relative to the current directory, and not relative to the config file itself.)NOTE: This directory structure works well for me, but feel free to set things up however you please. The paths to these directories are all specified in the configuration files.
b) You now need to write a delegating Ant build script, which cruise will run to build your project. Call this file "build-MY_PROJECT_1.xml", and put it in WORK_DIR. Basically, this build script should just call through to your project build file (WORK_DIR/checkout/MY_PROJECT/build.xml), but it will probably contain extra steps which are specific to the cruise build, like getting the latest sources from CVS, and tagging the CVS tree after a successful build. Of course, if your build already does this, you won't need to add these commands to the cruise-build.
Heres an example of a delegating build script:<!-- Delegating build script, used by cruisecontrol to build MY_PROJECT_1. Note that the basedir is set to the checked out project --> <project name="build-MY_PROJECT_1" default="build" basedir="checkout/MY_PROJECT_1"> <target name="build"> <!-- Get the latest from CVS --> <cvs command="up -d -P"/> <!-- Call the target that does everything --> <ant antfile="build.xml" target="build-everything"/> </target> </project>
<vssget login="${vss.login},${vss.password}"
ssdir="${vss.executable.dir}"
vsspath="${vss.src.path}"
localPath="${source.dir}"
recursive="true"
writable="false" />
Also, you may find that you want your ant script to make use of the build label. The build label is passed in to the script as a property named label. Simply use ${label} in the ant script. For an overview of all properties passed to your build script, see Properties Passed To The Build Scripts.
You now need to add project information to config.xml, so that cruise will build your project. The config.xml file is the key to your Cruise Control process, so this section is a bit more detailed than some of the others. For more information, see the CruiseControl Configuration Guide.
<cruisecontrol> <project name="MY_PROJECT_1" buildafterfailed="true"> <!-- Bootstrappers are run every time the build runs, *before* the modification checks --> <bootstrappers> <currentbuildstatusbootstrapper file="logs/MY_PROJECT_1/buildstatus.txt"/> </bootstrappers> <!-- Defines where cruise looks for changes, to decide whether to run the build --> <modificationset quietperiod="10"> <cvs localworkingcopy="checkout/MY_PROJECT_1"/> </modificationset> <!-- Configures the actual build loop, how often and which build file/target --> <schedule interval="60"> <ant antscript="C:\apache-ant-1.6.2\bin\ant.bat" buildfile="build-MY_PROJECT_1.xml" target="build" uselogger="true" usedebug="false"/> </schedule> <!-- directory to write build logs to --> <log dir="logs/MY_PROJECT_1"/> <!-- Publishers are run *after* a build completes --> <publishers> <currentbuildstatuspublisher file="logs/MY_PROJECT_1/buildstatus.txt"/> </publishers> </project> </cruisecontrol>
Notes: - The "buildafterfailed" property tells cruise if it should keep on trying to build, even if the last time failed and there have been no changes. The good thing about this is that if the build failed because a database server was unavailable, or some other transient problem, the next attempt might succeed. The bad thing is that if there is a real problem with the source in CVS, cruise will just keep on trying to build until you fix the problem and commit it to CVS.
<modificationset quietperiod="5"> <vss ssdir="\\Vssserver\vss\win32\" vsspath="/Software/Source/portal" login="username,password" serverpath="\\Vssserver\vss" /> </modificationset>
1. ssdir is the path (local or network) to your VSS Server ss.exe file (not your VSS client).
2. vsspath is the location of your project in the VSS source tree (this directory and down is what cruise will watch to determine if changes have occurred in your project).
3. serverpath is the path (local or network) to your VSS Server srcsafe.ini file.
4. multiple vcs directories can be specified, example:
<modificationset quietperiod="5"> <clearcase branch="v12dev" viewpath="\\views\dev\gui"/> <clearcase branch="v12dev" viewpath="\\views\dev\osr"/> </modificationset>
<ant antscript="C:\apache-ant-1.6.2\bin\ant.bat" buildfile="\\views\dev\build.xml" target="buildanddeploy"> <property name="unittest" value="true"/> </ant>
If you now run cruise from your WORK_DIR, you should see cruise start. To kick off a build, you may need to commit changes to CVS (not from the checkout/MY_PROJECT_1, but from another location). If the build fails, cruise will keep on trying, until you get it right. You don't need to restart cruise if you change config.xml or your delegating build file, since cruise reloads these every time a build is performed.
If you look in WORK_DIR/logs/MY_PROJECT_1, you'll see the cruise build reports, which are big, ugly XML files. Any file that ends with "build.?.xml" indicates a successful build, while other xml files indicate failures. Fortunately, you don't need to parse these files yourself, because CC provides a web application which can present these results in HTML format. But for now, you're up and running, and every time you commit to CVS, cruise will pick up those changes and build them.Note: You should really start cruise control using the cruisecontrol.sh script in main/bin, as this will add tools.jar to your classpath. If you don't your compile targets may fail, leaving you possibly (as I was when trying all this), one confused puppy.
The CC web reporting application, like CC core, needs to be built before it can be used. This time, the build process needs to be told where to find your WORK_DIR and other details.
Unfortunately, the only way to do this presently is by adding a properties file to your installation directory. Hopefully, we can soon have a webapp build which doesn't require modifications to INSTALL_DIR, but can read these properties from a different file.a) Open the "INSTALL_DIR/reporting/jsp" directory.
b) Create a new file called "override.properties", the properties in this file will be used to generate the Web.xml (deployment descriptor) for the web app. The file should look like this:# This should be the full path to your CruiseControl log directory. # If you are in multi-project mode, there will be multiple sub-directories # inside this log directory, one for each project. user.log.dir=WORK_DIR/logs # This should be the path to your current build status file, # expressed relative to the project's log directory. user.build.status.file=buildstatus.txt # This should be the absolute path to the directory where # additional build artifacts are stored. cruise.build.artifacts.dir=WORK_DIR/artifacts
If using JDK 1.4, add
jdk1.4=true
to override.properties.
c) Generate cruisecontrol.war by executing "build.sh war" or "build.bat war" in the directory INSTALL_DIR/reporting/jsp.d) Deploy the generated web application "INSTALL_DIR/reporting/jsp/dist/cruisecontrol.war" to your application server, and browse to APPLICATION_PATH/index.jsp. This page provides links to the buildresults page for each project (good for multi-project configurations).
e) The "Build Results" tab provides a formatted set of reports on what was changed, and if the build was successful. The "XML Log File" tag shows the XML log as a raw HTML file. Don't worry about the "Test Details" and "Control Panel" tabs; they are just placeholders, and aren't implemented yet鈥?NOTE: To run under Tomcat 4.1.27 with JDK1.4, I needed to remove xalan.jar and xerces.jar from the INSTALL_DIR/reporting/jsp/lib directory. These files clash with the regular JDK versions. Do this before step c)
By using the artifacts publisher, together with the Artifacts link in the reporting app, cruise can provide access to historical build output, test results and other important build artifacts.
a) Add an <artifactspublisher> element to the <publishers> element of your config.xml, which publishes the desired build artifact(s) to a timestamped directory under the WORK_DIR/artifacts directory.<artifactspublisher
dir="checkout/MY_PROJECT_1/build/output"
dest="artifacts/MY_PROJECT_1"/>
b) The "Build Artifacts" link should now work. NOTE: in some browsers (namely Mozilla) this page doesn't render correctly, you just see the raw HTML. This should be fixed soon.
A good way to keep track of your continuous integration is by receiving emails, either for every build, or just for the ones that fail. This is done by adding an <email> publisher to the set of publishers.
a) The most basic email functionality sends emails to one set of addresses on every single build (success or failure), and another set of addresses just on failured builds. To set this up, add an element like this to your <publishers> element:<email mailhost="SMTP_HOST" returnaddress="cruise@mydomain.com" buildresultsurl="http://localhost/cc/buildresults/MY_PROJECT_1" skipusers="true" spamwhilebroken="true"> <always address="dev1@mydomain.com"/> <always address="dev2@mydomain.com"/> <failure address="failed-builds@mydomain.com"/> </email>
In this case, there are 2 addresses that always get sent build notifications, and another that will only receive notifications of failures.
b) If you also want individual committers to receive email for all builds where they made changes, then set "skipusers" to false, and add a <map alias="cvsuser" address="cvsuser@mydomain.com"/> for each user inside the <email> element. Alternatively, you can add an email map to the CVS module. Or, as a 3rd alternative, cruise can append a default suffix to the user name to derive an email address.c) To get nicely formatted HTML mail you need to use the HTML email publisher. Replace <email> with <htmlemail> and add some extra configuration.
Add these 3 required attributes to the <htmlemail> element you set up in step 1):css="INSTALL_DIR/reporting/jsp/webcontent/css/cruisecontrol.css" xsldir="INSTALL_DIR/reporting/jsp/webcontent/xsl" logdir="logs/MY_PROJECT_1"
By default, the log report is formatted like this:
<cruisecontrol> <modifications> (contains details of CVS changes since last build) </modifications> <info> (contains project details) </info> <build> (the XML output from ant) </build> </cruisecontrol>
The header message you see on the web page is generated by an XSL stylesheet that reads the <info> element, and the "Modifications since last build" section is built by a stylesheet that uses the <modifications> element.
Various XSLT stylesheets are provided with the CC distribution, located in INSTALL_DIR/reporting/jsp/webcontent/xsl.These include:
header.xsl: Generates the build failed / success messages, and outputs the time of build and last changes. Uses the <info> and <modifications> elements.modifications.xsl: Generates the "Modifications since last build" report, from the <modifications> element.
compile.xsl: looks for <javac> and <ejbjar> elements in your build output, and creates a report of the errors and warningsdistributables.xsl: builds a list of jars and wars generated by you build by searching the build output for <jar> and <war> tasks.
javadoc.xsl: Reports on errors and warnings generated by <javadoc> elements in your build.logfile.xml: prints the entire XML log to HTML (can be viewed in the XML Log File tab of the web app)
unittests.xsl: Builds a report on unit test failures, based on the presense of <testsuite> elements in your log file. These <testsuite> elements can be generated automatically by a <junitreport> task, but you must tell CC to merge these into the generated log file (see below).checkstyle.xml: Builds a report of checkstyle failures, based on the presence of a <checkstyle> element in your log file. You must tell CC to merge your checkstyle output into your log file for this to work. (see below)
In order for the "unittests" and "checkstyle" reports to work, you need to tell Cruise to merge the separate XML log files generated by <junit> and <checkstyle> into your main CC log file. This is done by adding a <merge> element to your <log> element in the config file.
<!-- directory to write build logs to --> <log dir="logs/MY_PROJECT_1"> <merge dir="checkout/MY_PROJECT_1/build/junit-reports/"/> </log>
(Once again, it may be better to copy any required files to a common temporary location in your cruise-build file, rather than coding the path to your checked out project in the config file.)
Note that you can have CC include a report from <junitreport> by using the file attribute (e.g: <merge file="..."/>).After doing this, the checkstyle report should appear in you webapp report, and HTML emails. (The report only shows up if there are checkstyle warnings/errors in the merged report). The same mechanism can be used to provide unit test reports, and any other reports you care to code up in XSLT.