Yesterday we got our API code up to 100% code coverage. For me, it’s one of those things that once you get there, you really don’t want to lose it again. We use Code Climate’s Github integration to ensure that our coverage is at least above 90%, but as far as I know there is no way to set that requirement at 100%.

The CI/CD system that we use is Atlassian Bamboo, and it allows for arbitrary shell scripts to be run during a build. Currently we use that functionality to send updates to the Github API to report success/failure on various build steps. For example:

# cribbed from
cd ${}

##check for test failures, or that they ran at all.
if test -e "api/test-reports/rspec.xml"; then
    if (grep 'failure message' api/test-reports/*.xml 1> /dev/null 2>&1) then
        mainJunit=$(find api/test-reports/*.xml -print0 | xargs -0 grep 'failure message' | wc -l)
        curl -s -H "Authorization: token <redacted>" --request POST --data '{"state": "failure", "context": "bamboo/tests", "description": "'"${mainJunit}"' Test(s) failed!", "target_url": "${bamboo.buildResultsUrl}"}'<user>/<repo>/statuses/${bamboo.repository.revision.number} > /dev/null
        curl -s -H "Authorization: token <redacted>" --request POST --data '{"state": "success", "context": "bamboo/tests", "description": "Tests Passed", "target_url": "${bamboo.buildResultsUrl}"}'<user>/<repo>/statuses/${bamboo.repository.revision.number} > /dev/null
    curl -s -H "Authorization: token <redacted>" --request POST --data '{"state": "failure", "context": "bamboo/tests", "description": "Error running tests", "target_url": "${bamboo.buildResultsUrl}"}'<user>/<repo>/statuses/${bamboo.repository.revision.number} > /dev/null

I figured it shouldn’t be a far reach to do something similar for code coverage. So, I did some digging in the /coverage directory of our project and saw: .last_run.json, and inside:

# coverage/.last_run.json
  "result": {
    "covered_percent": 100.0

That might be useful!

Now, how to get the percentage out of the json? jq is great, but I didn’t want to apt-get yet one more dependency on our CI server; and, I thought it would be a good opportunity to get some practice with grep and sed. I came up with this:

grep -o '"covered_percent":.*[0-9]*' coverage/.last_run.json | sed 's/"covered_percent": //g' | sed 's/\.[0-9]*//g'

From the file above, this yields:



What this does is, find lines with "covered_percent" and a number, delete the "covered_percent": , and delete the decimal places (bash doesn’t do floats, only integers). There may be a better way to do this, but it works! Now I needed to integrate it into our build to notify Github whether we maintained 100% coverage or not. Using something like the above, I came up with this:

coverage=$(grep -o '"covered_percent":.*[0-9]*' api/coverage/.last_run.json | sed 's/"covered_percent": //g' | sed 's/\.[0-9]*//g')
if [ $coverage -ge 100 ]; then
  curl -s -H "Authorization: token <redacted>" --request POST --data '{"state": "success", "context": "100% Code Coverage", "description": "Coverage == 100%", "target_url": "${bamboo.buildResultsUrl}"}'<user>/<repo>/statuses/${bamboo.repository.revision.number} > /dev/null
  curl -s -H "Authorization: token <redacted>" --request POST --data '{"state": "failure", "context": "100% Code Coverage", "description": "Coverage < 100%", "target_url": "${bamboo.buildResultsUrl}"}'<user>/<repo>/statuses/${bamboo.repository.revision.number} > /dev/null

After completing a build with 100% code coverage, we were able to tell our Github repo to require the 100% Code Coverage status check, and now all subsequent pull requests will be required to meet 100% code coverage. Success!