Skip to content

Commit 58a5cf1

Browse files
authored
ci: keep build timing report non-blocking when PR comment fails (#592)
Grant the Build Timing Report job the permissions it uses: `actions: read`, `contents: read`, and `pull-requests: write`. Scope them to the `report` job and remove the redundant `issues` permission. Keep expected PR comment API failures (HTTP 403, 404, 410, 422, and 429) non-blocking while recording the status and message and preserving the rendered report in the job summary. Unexpected JavaScript errors and unexpected HTTP statuses still fail. Consolidates the permission fix from #632.
1 parent a786012 commit 58a5cf1

1 file changed

Lines changed: 55 additions & 22 deletions

File tree

.github/workflows/build-timing-report.yml

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,16 @@ concurrency:
99
group: ${{ github.workflow }}-${{ github.event.workflow_run.id }}
1010
cancel-in-progress: false
1111

12-
permissions:
13-
actions: read
14-
contents: read
15-
issues: write
16-
pull-requests: read
17-
1812
jobs:
1913
report:
2014
if: >-
2115
github.event.workflow_run.event == 'pull_request' &&
2216
github.event.workflow_run.conclusion == 'success'
2317
runs-on: ubuntu-latest
18+
permissions:
19+
actions: read
20+
contents: read
21+
pull-requests: write
2422
steps:
2523
- name: Locate pull request and timing artifact
2624
id: timing-context
@@ -247,26 +245,61 @@ jobs:
247245
const body = fs.readFileSync(process.env.BUILD_TIMING_COMMENT, 'utf8');
248246
const { owner, repo } = context.repo;
249247
const issue_number = Number('${{ steps.timing-context.outputs.pr-number }}');
250-
const comments = await github.paginate(
251-
github.rest.issues.listComments,
252-
{ owner, repo, issue_number, per_page: 100 }
253-
);
248+
249+
const expectedCommentApiStatuses = new Set([403, 404, 410, 422, 429]);
250+
const warnExpectedCommentApiFailure = (operation, error) => {
251+
if (!Number.isInteger(error.status) ||
252+
!expectedCommentApiStatuses.has(error.status)) {
253+
throw error;
254+
}
255+
256+
const apiMessage = error.response?.data?.message || error.message || 'unknown error';
257+
const permissionHint = error.status === 403
258+
? ' Check that the report job has `pull-requests: write` and that ' +
259+
'repository or organization Actions settings permit requested workflow permissions.'
260+
: '';
261+
core.warning(
262+
`Could not ${operation} the build timing PR comment ` +
263+
`(HTTP ${error.status}: ${apiMessage}).${permissionHint} ` +
264+
'The report is still available in the job summary above.'
265+
);
266+
};
267+
268+
let comments;
269+
try {
270+
comments = await github.paginate(
271+
github.rest.issues.listComments,
272+
{ owner, repo, issue_number, per_page: 100 }
273+
);
274+
} catch (error) {
275+
warnExpectedCommentApiFailure('list existing comments for', error);
276+
return;
277+
}
278+
254279
const existing = comments.find(comment =>
255280
comment.user?.type === 'Bot' && comment.body?.includes(marker)
256281
);
257282
258283
if (existing) {
259-
await github.rest.issues.updateComment({
260-
owner,
261-
repo,
262-
comment_id: existing.id,
263-
body,
264-
});
284+
try {
285+
await github.rest.issues.updateComment({
286+
owner,
287+
repo,
288+
comment_id: existing.id,
289+
body,
290+
});
291+
} catch (error) {
292+
warnExpectedCommentApiFailure('update', error);
293+
}
265294
} else {
266-
await github.rest.issues.createComment({
267-
owner,
268-
repo,
269-
issue_number,
270-
body,
271-
});
295+
try {
296+
await github.rest.issues.createComment({
297+
owner,
298+
repo,
299+
issue_number,
300+
body,
301+
});
302+
} catch (error) {
303+
warnExpectedCommentApiFailure('create', error);
304+
}
272305
}

0 commit comments

Comments
 (0)