name: Sequential Navigation Soak Report on: workflow_run: workflows: [CI] types: [in_progress] concurrency: group: sequential-navigation-soak-report-${{ github.event.workflow_run.pull_requests[0].number || github.event.workflow_run.id }} cancel-in-progress: true # This trusted workflow starts with CI, then waits only for the immutable v4 # artifact. It runs from the default branch, never executes PR code, and renders # only bounded numeric fields into an Actions summary and an upserted PR comment. permissions: actions: read contents: read pull-requests: write jobs: comment: name: Publish soak report if: >- github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.pull_requests[0].head.repo.id == github.event.repository.id && github.event.workflow_run.actor.login != 'dependabot[bot]' runs-on: ubuntu-latest timeout-minutes: 120 steps: - name: Checkout trusted comment renderer uses: actions/checkout@v4 with: persist-credentials: false ref: ${{ github.event.repository.default_branch }} - name: Wait for soak evidence id: wait uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 env: ARTIFACT_NAME: sequential-navigation-soak-results with: retries: 3 script: | const waitForWorkflowArtifact = require( './.github/scripts/wait-for-workflow-artifact.cjs' ); await waitForWorkflowArtifact({ github, context, core, artifactName: process.env.ARTIFACT_NAME, }); - name: Download soak evidence if: steps.wait.outputs.artifact_available == 'true' id: evidence continue-on-error: true uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: sequential-navigation-soak-results path: sequential-navigation-soak-results github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} - name: Render trusted PR comment if: steps.wait.outputs.conclusion != 'cancelled' id: render env: PYTHONPATH: moli-benchmark RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }} CONCLUSION: ${{ steps.wait.outputs.conclusion || 'failure' }} EVIDENCE_OUTCOME: ${{ steps.evidence.outcome }} run: | if [[ "$EVIDENCE_OUTCOME" == success && -f sequential-navigation-soak-results/comparison.json ]]; then if python3 -m moli_benchmark.sequential_navigate_ci check \ --input sequential-navigation-soak-results/comparison.json; then benchmark_conclusion=success else benchmark_conclusion=failure fi python3 -m moli_benchmark.sequential_navigate_ci comment \ --input sequential-navigation-soak-results/comparison.json \ --run-url "$RUN_URL" \ --conclusion "$benchmark_conclusion" \ --output sequential-navigation-soak-comment.md echo "has_comparison=true" >> "$GITHUB_OUTPUT" else python3 -m moli_benchmark.sequential_navigate_ci infrastructure-comment \ --run-url "$RUN_URL" \ --conclusion "$CONCLUSION" \ --output sequential-navigation-soak-comment.md echo "has_comparison=false" >> "$GITHUB_OUTPUT" fi - name: Publish Actions report if: steps.wait.outputs.conclusion != 'cancelled' run: cat sequential-navigation-soak-comment.md >> "$GITHUB_STEP_SUMMARY" - name: Post PR soak comment if: steps.wait.outputs.conclusion != 'cancelled' uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 env: COMMENT_PATH: sequential-navigation-soak-comment.md COMPARISON_PATH: sequential-navigation-soak-results/comparison.json HAS_COMPARISON: ${{ steps.render.outputs.has_comparison }} with: script: | const fs = require('fs'); const run = context.payload.workflow_run; const association = run.pull_requests?.[0]; if (!association) { core.notice('No pull request is associated with this workflow run.'); return; } const pull = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, pull_number: association.number, }); if (pull.data.head.sha !== association.head.sha) { core.notice('Skipping a stale Sequential Navigation Soak result.'); return; } if (process.env.HAS_COMPARISON === 'true') { const comparison = JSON.parse(fs.readFileSync(process.env.COMPARISON_PATH, 'utf8')); const compared = await github.rest.repos.compareCommitsWithBasehead({ owner: context.repo.owner, repo: context.repo.repo, basehead: `${association.base.sha}...${association.head.sha}`, }); const expectedCommonAncestor = compared.data.merge_base_commit?.sha; if ( comparison.schema !== 'moli.sequential-navigation.comparison.v1' || comparison.expected_navigations !== 200 || comparison.head?.sha !== association.head.sha || comparison.base?.sha !== expectedCommonAncestor ) { core.setFailed( 'Sequential Navigation Soak artifact identities do not match the PR.' ); return; } } const body = fs.readFileSync(process.env.COMMENT_PATH, 'utf8'); const marker = ''; if (!body.includes(marker) || Buffer.byteLength(body, 'utf8') > 32 * 1024) { core.setFailed('Rendered soak comment is missing its marker or exceeds 32 KiB.'); return; } const comments = await github.paginate(github.rest.issues.listComments, { owner: context.repo.owner, repo: context.repo.repo, issue_number: association.number, per_page: 100, }); const existing = comments.find( (comment) => comment.user?.login === 'github-actions[bot]' && comment.body?.includes(marker) ); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: association.number, body, }); }