I work for Akkio, where I'm building out a no-code predictive AI platform. If you're looking to harness the power of AI without needing a data scientist, give us a try!
Had some difficulty finding an up-to-date way to do this, so I figure I save anybody looking for this in the future some time.
Without future ado, here's the .github/workflows/.yml:
name: Code Coverage
on:
pull_request:
branches: [ "master" ]
push:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: 17
distribution: 'temurin'
cache: maven
- name: Generate Coverage Report
run: |
mvn -B package --file pom.xml
- name: Upload Report
uses: 'actions/upload-artifact@v2'
with:
name: jacoco-report
path: ${{ github.workspace }}/target/site/jacoco/jacoco.xml
- name: Add coverage to PR
id: jacoco
uses: madrapps/jacoco-report@v1.2
with:
paths: ${{ github.workspace }}/target/site/jacoco/jacoco.xml
token: ${{ secrets.GITHUB_TOKEN }}
min-coverage-overall: 80
min-coverage-changed-files: 80
title: Code Coverage
- name: Save Coverage To Environment Variable
run: |
echo "TOTAL_COVERAGE=${{ steps.jacoco.outputs.coverage-overall }}" >> $GITHUB_ENV
echo "CHANGED_FILES_COVERAGE=${{ steps.jacoco.outputs.coverage-changed-files }}" >> $GITHUB_ENV
- name: Print & Check Coverage Info
run: |
import os
import sys
print("Total Coverage: " + str(os.environ["TOTAL_COVERAGE"]))
print("Changed Files Coverage: " + str(os.environ["CHANGED_FILES_COVERAGE"]))
if float(os.environ["TOTAL_COVERAGE"]) < 80 or float(os.environ["CHANGED_FILES_COVERAGE"]) < 80:
print("Insufficient Coverage!")
sys.exit(-1) # Cause Status Check Failure due to noncompliant coverage
sys.exit(0)
shell: python
The Python script at the end technically returns a 255 for some reason in case of insufficient coverage, but it still returns a nonzero exit code, which is what we need.
Some notes:
- Maven dependencies are cached. Subsequent runs should be much faster than the initial one.
- Python is necessary because I couldn't find a convenient way to parse the coverage number jacoco-report gives us (which ends up as a string) into a float in Bash.
- madrapps/jacoco-report is not optional, though you can disable the comment it adds onto the PR if you like. It's necessary because it outputs the
steps.jacoco.outputs.coverage-overall
andsteps.jacoco.outputs.coverage-changed-files
variables.
Top comments (5)
Another way to do this is with:
cicirello / jacoco-badge-generator
Coverage badges, and pull request coverage checks, from JaCoCo reports in GitHub Actions
jacoco-badge-generator
Check out all of our GitHub Actions: actions.cicirello.org/
About
The jacoco-badge-generator can be used in one of two ways: as a GitHub Action or as a command-line utility (e.g., such as part of a local build script). The jacoco-badge-generator parses a
jacoco.csv
from a JaCoCo coverage report, computes coverage percentages from JaCoCo's Instructions and Branches counters, and generates badges for one or both of these (user configurable) to provide an easy to read visual summary of the code coverage of your test cases. The default behavior directly generates the badges internally with no external calls, but the action also provides an option to instead generate Shields JSON endpoints. It supports both the basic case of a singlejacoco.csv
, as well as multi-module projects in which case the action can produce coverage badges from the combination of…It supports checking for min coverage as well as min branches coverage. It also can check for decreased coverage.
However, it doesn't currently check just the changed files. It also doesn't currently comment on PRs, but that is easy enough to do with a step in workflow using GitHub CLI. I have a DEV post with a sample workflow showing how to do that:
JaCoCo coverage badges, PR coverage checks, and PR coverage comments, from GitHub Actions
Vincent A. Cicirello ・ Nov 29 '21 ・ 6 min read
Ah, I tried out your plugin and ran into an issue. I forget why, sorry. Would probably work if I took another shot at it again.
I just happened to gravitate to a slightly custom solution because this is for a private project where I don't really need badges and all that fancy stuff. Just wanted a simple way to gate merging behind code coverage requirements.
If all you want to do is fail the workflow run if coverage is below some target, you can configure jacoco to do that without using any special github actions. Check out the jacoco:check goal and its rules parameter. If you use that and coverage is below what you set, the build will halt with a non-zero code, which in turn will fail the github workflow run.
The sys.exit(-1) is giving you an actual exit code of 255 because on unix systems Python exit codes are unsigned bytes, so your -1 is an underflow.
Ah, good to know. Makes sense!