CI and Dependency Management in Ruby

In my last post, "Continuous Integration Testing," I touched on the fact that I've been adding continuous integration testing to OCLC's authentication code libraries where it was missing, and I showed an example in PHP. In addition to our libraries in PHP, we also have code libraries in Ruby for authentication and the WorldCat Discovery API. Neither of these libraries had continuous integration testing. So it seemed to be a good idea to add this to them before making any future updates to their code bases. 

In order to ensure continuous integration works properly, the project must clearly specify its dependencies so they can be installed as part of the continuous integration testing. Dependency management is done via two files: Gemfile and .gemspec. Dependency management for the oclc-auth library is fairly simple, as it relies on gems that exist in the Ruby Gems repository. So I just specify the following in my .gemspec:

  gem.add_dependency 'json', '~> 2.0', '>= 2.0.3' 
  gem.add_dependency 'rest-client', '~> 2.0', '>= 2.0.1' 
  gem.add_dependency 'rake', '~> 10.4' 
   
  gem.add_development_dependency 'rspec', '~> 3.5', '>= 3.5' 
  gem.add_development_dependency 'simplecov', '~> 0.14', '>= 0.14.1' 
  gem.add_development_dependency 'webmock', '~> 2.3'

Now that I've handled my dependencies, I need to add two new files to make CI work.

  1. A Rakefile for specifying tasks to run
  2. A simple Travis CI configuration file  

Travis CI is a hosted tool for performing continuous integration (CI). CI is a development practice through which code is checked into a repository and verified by an automated build and test process.

Rake is a tool for specifying tasks to be run during a build. By default, each Travis CI build runs Rake. So we use Rake to specify the tests to run. My Rakefile looks like the following:

require "bundler/gem_tasks" 
require 'rspec/core/rake_task' 

RSpec::Core::RakeTask.new 
task :default => :spec 

The last line in the example above specifies a task named “default,” which runs spec which is a default Rake task included with the RSpec gem that allows you to run RSpec tests.

Now that I have a Rakefile to run my testing tasks, I can create my Travis CI configuration for the OCLC Ruby Authentication library.  

language: ruby  
before_install: 
  - rvm get head 
  - gem install bundler 
rvm: 
  - 2.2 
  - 2.3.3 
  - 2.4.0  

# configure notifications (email, IRC, campfire etc) 
notifications: 
    email: 
        recipients: 
        - coombsk@oclc.org
       on_success: always 
       on_failure: always 

In this case, 

  • Travis CI builds against three versions of Ruby,
  • bundler is installed and used to install dependencies, and
  • RSpec runs by default.

The result of that looks like:  

file

Adding CI to the worldcat-discovery-ruby library presented a slightly larger challenge than I expected. The reason that this was more challenging was that this library has a dependency on the oclc-auth-ruby library, and to get the tests to work properly, my CI scripts needed to ensure the proper version of oclc-auth-ruby was installed. With most gems, this would be simple, because the gem is published via RubyGems.org. However, our Ruby authentication library isn't available on RubyGems. So the standard syntax for specifying it as a dependency wouldn't work.

This led me to do some reading on how to install a dependency from a git repository using Bundler (http://bundler.io). For those of you who aren't familiar with Bundler, it’s a tool that helps manage dependencies in Ruby. It looks at two different files within the project:

  • Gemfile and
  • .gemspec.

And it uses these files to install the relevant dependencies for a given project.

In the case of the Ruby library for the WorldCat Discovery API, I needed to specify oclc-auth as a dependency for the worldcat-discovery library.

In the Gemfile:

gem 'oclc-auth', :git => 'https://github.com/OCLC-Developer-Network/oclc-auth-ruby' , :tag => '1.0.0'

In the .gemspec file:

spec.add_runtime_dependency 'oclc-auth', '~> 1.0', '>= 1.0.0'

Then, I added a Rakefile that looks like the following:

require "bundler/gem_tasks" 
require 'rspec/core/rake_task' 

RSpec::Core::RakeTask.new 
task :default => :spec 

Then, I added a Travis CI configuration file that looks like the following:

language: ruby  
before_install: 
  - rvm get head 
  - gem install bundler 
rvm: 
  - 2.2 
  - 2.3.3 
  - 2.4.0  

# configure notifications (email, IRC, campfire etc) 
notifications: 
    email: 
        recipients: 
        - coombsk@oclc.org
        on_success: always 
        on_failure: always 

When Travis CI runs, the result looks like the following:  

file

Like the PHP libraries, options such as code coverage and API documentation can also be added via Travis CI. The simplest way to add code coverage is to use codecov.io and the Ruby gem SimpleCov. 

In order to generate API documentation, I would need to use a documentation creation tool such as:

And then I would use Rake for running a task to create the documentation. I haven't been able to add either of these processes to the continuous integration for the Ruby libraries. However, I hope to be able to get this done over the summer.

  • Karen Coombs

    Karen Coombs

    Senior Product Analyst