CruiseControl.rb is an excellent tool for continuous integration (CI). It runs a server and tries to build your project whenever you make a commit to your repository, reporting errors when they come up. Here I’ll show you how to get a basic project off the ground.
First off, you’re going to need a couple of gems installed if you don’t have them already, so:
sudo gem install rake rspec
Download and unzip the latest version of CruiseControl from http://rubyforge.org/frs/?group_id=2918
Start a project:
cd into cruise_test and make a couple of files
class User end
require 'user' describe User do end
start our git repository:
git init git add . git commit -m 'first commit, woohoo!'
cd into the cruisecontrol directory and add our project to be managed:
./cruise add cruise_test -s git \ -r /path/to/cruise_test/
Start up cruisecontrol:
We’ll see the server logs come pouring down the screen. Among the logs we see something like:
Build 613d2b5 started Build 613d2b5 FAILED
We can check out localhost:3333 for a little more information. Click on the red build title on the left and expand the build log section. Here we see the following message:
No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)
So let’s give it a Rakefile. In the cruise_test directory type:
touch Rakefile git add Rakefile git commit -m 'added Rakefile'
Now, when we return to the build page we get a new error:
'cruise', test' or 'default' tasks not found. CruiseControl doesn't know what to build.
Let’s keep playing it dumb for the moment. Add the following lines to the Rakefile:
task :cruise do end
Go back to localhost:3333, and if it hasn’t already been built, click ‘Build Now’. This time it passes! Of course, that doesn’t mean much, seeing as how we didn’t give it anything to do, so now let’s stretch our wings just a little. Change the task you just added to look like this:
task :cruise do system('rspec spec/*') end
Alright, still passes. Let’s see if we can make it fail, TDD style. Open up spec/user_spec.rb and make it look like this:
require 'user' describe User do it 'creates an instance and names it' do user = User.new user.name = 'Big Al' end end
rspec spec/* at the command line and we see it fails. Now git add and git commit and try building again at localhost:3333. Hmm, it passes. If you look in the log you can see that the specs failed, and yet the build passed. Funky ruby behavior as it turns out. We’ll have to get the return value from the rspec command and pass or fail based on how it turned out. Back to the Rakefile:
task :cruise do system('rspec spec/*') exit(1) if $? != 0 end
A command entered at the command line has a return value. If it’s 0 this means the command executed without any errors. Anything else means there was a problem. To access the return value of the most recently executed command you can type
$? at the command line, or conveniently access it within your ruby scripts. In short, here we’re saying “exit with an error status if the rspec command exited with an error status”. Commit your changes and head back to the build page. Success! It failed! Now we can round it out just a bit and get things back on track. Edit user.rb as follows:
class User attr_accessor :name end
One last build on the build page shows us that things are peachy.
So there you have it. A running instance of CruiseControl.rb hooked up to a project ripe for some test driven development. Now you can start to customize the experience. You can place CruiseControl on a server somewhere and have it hooked up to a git repository if you like, so that whenever you push it tries the build again. You can configure notifications to be sent via email or instant message whenever something doesn’t (or does) build correctly. Check out the documentation on their website for more info at http://cruisecontrolrb.thoughtworks.com/.