forked from heavy-duty/ceremony
fix(labels): the bootstrap keys on the BOOTSTRAP input, never the event name
The venue drill caught what no hermetic test had: with the workflow_call bridge delivering "no" perfectly, drill runs 16/17 still bootstrapped. The script gated on GITHUB_EVENT_NAME = workflow_dispatch and never read $BOOTSTRAP at all; the wrapper's only coupling was exporting the event name for yes. Correct while an operator's manual dispatch was the only dispatch there was — inert from #209 on, when the trigger job made every machine wake a workflow_dispatch event. Runs 459/523 bootstrapped for this reason, not for the input-delivery defect, which is real but was never the operative cause of the observed re-upserts. The script now gates on ${BOOTSTRAP:-no} = yes; the wrapper passes the input through untouched; the hermetic suite pins the exact regression pair (a dispatch event with no/unset creates and deletes nothing) alongside the yes path's full create+delete assertions. Refs #215
This commit is contained in:
parent
ceaf66bd13
commit
6986deede7
4 changed files with 45 additions and 15 deletions
|
|
@ -23,7 +23,8 @@ runs:
|
||||||
BOOTSTRAP: ${{ inputs.bootstrap }}
|
BOOTSTRAP: ${{ inputs.bootstrap }}
|
||||||
LABELS_CONF: ${{ github.workspace }}/.github/labels.conf
|
LABELS_CONF: ${{ github.workspace }}/.github/labels.conf
|
||||||
run: |
|
run: |
|
||||||
if [ "$BOOTSTRAP" = yes ]; then
|
# BOOTSTRAP passes through as-is: the script gates on the input. The
|
||||||
export GITHUB_EVENT_NAME=workflow_dispatch
|
# export-the-event-name hack that lived here died with ceremony#215 —
|
||||||
fi
|
# the script keyed on GITHUB_EVENT_NAME, which #209 made true for
|
||||||
|
# every machine wake, so "no" could never mean no.
|
||||||
bash "$GITHUB_ACTION_PATH/labels-reconcile.sh"
|
bash "$GITHUB_ACTION_PATH/labels-reconcile.sh"
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,9 @@ fi
|
||||||
# stale approval must never promote unreviewed code to the human.
|
# stale approval must never promote unreviewed code to the human.
|
||||||
#
|
#
|
||||||
# DRY_RUN=1 narrates every mutation instead of performing it (how this script
|
# DRY_RUN=1 narrates every mutation instead of performing it (how this script
|
||||||
# is rehearsed against the live repo). A workflow_dispatch run also bootstraps
|
# is rehearsed against the live repo). A run with BOOTSTRAP=yes also
|
||||||
# the taxonomy (label create --force) — that heal is dispatch-only; the cron
|
# bootstraps the taxonomy (label create --force) — the operator's manual
|
||||||
|
# dispatch defaults the input to yes; every machine wake passes no. The cron
|
||||||
# sweep tolerates a missing label rather than recreating it.
|
# sweep tolerates a missing label rather than recreating it.
|
||||||
#
|
#
|
||||||
# The state machine below is pure (globals in, state out) and covered by
|
# The state machine below is pure (globals in, state out) and covered by
|
||||||
|
|
@ -1021,8 +1022,15 @@ main() {
|
||||||
load_config "$LABELS_CONF"
|
load_config "$LABELS_CONF"
|
||||||
NOW="$(date +%s)"
|
NOW="$(date +%s)"
|
||||||
|
|
||||||
if [ "${GITHUB_EVENT_NAME:-}" = workflow_dispatch ]; then
|
# The bootstrap keys on the INPUT, never the event name. It used to test
|
||||||
log "workflow_dispatch: bootstrapping the taxonomy"
|
# GITHUB_EVENT_NAME = workflow_dispatch — correct while an operator's manual
|
||||||
|
# dispatch was the only dispatch there was, and wrong from #209 on, when the
|
||||||
|
# trigger job made EVERY event-woken sweep a workflow_dispatch run: the
|
||||||
|
# bootstrap=no input became inert by construction, and every board event
|
||||||
|
# re-upserted the taxonomy (ceremony#215 — runs 459/523, then venue drill
|
||||||
|
# runs 16/17, which bootstrapped on a delivered "no" and caught this).
|
||||||
|
if [ "${BOOTSTRAP:-no}" = yes ]; then
|
||||||
|
log "bootstrap=yes: bootstrapping the taxonomy"
|
||||||
bootstrap_labels
|
bootstrap_labels
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,3 +31,17 @@
|
||||||
- The same test drives the four value paths — schedule-empty, `no`, `yes`,
|
- The same test drives the four value paths — schedule-empty, `no`, `yes`,
|
||||||
invalid — through the shipped expressions into the action's real
|
invalid — through the shipped expressions into the action's real
|
||||||
validator (#215).
|
validator (#215).
|
||||||
|
|
||||||
|
- The taxonomy bootstrap keys on the `BOOTSTRAP` input, never the event name.
|
||||||
|
It tested `GITHUB_EVENT_NAME = workflow_dispatch` — correct while an
|
||||||
|
operator's manual dispatch was the only dispatch there was, inert-by-
|
||||||
|
construction from #209 on, when every machine wake became a dispatch
|
||||||
|
event (#215).
|
||||||
|
|
||||||
|
- The venue drill caught that: with the bridge delivering `no` perfectly,
|
||||||
|
drill runs 16/17 still bootstrapped, because the script never read the
|
||||||
|
input the whole chain existed to deliver (#215).
|
||||||
|
|
||||||
|
- `test/labels-reconcile.test.sh` pins the regression pair exactly: a
|
||||||
|
`workflow_dispatch` event with `BOOTSTRAP=no` (or unset) creates and
|
||||||
|
deletes nothing; only `BOOTSTRAP=yes` bootstraps (#215).
|
||||||
|
|
|
||||||
|
|
@ -1148,17 +1148,18 @@ EOF
|
||||||
chmod +x "$EXEC/stub/gh"
|
chmod +x "$EXEC/stub/gh"
|
||||||
printf 'panel=bot-a bot-b bot-c\n' >"$EXEC/labels.conf"
|
printf 'panel=bot-a bot-b bot-c\n' >"$EXEC/labels.conf"
|
||||||
|
|
||||||
exec_env() { # $1 = event name → the real script, executed under the PATH stub
|
exec_env() { # $1 = event name, $2 = BOOTSTRAP value ("" = unset)
|
||||||
: >"$EXEC/record"
|
: >"$EXEC/record"
|
||||||
env PATH="$EXEC/stub:$PATH" GH_RECORD="$EXEC/record" \
|
env PATH="$EXEC/stub:$PATH" GH_RECORD="$EXEC/record" \
|
||||||
CEREMONY_FORGE=github \
|
CEREMONY_FORGE=github \
|
||||||
REPO=owner/repo LABELS_CONF="$EXEC/labels.conf" GITHUB_EVENT_NAME="$1" \
|
REPO=owner/repo LABELS_CONF="$EXEC/labels.conf" GITHUB_EVENT_NAME="$1" \
|
||||||
|
${2:+BOOTSTRAP="$2"} \
|
||||||
bash actions/labels-reconcile/labels-reconcile.sh
|
bash actions/labels-reconcile/labels-reconcile.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
exec_rc=0
|
exec_rc=0
|
||||||
exec_out="$(exec_env workflow_dispatch 2>&1)" || exec_rc=$?
|
exec_out="$(exec_env workflow_dispatch yes 2>&1)" || exec_rc=$?
|
||||||
expect "an executed dispatch with all six absent completes green" 0 "$exec_rc"
|
expect "an executed bootstrap=yes with all six absent completes green" 0 "$exec_rc"
|
||||||
expect "...reaching the end of the sweep" \
|
expect "...reaching the end of the sweep" \
|
||||||
yes "$(grep -q 'reconciled.' <<<"$exec_out" && echo yes || echo no)"
|
yes "$(grep -q 'reconciled.' <<<"$exec_out" && echo yes || echo no)"
|
||||||
expect "...having attempted all six deletions" \
|
expect "...having attempted all six deletions" \
|
||||||
|
|
@ -1167,12 +1168,18 @@ expect "...and created the full taxonomy" \
|
||||||
"$(core_label_rows | cut -d'|' -f1)" \
|
"$(core_label_rows | cut -d'|' -f1)" \
|
||||||
"$(sed -n 's/^create //p' "$EXEC/record")"
|
"$(sed -n 's/^create //p' "$EXEC/record")"
|
||||||
|
|
||||||
# -- bootstrap is dispatch-only, deletes included: the cron and
|
# -- the bootstrap keys on the INPUT, never the event (ceremony#215): from
|
||||||
# pull_request_target paths touch no label
|
# #209 on, EVERY machine wake is a workflow_dispatch event, so an event
|
||||||
for ev in schedule pull_request_target; do
|
# gate made bootstrap=no inert — runs 459/523 and venue drill runs 16/17
|
||||||
|
# bootstrapped on a delivered "no". The regression case is exactly that
|
||||||
|
# pair: dispatch event, no.
|
||||||
|
for pair in "workflow_dispatch:no" "workflow_dispatch:" "schedule:no" "schedule:" "pull_request_target:"; do
|
||||||
|
ev="${pair%%:*}"; bs="${pair#*:}"
|
||||||
ev_rc=0
|
ev_rc=0
|
||||||
exec_env "$ev" >/dev/null 2>&1 || ev_rc=$?
|
exec_env "$ev" "$bs" >/dev/null 2>&1 || ev_rc=$?
|
||||||
expect "the $ev path completes green" 0 "$ev_rc"
|
expect "the $ev event with BOOTSTRAP='${bs:-unset}' completes green" 0 "$ev_rc"
|
||||||
|
expect "...and creates nothing" \
|
||||||
|
no "$(grep -q '^create ' "$EXEC/record" && echo yes || echo no)"
|
||||||
expect "...and deletes nothing" \
|
expect "...and deletes nothing" \
|
||||||
no "$(grep -q '^delete ' "$EXEC/record" && echo yes || echo no)"
|
no "$(grep -q '^delete ' "$EXEC/record" && echo yes || echo no)"
|
||||||
done
|
done
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue