Hudson for a Rails3 project
Configuring Hudson for a Rails3 project
Using rSpec2, rCov, Cucumber, Bundler, rvm and git
Hudson: why?
Since a week my colleague and I have been using a Continuous Integration server. Let me explain in a few words why we think that's an enormous step forward.
We noticed that large projects on which we hadn't worked for several months started to wreck our Cucumber features and rSpec specs in some mysterious, unexpected way. This started to really hold us up too long and we felt discouraged to run all of our tests before a deploy. Quite a large part of this problem can of course be solved today using Bundler.
A second problem we faced is time. Running all tests in some javascript-heavy projects easily takes up half an hour.
A Continuous Integration server is what has changed all that. We now run each of our projects overnight whether we have worked on it or not. That's why we are able to stay confident about the quality of the tests and the software.
Why Hudson and not anything else? Well, let's be clear, we're a company run by two developers. We want something that gets us up to date as fast as possible. We had read good things about Hudson and after trying several possible solutions, Hudson seemed the most stable one that kept stuff really simple while offering tons of cool plugins (like the ones for "extreme feedback").
The setup
Up till now Hudson has run locally on my own MacBook Pro. So far this has been a good solution but it's obvious that as this laptop is also the one I constantly work on, it isn't possible to run tests after each git commit.
Therefore, we will consider two options in the future: buying a cheap desktop computer running Ubuntu or keep the Macbook Pro setup when we buy some new MacBooks for ourselves later this year. The latter seems the most interesting option as it won't cost us a lot of money, we can keep our beloved OS X, and so we will keep a backup laptop in case one of our new MacBook Pro's breaks down.
Installing
I'll explain what to do to get a similar setup.
Download the war file from the hudson-ci website and run (in the correct dir):
java -jar hudson.war
Once running, you can connect to http://localhost:8080 to configure the setup. (Yes, that was all there is to it ...)
Configuration
Hudson Plugins
Through the plugin system install the next plugins:
- Hudson Git plugin
- Hudson Rake plugin
- Notifo plugin: this one notifies us of the outcome of builds on our iPhones
We also uploaded a plugin to be able to easily build with rvm support:
- hudson-rvmRubyMetrics-plugin (to install, click the downloads button on github and download the .hpi file. Upload it as a plugin in the Hudson plugin configuration panel)
We think you don't need the rvmRuby plugin. The rvmRake plugin is already merged with the official Hudson Rake plugin. So no need to install that one either.
Rvm
You will need the latest rvm (or at least one with the rvm-shell command) (run rvm update and rvm reload to get up and running).
Your Rails project
You need to make sure your own project has the necessary requirements.
For starters, make sure your tests run on rSpec2, and not a beta-version.
Make a config/database.ci.yml file which you configure for a test db (if you work with ActiveRecord of course) and add it to your git repo.
Most importantly, you need rake tasks that run your tests and generate rcov data. It's also better to produce jUnit xml test reports. If you don't care, you will have to read through the console output. With the jUnit test reports, however, you will get nice, readable feedback.
I use the following rake task (not really polished). It does all I have said above:
At this stage you should be able to run the rake tasks Hudson will run:
rake hudson:rcov RAILS_ENV=test
rake hudson:cucumber RAILS_ENV=test
Cucumber should not exit with an error if there are pending steps
Cucumber is configured to exit with an error code if there are pending steps. If you do not want this to happen, remove the --strict from your config/cucumber.yml file.
Hudson Project
Finally, you can set up your project in Hudson:
I've got the following configuration:
- Discard Old Builds and keep the last 200 builds
- Get source code through git
- Build periodically:
1 3 * * *. I've also set my Mac to wake at 3am and go back to sleep at 5am. You can schedule this through the energy panel (click the schedule button). Make sure the lid of the MacBook is not closed and the MacBook is plugged in. Build steps (for Rake tasks I always select the appropriate Rake version, like
ruby-1.8.7-p249@<project-name>):- shell script:
- Invoke Rake:
db:schema:load RAILS_ENV=test - shell script:
- Invoke Rake:
hudson:rcov RAILS_ENV=test - Invoke Rake:
hudson:cucumber RAILS_ENV=test
After build:
- Publish JUnit test result report, Test report XMLs:
hudson/reports/**/*.xml - Publish Rails Notes report, fill in RVM Ruby string
- Publish flog report: Ruby class directories:
app(anyone knows how to set multiple directories here?) - Publish Rails stats report, fill in RVM Ruby string
- Publish Rcov report, Rcov report directory:
rcov, Coverage metric targets: 80, 0, 0 - E-mail Notification (configure smtp server through
Hudson > Manage Hudson > Configure System - Notifo: Instructions here, works like a charm!
- Publish JUnit test result report, Test report XMLs:
I needed to install the
floggem on my system ruby to get the flog report to work.
Conclusion
I really like Hudson: it's easy to set up and most importantly, it makes my colleague and me feel very confident about our code.
If you have other tips or tricks on using Hudson or if you do things differently and better, I'll be glad to hear how from you.
These are the sources I used to figure everything out:
- http://blog.ninjahideout.com/posts/rvm-improved-support-for-hudson
- http://reprocessed.org/blog/easy_rails_ci_with_hudson
- http://wiki.hudson-ci.org
- http://ruby.sadi.st/
- https://github.com/aslakhellesoy/cucumber/wiki/Using-RCov-with-Cucumber-and-Rails