This is the CruiseControl.rb manual. If you can’t find what you’re looking for here, make sure to look at the docs for plugins or just contact us.
The CruiseControl.rb package includes a file called $cruise/config/site_config.rb.example. By copying it to $cruise/config/site_config.rb and uncommenting some lines you can set a number of global configuration settings. Normally you would only need to do this to configure an SMTP server for email notices. Email is configured using Rails’ ActionMailer component and accepts its standard configuration settings.
If you don’t provide a Cruise configuration for your project, CC.rb will try to make some reasonable guesses about how to build your project, particularly if it’s a Ruby application. (See Default build tasks below.)
However, there are only a few configuration settings that CC.rb can guess at. Specific projects will require more advanced configuration if you need to add email notification recipients, configure plugins, or otherwise tweak your build run. A typical project configuration in CC.rb is about 3 to 5 lines of very simple Ruby.
When you first add a project, a configuration file called cruise_config.rb is created for you in the
$cruise_data/projects/your_project/ directory. It contains a number of comments, but two lines are important:
Project.configure do |project|
end
Every cruise_config.rb must have these two lines, and all your other configuration goes between them. It’s recommended that you check this file into version control, and if you do then changes made to the configuration will be automatically be picked up by CC.rb the next time you check in without any additional work required.
Optionally, you can put a configuration file in both places above. CruiseControl.rb loads both files, but settings from the cruise_config.rb in $cruise_data/projects/your_project/ override those stored in your project’s root directory. This can be useful when you want to see the effect of some configuration settings without checking them in, or have some location-dependent settings.
Hint: configuration examples below include lines like ’...’. This represents other
configuration statements that may be in cruise_config.rb. You are not meant to copy-paste those dots into
your configuration file, as they are not valid Ruby. If you do, ./cruise start will fail to start
due to a syntax error.
Since configuration files are written in a real programming language (Ruby), you can modularize them, use logical statements, and generally do whatever makes sense. For example, consider the following snippet:
Project.configure do |project|
case project.name
when 'MyProject.Quick' then project.rake_task = 'test:units'
when 'MyProject.BigBertha' then project.rake_task = 'cruise:all_tests'
else raise "Don't know what to build for project #{project.name.inspect}"
end
end
Hint: Use code like above to source-control configuration of multiple CruiseControl.rb projects building the same codebase.
cruise,
test, and default (what happens when you just type rake with no arguments) tasks,
in that order, and execute the first one it finds.
Note that Rails provides you with an automatic test task when you first create your project. The behavior
for that task is documented here.
WARNING: with Rails projects, it is important that RAILS_ENV does not default to ‘production’. Unless you want your migration scripts and unit tests to hit your production database, of course. CruiseControl.reb leaves this variable unchanged when invoking ‘cruise’ or other custom Rake task, and sets it to ‘test’ before invoking the defaults.
cruise may be the task for a quick build, but you may also want to run a long build with all acceptance
tests included. This can be done by assigning the project.rake_task attribute in cruise_config.rb:
Project.configure do |project|
...
project.rake_task = ‘big_bertha_build’
...
end
Hint: Be careful when defining additional build tasks. If two builds share the same RAILS_ENV value
then they will operate against the same database, which means that if two builds run simultaneously there is
a chance that they will interfere with each other. You can avoid this issue this by creating a separate environment
and making sure that the Rake task for your build sets the RAILS_ENV value to that environment in your
Rake task. Copy config/environments/test.rb to config/environments/big_bertha.rb, add a :big_bertha_init
Rake task with ENV['RAILS_ENV'] = 'big_bertha' in it, and put it in the beginning of
:big_bertha_build list of depenedencies.
Hint: Ideally, you’d also want some way to chain builds so that the long build for a new checkin is only
launched once the short build has finished succesfully. CruiseControl.rb provides support for this option through
the triggered_by project build configuration feature; see
Build Chaining & Triggers.
CC.rb may be written in Ruby on Rails, but you don’t need to be using Ruby and Rake in order to take advantage of it. Other build tools like make, Ant and MSBuild are also supported— really, any command that can return a success or failure status code.
A custom build command can be set with the project.build_command attribute. Modify cruise_config.rb file like
this:
Project.configure do |project|
...
project.build_command = 'my_build_script.sh'
...
end
If project.build_command is set, CC.rb will invoke the specified command from the project’s work directory
($cruise_data/projects/your_project/work/) and examine the exit code to determine whether the
build passed or failed.
Hint: You cannot set both the rake_task and build_command attributes in a a given project configuration.
Some build tasks generate custom output, like test coverage statistics, that you may want to keep and see on the build page. CruiseControl.rb supports the integration of that output by setting the CC_BUILD_ARTFACTS environment variable to a directory that’s been set aside specifically to collect them.
If you ensure that your special task writes its output to that directory or a subdirectory of it, then the resulting build artifacts page will automatically include links to every file or subdirectory found in the build artifacts directory.
Hint: Code coverage analysis is a good example of custom build output. CruiseControl.rb’s own build uses rcov. If you drill down into a recent CC.rb build on http://cruisecontrolrb.thoughtworks.com, you can see links to test coverage reports.
Hint: The metric_fu project collects a number of helpful Ruby code metrics into a single, easy-to-configure plugin and integrates well with CC.rb.
By default, the builder polls Subversion every 10 seconds for new revisions. This can be changed by adding the following line to cruise_config.rb:
Project.configure do |project|
...
project.scheduler.polling_interval = 5.minutes
...
end
What if you want a scheduler with some interesting logic? Well, a default scheduler can be substituted by placing your own scheduler implementation into the plugins directory and configuring it as follows:
Project.configure do |project|
...
project.scheduler = MyCustomScheduler.new(project)
...
end
After initializing everything, and loading the project (this step includes evaluation of cruise_config.rb), the builder invokes project.scheduler.run. A builder must be able to detect when its configuration has changed, or when a build is requested by user (by pressing the Build Now button), so a custom scheduler needs to know how to recognize that situation.
Look at $cruise/app/models/polling_scheduler.rb to understand how a scheduler interacts with a project.
To remove your_project from CruiseControl.rb, kill its builder process and then delete the $cruise_data/projects/your_project/ directory.
CC.rb uses triggers to tell it when to build a project. Every project is configured, by default, with a ChangeInSourceControl trigger: it builds when (surprise) it detects a change in a project’s source control.
However, you can add additional triggers or replace a trigger entirely. For example, you can have one project’s successful build trigger another project’s build with our SuccessfulBuildTrigger.
project.triggered_by SuccessfulBuildTrigger.new(project, 'indie')
or, in short hand:
project.triggered_by 'indie'
Why would you want one build to trigger another? In this instance, maybe our project depends on indie and we want to know if a change to indie breaks our project.
These examples, added a SuccessfulBuildTrigger. We could also replace the default trigger by writing
project.triggered_by = [SuccessfulBuildTrigger.new(project, "fast_build")]
Why wouldn’t we want our project to be triggered by a change to it’s source code? In this case, maybe we’ve separated our project into a fast and slow build. We could use this to only trigger a slow build if the fast one passes.
CC.rb can set any custom environment variables that your build requires. Every project can be configured to build with different environment variables. For example:
Project.configure do |project|
project.environment['DB_HOST'] = 'db.example.com'
project.environment['DB_PORT'] = '1234'
end
CC_BUILD_REVISION – this is the revision number of the current build, it looks like “5” or “56236” CC_BUILD_LABEL – usually this is the same as CC_BUILD_REVISION, but if there is more than one build of a particular revision, it will have a ”.n” after it, so it might look like “323”, “323.2”, “4236.20”, etc.CC_BUILD_ARTIFACTS – this is the directory which the dashboard looks in. Any files you copy into here will be available from the dashboard.CC.rb can run builds on remote servers. This is done by sshing to the server in your build command. For example:
project.build_command = 'ssh user@server ./run_remotely.sh $CC_BUILD_REVISION'
run_remotely.sh might look something like:
svn up -r$1 rake test:integration
Of course you will need to checkout the code on the remote server before running the first build.
Note that CC.rb will still maintain a checkout of the code on the local server, use it to check for modifications and store build results locally. More robust support for builders on remote servers is expected in release 2.0.
CC.rb supports clean checkouts, though they are not the default behavior. To enable them, you must use the do_clean_checkout
flag together with an optional frequency. Acceptable values are :always, :never, and :every => [duration].
project.do_clean_checkout :every => 6.hours
If you have an issue that you cannot fix on your own, please consider subscribing to our mailing list at cruisecontrolrb-users@rubyforge.org and asking for help. Please note, though, that we take great pains to make CC.rb easy to hack, and we encourage you to poke around in the source code and hack away.
Should you require commercial support, training or consulting around this or other tool, ThoughtWorks can provide it to you. We also offer a commercial CI product, Cruise, through ThoughtWorks Studios, our product division.
Hint to would-be contributors: documentation patches are as important, if not more so, than code patches, and would be gratefully accepted.