Skip to main content

Setting up code coverage for your repository

Give your teams visibility into code coverage directly on pull requests, without paying for or maintaining a separate third-party coverage service.

Who can use this feature?

Repository owners, organization owners, and users with the admin role

GitHub Team or GitHub Enterprise Cloud

In this article

You can set up code coverage for your repository in two ways:

  • Automatic setup: Use the AI-powered agent to generate a workflow automatically. Choose this option if:
    • You want to get started quickly without writing YAML configuration.
    • Your project uses common test frameworks and build patterns.
    • You're comfortable iterating on an AI-generated workflow.
  • Manual setup: Configure your CI workflow yourself. Choose this option if:
    • You need precise control over the coverage process.
    • You have complex CI requirements (such as private registries or custom build steps).
    • You want to understand exactly how coverage is configured.

Automatic setup

You can use the automatic setup option to generate a working code coverage workflow without manually authoring CI configuration. An agent analyzes your repository, identifies your test framework, and opens a pull request with a coverage workflow ready for review.

Note

Automatic setup uses AI to generate the workflow file. There is no additional cost for using this feature.

Prerequisites for automatic setup

Generating a coverage workflow automatically

  1. On GitHub, navigate to the main page of the repository.

  2. Under your repository name, click Settings. If you cannot see the "Settings" tab, select the dropdown menu, then click Settings.

    Screenshot of a repository header showing the tabs. The "Settings" tab is highlighted by a dark orange outline.

  3. In the sidebar, under "Security", click Code quality to display the "Code quality" page.

  4. In the "Code coverage analysis" section, click the Setup dropdown box.

  5. In the list, select Generate workflow with AI. Wait for the agent to analyze your repository. The agent opens a draft pull request and posts a checklist of the steps it is working through.

  6. To review the pull request, click Review pull request. Review the pull request once the agent completes its work. The pull request description summarizes the changes, including any project configuration updates, workflow file changes, and coverage output settings.

  7. If the workflow runs successfully in CI and coverage uploads correctly, merge the pull request.

    If the workflow needs adjustments, see Automatic code coverage setup for guidance on the different outcomes and how to iterate.

For more information about how the agent works and what to expect, see Automatic code coverage setup.

Manual setup

Built-in code coverage lets you track how thoroughly your tests exercise your code, without adding a third-party service to your toolchain or budget. In the following procedures, you will generate a Cobertura XML coverage report from your test suite, upload it to GitHub, and view the coverage results on your pull requests.

Prerequisites for manual setup

  • Code Quality is enabled for your repository.
  • Your repository has a test suite that runs in GitHub Actions.
  • Your test framework can produce a coverage report in Cobertura XML format.

Step 1: Generate a Cobertura XML coverage report

Configure your test framework to output a coverage report in the Cobertura XML format. Code coverage works with any programming language that can produce this format.

  1. Identify the coverage tool for your language from the table below.
  2. Add the appropriate command or configuration to your CI workflow so that a Cobertura XML file is generated each time your tests run.
LanguageFramework / ToolHow to generate Cobertura XML
Pythonpytest + pytest-covpytest --cov=. --cov-report=xml
JavaJaCoCoUse the cover2cover.py script or the JaCoCo-to-Cobertura Gradle/Maven plugin
JavaScript/TypeScriptIstanbul / nycnyc report --reporter=cobertura
RubySimpleCovAdd SimpleCov::Formatter::CoberturaFormatter
Gogo test + gocover-coberturago test -coverprofile=cover.out && gocover-cobertura < cover.out > coverage.xml

Tip

If your framework isn't listed above, check its documentation for Cobertura output support. Many tools either support it directly or can convert to Cobertura XML from other formats.

Step 2: Upload the coverage report

After your tests generate a Cobertura XML report, upload it to GitHub so coverage results appear on pull requests.

  1. Open your repository's CI workflow file (for example, .github/workflows/ci.yml).

  2. Add the following step after the step that runs your tests and generates the coverage report:

    YAML
    - 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:
        file: COVERAGE-FILE-PATH.xml
        language: LANGUAGE
        label: LABEL
    
  3. Replace the following values:

    • COVERAGE-FILE-PATH.xml: The path to your Cobertura XML report (for example, coverage.xml or target/site/jacoco/cobertura.xml).
    • LANGUAGE: The primary language of the code being covered (for example, Python, Java, JavaScript).
    • LABEL: An optional label to identify this coverage report (for example, code-coverage/pytest).
  4. Commit and push the workflow change.

Full workflow example

This example runs Python tests with pytest-cov and uploads the coverage report:

YAML
name: Code Coverage

This workflow runs your test suite, generates a Cobertura XML coverage report, and uploads it to GitHub. Once this workflow is committed, coverage results appear automatically on every pull request.

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

Run on pushes to the default branch (to establish the baseline) and on pull requests (to compare against it). Code Quality compares PR branch coverage to the default branch, so both triggers are needed.

permissions:
  contents: read
  code-quality: write
jobs:
  test:
    runs-on: ubuntu-latest
    steps:

The code-quality: write permission is required to upload coverage data. No other elevated permissions are needed.

      - uses: actions/checkout@v6
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

Check out the PR head commit (not the merge commit) so coverage line numbers map correctly to the diff.

      - uses: actions/setup-python@v5
        with:
          python-version: "3.x"
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
          pip install pytest pytest-cov

Replace this step with whatever language setup your project uses (Node.js, Java, Go, etc.). The upload action works with any language that produces a Cobertura XML report.

      - name: Run tests with coverage
        run: pytest --cov=. --cov-report=xml

Adapt this step for your test framework. The key requirement is producing a Cobertura XML file. For other languages, see the framework table earlier in this article.

      - 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:
          file: coverage.xml
          language: Python
          label: code-coverage/pytest

This step replaces any third-party coverage upload (Codecov, Coveralls, etc.). After this runs, the github-code-quality[bot] bot posts a coverage summary directly on the pull request.

# This workflow runs your test suite, generates a Cobertura XML coverage report, and uploads it to GitHub. Once this workflow is committed, coverage results appear automatically on every pull request.
name: Code Coverage

# Run on pushes to the default branch (to establish the baseline) and on pull requests (to compare against it). Code Quality compares PR branch coverage to the default branch, so both triggers are needed.
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

# The `code-quality: write` permission is required to upload coverage data. No other elevated permissions are needed.
permissions:
  contents: read
  code-quality: write

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      # Check out the PR head commit (not the merge commit) so coverage line numbers map correctly to the diff.
      - uses: actions/checkout@v6
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      # Replace this step with whatever language setup your project uses (Node.js, Java, Go, etc.). The upload action works with any language that produces a Cobertura XML report.
      - uses: actions/setup-python@v5
        with:
          python-version: "3.x"

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
          pip install pytest pytest-cov

      # Adapt this step for your test framework. The key requirement is producing a Cobertura XML file. For other languages, see the framework table earlier in this article.
      - name: Run tests with coverage
        run: pytest --cov=. --cov-report=xml

      # This step replaces any third-party coverage upload (Codecov, Coveralls, etc.). After this runs, the `github-code-quality[bot]` bot posts a coverage summary directly on the pull request.
      - 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:
          file: coverage.xml
          language: Python
          label: code-coverage/pytest

Step 3: View coverage results on pull requests

  1. Open a pull request (or push to an existing one) that triggers the workflow you configured.
  2. After the workflow completes, look for a comment from github-code-quality[bot] on the pull request. The comment includes:
    • The aggregate coverage percentage for the pull request branch compared to the default branch.
    • A per-file breakdown showing which files gained or lost coverage.

Next steps