name: Comment PR Artifacts on: pull_request_target: types: - opened - synchronize - reopened - ready_for_review permissions: actions: read contents: read issues: write pull-requests: write jobs: comment: runs-on: ubuntu-latest env: ALLOWED_ACTORS: ${{ vars.ALLOWED_NON_DEV_PR_ACTORS }} ACTOR: ${{ github.actor }} BASE_REF: ${{ github.event.pull_request.base.ref }} IS_DRAFT: ${{ github.event.pull_request.draft }} PR_NUMBER: ${{ github.event.pull_request.number }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} RETENTION_DAYS: 7 steps: - name: Check PR authorization id: auth shell: bash run: | set -euo pipefail if [ "$BASE_REF" = "dev" ]; then echo "allowed=true" >> "$GITHUB_OUTPUT" exit 0 fi normalized=",${ALLOWED_ACTORS}," if [[ "$normalized" == *",${ACTOR},"* ]]; then echo "allowed=true" >> "$GITHUB_OUTPUT" else echo "allowed=false" >> "$GITHUB_OUTPUT" fi - name: Wait for PR build and comment if: ${{ steps.auth.outputs.allowed == 'true' && env.IS_DRAFT != 'true' }} uses: actions/github-script@v8 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const owner = context.repo.owner; const repo = context.repo.repo; const prNumber = Number(process.env.PR_NUMBER); const headSha = process.env.HEAD_SHA; const retentionDays = Number(process.env.RETENTION_DAYS || '7'); const marker = ''; const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); let matchedRun = null; for (let attempt = 1; attempt <= 30; attempt += 1) { const runs = await github.paginate(github.rest.actions.listWorkflowRuns, { owner, repo, workflow_id: 'pr-build.yml', event: 'pull_request', per_page: 100, }); const matchingRuns = runs .filter((run) => run.head_sha === headSha) .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); matchedRun = matchingRuns[0] || null; if (matchedRun && matchedRun.status === 'completed') { break; } core.info(`Waiting for PR Build Validation run for ${headSha} (attempt ${attempt}/30)`); await sleep(10000); } if (!matchedRun) { core.setFailed(`Could not find PR Build Validation run for ${headSha}.`); return; } if (matchedRun.status !== 'completed') { core.setFailed(`PR Build Validation run ${matchedRun.id} did not complete in time.`); return; } const artifacts = await github.paginate( github.rest.actions.listWorkflowRunArtifacts, { owner, repo, run_id: matchedRun.id, per_page: 100 } ); const active = artifacts.filter((artifact) => !artifact.expired); const runUrl = matchedRun.html_url; const artifactsBlock = active.length ? ['Artifacts:', ...active.map((artifact) => `- ${artifact.name}`)].join('\n') : 'Artifacts: (none found on this run)'; const body = [ marker, 'PR builds are available as GitHub Actions artifacts:', '', runUrl, '', `Artifacts expire in ${retentionDays} days.`, artifactsBlock, ].join('\n'); const created = await github.rest.issues.createComment({ owner, repo, issue_number: prNumber, body, }); core.info(`Created artifacts comment: ${created.data.html_url}`);