Skip to content

Commit 2752d15

Browse files
committed
fix(label-pr-review-state): fixing behaviour on forked prs
1 parent 39351a9 commit 2752d15

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

.github/workflows/label-pr-review-state.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,29 @@ jobs:
4343
});
4444
}
4545
46+
// Only a `pull_request`/`pull_request_review` run that was itself triggered
47+
// FROM a fork gets a read-only GITHUB_TOKEN — label mutations there 403 with
48+
// "Resource not accessible by integration". `schedule` and `workflow_dispatch`
49+
// runs always execute in the base repo's context with a read/write token, even
50+
// when the PR they're reconciling happens to come from a fork, so they must NOT
51+
// be skipped or fork PRs would never get stale labels cleaned up.
52+
// See: https://docs.github.com/en/actions/concepts/security/github_token
53+
const isReadOnlyRun = Boolean(context.payload.pull_request) &&
54+
context.payload.pull_request.head?.repo?.owner?.login !== owner;
55+
56+
function isForkPR(pr) {
57+
return pr.head?.repo?.owner?.login && pr.head.repo.owner.login !== owner;
58+
}
59+
4660
// Strips stateLabels from a PR, optionally keeping one.
4761
// Also removes stale-awaiting-author when not keeping awaiting-author.
62+
// Only skipped when this run's own token is read-only (see isReadOnlyRun) —
63+
// schedule/workflow_dispatch runs reconcile fork PRs normally.
4864
async function reconcileLabels(pr, desiredLabel) {
65+
if (isReadOnlyRun && isForkPR(pr)) {
66+
core.info(`PR #${pr.number}: fork PR on a read-only run — skipping label mutation`);
67+
return;
68+
}
4969
const currentLabels = new Set(pr.labels.map(l => l.name));
5070
for (const label of stateLabels) {
5171
if (label !== desiredLabel && currentLabels.has(label)) {

0 commit comments

Comments
 (0)