fix: review_requested wakes the labels sweep — blocker:unrequested clears when the ask lands #143
5 changed files with 70 additions and 5 deletions
8
.github/workflows/labels.yml
vendored
8
.github/workflows/labels.yml
vendored
|
|
@ -30,10 +30,16 @@ jobs:
|
|||
scope:
|
||||
# Not on labeled/unlabeled: those events change no paths, so labeler has
|
||||
# nothing new to derive — and label churn is precisely what they are.
|
||||
# review_requested/review_request_removed likewise change no paths — they
|
||||
# exist to wake reconcile (#137) — and running labeler on them widens
|
||||
# exactly the window #130 documents, where a label written during a
|
||||
# scope run is clobbered.
|
||||
if: >-
|
||||
github.event_name == 'pull_request_target' &&
|
||||
github.event.action != 'labeled' &&
|
||||
github.event.action != 'unlabeled'
|
||||
github.event.action != 'unlabeled' &&
|
||||
github.event.action != 'review_requested' &&
|
||||
github.event.action != 'review_request_removed'
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: labels-scope-${{ github.event.pull_request.number }}
|
||||
|
|
|
|||
6
.github/workflows/self-labels.yml
vendored
6
.github/workflows/self-labels.yml
vendored
|
|
@ -10,7 +10,11 @@ on:
|
|||
issues:
|
||||
types: [opened, edited, assigned, unassigned, labeled, unlabeled, closed, reopened]
|
||||
pull_request_target:
|
||||
types: [opened, reopened, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled]
|
||||
# review_requested/review_request_removed wake the sweep that clears (or
|
||||
# restores) blocker:unrequested — without them the one event that makes
|
||||
# the label false could not clear it, and a quiet repo wore the red flag
|
||||
# until the advisory cron (#137).
|
||||
types: [opened, reopened, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled, review_requested, review_request_removed]
|
||||
permissions:
|
||||
contents: read
|
||||
checks: read # mergeability/check-rollup read for PR state
|
||||
|
|
|
|||
10
changelog.d/137.md
Normal file
10
changelog.d/137.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
### Fixed
|
||||
|
||||
- `blocker:unrequested` now clears the moment the panel is asked: the labels
|
||||
caller (and the `docs/CONSUMERS.md` stub) listens on `review_requested` and
|
||||
`review_request_removed`, so the one event that falsifies the label — or
|
||||
makes it true again — wakes the reconcile sweep instead of waiting for an
|
||||
unrelated push or the advisory cron. The `scope` job skips both events:
|
||||
they change no paths, and running the labeler on them widens the #130
|
||||
clobber window. Adopting the new triggers is a stub edit riding the pin
|
||||
bump to the first tag carrying this change (#137).
|
||||
|
|
@ -284,7 +284,10 @@ on:
|
|||
schedule: [{cron: "*/15 * * * *"}] # advisory; the handoff label is the real wake
|
||||
workflow_dispatch: # bootstraps missing labels on a fresh repo
|
||||
pull_request_target:
|
||||
types: [opened, reopened, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled]
|
||||
# review_requested/review_request_removed are unreleased — not in 0.2.0;
|
||||
# add them with the pin bump to the first tag carrying ceremony#137. They
|
||||
# wake the sweep that clears blocker:unrequested when the panel is asked.
|
||||
types: [opened, reopened, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled, review_requested, review_request_removed]
|
||||
# Unreleased — not in 0.1.0; add only with the first tag carrying ceremony#32.
|
||||
issues:
|
||||
types: [opened, labeled, unlabeled, assigned, unassigned, closed]
|
||||
|
|
@ -311,8 +314,13 @@ to the first tag carrying ceremony#32; never mix refs to adopt it early.
|
|||
`pull_request_target` is intentional: fork PRs need the base repository's
|
||||
token to write labels. The reusable workflow executes no PR code. It checks
|
||||
out only the consumer's base branch and the pinned ceremony implementation.
|
||||
The #52 ruling invariants ride exactly these triggers — the caller above is
|
||||
unchanged since #18, so adopting them is a pin bump, not a stub edit.
|
||||
The #52 ruling invariants ride exactly these triggers — but the caller above
|
||||
is no longer the #18 shape, so adopting current triggers is a stub edit, not
|
||||
a bare pin bump. The pending edit is `review_requested` and
|
||||
`review_request_removed` (#137): the wake that clears `blocker:unrequested`
|
||||
the moment the panel is asked, without which a quiet repo wears that flag
|
||||
until the advisory cron. Make that edit with the pin bump to the first tag
|
||||
carrying ceremony#137 — never before it and never through mixed refs.
|
||||
|
||||
`.github/labels.conf` has one mandatory panel setting, one mandatory
|
||||
`triage-actors` setting, and then zero or more scope rows:
|
||||
|
|
|
|||
|
|
@ -65,4 +65,41 @@ check "PR author is recused from the required panel" 0 "one three" printf '%s\n'
|
|||
check "LABELS.md enumerates no repo's scope labels" 1 "0" \
|
||||
grep -c 'scope:[a-z0-9]' "$ROOT/LABELS.md"
|
||||
|
||||
# The caller's pull_request_target list and the CONSUMERS.md stub's must be
|
||||
# the same list. review_requested/review_request_removed are the wake that
|
||||
# clears blocker:unrequested — the label sat false for as long as a quiet
|
||||
# repo stayed quiet because the one event that falsifies it was never
|
||||
# listed (#137). The stub is prose, so nothing but this row keeps the two
|
||||
# lists from drifting: a type in one file only is a wake that fires at home
|
||||
# and nowhere in the fleet, or the reverse.
|
||||
pr_target_types() { # $1 = file → its pull_request_target types line, unindented
|
||||
awk '/pull_request_target:/{f=1; next} f && /types: /{sub(/^ */,""); print; exit}' "$1"
|
||||
}
|
||||
types_in_sync() { # $1 = caller, $2 = stub → 0 when both lists exist and match
|
||||
local a b
|
||||
a="$(pr_target_types "$1")" b="$(pr_target_types "$2")"
|
||||
[ -n "$a" ] && [ "$a" = "$b" ]
|
||||
}
|
||||
CALLER="$ROOT/.github/workflows/self-labels.yml"
|
||||
STUB="$ROOT/docs/CONSUMERS.md"
|
||||
check "caller and stub pull_request_target lists are identical" 0 "" \
|
||||
types_in_sync "$CALLER" "$STUB"
|
||||
# shellcheck disable=SC2016 # expansion belongs to the nested bash
|
||||
check "the caller lists both review-request wakes" 0 "" bash -c \
|
||||
'awk "/pull_request_target:/{f=1; next} f && /types: /{print; exit}" "$1" |
|
||||
grep -F review_requested | grep -qF review_request_removed' _ "$CALLER"
|
||||
# the failing cases: drop a type from either file, or reorder one list only,
|
||||
# and the identity row above goes red — exercised here on mutated copies
|
||||
mut_caller="$TMP/mut-caller.yml" mut_stub="$TMP/mut-stub.md"
|
||||
sed 's/, review_request_removed//' "$CALLER" >"$mut_caller"
|
||||
check "a type dropped from the caller goes red" 1 "" \
|
||||
types_in_sync "$mut_caller" "$STUB"
|
||||
sed 's/, review_request_removed//' "$STUB" >"$mut_stub"
|
||||
check "a type dropped from the stub goes red" 1 "" \
|
||||
types_in_sync "$CALLER" "$mut_stub"
|
||||
sed 's/review_requested, review_request_removed/review_request_removed, review_requested/' \
|
||||
"$STUB" >"$mut_stub"
|
||||
check "a reorder in one list only goes red" 1 "" \
|
||||
types_in_sync "$CALLER" "$mut_stub"
|
||||
|
||||
summary
|
||||
|
|
|
|||
Loading…
Reference in a new issue