Share a .NET coverage report
The pipeline is three steps, and only the last one produces something a human reads:
dotnet test --collect:"XPlat Code Coverage"
# → TestResults/<guid>/coverage.cobertura.xml (data, not a report)
dotnet tool install -g dotnet-reportgenerator-globaltool
reportgenerator \
-reports:"**/coverage.cobertura.xml" \
-targetdir:"coveragereport" \
-reporttypes:Html
What you get is coveragereport/ — index.html, a page per class with
the hit counts in the gutter, report.css, main.js and icons. The
drill-down is the report, and it's the first thing to die when someone
attaches index.html to a message.
Publish the directory
Drag coveragereport/ (or a zip of it) into
Comma:
index.htmlbecomes the report body.- Every per-class page and the CSS/JS upload alongside, and the relative
links between them are rewritten to the uploaded copies — so clicking
from the summary into
OrderServicestill works. - The sortable summary table keeps working: scripts run inside a sandboxed iframe with no same-origin access. See interactive HTML reports.
Nothing needs a local web server, which is the other reason these reports usually stay on the machine that generated them — see serving an HTML file locally.
From CI
reportgenerator -reports:"**/coverage.cobertura.xml" \
-targetdir:coveragereport -reporttypes:Html
curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile html coveragereport/index.html \
--arg title "Coverage — $GITHUB_SHA" '{title: $title, html: $html}')"
One report id per branch keeps one URL and appends a revision per run. The interesting question about coverage is never the number, it's the direction — and revisions answer that without buying a dashboard. See publishing from CI and the GitHub Actions or Azure DevOps walkthroughs.
If your pipeline already uses -reporttypes:HtmlInline_AzurePipelines
for the built-in tab, keep it — add the plain Html output alongside and
publish that, so the report survives the artifact retention window.
What review adds
- Anchored threads on an uncovered branch, in the source view — commenting on HTML.
- Revisions, so "coverage dropped" is a diff rather than an assertion.
- Access per report — private, team, domain-gated or link-based. See sharing & access control.
Limits
- Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files
total. A large solution can exceed 500 class pages — ReportGenerator's
-classfilters:and-assemblyfilters:keep the published report to the part actually under review. - 60 requests/minute per token.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.