Free Code Coverage for Pull Requests on GitHub. 
Published: 2021-08-28 19:17:47

Say that you want some of the benefits of [CodeCov](https://about.codecov.io/) 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'
        },
```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3wbig0xodksqsa3omuqk.png)

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
``` 

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

[Add PR Comment](https://github.com/marketplace/actions/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
```

**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
```

That lets you get this: 
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y78pddampiuizcx18mnz.png)
 
 
**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
```