Update PR size check workflow (#51948)

## Context

The PR size check workflow has been failing with `403 Resource not
accessible by integration` on every run
([example](https://github.com/zed-industries/zed/actions/runs/23281894554/job/67698634490)).
The root cause is a workflow-level `permissions` block that set a
read-only ceiling, silently preventing the job-level `issues: write` and
`pull-requests: write` grants from taking effect.

This also adds an idempotency improvement: when a new push doesn't
change the PR's size bracket, the workflow now skips the label
remove/re-add cycle, eliminating unnecessary timeline noise.

## How to Review

- Focus on `.github/workflows/pr-size-check.yml` — that's the only file
changed
- Lines 17-23: workflow-level `permissions` block removed, job-level
retained
- Lines 81-112: new `alreadyCorrect` check wraps the label mutation
block

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A
This commit is contained in:
John D. Swanson 2026-03-19 12:36:00 -04:00 committed by GitHub
parent 6cbb3b9635
commit 8a467a5958
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -11,12 +11,9 @@
name: PR Size Check
on:
pull_request_target:
pull_request:
types: [opened, synchronize]
permissions:
contents: read
jobs:
check-size:
if: github.repository_owner == 'zed-industries'
@ -74,15 +71,18 @@ jobs:
}
}
// Remove existing size labels, then apply the current one
// Update size label only if the classification changed
const existingLabels = (await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
})).data.map(l => l.name);
for (const label of existingLabels) {
if (label.startsWith('size/')) {
const existingSizeLabels = existingLabels.filter(l => l.startsWith('size/'));
const alreadyCorrect = existingSizeLabels.length === 1 && existingSizeLabels[0] === sizeLabel;
if (!alreadyCorrect) {
for (const label of existingSizeLabels) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
@ -90,27 +90,27 @@ jobs:
name: label,
});
}
}
// Create the label if it doesn't exist (ignore 422 = already exists)
try {
await github.rest.issues.createLabel({
// Create the label if it doesn't exist (ignore 422 = already exists)
try {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: sizeLabel,
color: labelColor,
});
} catch (e) {
if (e.status !== 422) throw e;
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
name: sizeLabel,
color: labelColor,
issue_number: context.issue.number,
labels: [sizeLabel],
});
} catch (e) {
if (e.status !== 422) throw e;
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: [sizeLabel],
});
// For large PRs (400+ LOC): auto-apply large-pr label and comment once
if (totalChanges >= 400) {
// Auto-apply the large-pr label