fix: labels/scope writes additively — a label applied mid-job survives #133

Merged
claude-bot-andresmgsl merged 6 commits from build/130-labels-scope-clobber into main 2026-07-24 13:14:03 +00:00
3 changed files with 19 additions and 6 deletions
Showing only changes of commit 40029242cb - Show all commits

10
.github/labeler.yml vendored
View file

@ -1,9 +1,11 @@
# Path → scope:* mapping for the labels workflow's scope job
# (actions/labeler@v5; additive only — the reusable workflow keeps
# sync-labels off, so a hand-applied scope survives the machine). The scope
# (actions/labels-scope since #130: it reads this mapping at the BASE ref
# and its only write is an additive POST, so a label applied while the job
# runs survives the machine — its predecessor, actions/labeler@v5, PUT the
# whole set and clobbered ceremony#128's `release` mid-job). The scope
# taxonomy itself lives in .github/labels.conf; LABELS.md carries the table
# these globs implement. Scopes locate, they do not alert — a path that maps
# to nothing is fine (labeler is advisory), so these rows chase the big
# to nothing is fine (the mapping is advisory), so these rows chase the big
# surfaces, not every file.
scope:release-flow:
- changed-files:
@ -41,9 +43,11 @@ scope:labels:
- .github/labeler.yml
- .github/labels.conf
- actions/labels-reconcile/**
- actions/labels-scope/**
- LABELS.md
- test/labels.test.sh
- test/labels-reconcile.test.sh
- test/labels-scope.test.sh
scope:docs:
- changed-files:
- any-glob-to-any-file:

View file

@ -86,9 +86,9 @@ jobs:
cancel-in-progress: false
steps:
# pull_request_target is required for fork PR write permission. It is
# safe here because no PR code is ever checked out or executed: labeler
# reads paths via the API, and reconcile checks out the BASE branch only.
# Keep it that way.
# safe here because no PR code is ever checked out or executed:
# labels-scope reads the mapping and changed paths via the API, and
# reconcile checks out the BASE branch only. Keep it that way.
- uses: actions/checkout@v4
with:
repository: ${{ github.repository }}

View file

@ -98,6 +98,15 @@ EOF
check "parse: ceremony's own labeler.yml" 0 \
"scope:labels${TAB}.github/labeler.yml" parses "$ROOT/.github/labeler.yml"
# the real mapping covers this implementation's own surface (#133 round):
# a PR touching only labels-scope must still derive scope:labels, like
# the neighboring labels-reconcile rows already did
real_rows="$(parses "$ROOT/.github/labeler.yml")"
check "derive: the real mapping labels a labels-scope-only change" 0 \
"scope:labels" derive_labels "$real_rows" 'actions/labels-scope/labels-scope.sh'
check "derive: the real mapping labels this test file" 0 \
"scope:labels" derive_labels "$real_rows" 'test/labels-scope.test.sh'
# refusals: unsupported shapes fail loudly, naming the label
cat >"$TMP/allglobs.yml" <<'EOF'
scope:x: