DEV Community

Cover image for Coverage Badge with GitHub Actions - FINALLY!

Coverage Badge with GitHub Actions - FINALLY!

The Jared Wilcurt on December 28, 2020

This is the only documented way to get coverage badges with GitHub Actions. It took a few months of research, trial, and error; but eventually I go...
Collapse
 
rainabba profile image
Michael Richardson •

I may be missing something here, but since this comes down to creating and stashing a .json file that can be accessed in the context of a viewer on the readme.md, couldn't a repo be used just as well (with a token generated having appropriate perms to commit changes to the repo/branch that will be used in the badge to retrieve that .json file?

Collapse
 
thejaredwilcurt profile image
The Jared Wilcurt •

That's another way, abusing Gist just has fewer steps. And lower risk (can't accidentally give permissions to the wrong repo, just to your gists).

Collapse
 
mishakav profile image
Misha Kav •

You can get PR number easily:

name: Test PR number
on:
  pull_request:
jobs:
  test-pr-num:
    runs-on: ubuntu-latest
    steps:
      - name: Get PR number
        run: |
          echo "Current PR Number is: ${{ github.event.pull_request.number }}"
Enter fullscreen mode Exit fullscreen mode
Collapse
 
forgetso profile image
Chris • • Edited

You can update the pull request template after the coverage badge has been created with an additional step in your workflow:

    - name: Update the Badge URL in the pull request body
      run: |
        BODY=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/<your-username>/<your-repo>/pulls/${{ github.event.pull_request.number }} | jq .body | sed -En "s/protocol__pull_##.json/protocol__pull_${{ github.event.pull_request.number }}.json/p")
        JSON="{\"body\":$(echo $BODY | jq -sR .)}"
        curl \
          -X POST \
          -H "Authorization: token ${{ secrets.GIST_SECRET }}" \
          -H "Content-Type: application/json" \
          -d $JSON \
          https://api.github.com/repos/<your-username>/<your-repo>/pulls/${{ github.event.pull_request.number }}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
paleika profile image
Nadezhda Ivashchenko •

Needed to make a few changes for Yarn (no need to add --, have to trim 3 lines on the tail)
Made a tiny version to renew the gist file only on push to main branch (when you need to display only in Readme)

name: coverage badge
on:
  push:
    branches: [ master ]

jobs:
  checks:
    runs-on: ubuntu-20.04
    steps:
    - uses: actions/checkout@v2

    - name: Install modules
      run: yarn --prefer-offline

    - name: Run unit tests with coverage
      run: |
        SUMMARY="$(yarn test --coverage --coverageReporters=text-summary | tail -3 | head -1)"
        TOKENS=($SUMMARY)
        echo "COVERAGE=$(echo ${TOKENS[2]})" >> $GITHUB_ENV

    - name: Create Coverage Badge
      uses: schneegans/dynamic-badges-action@v1.1.0
      with:
        auth: ${{ secrets.GIST_SECRET }}
        gistID: <your_gist_id>
        filename: <your_repo>_coverage.json
        label: coverage
        message: ${{ env.COVERAGE }}
        namedLogo: jest
        color: blue
        logoColor: lightblue
Enter fullscreen mode Exit fullscreen mode
Collapse
 
yuriyyakym profile image
Yuriy Yakym •

Instead of parsing text-summary output, you can use a json-summary reporter and then get values that you need with jq tool, like so:

- name: Get coverage output
  id: coverage
  run: echo "value=$(jq -r '.total.lines.pct|tostring + "%"' coverage/coverage-summary.json)" >> $GITHUB_OUTPUT
Enter fullscreen mode Exit fullscreen mode

You can see it in action at my repository.

Collapse
 
mishakav profile image
Misha Kav • • Edited

There are more easiest way like this action Jest Coverage Comment

It works in PR/Push, can extract the coverage, and there are also example of how to update the Readme with coverage.

Collapse
 
fritx profile image
Fritz Lin • • Edited

@mishakav @thejaredwilcurt consider this action, no secrets config at all.
It's simple and fits simple projects,
with a continuously updated badge output to gh-pages.
github.com/we-cli/coverage-badge-a...

Collapse
 
pbdesk profile image
Pinal Bhatt •

Great post. finally, something without any paid third-party usages.

Collapse
 
wesleyscholl profile image
Wesley Scholl • • Edited

Great article, I was able to implement this with a bit of tinkering. It might be good to note that the your-repo/.github/workflows/node.js.yml file needs to be configured with the gistID and filename (repo name):

- if: ${{ matrix.node-version == '14.x' }}
      name: Create the Badge
      uses: schneegans/dynamic-badges-action@v1.0.0
      with:
        auth: ${{ secrets.GIST_SECRET }}
        gistID: 7d4c25ef2e97e8de523ef7c1fee26e8e # <-- Update this
        filename: your-repo-name__${{ env.BRANCH }}.json # <-- And this
Enter fullscreen mode Exit fullscreen mode
Collapse
 
apomalyn profile image
Xavier Chretien •

Since one or two weeks Shield.io display "domain is blocked" when using this technique. Am I the only one getting this error?

Collapse
 
thejaredwilcurt profile image
The Jared Wilcurt •

Just tested with https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/TheJaredWilcurt/9c5d16fe3fa8f8ef414fe8b0eff17f7f/raw/red-perfume__pull_31.json and it is working fine for me.