Using Ruby Version Manager (RVM) in Jenkins CI

4 minute read

The Ruby Version Manager (RVM) is a great tool if your Ruby and Rails applications are based on different versions of Ruby and/or use different gem sets.

To integrate RVM with the Continuous Integration tool Jenkins, you can either follow this description on the RVM website, or use this Jenkins RVM Plugin. Both solutions have some drawbacks, so we were looking for a new solution.

The description on the RVM website suggests to run the build steps as shell scripts and specify the desired version in every script, which seems to be unnecessary and error prone.

The Jenkins RVM Plugin claims to run the whole build process in the RVM environment specified for the project as a whole. Thats true, but we make heavy use of Jenkins tasks, e. g. for deployment scripts.

Unfortunately, the RVM environment is not available inside the task scripts. To fix this, you can do something like (i captured this code from the console log of builds with the RVM plugin):

    bash -c "source ~/.rvm/scripts/rvm && rvm_install_on_use_flag=1 && rvm use --create 1.9.3@projectname && export > rvm.env"
    source rvm.env

Again, you have to specify the Ruby version in every task.

But we would like to have an easy RVM project workflow, specifying the project specific ruby setting only once to stay DRY.

####How it works

The comment section of this blog post led me to a solution which seems to work very well for our purposes without any major drawbacks.

  1. Set up RVM for user jenkins (or whatever user the jenkins process runs), especially add the rvm setup to the user profile

  2. Set up your projects with project specific RVM files (.ruby-version and .ruby-gemset if you use a current version of RVM)

  3. Use shell scripts for all ruby or rake based build steps and add this code to all scripts and tasks:

    #!/bin/bash -l
    cd ${WORKSPACE}

The trick is to add the -l option to the shebang, since the RVM setup code only executes if the shell is a login shell.

Now it is sufficient to keep .ruby-version and .ruby-gemset up to date, since the cd into the workspace directory sets up the correct RVM environment.

A complete example of a rails build script would be

    #!/bin/bash -l
    cd ${WORKSPACE}
    rvm info        # print info about rvm (for debugging)
    export RAILS_ENV=test
    bundle exec rake db:migrate
    bundle exec rake test