# Uses `workflow_run` to securely add a comment to the PR that triggered CI. # # Important: For security, the `workflow_run` trigger runs the workflow from the default branch, # so any changes to this workflow must be made in the default branch to take effect. # # This workflow is neccesary because PRs opened by external forks do not have write access to # their PR, so the PR-triggered workflow can't add comments to the PR. # If this was in the CI workflow, it'd be tidier and easier to debug but unfortunately that # isn't possible due to the lower security context that the CI workflow runs in. name: CI comment on: workflow_run: workflows: ["Continuous Integration"] types: - completed jobs: summary: if: github.event.workflow_run.event == 'pull_request' runs-on: ubuntu-slim steps: # If the workflow fails before uploading summaries, no artifacts exist and this step fails. # Allow failure so the "Delete PR comment" step still runs to clean up stale comments. - name: Download summaries id: download uses: actions/download-artifact@v4 continue-on-error: true with: run-id: ${{ github.event.workflow_run.id }} pattern: summary-* path: summaries github-token: ${{ secrets.GITHUB_TOKEN }} # When the triggering workflow is running in a restricted security context, some # data is omitted from `github.event.workflow_run` (including `pull_requests`). # Therefore, we have to take some extra steps to find out the PR that triggered # the original workflow. The simplest way is to iterate through our open PRs and # find the one with the same head SHA as the triggering workflow. - name: Get PR number id: get-pr-number uses: actions/github-script@v6 with: script: | const head_sha = "${{ github.event.workflow_run.head_sha }}"; console.log("Finding PR for SHA:", head_sha); const { data: prs } = await github.rest.pulls.list({ owner: context.repo.owner, repo: context.repo.repo, state: 'open', }); const pr = prs.find(pr => pr.head.sha === head_sha); if (pr) { console.log("Found PR:", pr.number); return pr.number; } else { core.warning("PR not found for SHA (maybe removed by force push)"); } - name: Merge summaries if: steps.get-pr-number.outputs.result id: summary run: | ls -R files=$(find summaries -type f 2>/dev/null || true) if [ -z "$files" ]; then echo "No files found in dir: $dir" exit 0 fi repo_url="${{ github.server_url }}/${{ github.repository }}" run_url="$repo_url/actions/runs/${{ github.event.workflow_run.id }}" { echo "message<> $GITHUB_OUTPUT - name: Set PR comment if: steps.get-pr-number.outputs.result && steps.summary.outputs.message uses: marocchino/sticky-pull-request-comment@v2 with: number: ${{ steps.get-pr-number.outputs.result }} header: ${{ github.event.workflow_run.name }} message: ${{ steps.summary.outputs.message }} - name: Delete PR comment if: ${{ steps.get-pr-number.outputs.result && !steps.summary.outputs.message }} uses: marocchino/sticky-pull-request-comment@v2 with: number: ${{ steps.get-pr-number.outputs.result }} header: ${{ github.event.workflow_run.name }} delete: true