Running Tests Against Multiple Ruby Versions Using CircleCI

I've been a long-term maintainer of the NetSuite ruby gem. Part of maintaining any library is automated tests against multiple versions of various dependencies. Most of the time, this is limited to the language version, but can include other dependencies as well.

Recently my build config stopped working as CircleCI upgraded to V2 of their infrastructure. I found it challenging to find an example CircleCI V2 config with the following characteristics:

  • No Gemfile.lock and therefore no caching of gems. When you are testing across ruby versions you can't use a single Gemfile.lock.
  • No rails, no databases, just plain ruby

Here's an heavily documented CircleCI config that tests multiple ruby versions:

version: 2.1

orbs:
  # orbs are basically bundles of pre-written build scripts that work for common cases
  # https://github.com/CircleCI-Public/ruby-orb
  ruby: circleci/ruby@1.1

jobs:
  # skipping build step because Gemfile.lock is not included in the source
  # this makes the bundler caching step a noop
  test:
    parameters:
      ruby-version:
        type: string
    docker:
      - image: cimg/ruby:<< parameters.ruby-version >>
    steps:
      - checkout
      - ruby/install-deps:
          bundler-version: '1.17.2'
          with-cache: false
      - ruby/rspec-test

# strangely, there seems to be very little documentation about exactly how martix builds work.
# By defining a param inside your job definition, Circle CI will automatically spawn a job for
# unique param value passed via `matrix`. Neat!
# https://circleci.com/blog/circleci-matrix-jobs/
workflows:
  build_and_test:
    jobs:
      - test:
          matrix:
            parameters:
              # https://github.com/CircleCI-Public/cimg-ruby
              # only supports the last three ruby versions
              ruby-version: ["2.5", "2.6", "2.7"]