Hook
Coverage is useful only when reviewers see it at decision time. If the number lives in a separate service, a separate tab, or a CI artifact, it is easy to ignore.
On May 26, 2026, GitHub added code coverage directly to pull requests in public preview for GitHub Code Quality. The flow is straightforward: a test job generates Cobertura XML, GitHub Actions uploads it through actions/upload-code-coverage@v1, and the PR gets a summary from github-code-quality[bot].
Problem / Context
Many teams already run tests in CI, but reviewers still do not see a useful coverage signal where they make the merge decision. In the best case, there is a green test check. In the worse case, someone has to open Codecov, Coveralls, an HTML report, or a build artifact.
A green check does not answer a simple question: did the changed code get tested? A PR can pass the whole test suite and still add new logic with no coverage at all. That is where a coverage summary in the PR helps. It does not replace review, but it adds another visible signal.
GitHub does not make this automatic by magic. You need three things:
- GitHub Code Quality enabled for the repository;
- a coverage report in Cobertura XML format;
- a workflow with
code-quality: writepermission that uploads the report.
Why It Matters
Coverage in the PR reduces context switching. Reviewers are already looking at the diff, comments, checks, and statuses. If the same surface shows aggregate coverage and a per-file breakdown, the team can notice an obvious problem faster: a new file was added, logic changed, and no tests touched it.
This is especially useful for teams already living in GitHub Team or Enterprise Cloud that do not want to maintain a separate coverage service just for a basic reviewer signal. During the public preview, GitHub Code Quality is not billed separately, although the workflow still consumes GitHub Actions minutes.
But it should not be oversold. This is not a complete replacement for every quality platform. If you need deep coverage history, team-level rules, multi-repository analytics, or custom quality gates, a dedicated tool may still be needed. GitHub coverage in PRs is mainly a native signal for everyday review.
How To Do It
1. Check availability
Start with plan and permissions. GitHub describes Code Quality for GitHub Team and GitHub Enterprise Cloud. Repository owners, organization owners, and users with the admin role can enable it.
If the repository is on GitHub Enterprise Server or a plan without Code Quality, do not start with YAML. Confirm availability first, or you will end up with a nice workflow that cannot upload data anywhere.
2. Generate Cobertura XML
GitHub expects the coverage report in Cobertura XML format. The language is not the key point; the important part is that your test framework can create or convert this file.
Examples:
# Python
pytest --cov=. --cov-report=xml
# JavaScript / TypeScript with nyc
nyc report --reporter=cobertura
# Go with coverprofile and a converter
go test -coverprofile=cover.out ./...
gocover-cobertura < cover.out > coverage.xml
Do not start with the upload action. First prove locally or in CI that the file exists, has the expected path, and represents the code that was actually tested.
3. Add the upload step
A minimal GitHub Actions pattern looks like this:
name: Code Coverage
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
code-quality: write
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Install dependencies
run: npm ci
- name: Run tests with coverage
run: npm test -- --coverage
- name: Upload coverage report
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: actions/upload-code-coverage@v1
with:
report: coverage/cobertura-coverage.xml
language: JavaScript
label: code-coverage/unit
Two details are not decorative.
First, the workflow should run on both push to the default branch and pull_request. GitHub compares the PR branch with the default branch, so it needs a baseline.
Second, code-quality: write is a dedicated fine-grained permission for uploading coverage. Do not grant broader workflow access just because it is quicker.
4. Be careful with forked PRs
The example uses an if condition that skips upload for pull requests from forked repositories. That matters because an external fork should not get the same trust level as a branch inside your own repository.
Tests can still run for forked PRs, but coverage upload to GitHub Code Quality should happen only where you control the workflow source and permissions.
5. Verify the first PR
After the workflow has run on the default branch, open a test PR. When CI finishes, look for a comment from github-code-quality[bot]. It should show aggregate coverage for the PR branch compared with the default branch and a per-file breakdown.
If the comment does not appear, check these in order:
- Code Quality is actually enabled;
- Cobertura XML is produced;
- the
report:path is correct; - the workflow has
code-quality: write; - a push baseline on the default branch has already run;
- the PR is not from a fork where upload is intentionally skipped.
Anti-patterns
Do not add a hard coverage gate too early. Watch a few real PRs first and understand the noise. If you set a strict threshold immediately, the team may start playing the metric instead of improving tests.
Do not confuse coverage with test quality. A high percentage does not mean all important scenarios are checked. It only means the code ran during tests.
Do not keep two coverage upload paths without a reason. If GitHub coverage replaces a third-party basic upload, remove the duplicate so reviewers do not get conflicting comments.
Conclusion
GitHub Code Quality coverage in PRs is a good small rollout for teams that already run tests in GitHub Actions. The best first step is one repository, one test job, Cobertura XML, actions/upload-code-coverage@v1, code-quality: write, and a test PR.
If reviewers actually start using the coverage signal next to the diff, the feature is doing its job. If not, do not add another gate for the sake of having a gate. First find the signal that helps the team merge with more confidence.
Quick checklist
- Verify that GitHub Code Quality is available for the repository.
- Enable Code Quality for the repository.
- Make the test job generate Cobertura XML.
- Add `permissions: code-quality: write`.
- Run the workflow on `push` to the default branch and on `pull_request`.
- Upload coverage with `actions/upload-code-coverage@v1`.
- Avoid uploading coverage from untrusted forked PRs.
- Check for the `github-code-quality[bot]` comment in a test PR.
Prompt Pack: add coverage summaries to GitHub PRs
Help prepare a GitHub Actions rollout for pull request coverage summaries through GitHub Code Quality. Input data: - project language and test framework; - current `.github/workflows/ci.yml`; - whether a coverage report exists today; - whether the project can produce Cobertura XML; - default branch; - whether the repository accepts pull requests from forks; - GitHub plan: Team or Enterprise Cloud. Return: 1. whether the repository fits the GitHub Code Quality coverage preview; 2. a minimal YAML diff; 3. where Cobertura XML is generated; 4. which permissions are required; 5. how to handle forked PRs; 6. verification criteria after the first PR. Format: verdict, prerequisites, YAML diff, fork handling, verification checklist.