Jenkins, RVM, and Selenium

I have been working on migrating half a dozen 8th Light projects to our continuous integration server last week. Barring one open-source gem project, most of them were Rails.

I have used Jenkins to build, pipeline, and install projects on Windows with batch commands and ant tasks in the past, but this would be the first time I set up Rails projects and deal with Ruby management and running features in a headless environment.

RVM

Obviously the center piece of this operation is RVM. The catch is that Jenkins does not load your bash profiles on slave environment for each build, which is usually how you load RVM into a shell session.

This can be resolved with either including RVM scripts in Jenkins’ startup, or run, source ~/.bash_profile at the beginning of your build steps assuming you followed the post install instruction in RVM installation guide.

Afterward, you can execute rvm use 1.9.2@gemset to pick up project setting, or take advantage of .rvmrc for business as usual.

Alternatively, you can install Jenkins’ Rake plugin. The plugin allows you to choose a Ruby installation per project, and since version 1.7, with RVM integration you can also pick a specific gemset you created on RVM.

From Jenkins’ homepage, go to Manage Jenkins → Configure System and fill out RVM installation path under the Rake section. Now at your project configuration, when you add a new build step to invoke Rake task, you will see a list of Ruby versions and available gemsets ready at your disposal. The Rake plugin refreshes this list every time you save the Configure System page.

Headless Selenium

Some Rails projects are set up to run acceptance tests against a real browser, and unfortunately our continuous integration box is without a display. The common solution for this type of problem seems to be installing Xvfb, a virtual framebuffer server that renders your GUI tools in memory:

1 # install Firefox, or any other browser under testing
2 apt-get install firefox
3 # install Xvfb
4 apt-get install xvfb
5 # boost X11 server
6 Xvfb :99 -ac -screen 0 1024x768x16
7 # set up environmental variable
8 export DISPLAY=:99
9 # launch Firefox

Moving forward, you can write a script to run Xvfb whenever you kick start a build, and make sure the DISPLAY variable is set accordingly when Selenium is up. Your other option is to install the headless gem, and call to launch the server with Ruby API in your features/support/env.rb file:

 1 # add this code to "features/support/env.rb"
 2 if ENV['HEADLESS'] == 'true'
 3   require 'headless'
 4 
 5   headless = Headless.new
 6   headless.start
 7 
 8   at_exit do
 9     headless.destroy
10   end
11 end

Now armed with RVM and headless gem, you can create a new job on Jenkins with relative ease. I hope, at this point, you will have a reasonably good grasp on how to set up your own Rails project on a CI server, and ready to reap the profits of the continuous integration process.

To sum it up, here is the final recipe for a Rails project’s build step:

1 #!/bin/bash -x
2 source ~/.bashrc
3 rvm use 1.9.2@project
4 bundle install
5 rake db:migrate
6 rake spec
7 HEADLESS=true

Li-Hsuan Lung enjoys reading, writing, and translating between Chinese and English and is part of the ongoing effort to bring the Agile Manifesto to a Chinese audience.