Publishing Coverage Reports with ReportGenerator to GitHub Pages
As a big fan of the ReportGenerator .NET tool, I’ve been relying on it to visualize code coverage in my .NET projects. It’s flexible and supports a variety of output formats such as HTML, Markdown, and even badges.
When I was using Azure DevOps, integrating ReportGenerator into my CI pipelines was simple, thanks to the official extension that displays reports in a dedicated tab within the job summary UI.
However, once I moved my CI pipelines to GitHub Actions, I noticed a gap. GitHub doesn’t provide native UI support for browsing rich coverage reports. I wanted a simple, automated solution that:
- Generates interactive reports.
- Publishes them with every push to
main
. - Gives me a badge in my
README.md
that links directly to the latest report.
That’s when GitHub Pages came to the rescue. GitHub Pages is a free static site hosting feature available for public repositories. By leveraging a dedicated branch (e.g., coverage-reports
) and GitHub Actions, we can automatically publish the HTML output from ReportGenerator.
GitHub Actions Workflow
You can check the original content here.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
name: Full Build
on:
workflow_dispatch:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x
- name: Build
run: dotnet build --configuration Release
- name: Test
run: dotnet test --configuration Release --no-build --no-restore --collect:"XPlat Code Coverage"
- name: ReportGenerator
uses: danielpalme/[email protected]
with:
reports: tests/**/coverage.cobertura.xml
targetdir: ${{ runner.temp }}/coveragereport
reporttypes: 'Html;Badges;MarkdownSummaryGithub'
assemblyfilters: -*Tests*
- name: Publish coverage report in build summary
run: cat '${{ runner.temp }}'/coveragereport/SummaryGithub.md >> $GITHUB_STEP_SUMMARY
shell: bash
- name: Create coverage-reports branch and push content
run: |
git fetch
git checkout coverage-reports || git checkout --orphan coverage-reports
git reset --hard
git clean -fd
cp -rp '${{ runner.temp }}'/coveragereport/* ./
echo "YOUR_CUSTOM_DOMAIN" > CNAME
git config user.name github-actions
git config user.email [email protected]
git add .
git commit -m "Update coverage reports [skip ci]" || echo "No changes to commit"
git push origin coverage-reports --force
shell: bash
What This Does
- Runs your tests with coverage collection enabled (
XPlat Code Coverage
). - Uses ReportGenerator to produce:
- Rich HTML reports.
- Markdown summaries published to the job’s summary page.
- Badges that you can embed in your
README.md
.
- Publishes the output to a dedicated branch (
coverage-reports
) which can be served via GitHub Pages. - Uses a custom domain (optional) if you’re using a GitHub Pages custom domain. Exclude the following line if you don’t use a custom domain
echo "YOUR_CUSTOM_DOMAIN" > CNAME
.
Add the Badge to Your README
Once the report is published to GitHub Pages, you can link to the badge generated by ReportGenerator. If you click on the badge you’re redirected to the coverage report.
1
[](https://<your-username>.github.io/<repo-name>)
Final Thoughts
This was one feature I truly missed after moving away from Azure DevOps. Thankfully, with a bit of GitHub Actions magic, I was able to recreate a similar (and fully automated) experience.
This setup has been working great across my projects. If you’re curious to see it in action, check out the QuerySpecification repository.
I hope you found this article useful. Happy coding!
Comments powered by Disqus.