Skip to content

Commit ab2aee0

Browse files
committed
Bootstrap docs-comment.yml for workflow_run PR commenting
1 parent d246021 commit ab2aee0

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

.github/workflows/docs-comment.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2+
3+
# Posts a PR preview comment after the Documentation workflow completes.
4+
#
5+
# This is intentionally a separate workflow from docs.yml. The
6+
# `pull_request` event (used in docs.yml) always runs with a read-only
7+
# GITHUB_TOKEN for fork PRs, so it cannot post comments. The
8+
# `workflow_run` event runs code from the BASE branch — never from the
9+
# fork — and is granted write permissions safely. No fork code executes
10+
# here; we only read trusted metadata from the workflow_run context.
11+
#
12+
# Reference: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run
13+
14+
name: Documentation Preview Comment
15+
16+
on:
17+
workflow_run:
18+
workflows: ["Documentation"]
19+
types: [completed]
20+
21+
permissions:
22+
pull-requests: write
23+
24+
jobs:
25+
comment:
26+
name: Post preview link
27+
runs-on: ubuntu-latest
28+
# Only comment on PR builds that succeeded. Push and
29+
# workflow_dispatch builds don't have a PR to comment on.
30+
if: >
31+
github.event.workflow_run.event == 'pull_request' &&
32+
github.event.workflow_run.conclusion == 'success'
33+
34+
steps:
35+
- name: Harden the runner (Audit all outbound calls)
36+
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0
37+
with:
38+
egress-policy: audit
39+
40+
- name: Post or update PR preview comment
41+
uses: actions/github-script@v7
42+
with:
43+
script: |
44+
const MARKER = '<!-- docs-preview-comment -->'
45+
const run = context.payload.workflow_run
46+
const runUrl = run.html_url
47+
const sha = run.head_sha.slice(0, 7)
48+
const body = [
49+
MARKER,
50+
`📚 **Documentation preview** for \`${sha}\` — [workflow run](${runUrl})`,
51+
'',
52+
'To review: open the **docs-site** artifact from that run,',
53+
'extract the zip, and open `index.html` in a browser.',
54+
].join('\n')
55+
56+
// Locate the open PR that matches this workflow run's head
57+
// branch. For same-repo PRs github.event.pull_request is
58+
// available directly; for fork PRs we search by head label.
59+
const headLabel = `${run.head_repository.owner.login}:${run.head_branch}`
60+
const { data: prs } = await github.rest.pulls.list({
61+
owner: context.repo.owner,
62+
repo: context.repo.repo,
63+
head: headLabel,
64+
state: 'open',
65+
})
66+
if (prs.length === 0) {
67+
core.info(`No open PR found for head ${headLabel}; skipping comment.`)
68+
return
69+
}
70+
const issue_number = prs[0].number
71+
72+
const { data: comments } = await github.rest.issues.listComments({
73+
owner: context.repo.owner,
74+
repo: context.repo.repo,
75+
issue_number,
76+
})
77+
const existing = comments.find(c => c.body.includes(MARKER))
78+
if (existing) {
79+
await github.rest.issues.updateComment({
80+
owner: context.repo.owner,
81+
repo: context.repo.repo,
82+
comment_id: existing.id,
83+
body,
84+
})
85+
} else {
86+
await github.rest.issues.createComment({
87+
owner: context.repo.owner,
88+
repo: context.repo.repo,
89+
issue_number,
90+
body,
91+
})
92+
}

0 commit comments

Comments
 (0)