Skip to content

Commit fe2bc77

Browse files
authored
feat: post PR asset previews as DiMerP with some personality (#10858)
- Authenticate via the DiMerP GitHub App token (same pattern as dns-check/assets-updater) so comments and labels come from DiMerP[bot] instead of github-actions[bot] - Skip on forks where the app secrets don't exist - Give the comment a voice: per-PR stable quip, themed deletion/empty states and footer
1 parent 9e18783 commit fe2bc77

2 files changed

Lines changed: 30 additions & 10 deletions

File tree

.github/scripts/pr-assets.mjs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ const IMAGE_URL_RE = /https?:\/\/[^\s"'`)\]]+\.(?:png|jpe?g|gif|webp|svg|ico)(?:
1616
// GitHub caps comment bodies at 65536 characters.
1717
const MAX_COMMENT_LENGTH = 65000
1818

19+
// DiMerP's opening lines — picked by PR number so the quip stays stable
20+
// across pushes to the same PR.
21+
const QUIPS = [
22+
'Fresh pixels, hot off the CDN — I lined them all up for inspection. 👀',
23+
'I fetched these assets so you don\'t have to. My hobbies include embedding images and silently judging diffs.',
24+
'Behold, the gallery! Admission is free, but I do accept tips in the form of approvals.',
25+
'Another day, another diff. Here\'s everything shiny I could dig out of this one.',
26+
'I rummaged through the diff and found these. Finders keepers? No? Fine, they\'re yours.',
27+
'Asset inspection complete. No pixels were harmed in the making of this comment. 🤖',
28+
]
29+
1930
/**
2031
* Extract the activity folder key from a changed file path.
2132
* Example: websites/Y/YouTube/v2/presence.ts -> websites/Y/YouTube/v2
@@ -85,24 +96,25 @@ export function displayName(folder) {
8596

8697
/**
8798
* Render the sticky comment body for the collected activities.
99+
* The PR number keeps DiMerP's quip stable across pushes.
88100
*/
89-
export function buildCommentBody(activities) {
101+
export function buildCommentBody(activities, pullNumber = 0) {
90102
if (activities.length === 0)
91-
return `${COMMENT_MARKER}\nNo activity assets in this PR.`
103+
return `${COMMENT_MARKER}\nNo activity assets in this PR. I looked everywhere. Twice. 🤖`
92104

93105
const sections = activities.map((activity) => {
94106
const lines = [`### ${activity.name} (\`${activity.folder}\`) — ${activity.type}`, '']
95107

96108
if (activity.type === 'deletion') {
97-
lines.push('_Activity deleted in this PR._')
109+
lines.push('_This activity is being sent to the shadow realm. Press F to pay respects. 🪦_')
98110
return lines.join('\n')
99111
}
100112

101113
if (activity.metadataError)
102-
lines.push('_⚠️ `metadata.json` could not be loaded — logo/thumbnail previews unavailable._', '')
114+
lines.push('_⚠️ I couldn\'t load `metadata.json` — no logo/thumbnail previews, my crystal ball is in the shop._', '')
103115

104116
if (activity.assets.length === 0) {
105-
lines.push('_No asset URLs found in this change._')
117+
lines.push('_No asset URLs found in this change — not a single pixel to show off._')
106118
return lines.join('\n')
107119
}
108120

@@ -112,8 +124,9 @@ export function buildCommentBody(activities) {
112124
return lines.join('\n')
113125
})
114126

115-
const header = `${COMMENT_MARKER}\n## 🖼️ Activity asset preview\n`
116-
const footer = '\n---\n<sub>Auto-generated — updates on each push.</sub>'
127+
const quip = QUIPS[pullNumber % QUIPS.length]
128+
const header = `${COMMENT_MARKER}\n## 🖼️ Activity asset preview\n\n_${quip}_\n`
129+
const footer = '\n---\n<sub>Beep boop — I refresh this comment on every push, so no need to scroll. 🤖</sub>'
117130

118131
let omitted = 0
119132
let body = [header, ...sections].join('\n')
@@ -178,7 +191,7 @@ async function upsertComment(github, context, core, activities) {
178191
return
179192
}
180193

181-
const body = buildCommentBody(activities)
194+
const body = buildCommentBody(activities, context.payload.pull_request.number)
182195
if (existing) {
183196
await github.rest.issues.updateComment({
184197
owner: context.repo.owner,

.github/workflows/pr-assets.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ on:
66

77
permissions:
88
contents: read
9-
issues: write
10-
pull-requests: write
119

1210
concurrency:
1311
group: pr-assets-${{ github.event.pull_request.number }}
1412
cancel-in-progress: true
1513

1614
jobs:
1715
pr-assets:
16+
# The DiMerP app secrets only exist upstream — skip on forks.
17+
if: github.repository_owner == 'PreMiD'
1818
runs-on: ubuntu-latest
1919
steps:
20+
- uses: actions/create-github-app-token@v3
21+
id: generate-token
22+
with:
23+
app-id: ${{ secrets.APP_ID }}
24+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
25+
2026
# SECURITY: no `ref:` on purpose — this checks out the trusted base
2127
# branch, never fork code. All PR content is read via the GitHub API.
2228
- name: Sparse checkout PR assets script
@@ -28,6 +34,7 @@ jobs:
2834
- name: Post asset preview comment and sync labels
2935
uses: actions/github-script@v9
3036
with:
37+
github-token: ${{ steps.generate-token.outputs.token }}
3138
script: |
3239
const { pathToFileURL } = require('node:url')
3340
const script = pathToFileURL(`${process.env.GITHUB_WORKSPACE}/.github/scripts/pr-assets.mjs`)

0 commit comments

Comments
 (0)