forked from hiero-hackers/analytics
-
Notifications
You must be signed in to change notification settings - Fork 0
116 lines (106 loc) · 4.78 KB
/
Copy pathdashboard-preview-comment.yml
File metadata and controls
116 lines (106 loc) · 4.78 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
name: Dashboard Preview Comment
# Posts (and keeps updated) a PR comment linking to the dashboard-preview
# artifact built by the "Dashboard Preview" workflow.
#
# Why a separate workflow: the build runs on `pull_request` with `contents: read`
# and no PR-write token, so it cannot comment on fork PRs (a fork's token is
# read-only). This job runs on `workflow_run`, i.e. in the base-repo context with
# trusted code (never the PR's), which is the only safe way to comment on forks.
#
# NOTE: workflow_run workflows only trigger when this file exists on the default
# branch. The comment therefore starts appearing on PRs after this is merged to
# main — it will not comment on the PR that introduces it.
on:
workflow_run:
workflows: ["Dashboard Preview"]
types: [completed]
permissions:
contents: read
actions: read # read/download artifacts from the triggering run
pull-requests: write # post the preview comment
# Key by the PR's source (repo + branch), not the run id: a run-id group would be
# unique per run, making cancel-in-progress a no-op. Serializing per source PR lets
# a newer comment job cancel an older in-flight one, so two preview runs completing
# close together can't race into duplicate comments.
concurrency:
group: >-
dashboard-preview-comment-${{ github.event.workflow_run.head_repository.full_name }}-${{ github.event.workflow_run.head_branch }}
cancel-in-progress: true
jobs:
comment:
name: Comment preview link
runs-on: ubuntu-latest
# Only for PR builds, and skip cancelled runs (which upload no metadata).
if: >-
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion != 'cancelled'
steps:
- name: Download preview metadata
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: dashboard-preview-meta
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Read PR number
id: meta
run: |
number="$(tr -cd '0-9' < pr-number.txt)"
if [ -z "$number" ]; then
echo "No PR number recorded; nothing to comment on."
fi
echo "number=$number" >> "$GITHUB_OUTPUT"
- name: Post or update the preview comment
if: steps.meta.outputs.number != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const prNumber = Number('${{ steps.meta.outputs.number }}');
const run = context.payload.workflow_run;
const succeeded = run.conclusion === 'success';
// Prefer a direct link to the artifact; fall back to the run page.
const arts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: run.id,
});
const art = arts.data.artifacts.find(
(a) => a.name === `dashboard-preview-${prNumber}`,
);
const link = art ? `${run.html_url}/artifacts/${art.id}` : run.html_url;
const marker = '<!-- dashboard-preview-comment -->';
const body = [
marker,
'### 📊 Dashboard preview',
'',
succeeded
? 'The dashboard was built for this PR.'
: '⚠️ The build reported failures, but a partial dashboard may still be attached.',
'',
`➡️ **[Download \`dashboard-preview-${prNumber}\`](${link})**, unzip, and open \`dashboard.html\` in a browser.`,
'',
'> The artifact is contributor-authored HTML — glance at the diff before opening it. It expires after 7 days and is replaced on each new push.',
].join('\n');
// Paginate: on a busy PR the marker comment may sit past the first
// page, and missing it would create a duplicate instead of updating.
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
per_page: 100,
});
const existing = comments.find((c) => c.body && c.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: prNumber,
body,
});
}