Skip to content

Post CI results

Post CI results #3163

name: Post CI results
# Triggered after "Build and test" completes. Runs in the context of the base
# branch (not the PR branch), which grants pull-requests: write permission.
# This is the GitHub-recommended pattern for safely posting PR comments from CI:
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run
on:
workflow_run:
workflows: ['Build and test']
types: [completed]
jobs:
post-comment:
name: Post test results to PR
runs-on: ubuntu-latest
# Only comment on PR-triggered runs, not direct branch pushes
if: github.event.workflow_run.event == 'pull_request'
permissions:
pull-requests: write
actions: read # required to download artifacts from the triggering run
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
# Resolve the PR number from the workflow_run event.
# For PRs within the same repo, pull_requests[] is populated directly.
# For fork PRs it is empty, so we fall back to searching by head branch.
- name: Get PR number
id: get-pr
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
script: |
const run = context.payload.workflow_run;
const prs = run.pull_requests;
if (prs && prs.length > 0) {
core.setOutput('pr_number', String(prs[0].number));
return;
}
// Fork PR fallback: match by owner:branch
const { data } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${run.head_repository.owner.login}:${run.head_branch}`,
});
core.setOutput('pr_number', data[0] ? String(data[0].number) : '');
- name: Download unit test JUnit artifacts
if: github.event.workflow_run.conclusion == 'failure' && steps.get-pr.outputs.pr_number != ''
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
# Matches junit-jest-group1-Linux, junit-jest-group2-Windows, etc.
# Each artifact lands in its own subdirectory; the script recurses into all of them.
pattern: junit-jest-group*
path: downloaded-junit
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Download integration test JUnit artifacts
if: github.event.workflow_run.conclusion == 'failure' && steps.get-pr.outputs.pr_number != ''
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
# Matches junit-jest-integration-Linux, junit-jest-integration-Windows
pattern: junit-jest-integration*
path: downloaded-junit
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build failure comment body
if: github.event.workflow_run.conclusion == 'failure' && steps.get-pr.outputs.pr_number != ''
shell: bash
run: |
{
echo "<!-- ci-test-failure-summary -->"
echo "> 🔗 [Workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}) · commit \`${{ github.event.workflow_run.head_sha }}\`"
echo ""
GITHUB_STEP_SUMMARY="" node scripts/summarize_jest_failures.js --dir=downloaded-junit
} > pr-comment.md
- name: Build success comment body
if: github.event.workflow_run.conclusion == 'success' && steps.get-pr.outputs.pr_number != ''
shell: bash
run: |
{
echo "<!-- ci-test-failure-summary -->"
echo "## ✅ All unit and integration tests passing"
echo ""
echo "> 🔗 [Workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}) · commit \`${{ github.event.workflow_run.head_sha }}\`"
} > pr-comment.md
- name: Find existing comment
id: find-comment
if: steps.get-pr.outputs.pr_number != ''
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3
with:
issue-number: ${{ steps.get-pr.outputs.pr_number }}
comment-author: 'github-actions[bot]'
body-includes: '<!-- ci-test-failure-summary -->'
# Post on first failure, update on subsequent runs.
# On success, only update if a prior failure comment exists — avoids
# posting a green banner on every clean PR.
- name: Post or update PR comment
if: |
steps.get-pr.outputs.pr_number != '' &&
(github.event.workflow_run.conclusion == 'failure' || steps.find-comment.outputs.comment-id != '')
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ steps.get-pr.outputs.pr_number }}
body-path: pr-comment.md
edit-mode: replace