Search code examples
gradlegithubjacocobadgegithub-actions

How to create a badge with test coverage (jacoco) on github (actions)


In spring project, I use jacoco plugin to measure test coverage.

I see the html report like below:

enter image description here

Now I would like to add a badge to github project with this percentage, something like this:

enter image description here

Any idea how can I combine jacoco with github actions?


Solution

  • You can use GitHub actions to generate a badge using GitHub Workflow (no need to other servers). You could write your own jobs/steps or use my just published action: https://github.com/marketplace/actions/badge-action .

    First, you need to parse the coverage result file and extract the value (81 in your example). Here, I used parse-coverage-report as an example command (you'll need to create it by yourself). Finally, save this value as a GitHub workflow output:

    on: [push]
    
    jobs:
      coverage:
        runs-on: ubuntu-latest
        name: Generate test coverage badge
        steps:
    
        - name: Generate a coverage value
          id: coverage
          # Generates a GitHub Workflow output named `lines`
          run: |
            COVERAGE="$( parse-coverage-report )"
            echo "##[set-output name=lines;]${COVERAGE}%"
    
        # Use the output from the `coverage` step
        - name: Generate the badge SVG image
          uses: emibcn/badge-action@v1
          with:
            label: 'Test coverage'
            status: ${{ steps.coverage.outputs.lines }}
            color: 'blue,555,daf'
            path: badge.svg
    

    This saves the badge as file badge.svg. Now, you decide wether to upload this badge to the same repository, to an S3 or whatever you prefer. Being that a coverage report, I suppose you'll like to upload that to same's repo 1) same branch it was extracted from or 2) dedicated branch badges:

    1) Push to same branch it was extracted from

        - name: Extract branch name
          shell: bash
          run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
          id: extract_branch
        - name: Create badges dir if necessary
          run: mkdir -p .github/badges
        - name: Generate the badge SVG image
          uses: emibcn/badge-action@v1
          with:
            label: 'Test coverage'
            status: ${{ steps.coverage.outputs.lines }}
            color: 'blue,555,daf'
            path: .github/badges/badge.svg
        - name: Commit badge
          run: |
            git config --local user.email "[email protected]"
            git config --local user.name "GitHub Action"
            git add .github/badges/badge.svg
            git commit -m "Add/Update badge"
        - name: Push badge commit
          uses: ad-m/github-push-action@master
          with:
            github_token: ${{ secrets.GITHUB_TOKEN }}
            branch: ${{ steps.extract_branch.outputs.branch }}
    

    The extract_branch step has been taken from https://stackoverflow.com/a/58035262/2928168 .

    2) Push to dedicated branch badges

    First, create and push the dedicated branch badges with (extracted from StackOverflow):

    git checkout master
    
    # Use a fresh start
    git checkout --orphan badges
    
    # Unstage all the files in your working tree.
    git rm --cached $(git ls-files)
    
    # Create a dedicated README file, so it's clear what's going on here
    echo '# Badges branch' > README.md
    git add README.md
    git commit -m 'Add dedicated README'
    git push origin badges
    
        - name: Extract branch name
          shell: bash
          run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
          id: extract_branch
        - uses: actions/checkout@v1
          with:
            ref: badges
            path: badges
        - name: Create badges dir if necessary
          env:
            BRANCH: ${{ steps.extract_branch.outputs.branch }}
          run: mkdir -p badges/${BRANCH}
        - name: Generate the badge SVG image
          uses: emibcn/badge-action@v1
          with:
            label: 'Test coverage'
            status: ${{ steps.coverage.outputs.lines }}
            color: 'blue,555,daf'
            path: badges/${{ steps.extract_branch.outputs.branch }}/badge.svg
        - name: Commit badge
          env:
            BRANCH: ${{ steps.extract_branch.outputs.branch }}
          run: |
            pushd badges
                git config --local user.email "[email protected]"
                git config --local user.name "GitHub Action"
                git add "${BRANCH}/badge.svg"
                git commit -m "Add/Update badge"
            popd
        - name: Push badge commit
          uses: ad-m/github-push-action@master
          with:
            github_token: ${{ secrets.GITHUB_TOKEN }}
            branch: badges
            directory: badges
    

    UPDATE

    If you coverage report is a typical clover coverage.xml file, you can use this action to parse and output the coverage value. For example:

    - name: Check test coverage
      uses: johanvanhelden/gha-clover-test-coverage-check@v1
      id: coverage
      with:
        percentage: "50"
        filename: "coverage.xml"
    # Use the output from the `coverage` step
    - name: Generate the badge SVG image
      uses: emibcn/badge-action@v1
      id: badge
      with:
        label: 'Coverage'
        status: ${{ steps.coverage.outputs.coverage }}
        path: ./badges/test-coverage.svg
        color: ${{ steps.coverage.outputs.coveragelines > 75 && 'green' || 'red' }}
    

    UPDATE 2

    You can make your badge change its background color depending on the coverage value, even using gradients:

    # Use the output from the `coverage` step
    - name: Generate the badge SVG image
      uses: emibcn/badge-action@v1
      id: badge
      with:
        label: 'Coverage'
        status: ${{ steps.coverage.outputs.coverage }}
        path: ./badges/test-coverage.svg
        color: ${{
              steps.coverage.outputs.coverage > 90 && 'green'              ||
              steps.coverage.outputs.coverage > 80 && 'yellow,green'       ||
              steps.coverage.outputs.coverage > 70 && 'yellow'             ||
              steps.coverage.outputs.coverage > 60 && 'orange,yellow'      ||
              steps.coverage.outputs.coverage > 50 && 'orange'             ||
              steps.coverage.outputs.coverage > 40 && 'red,orange'         ||
              steps.coverage.outputs.coverage > 30 && 'red,red,orange'     ||
              steps.coverage.outputs.coverage > 20 && 'red,red,red,orange' ||
              'red' }}
    

    UPDATE 3

    Updated the 2 workflows:

    • Same branch: Save badges into .github/badges/
    • Dedicated branch: Use a sub directory in the workflow to manage the badges, so workflow environment remains usable for further steps (for example, saving some cache).

    UPDATE 4: Working examples

    You can see working examples in some repositories workflows (add yours by editing the answer or commenting on it):