GitHub Action to upload SimpleCov Coverage Results

This post was originally published on my previous blog jer-k.github.io

Published on 2019-10-16

What a wonderful day that was! I've been playing around with Actions ever since and one of my new projects, a Ruby Gem, didn't have any form of CI as of this morning. I set out to create an Action that would run the tests for the gem and produce coverage results via SimpleCov. While it's nothing too extravagant, there was a small nuance that I had to resolve and I decided I wanted to share that info.

Let's start off with some changes to the SimpleCov configuration.

if ENV.fetch('COVERAGE', false)
SimpleCov.start do
minimum_coverage 90
maximum_coverage_drop 2
end
end
if ENV.fetch('COVERAGE', false)
SimpleCov.start do
minimum_coverage 90
maximum_coverage_drop 2
end
end

This ensures that the coverage is above 90% and any changes in the future must not drop the coverage by more than 2%. The Gem, in its infancy, does not pass this requirement. Due to that failure, I had to figure out why the Action was not uploading the coverage results. Remember to put the SimpleCov code at the very top of spec_helper.rb, before you do require 'your_gem' to ensure it knows what files to track.

Now let's look at the Action, which is based off the default Ruby Action supplied by GitHub.

name: RSpec with SimpleCov for a Gem

on: [push]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6.x
- name: Build and test with Rake
run: |
gem install bundler -v '1.17.3'
bundle install --jobs 4 --retry 3
COVERAGE=true bundle exec rspec
- name: Upload coverage results
uses: actions/upload-artifact@master
if: always()
with:
name: coverage-report
path: coverage
name: RSpec with SimpleCov for a Gem

on: [push]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6.x
- name: Build and test with Rake
run: |
gem install bundler -v '1.17.3'
bundle install --jobs 4 --retry 3
COVERAGE=true bundle exec rspec
- name: Upload coverage results
uses: actions/upload-artifact@master
if: always()
with:
name: coverage-report
path: coverage

The only additions are the last step.

- name: Upload coverage results
uses: actions/upload-artifact@master
if: always()
with:
name: coverage-report
path: coverage
- name: Upload coverage results
uses: actions/upload-artifact@master
if: always()
with:
name: coverage-report
path: coverage

It uses the upload-artifact Action created by Github to upload the coverage/ folder generated by SimpleCov. At first, I could not figure out why the artifact was never being uploaded, but I realized that the step was never being run. We can see this in the Actions UI.

action no artifact

The key to making this work is the if: always() clause. Looking at the documentation for Contexts and Expression Syntax, always() is described as Forces a conditional to evaluate as true, even when canceled. Since SimpleCov is failing the Build and test with Rake step, we have to force the Upload coverage results step to always run. After adding in the if clause, we can see a successful upload in the Actions UI.

action with artifact

Next we scroll to the top of the page and download the artifact, which is a zip file of the coverage/ folder.

download artifact

Inside the folder we can open the generated index.html to see which files we didn't have coverage for.

coverage report

Now we can successfully check the coverage report on our gem and see where the tests are lacking. Hopefully your gem has better coverage than mine!

You can find the file in my actions repository, or directly here