Codegraph Impact Comment #238
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This workflow posts the impact analysis comment on PRs. | |
| # It is split from codegraph-impact.yml so fork PRs work: the `pull_request` | |
| # event from a fork provides a read-only GITHUB_TOKEN, which cannot post PR | |
| # comments. Running here via `workflow_run` gives us a write-scoped token | |
| # without exposing it to untrusted fork code. See GitHub's fork-safe pattern: | |
| # https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/ | |
| name: Codegraph Impact Comment | |
| on: | |
| workflow_run: | |
| workflows: ['Codegraph Impact Analysis'] | |
| types: [completed] | |
| permissions: | |
| pull-requests: write | |
| # Required by actions/download-artifact@v4 when downloading from another | |
| # workflow run (cross-run artifact API calls require actions: read). | |
| actions: read | |
| concurrency: | |
| # Prevent duplicate comments if two analysis runs complete in quick succession | |
| # for the same PR head. Keyed by the head SHA of the triggering workflow run. | |
| group: codegraph-impact-comment-${{ github.event.workflow_run.head_sha }} | |
| cancel-in-progress: true | |
| jobs: | |
| comment: | |
| runs-on: ubuntu-latest | |
| if: github.event.workflow_run.conclusion == 'success' | |
| steps: | |
| - name: Download impact artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: codegraph-impact | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Comment on PR | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const prNumber = parseInt(fs.readFileSync('pr-number.txt', 'utf-8').trim(), 10); | |
| const impact = JSON.parse(fs.readFileSync('impact.json', 'utf-8')); | |
| if (!impact.summary || (impact.summary.functionsChanged === 0 && impact.summary.callersAffected === 0)) { | |
| console.log('No impact data to report.'); | |
| return; | |
| } | |
| const body = `## Codegraph Impact Analysis\n\n` + | |
| `**${impact.summary.functionsChanged} functions changed** → ` + | |
| `**${impact.summary.callersAffected} callers affected** across ` + | |
| `**${impact.summary.filesAffected} files**\n\n` + | |
| (impact.affectedFunctions || []).slice(0, 20).map(f => | |
| `- \`${f.name}\` in \`${f.file}:${f.line}\` (${f.transitiveCallers} transitive callers)` | |
| ).join('\n'); | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| }); | |
| const existing = comments.find(c => c.body.startsWith('## Codegraph Impact Analysis')); | |
| 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: prNumber, | |
| body, | |
| }); | |
| } |