Joshua Hale 5d8f3aaf7e Merge pull request #1 from code-quality-org/skip-merge-queue
Skip coverage upload for merge queue runs
2026-04-01 15:09:47 +01:00

Upload Code Coverage Action

Note: This repo (code-quality-org/upload-code-coverage-action) is a temporary home while the action is being developed. It will move to github/upload-code-coverage-action once it's ready for general use.

Upload a Cobertura XML coverage report to GitHub's code coverage API.

Usage

- uses: code-quality-org/upload-code-coverage-action@main
  with:
    file: cobertura.xml
    language: Java
    label: code-coverage/jacoco

The action handles everything else automatically: gzip/base64 encoding, resolving the correct commit SHA and ref, detecting PR number (from both pull_request and push events), and calling the upload API.

Inputs

Input Required Description
file Yes Path to the Cobertura XML coverage report
language Yes Linguist language name (e.g. Java, Go, Python)
label Yes Label for the report (e.g. code-coverage/jacoco)
token No GitHub token (defaults to github.token)

Permissions

The calling workflow or job must grant security-events: write. The action cannot declare this itself.

permissions:
  contents: read
  # Required for coverage upload. Will be reduced to code-quality:write
  # once that permission scope is available (github/code-scanning#22168).
  security-events: write

For push-only workflows where the action looks up PR numbers via gh pr list, also add pull-requests: read.

Event handling

The action auto-detects the event type and resolves the correct values:

  • pull_request / pull_request_target: Uses the PR head SHA and ref (not the merge commit), and includes the PR number.
  • push: Uses github.sha and github.ref, and looks up whether the branch has an open PR via gh pr list.

This means it works with both patterns — workflows triggered by pull_request and push-only workflows that serve PRs via branch pushes.

Full example (separate upload job)

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      # ... build and generate cobertura.xml ...

      - uses: actions/upload-artifact@v4
        if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
        with:
          name: cobertura-report
          path: cobertura.xml

  upload-coverage:
    needs: build
    if: ${{ !cancelled() && needs.build.result == 'success' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: cobertura-report

      - uses: code-quality-org/upload-code-coverage-action@main
        with:
          file: cobertura.xml
          language: Java
          label: code-coverage/jacoco

Prerequisites

The repository must have the following feature flags enabled:

  • code_coverage_upload_api (org-level)
  • code_coverage_processing (repo-level)

Caveats

  • Fork PRs are not supported. Pull requests from forks don't have write access to the base repository, so the action cannot upload coverage. When a fork PR is detected, the action exits gracefully with a notice — it won't fail your CI.
  • Merge queue runs are skipped. Coverage should be uploaded for PRs and the default branch, making merge queue uploads unnecessary. The action logs a warning and exits successfully.