jinfeng_wang

G-G-S,D-D-U!

BlogJava 首页 新随笔 联系 聚合 管理
  400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
Last changed on Jan 24, 2005 by Joe Schmetzer
  1. Download and Build Cruise Control
  2. Setup your Cruise Control working area
  3. Setup a project for Cruise Control to build
  4. Configure Cruise Control to build your project
  5. Configure Cruise Control to schedule your build
  6. Start Cruise Control
  7. Getting the build artifacts link working
  8. Building the web app
  9. Reporting build status via email
  10. Modifying the HTML reports
  11. Merging other XML files into your logfile

We're intentionally avoiding providing an initial, fill-in-the-blanks template, but instead will add features one by one, hopefully to instill a better understanding of how everything works.

You might find CruiseControlInstalled useful as well (if a little out of date).

Before you begin

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.

1) Download and Build Cruise Control

a) You'll first need to get a copy of CruiseControl from http://cruisecontrol.sourceforge.net/ . Unzip this file to your applications directory. The top-level directory created when you unzipped this file will be referred to as INSTALL_DIR.

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.

2) Setup your Cruise Control working area

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.

c) Create WORK_DIR/config.xml, like so:
<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.

3) Setup a project for Cruise Control to build

a) Manually checkout the CVS module for the project you want to build, into WORK_DIR/checkout. We will refer to your project name as MY_PROJECT_1, and assume that the CVS module has the same name. You will now have a subdirectory like WORK_DIR/checkout/MY_PROJECT_1.

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>

Notes: - If you're using VisualSourceSafe, try this vssget (latest) command in place of the <cvs> call above. Be sure to substitue in your properties where appropriate.
<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.

4) Configure Cruise Control to build your project

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.

a) Here is a config.xml example for the project configured above. Note that this is the very minimum you'll need; we'll add extra stuff in later. This "project" element is added inside the <cruisecontrol> tags you created earlier:
<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.

  • The <log> element tells cruise where to put it's log reports, which are the main output of a Cruise build.
  • The <currentbuildstatusbootstrapper> element tells cruise the name of a file where it can write notes about it's current activity. This file is required by the web application, so we configure it here. For multi-project configs it is probably easiest to place it in the project logs directory, as above. This bootstrapper writes "Current Build Started At: date" to this file.
  • The <modificationset> element configures how cruise checks for CVS changes, before running the build. The example given tells cruise to use CVS to check for changes in it's local working copy of the module, which you checked out earlier.
  • If you're trying to get started with VisualSourceSafe (instead of CVS), try this <modificationset> example:
    <modificationset quietperiod="5">
        <vss ssdir="\\Vssserver\vss\win32\"
    	 vsspath="/Software/Source/portal"
    	 login="username,password"
    	 serverpath="\\Vssserver\vss" />
      </modificationset>

Notes on the Vss element:

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>

5. If you're using Subversion, check out the Using CruiseControl with Subversion page.
6. The "quietperiod" attribute tells cruise not to try to build while the CVS repository is being actively updated. Instead, cruise waits until it sees a period of quiet in the repository, before doing a build. So if you're committing files individually to CVS, cruise will wait until you've finished, as long as you don't take longer than the quietperiod between commits. It is specified in seconds.

5) Configure Cruise Control to schedule your build

  • The <schedule> element sets up the build-loop for your project, with the "interval" attribute telling cruise how many seconds to sleep in between builds.
  • The <ant> element tells cruise which ant build file to run, and which target. The uselogger and usedebug elements together tell cruise not to write Ant debug statements to the build logs (This can make them much smaller).
  • The <ant> element allows properties to be set:
    <ant antscript="C:\apache-ant-1.6.2\bin\ant.bat"
                  buildfile="\\views\dev\build.xml" 
                  target="buildanddeploy">
                  <property name="unittest" value="true"/>
           </ant>
  • The <publishers> element configures actions to perform after the build completes, such as sending emails, and copying files. At the moment, all we're doing is writing a status message, using the <currentbuildstatuspublisher>, which writes "Next Build Starts At: time" to buildstatus.txt.
  • With the "interval"(60) and "quietperiod"(10) above, cruise will check for modifications in CVS every 60 seconds. If modifications were made in the 10 seconds before the check, cruise will wait until a 10 second window with no changes is found. Once this happens, cruise will kick off the ant build. These values are probably a bit low for the real world, but they are OK for getting started.
  • See the SchedulingExample page for more information on the <modificationset> and <schedule> elements, as well as more complex scheduling.

6) Start Cruise Control

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.

7) Building the web app

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)

8) Getting the build artifacts link working

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"/>

This assumes that you want to publish all files that end up in the "build/output" directory after running the ant build. You can also use the file="" form, but this unfortunately creates the entire directory structure under the artifacts dir, just to get the single file. (Probably a better approach would be to modify your cruise build to first copy the build artifacts to a common temporary location, so that your config file doesn't have to contain the path to the actual files in the checked-out project.)

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.

9) Reporting build status via email

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"

10) Modifying the HTML reports

The output you see in the web application, and the HTML emails, is the result of applying a number of XSLT stylesheets to the single XML build report that cruise creates. (You can see these reports in your WORK_DIR/logs directory).

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 warnings

distributables.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)

11) Merging other XML files into your logfile.

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.

posted on 2005-03-10 17:50 jinfeng_wang 阅读(1772) 评论(0)  编辑  收藏 所属分类: ZZCruise Controle

只有注册用户登录后才能发表评论。


网站导航: