fix: stop the zone labeller from eating the PR size label - #204
Closed
qiuethan wants to merge 1 commit into
Closed
Conversation
actions/labeler writes with setLabels — PUT /issues/{n}/labels, which
REPLACES the whole label set rather than adding to it. It reads the PR's
labels, computes, and writes back, so anything added between that read and
that write is discarded. Both label workflows fire on the same event, so
they interleave.
Observed on PR #203, from the issue timeline:
23:50:36 labeled size/l
23:50:37 unlabeled size/l <- labeler's setLabels
23:50:37 labeled zone: docs, scripts, .github, root
It is a coin flip rather than a permanent failure: when labeler happens to
finish first, the size labeller's addLabels is additive and both survive.
That is also why a rerun looked like it fixed itself — by then the zone
labels existed, so labeler's read included size/l.
Both workflows now share one repo-wide concurrency group, which serialises
them. Either resulting order is correct: run after, and labeler's live read
already includes size/l; run before, and addLabels is additive.
cancel-in-progress must be false — with true the two would cancel each
other rather than queue, which is the opposite of what is needed.
Upgrading is not the fix: v6 and v7 still call setLabels. Only the
unreleased main branch switched to addLabels/removeLabels.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
zone-label.ymlandpr-size-label.ymlnow share one concurrency group, so they serialise instead of interleaving.Why
actions/labelerwrites labels withsetLabels—PUT /issues/{n}/labels, which replaces the whole label set rather than adding to it:Read, compute, write back. Both label workflows fire on the same event, so anything one adds between the other's read and write is silently discarded — a textbook lost update.
This is not hypothetical. From PR #203's issue timeline:
It's a coin flip, not a permanent failure. When labeler happens to finish first, the size labeller's
addLabelsis additive and both survive — which is also why rerunning the job looked like it fixed itself. By then the zone labels already existed, so labeler's read includedsize/l.The symptom is nasty precisely because nothing fails: both jobs report success, and the label just quietly isn't there.
The fix
Identical in both files. Concurrency group names are repo-wide, so two different workflows sharing one serialise.
Once serialised, either order is correct:
size/l, sosetLabelswrites it backaddLabelsis additivecancel-in-progress: falseis load-bearing — withtruethe two would cancel each other rather than queue, which is the opposite of what's needed. This replaces the narrowerpr-size-${{ ... }}group added in #202, which guarded size-vs-size races but not size-vs-zone.Why not just upgrade the action
I checked. v6 and v7 still call
setLabels(v7 line 133). Only the unreleasedmainswitched toaddLabels/removeLabels. A version bump fixes nothing here, and v6+ additionally requires Node 24 runners.Zone
.github·docsTwo zones: the workflows and the note describing the constraint.
How to verify
The mechanism is a race, so the honest check is behavioural — after this merges, open any PR and confirm it ends up with both a
zone: *and asize/*label. Before the fix that succeeded roughly half the time.Structurally verified here:
The group strings must match exactly — that's the entire mechanism, so a typo in one file silently restores the bug.
make labelsstill passes.Checklist
stagingand targetingstaging.make labelsclean.CODE-OWNERSHIP.mdnow warns that any future PR labeller must join this group.Anything you're unsure about
cancel-in-progress: falsemeans rapid pushes queue rather than cancel, so a busy PR may run the labellers a few times in sequence. That's the right trade for correctness — both are seconds long and idempotent — but it is a behaviour change from thetruethis had before.🤖 Generated with Claude Code