The jacoco-badge-generator GitHub Action is now also available as a CLI tool from PyPI
Tags: java, github, kotlin, python
Published: 2022-07-08 17:24:00

The jacoco-badge-generator began its life as a GitHub Action for use in GitHub workflows to do the following: parse a JaCoCo coverage report, generate coverage badges as SVGs entirely within GitHub Actions, optionally generate Shields JSON badge endpoints rather than direct badge generation, and optionally to perform pull request checks to fail workflow runs if coverage or branches coverage is below a user-configurable threshold, or if coverage or branches coverage decreased relative to prior run. It is suitable for use with Java projects, as well as projects with any other JVM language supported by JaCoCo such as Kotlin. The badges can be configured in a variety of ways, such as color scheme (e.g., mapping from coverage ranges to colors), and label text (e.g., defaults are "coverage" and "branches" but for a multi-module project, you might want something like "coverage (module name)" and "branches (module name)").

At the request of multiple users, the jacoco-badge-generator can now also be used as a command-line utility outside of GitHub Actions, such as executing it from a local build script. For this CLI use-case, it can now be installed locally from PyPI using pip. The jacoco-badge-generator is implemented 100% in Python. Within GitHub Actions, it is a container Action, relying on Docker to ensure a compatible Python version is available within the workflow. As a CLI tool, Docker is not needed, but you must have a compatible version of Python installed. It has been tested with Python 3.8, 3.9, and 3.10 (it may or may not work with earlier versions).

