OSS
Back to Open Source
OPEN SOURCE · Jul 2025

gh-clover-annotate

A GitHub CLI extension to annotate GitHub Actions runs with code coverage statistics for projects using Clover style XML reports.

Project Metadata

Technologies
GITHUB PHP PHPUNIT PEST
GitHub

This is a GitHub CLI extension that allows you to annotate your PHP test coverage reports in GitHub Actions using the Clover XML format.

What?

This extension reads a Clover XML file (usually generated by PHPUnit or Pest) and annotates the GitHub Actions summary with the coverage report. It will produce a table similar to the following:

[!NOTE] Code coverage is at 86.13%

Coverage Total Statements Covered Statements File
🟢 100% 15 15 app/Enums/UserRole.php
🟢 100% 15 15 app/Models/User.php
🟢 100% 1 1 app/Http/Controllers/Api/V1/PingController.php

Installation

At BuiltFast, we like to run test coverage reports on-demand since it is slower than standard CI runs.

We commonly ship a .github/workflows/coverage.yml file with something like this:

name: Coverage

on:
  workflow_dispatch:

jobs:
  tests:
    name: Run test suite with coverage

    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: dom, curl, libxml, mbstring, zip, bcmath
          ini-values: error_reporting=E_ALL
          tools: composer:v2
          coverage: xdebug

      - name: Set GitHub Actions problem matchers
        run: |
          echo "::add-matcher::${{ runner.tool_cache }}/php.json"

      - name: Get composer cache directory
        id: composer-cache
        run: |
          echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"

      - name: Cache composer dependencies
        uses: actions/cache@v4
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: ${{ runner.os }}-composer-

      - name: Install dependencies
        run: |
          composer install -q --no-ansi --no-interaction --no-scripts --no-progress
          npm ci

      - name: Prepare the environment
        run: |
          cp .env.example .env

      - name: Generate an application key
        run: php artisan key:generate

      - name: Run migrations
        run: php artisan migrate --env=testing --force

      - name: Run Pest testsuite with coverage
        run: |
          ./vendor/bin/pest --coverage-clover clover.xml --parallel

      - name: Annotate coverage report
        run: |
          gh extension install built-fast/gh-clover-annotate
          gh clover-annotate clover.xml >> "$GITHUB_STEP_SUMMARY"

That allows us to go to the Actions tab on one of our repos and then click the “Run workflow” button to run the test suite with coverage for a specific branch.

License

MIT License.