PHPackages                             brianhenryie/php-codecoverage-markdown - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. brianhenryie/php-codecoverage-markdown

ActiveLibrary[Testing &amp; Quality](/categories/testing)

brianhenryie/php-codecoverage-markdown
======================================

Generate markdown coverage reports from PHPUnit code coverage data for GitHub PR comments

0.2(4mo ago)16.8k↑48.8%3MITPHPPHP &gt;=7.4

Since Jan 18Pushed 4mo agoCompare

[ Source](https://github.com/BrianHenryIE/php-codecoverage-markdown)[ Packagist](https://packagist.org/packages/brianhenryie/php-codecoverage-markdown)[ RSS](/packages/brianhenryie-php-codecoverage-markdown/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (2)Dependencies (7)Versions (4)Used By (3)

[![PHP 7.4](https://camo.githubusercontent.com/80506e1344b3485491afb7db3eb77dcee6d651d0119a1b2fa37e654a9c62c503/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d372e342d3838393242462e7376673f6c6f676f3d706870)](https://php.net)

PHP Code Coverage Markdown Report Printer
=========================================

[](#php-code-coverage-markdown-report-printer)

Generate Markdown coverage reports from PHPUnit code coverage data, for GitHub PR comments.

[![PHPUnit ](.github/example-github-pr-comment.png)](https://github.com/BrianHenryIE/strauss/pull/139#issuecomment-2614192979)

Features
--------

[](#features)

- 📊 Convert PHPUnit `.cov` coverage files to Markdown
- 🔗 Link files to GitHub blob URLs
- 📝 Filter reports to specific files
- 🎨 Visual coverage bars using emojis (🟩🟧🟥⬜)

The Markdown report includes:

- Total coverage summary
- Per-file coverage details with:
    - Lines coverage percentage
    - Visual coverage bar
    - Methods coverage
    - Classes coverage
    - Clickable source/HTML report links, set with `--base-url`

### Options

[](#options)

Primary input: coverage file in PHP format from [phpunit/php-code-coverage](https://github.com/sebastianbergmann/php-code-coverage):`^9|^10|^11|^12`, i.e. `phpunit --coverage-php coveragephp.cov`.

OptionShortDescription`--input-file``-i`Path to PHPUnit `.cov` coverage file (required)`--output-file``-o`Output file path (default: stdout)`--base-url``-b`Base URL for source file links (use `%s` as relative path placeholder)`--covered-files``-c`Comma-separated list of files to include (i.e. the files in the PR)### Limitation

[](#limitation)

GitHub Actions permissions limit new comments to users with write access to the repo. I.e. this works great for teams using private repos and works ok for PRs on public repos. There is a workaround at [mshick/add-pr-comment-proxy](https://github.com/mshick/add-pr-comment-proxy) which runs on Google Cloud.

Installation
------------

[](#installation)

```
composer require --dev brianhenryie/php-codecoverage-markdown:"^0.1|^1.0"
```

Usage
-----

[](#usage)

### CLI

[](#cli)

Generate a Markdown report from a PHPUnit coverage file:

```
php-codecoverage-markdown \
  --input-file tests/_reports/coveragephp.cov \
  --output-file coverage-report.md
```

With GitHub links:

```
php-codecoverage-markdown \
  --input-file tests/_reports/coveragephp.cov \
  --base-url "https://github.com/user/repo/blob/main/%s" \
  --output-file coverage-report.md
```

Filter to specific files:

```
php-codecoverage-markdown \
  --input-file tests/_reports/coveragephp.cov \
  --covered-files "src/MyClass.php,src/AnotherClass.php" \
  --output-file coverage-report.md
```

### GitHub Actions

[](#github-actions)

Use this to post coverage reports as PR comments:

```
name: PHP Tests with Code Coverage Report Comment

on:
  pull_request:
    types: [opened, synchronize]

env:
  COVERAGE_PHP_VERSION: '8.4'

jobs:
  php-tests:
    runs-on: ubuntu-latest

    permissions:
      pull-requests: write

    strategy:
      matrix:
        php: [ '8.2', '8.3', '8.4', '8.5' ]

    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          coverage: ${{ matrix.php == env.COVERAGE_PHP_VERSION && 'xdebug' || 'none' }}

      - name: Install dependencies
        run: composer install

      - name: Run tests with coverage
        if: ${{ matrix.php == env.COVERAGE_PHP_VERSION }} # We only need the coverage data once
        run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-php coveragephp.cov

      - name: Run tests without coverage
        if: ${{ matrix.php != env.COVERAGE_PHP_VERSION }}
        run: vendor/bin/phpunit

      - name: Get changed files
        if: ${{ matrix.php == env.COVERAGE_PHP_VERSION }}
        id: changed-files
        uses: tj-actions/changed-files@v47
        with:
          separator: ','
          files: '**/**.php'

      - name: Generate markdown report
        if: ${{ matrix.php == env.COVERAGE_PHP_VERSION }}
        run: |
          vendor/bin/php-codecoverage-markdown \
            --input-file coveragephp.cov \
            --covered-files=${{ steps.changed-files.outputs.all_changed_files }} \
            --base-url "https://github.com/${{ github.repository }}/blob/${{ github.event.pull_request.head.sha }}/%s" \
            --output-file coverage-report.md

      - name: Comment on PR
        uses: mshick/add-pr-comment@v2
        if: ${{ matrix.php == env.COVERAGE_PHP_VERSION }}
        with:
          message-id: coverage-report # Causes it to update the same PR comment each time.
          message-path: coverage-report.md
        continue-on-error: true # When a PR is opened by a non-member, there are no write permissions (and no access to secrets), so this step will always fail.
```

### Programmatic

[](#programmatic)

```
use BrianHenryIE\CodeCoverageMarkdown\MarkdownReport;
use SebastianBergmann\CodeCoverage\CodeCoverage;

/** @var CodeCoverage $coverage */
$coverage = include 'path/to/coveragephp.cov';

$report = new MarkdownReport();
$markdown = $report->process(
    coverage: $coverage,
    projectRoot: '/path/to/project/',
    baseUrl: 'https://github.com/user/repo/blob/main/%s',
    coveredFilesList: ['src/MyClass.php']
);

file_put_contents('coverage-report.md', $markdown);
```

Status
------

[](#status)

- Ironically, this project's tests pass locally but fail in GitHub Actions! I'll tag 1.0 when I figure that out
- This should be spun into its own GitHub Action so it is not a dependency in a project

See Also
--------

[](#see-also)

- [mshick/add-pr-comment-proxy](https://github.com/mshick/add-pr-comment-proxy)
- [BrianHenryIE/php-diff-test](https://github.com/BrianHenryIE/php-diff-test)

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance74

Regular maintenance activity

Popularity25

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity27

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~25 days

Total

2

Last Release

141d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4720401?v=4)[Brian Henry](/maintainers/BrianHenryIE)[@BrianHenryIE](https://github.com/BrianHenryIE)

---

Top Contributors

[![BrianHenryIE](https://avatars.githubusercontent.com/u/4720401?v=4)](https://github.com/BrianHenryIE "BrianHenryIE (53 commits)")

---

Tags

codecoveragegithub-actionsphpunittestingphpunitmarkdowncode coverageGithub Actions

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/brianhenryie-php-codecoverage-markdown/health.svg)

```
[![Health](https://phpackages.com/badges/brianhenryie-php-codecoverage-markdown/health.svg)](https://phpackages.com/packages/brianhenryie-php-codecoverage-markdown)
```

###  Alternatives

[phpunit/phpunit

The PHP Unit Testing framework.

20.0k955.1M155.1k](/packages/phpunit-phpunit)[brianium/paratest

Parallel testing for PHP

2.5k136.1M986](/packages/brianium-paratest)[behat/behat

Scenario-oriented BDD framework for PHP

4.0k101.8M2.2k](/packages/behat-behat)[infection/infection

Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.

2.2k28.9M2.4k](/packages/infection-infection)[nette/tester

Nette Tester: enjoyable unit testing in PHP with code coverage reporter. 🍏🍏🍎🍏

4957.6M1.7k](/packages/nette-tester)[facile-it/paraunit

paraunit

145845.1k17](/packages/facile-it-paraunit)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
