-
-
Notifications
You must be signed in to change notification settings - Fork 119
Expand file tree
/
Copy pathcoverage-parse-diff-comment.yml
More file actions
118 lines (107 loc) · 4.89 KB
/
Copy pathcoverage-parse-diff-comment.yml
File metadata and controls
118 lines (107 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
name: Coverage parse-diff comment
# Posts the parse-detail diff (built by ci.yml's "Parse-detail diff" step) as a
# single sticky PR comment, for the reviewing LLM.
#
# Why workflow_run and not a step in ci.yml: the diff is computed in the
# untrusted `pull_request` context (fork code, read-only token). Commenting
# needs `pull-requests: write`, which fork PRs don't get. workflow_run runs in
# the BASE repo's trusted context AFTER ci.yml finishes, and — critically — does
# NOT check out PR code; it only consumes the uploaded artifact as data. This is
# the safe half of the fork-comment pattern (the dangerous variant is
# pull_request_target-with-checkout, which we deliberately avoid).
#
# The artifact (card names + Oracle fragments) is fork-controlled, so it is
# treated as untrusted: its contents are read into a JS string and passed as the
# octokit `body` param (JSON-encoded) — never concatenated into a shell/exec.
on:
workflow_run:
workflows: ["CI"]
types: [completed]
# A new push to the same branch cancels an in-flight comment job so a slower
# older run can't land its (stale) comment after a newer one.
concurrency:
group: parse-diff-comment-${{ github.event.workflow_run.head_repository.full_name }}-${{ github.event.workflow_run.head_branch }}
cancel-in-progress: true
permissions:
contents: read
actions: read # download the artifact from the triggering run
pull-requests: write # upsert the sticky comment
jobs:
comment:
name: Sticky parse-diff comment
runs-on: ubuntu-latest
timeout-minutes: 5
# Only PR-triggered CI runs produce the artifact. Skipping non-PR runs keeps
# this job off main/merge_group entirely.
if: github.event.workflow_run.event == 'pull_request'
steps:
- name: Download parse-diff artifact
id: dl
uses: actions/download-artifact@v4
# Absent artifact = the PR didn't change engine source (compute step
# skipped its upload). Nothing to comment; degrade silently.
continue-on-error: true
with:
name: parse-diff
path: parse-diff-artifact
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upsert sticky comment
if: steps.dl.outcome == 'success'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const MARKER = '<!-- coverage-parse-diff -->';
const dir = 'parse-diff-artifact';
// pr-number.txt is authoritative (workflow_run.pull_requests is
// unreliable for forks). Absent => nothing to do.
let prNumber;
try {
prNumber = parseInt(fs.readFileSync(`${dir}/pr-number.txt`, 'utf8').trim(), 10);
} catch {
core.info('No pr-number.txt in artifact; nothing to comment.');
return;
}
if (!Number.isInteger(prNumber)) {
core.info('pr-number.txt malformed; skipping.');
return;
}
let body;
try {
body = fs.readFileSync(`${dir}/parse-diff.md`, 'utf8');
} catch {
core.info('No parse-diff.md in artifact; nothing to comment.');
return;
}
if (!body.includes(MARKER)) {
core.info('parse-diff.md missing marker; refusing to post.');
return;
}
// Bound to GitHub's 65536-char comment limit (untrusted content can
// be large in pathological diffs).
const LIMIT = 60000;
if (body.length > LIMIT) {
body = body.slice(0, LIMIT) + '\n\n_…truncated — see the `parse-diff.json` run artifact for the full diff._\n';
}
const { owner, repo } = context.repo;
const comments = await github.paginate(github.rest.issues.listComments, {
owner, repo, issue_number: prNumber, per_page: 100,
});
const existing = comments.find(c => c.body && c.body.includes(MARKER));
if (existing) {
// EDIT in place — GitHub does not notify on edits, so re-pushes
// are silent. Never delete-and-recreate (that would notify).
await github.rest.issues.updateComment({
owner, repo, comment_id: existing.id, body,
});
core.info(`Updated sticky comment ${existing.id} on PR #${prNumber}.`);
} else {
// A no-change parse diff is still required review evidence for
// parser PRs. If we suppress the first sticky, local review tools
// can only report "absent" even though the CI artifact exists.
await github.rest.issues.createComment({
owner, repo, issue_number: prNumber, body,
});
core.info(`Created sticky comment on PR #${prNumber}.`);
}