DEV Community

Matt Gaiser
Matt Gaiser

Posted on

Free Code Coverage for Pull Requests on GitHub.

Say that you want some of the benefits of CodeCov but your company is too cheap to pay for it or you just don't want to have to go through the procurement process. What do you do?

Step 1: Generate a code coverage report in a text format.

I did this for an Angular project, it was just a matter of changing the test coverage reporters in karma.conf.js to include:

      reporters: [
        { type: 'text-summary',
          dir : '../../coverage',
          file : 'coverage.txt'
        },
Enter fullscreen mode Exit fullscreen mode

This gives me a text file that I can read to get the lines of code coverage. Because code coverage reporting is highly framework and language specific, I am not going to go into detail here about it. Already having the code coverage numbers is a prerequisite for the rest of the tasks.

Step 2: Figure out the grep or awk bash command to read the text file.

My code coverage tool generates this as its text output. This image is from the console, but what it writes to the file is the same.

image

It lives in the coverage directory in a file called coverage.txt. I want the percent of lines covered by tests, so I use this:

awk '/^Lines/ { print $3 }' < coverage/coverage.txt

Step 3: Have your Github Action generate the coverage report.

I assume that you have already set up automated testing on Github Actions for each PR (but if not, the full code is at the bottom of the page), so all you must do is set up another Github Action that runs the coverage portion and generates the report. You can likely take the existing GitHub Action and just replace its run with these lines.

 - name: Run tests
   run: npm run test:coverage
Enter fullscreen mode Exit fullscreen mode

Step 4: Add mshick/add-pr-comment@v1 to your GitHub Action to add a comment.

Add PR Comment is a GitHub Action that adds a comment to a PR (the name is pretty straightforward). It is what will post the coverage info to the PR. Each time a new push is made, it will make a new comment if the coverage has changed (it will not comment if the coverage has not changed).

- uses: mshick/add-pr-comment@v1
        with:
          message: | <Message goes here without arrows>
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens
          allow-repeats: false # This is the default
Enter fullscreen mode Exit fullscreen mode

Step 5: Use your bash command to get the coverage value and insert it into the comment.

Run the bash command and assign it to a variable. Add the variable to the string and have it printed out.

      - name: Get coverage output
        id: get_coverage
        run: echo "::set-output name=coverage::$(awk '/^Lines/ { print $3 }' < coverage/coverage.txt)"

      - uses: mshick/add-pr-comment@v1
        with:
          message: |
            Lines Covered: ${{steps.get_coverage.outputs.coverage}}
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens
          allow-repeats: false # This is the default
Enter fullscreen mode Exit fullscreen mode

That lets you get this:
image

Full Example GitHub Action

name: Report Code Coverage

on:
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Use Node.js 12.x
        uses: actions/setup-node@v1
        with:
          node-version: 12.x

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm run test:coverage

      - name: Get coverage output
        id: get_coverage
        run: echo "::set-output name=coverage::$(awk '/^Lines/ { print $3 }' < coverage/coverage.txt)"

      - uses: mshick/add-pr-comment@v1
        with:
          message: |
            Lines Covered: ${{steps.get_coverage.outputs.coverage}}
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens
          allow-repeats: false # This is the default
Enter fullscreen mode Exit fullscreen mode

Top comments (0)