name: "PR Reports" on: # We intentionally run this workflow in the context of the target of a PR; we are careful # an intentional about how we handle the data coming from the PR. workflow_run: # zizmor: ignore[dangerous-triggers] workflows: ["CI"] types: - completed permissions: {} jobs: report: name: "Report" permissions: actions: read checks: write contents: read pull-requests: write runs-on: ubuntu-24.04 # We only run this job if the workflow run that completed was triggered by a pull request. if: github.event.workflow_run.event == 'pull_request' steps: - name: Extract PR number and create event file id: get-pr uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); // Find the workflow run that triggered this job. const workflowRun = await github.rest.actions.getWorkflowRun({ owner: context.repo.owner, repo: context.repo.repo, run_id: context.payload.workflow_run.id, }); // Extract the source commit info. const { head_branch, head_sha, head_repository } = workflowRun.data; const head_repo_owner = head_repository.owner.login; core.setOutput('head_branch', head_branch); core.setOutput('head_sha', head_sha); core.setOutput('head_repo', head_repository.full_name); // Try to find all PRs from that source. const { data: prs } = await github.rest.pulls.list({ owner: context.repo.owner, repo: context.repo.repo, state: 'open', head: `${head_repo_owner}:${head_branch}`, per_page: 20 }); // Filter PRs to find the one that targets the main branch. // NOTE: This only supports a target branch of 'main'. const filtered_prs = prs.filter(pr => pr.base.ref === 'main'); if (filtered_prs.length > 0) { const pr = filtered_prs[0]; core.setOutput('pr_number', pr.number); // Write out a mostly-stubbed event file. const eventData = { pull_request: { head: { sha: head_sha, repo: { full_name: head_repository.full_name } } } }; fs.writeFileSync('event-file.json', JSON.stringify(eventData), 'utf-8'); } else { core.setOutput('pr_number', ''); } - name: Download code coverage reports if: steps.get-pr.outputs.pr_number != '' continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: codecov-reports* merge-multiple: true github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: reports/ - name: Download performance reports if: steps.get-pr.outputs.pr_number != '' continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: perf-reports* merge-multiple: true github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: reports/ - name: Download test results if: steps.get-pr.outputs.pr_number != '' continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: test-reports* merge-multiple: true github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: reports/ - name: Show published reports continue-on-error: true if: steps.get-pr.outputs.pr_number != '' run: | ls -lR reports/ - name: "Publish test results" uses: EnricoMi/publish-unit-test-result-action@c950f6fb443cb5af20a377fd0dfaa78838901040 # v2.23.0 if: steps.get-pr.outputs.pr_number != '' continue-on-error: true with: commit: ${{ github.event.workflow_run.head_sha }} event_file: event-file.json event_name: ${{ github.event.workflow_run.event }} files: reports/test-results-*.xml - name: "Publish available .md reports to PR" uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 # v3.0.4 if: steps.get-pr.outputs.pr_number != '' with: path: reports/*.md number: ${{ steps.get-pr.outputs.pr_number }}