Skip to content

CI Summary Report (Publish) #678

CI Summary Report (Publish)

CI Summary Report (Publish) #678

# Copyright (c) 2026 The Jaeger Authors.
# SPDX-License-Identifier: Apache-2.0
# CI Summary Report (Publish): posts PR comments and check runs from the
# pre-computed ci-summary artifact produced by ci-summary-report.yml.
#
# Triggered by workflow_run on CI Orchestrator completion (success OR failure).
# pull_request workflows from forks run with read-only permissions regardless of
# what the workflow file declares, so they cannot post PR comments or check runs.
# workflow_run always executes in the base repository context and gets the
# permissions declared here — that is why posting is split into this workflow.
# The heavy computation runs inside the CI Orchestrator itself (ci-summary-report.yml),
# making gate failures immediately visible in the PR Checks table without waiting
# for this workflow's separate approval step.
#
# Design: docs/adr/004-migrating-coverage-gating-to-github-actions.md
# Security model: see .github/scripts/ci-summary-report-publish.js
name: CI Summary Report (Publish)
on:
workflow_run:
workflows: ["CI Orchestrator"]
types: [completed]
workflow_dispatch:
inputs:
run_id:
description: 'CI Orchestrator run ID to publish summary for'
required: true
pr_number:
description: 'PR number to post summary report for'
required: true
permissions:
contents: read
pull-requests: write
checks: write
actions: read
jobs:
publish:
name: Post Summary
if: |
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success' ||
github.event.workflow_run.conclusion == 'failure'
runs-on: ubuntu-latest
steps:
# Resolve the CI Orchestrator run ID and head SHA.
# PR number is read from the ci-summary artifact after download (see below).
- name: Resolve source run
id: source-run
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
RUN_ID="${{ github.event.inputs.run_id }}"
PR_NUMBER="${{ github.event.inputs.pr_number }}"
for var in RUN_ID PR_NUMBER; do
if ! [[ "${!var}" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::Invalid $var input: must be a positive integer, got: '${!var}'"
exit 1
fi
done
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
HEAD_SHA=$(gh api "repos/${{ github.repository }}/actions/runs/$RUN_ID" --jq '.head_sha')
else
RUN_ID="${{ github.event.workflow_run.id }}"
HEAD_SHA="${{ github.event.workflow_run.head_sha }}"
fi
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
echo "head_sha=$HEAD_SHA" >> $GITHUB_OUTPUT
echo "source_run_url=https://github.com/${{ github.repository }}/actions/runs/$RUN_ID" >> $GITHUB_OUTPUT
echo "summary_run_url=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_OUTPUT
# Checkout the base repo so that .github/scripts/ci-summary-report-publish.js
# is available for require() in the github-script step below.
# Do NOT checkout the PR head: this workflow must only run base-repo code.
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
# Download only the ci-summary artifact (pre-computed by ci-summary-report.yml).
- name: Download CI summary artifact
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh run download "${{ steps.source-run.outputs.run_id }}" \
--repo "${{ github.repository }}" \
--name ci-summary \
--dir .artifacts \
|| echo "::warning::ci-summary artifact not found; proceeding without summary artifact (later checks may fail)."
# For workflow_run triggers, read pr_number from ci-summary.json (written
# by ci-summary-report.yml inside the CI Orchestrator, where
# github.event.pull_request.number is accurate).
# For workflow_dispatch, pr_number is already set from the input above.
- name: Read PR number from artifact
id: pr
if: github.event_name != 'workflow_dispatch'
run: |
if [ -f .artifacts/ci-summary.json ]; then
PR_NUMBER=$(jq -r '.pr_number // empty' .artifacts/ci-summary.json 2>/dev/null || true)
if [ -n "$PR_NUMBER" ]; then
echo "Found PR #$PR_NUMBER in ci-summary.json"
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
else
echo "No PR number in ci-summary.json; PR comment will be skipped."
fi
else
echo "ci-summary.json not found; PR comment will be skipped."
fi
- name: Post PR comment and create check runs
if: steps.source-run.outputs.head_sha
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const handler = require('./.github/scripts/ci-summary-report-publish.js');
await handler({
github, core, fs: require('fs'),
inputs: {
owner: context.repo.owner,
repo: context.repo.repo,
headSha: '${{ steps.source-run.outputs.head_sha }}',
prNumber: '${{ steps.source-run.outputs.pr_number || steps.pr.outputs.pr_number }}',
ciRunUrl: '${{ steps.source-run.outputs.source_run_url }}',
publishUrl: '${{ steps.source-run.outputs.summary_run_url }}',
sourceRunId: '${{ steps.source-run.outputs.run_id }}',
},
});
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}