The remainder of this post is organized as follows:
* [GitHub Actions usage examples](#github-actions-usage-examples)
* [CLI utility installation and usage examples](#cli-utility-installation-and-usage-examples) 
* [Learn more](#learn-more)
* [Support the project](#support-the-project)

The GitHub repository includes the source code, as well as more detailed documentation including additional examples:

{% github cicirello/jacoco-badge-generator %}


## GitHub Actions usage examples

In addition to the GitHub repository, embedded above, there is also a template repository with a few runnable GitHub workflows:

{% github cicirello/examples-jacoco-badge-generator %}

The following example workflows demonstrate how to use some of the functionality. See the [GitHub repository](https://github.com/cicirello/jacoco-badge-generator) for complete documentation.

### Example 1: All defaults

This first example GitHub workflow uses all of the default inputs, and also assumes the JaCoCo report is in Maven's default location. The default behavior only generates the coverage badge (and does not generate the branches coverage badge). The jacoco-badge-generator doesn't commit the badge, so there is an additional step in this workflow to do that.

```yml
name: build

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Set up the Java JDK
      uses: actions/setup-java@v2
      with:
        java-version: '17'
        distribution: 'adopt'

    - name: Build with Maven and run tests
      run: mvn -B test

    - name: Generate JaCoCo Badge
      id: jacoco
      uses: cicirello/jacoco-badge-generator@v2

    - name: Log coverage percentage to the workflow log
      run: |
        echo "coverage = ${{ steps.jacoco.outputs.coverage }}"
        echo "branch coverage = ${{ steps.jacoco.outputs.branches }}"

    - name: Commit and push the badge (if it changed)
      uses: EndBug/add-and-commit@v7
      with:
        default_author: github_actions
        message: 'commit badge'
        add: '*.svg'
```

### Example 2: Both coverage and branches coverage badges

If you want badges for both instructions coverage and branches coverage, replace the jacoco-badge-generator step with:

```yml
    - name: Generate JaCoCo Badge
      id: jacoco
      uses: cicirello/jacoco-badge-generator@v2
      with:
        generate-branches-badge: true
```

### Example 3: Changing the color theme and coverage intervals

If you want to change the colors used and the coverage intervals for each color, you can use the `colors` and `intervals` inputs. In the following example, green is used if coverage is at least 90 percent, yellow if coverage is less than 90 but at least 75 percent, orange is used if coverage is less than 75 percent but at least 60 percent, and red is used if coverage is less than 60 percent. This example also generates both badges. Colors can be specified as either SVG named colors as in this example or as 6-digit or 3-digit hex colors.

```yml
    - name: Generate JaCoCo Badge
      id: jacoco
      uses: cicirello/jacoco-badge-generator@v2
      with:
        generate-branches-badge: true
        colors: green yellow orange red
        intervals: 90 75 60 
```

### Example 4: Shields JSON endpoints instead of SVG badges

If you'd rather generate JSON instead of SVG badges that you can then pass to Shields custom endpoint, you can use the following step:

```yml
    - name: Generate JaCoCo Badge
      id: jacoco
      uses: cicirello/jacoco-badge-generator@v2
      with:
        generate-coverage-badge: false
        generate-coverage-endpoint: true
        generate-branches-endpoint: true
```

### Example 5: Gradle rather than Maven

All of the above examples assume that you are running the tests with Maven. If you are using Gradle, you can replace the Maven step and the jacoco-badge-generator step with something like the following, which runs the tests and JaCoCo with Gradle rather than Maven, and which passes Gradle's location of the JaCoCo report to the jacoco-badge-generator:

```yml
      - name: Run Tests
        run: ./gradlew test

      - name: Run Test Coverage
        run: ./gradlew jacocoTestReport

      - name: Generate JaCoCo Badge
        id: jacoco
        uses: cicirello/jacoco-badge-generator@v2
        with:
          jacoco-csv-file: build/reports/jacoco/test/jacocoTestReport.csv
```



## CLI utility installation and usage examples

The PyPI package page is found at:

{% embed https://pypi.org/project/jacoco-badge-generator/ %}

### Installing the CLI utility from PyPI

To install from PyPi (Unix and MacOS):

```Shell
python3 -m pip install jacoco-badge-generator
```

To install from PyPi (Windows):

```Shell
py -m pip install jacoco-badge-generator
```

### CLI examples

Here are a few example cases. All of the examples assume the Python 3 executable is `python3`, such as on Unix and MacOS. On Windows, just change `python3` to `py`. All of the examples assume that you have already generated the JaCoCo report, and also assume that you are running the command from the root of your project.

#### All defaults

Generates only the instructions coverage badge, and assumes the report is in Maven's default location:

```Shell
python3 -m jacoco_badge_generator
```

#### Generating instructions coverage and branches coverage badges

```Shell
python3 -m jacoco_badge_generator --generate-branches-badge true
```

#### Changing Colors and Coverage Intervals

If you want to change the colors used and the coverage intervals for each color, you can use the `--colors` and `--intervals` options. In the following example, green is used if coverage is at least 90 percent, yellow if coverage is less than 90 but at least 75 percent, orange is used if coverage is less than 75 percent but at least 60 percent, and red is used if coverage is less than 60 percent. Colors can be specified as either SVG named colors as in this example or as 6-digit or 3-digit hex colors.

```Shell
python3 -m jacoco_badge_generator --colors green yellow orange red --intervals 90 75 60
```

#### Generating Shields JSON endpoints instead of badges

If you want to generate Shields JSON endpoints instead of badges, you need
to disable generating the coverage badge, and enable the JSON endpoints:

```Shell
python3 -m jacoco_badge_generator --generate-coverage-badge false --generate-coverage-endpoint true --generate-branches-endpoint true
```

#### Gradle location of JaCoCo report

The utility by default assumes that the JaCoCo report is the Maven default of `target/site/jacoco/jacoco.csv`. If it is somewhere else, there is an option
to specify its location. Here is an example with Gradle's standard location and name of the JaCoCo csv report.

```Shell
python3 -m jacoco_badge_generator --jacoco-csv-file build/reports/jacoco/test/jacocoTestReport.csv
```

## Learn more

You can find additional information about the jacoco-badge-generator and other GitHub Actions that I've implemented on the following website:

{% embed https://actions.cicirello.org/ %}

Here is an earlier DEV post about the jacoco-badge-generator, including an example GitHub workflow that also comments the coverage percentage on pull requests:

{% link cicirello/jacoco-coverage-badges-pr-coverage-checks-and-pr-coverage-comments-from-github-actions-4a8f %}


## Support the project

You can support the project in a number of ways:
* __Starring__: If you find this utility 
  useful, consider starring the [GitHub repository](https://github.com/cicirello/jacoco-badge-generator).
* __Sharing with Others__: Consider sharing it with others who
  you feel might find it useful.
* __Reporting Issues__: If you find a bug or have a suggestion for
  a new feature, please report it via 
  the [Issue Tracker](https://github.com/cicirello/jacoco-badge-generator/issues). 
* __Contributing Code__: If there is an open issue that you think
  you can help with, submit a pull request.
* __Sponsoring__: You can also consider sponsoring via one of the following:

| GitHub | Liberapay | Ko-Fi |
| :---: | :---: | :---: |
| [![GitHub Sponsors](https://actions.cicirello.org/images/github-sponsors.svg)](https://github.com/sponsors/cicirello) | [![Liberapay](https://actions.cicirello.org/images/Liberapay.svg)](https://liberapay.com/cicirello) | [![Ko-Fi](https://actions.cicirello.org/images/ko-fi.svg)](https://ko-fi.com/cicirello) | |