Skip to content

Fork coverage (Codecov) #198

Fork coverage (Codecov)

Fork coverage (Codecov) #198

Workflow file for this run

# Uploads coverage/test results for PRs from forks to Codecov.
#
# PRs from forks do not have access to repository secrets, so the direct
# Codecov steps in the main CI workflow are skipped for them. This workflow
# runs on `workflow_run` (i.e. in the base-repo context, WITH secrets) after
# the main CI completes, downloads ONLY the coverage data artifact that the CI
# build produced, and uploads it to Codecov. It never checks out or executes
# fork code, so there is no risk of leaking secrets to untrusted contributions.
name: Fork coverage (Codecov)
on:
workflow_run:
workflows: ["Java CI with Maven"]
types: [completed]
permissions:
contents: read
actions: read
jobs:
codecov:
# Only for PRs that originate from a fork (same-repo PRs upload directly in
# the main CI workflow, which has secrets).
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.head_repository.full_name != github.event.workflow_run.repository.full_name
runs-on: ubuntu-latest
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- name: Download coverage payload from CI run
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: codecov-payload
path: codecov-payload
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Read PR metadata
id: meta
# The payload file is produced by the untrusted fork build, so extract
# only the expected keys and validate their format before exposing them
# as step outputs (prevents $GITHUB_OUTPUT injection).
run: |
env_file=codecov-payload/pr-event.env
pr_number=$(grep -m1 '^pr_number=' "$env_file" | cut -d= -f2-)
pr_head_sha=$(grep -m1 '^pr_head_sha=' "$env_file" | cut -d= -f2-)
pr_head_ref=$(grep -m1 '^pr_head_ref=' "$env_file" | cut -d= -f2-)
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid pr_number"; exit 1; }
[[ "$pr_head_sha" =~ ^[0-9a-f]{40}$ ]] || { echo "invalid pr_head_sha"; exit 1; }
[[ "$pr_head_ref" =~ ^[A-Za-z0-9._/-]+$ ]] || { echo "invalid pr_head_ref"; exit 1; }
{
echo "pr_number=$pr_number"
echo "pr_head_sha=$pr_head_sha"
echo "pr_head_ref=$pr_head_ref"
} >> "$GITHUB_OUTPUT"
- name: Publish fork PR test execution results to Codecov
if: env.CODECOV_TOKEN != ''
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: codecov-payload/surefire/*.xml,codecov-payload/failsafe/*.xml
override_commit: ${{ steps.meta.outputs.pr_head_sha }}
override_pr: ${{ steps.meta.outputs.pr_number }}
override_branch: ${{ steps.meta.outputs.pr_head_ref }}
fail_ci_if_error: true
verbose: false
- name: Publish fork PR test coverage to Codecov
if: env.CODECOV_TOKEN != '' && github.event.workflow_run.conclusion == 'success'
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: codecov-payload/jacoco.xml,codecov-payload/jacoco-aggregate.xml
flags: processor
name: codecov-upload-fork
override_commit: ${{ steps.meta.outputs.pr_head_sha }}
override_pr: ${{ steps.meta.outputs.pr_number }}
override_branch: ${{ steps.meta.outputs.pr_head_ref }}
fail_ci_if_error: true
verbose: false