Integrating CodeClimate with Ruby on Rails

Integrating CodeClimate with Ruby on Rails

Everyone is always going on about "test driven development" and unit tests and whatnot.

So here is a practical guide on how to set up CodeClimate with your Ruby on Rails application so you can keep track of maintainability and test coverage. (Plus you get to show some fancy badges in your readme)

The first thing you need are unit tests. With Rails these are very straightforward. Simply go into your test/ directory and start writing.

I won't be going into detail on how to write unit tests and what kind of things need unit tests, but I will assume you have at least a couple tests (even if they are just dummy tests, like the ones I'll be using)

The full project is available at github.com/TrailBuddies/api if you are interested.

Coverage reports??

A coverage report is a file showing the success/failure of your unit tests. They are often a JSON or HTML files and they can be generated through a variety of tools.

We will be using SimpleCov because it integrates seamlessly with CodeClimate.

So let's get started!

SimpleCov

First thing first, add the simplecov and simplecov_json_formatter gems to your Gemfile.

group :test do
  gem 'simplecov', '~> 0.21.2', require: false
  gem 'simplecov_json_formatter', '~> 0.1.2', require: false
end

Update the version numbers to your own needs

And don't forget to run bundle install!

Then, to initialise SimpleCov enter your test/test_helper.rb file and add this to the very top (before everything)

require 'simplecov'
require 'simplecov_json_formatter'
SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
SimpleCov.start 'rails'

With that, try running bin/rails test and you'll see a magical coverage directory in the root of your project. Inside it you'll find a couple different files. The important ones are coverage/coverage.json and coverage/index.html. We will only need coverage.json for our purposes, but take the time to check out index.html as well.

Eureka! We have coverage.json!

Now is the time to mix in a dash of CodeClimate to create the perfect blend.

I will be using GitHub Actions, but I'm sure any CI/CD service will work as well.

GitHub Actions

Create a .github/workflows/codeclimate.yml file and enter some boilerplate config:

name: CI

env:
  # Required app-wide environment variables
  API_DB_USER: test
  API_DB_PASSWORD: test

on:
  workflow_dispatch:
  push:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@master

      - uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true

⚠️ I use the API_DB_USER and API_DB_PASSWORD environment variables in my project, but you may use different ones (check your `config/database.yml)

Database on Github Actions

Now we will need to set up a database for our test environment (you would have configured a test database in config/database.yml when you created your Rails app). Rails supports many different databases, but a popular on is PostgreSQL (and it's the one I use). I will show you the needed config to run a postgresql server on a GitHub Actions worker, but you may well need a different setup depending on your chosen database.

Begin by adding a service to your test job:

# etc...
test:
    runs-on: ubuntu-latest
    # important bit
    services:
      postgres:
        image: postgres:13
        env:
          POSTGRES_USER: ${{ env.API_DB_USER }}
          POSTGRES_DB: ${{ env.API_DB_USER }}
          POSTGRES_PASSWORD: ${{ env.API_DB_PASSWORD }}
        ports: ['5432:5432']
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
# etc...

You will need to replace postgres:13 with your required postgresql version (e.g. postgres:11) and ports: ['5432:5432'] with the ports you need.

Actually testing

Finally we can create a test steps. You will need two steps at least to set this up properly: one to setup the database, and one to run the tests.

Setup (more, I know..)

Let's do the first step:

# etc...
steps:
      - uses: actions/checkout@master

      - uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
      # important bit
      - name: Setup Rails Database
         run: RAILS_ENV='test' bin/rails db:setup
# etc...

You should also run any additional setup in or after this step (but before the next step). For example, my project needs the bin/keygen script to be initialized before the app can run, so I simply modified the run key like this:

run: RAILS_ENV='test' bin/keygen && bin/rails db:setup

Testing (finally)

I will be using paambaati/codeclimate-action@v3.0.0, but there are probably other alternatives.

You will need to get your CodeClimate test reporter ID from your repository settings at codeclimate.com/dashboard.

Here are some images explaining how:

select repo

go to settings

go to test coverage

copy reporter id

Create a repository secret (on GitHub) called CC_TEST_REPORTER_ID containing your reporter ID (from above).

Then we can create the actual testing step in our workflow file:

# etc...
      - name: Test & publish code coverage
        uses: paambaati/codeclimate-action@v3.0.0
        env:
          CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
        with:
          coverageCommand: bin/rails test
          coverageLocations: ${{ github.workspace }}/coverage/coverage.json:simplecov
          debug: true

See github.com/paambaati/codeclimate-action/tre.. for more info on how to use this action.

Enjoy

Finally, you can push all your changes and watch as your CodeClimate repo updates.

The entire project is available here if you are interested:

If I missed anything please let me know in the comments!