From 1e3fb473c3e3daa8b73bb4ad3e9682d0627e763c Mon Sep 17 00:00:00 2001 From: dan-claude-bot Date: Mon, 20 Jul 2026 20:54:31 +0000 Subject: [PATCH] test: terminate the ci.yml step block at the job boundary too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The monotonic step is the LAST step of the `check` job, so stopping only at the next `- name:` ran the block into `rehearsal` and swallowed its job-level `if:`. Unanchored `grep -q 'if:'` then fired on it — reintroducing the bug the scoping was meant to fix, moved from "any step in the file" to "this step plus the head of the next job". Terminates on a new step OR a new job now, and the key is anchored so an `if:` inside a `run:` line is not mistaken for a step condition. Mutation-tested four ways: baseline green; an unrelated job gated stays green (was the failure); the monotonic step gated fails; the step renamed trips the companion found-the-block guard. Co-Authored-By: Claude Opus 4.8 --- test/release.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/release.sh b/test/release.sh index 36964c3..11c06c8 100644 --- a/test/release.sh +++ b/test/release.sh @@ -501,12 +501,19 @@ check "ci.yml: ...and STRICT, so a skip is a red run and not a green one" 0 "" \ # Scoped to the step's OWN block, deliberately. A file-wide negative would # forbid any FUTURE step in ci.yml from being pull_request-gated and would fail # citing #143 when one legitimately is — #143 constrains this step, not the file. +# Terminates on a new STEP or a new JOB. The job boundary is not optional: the +# monotonic step is the LAST step of `check`, so stopping only at the next +# `- name:` runs the block into the `rehearsal` job below and swallows its +# job-level `if:`. That reintroduces the very bug the scoping fixed — an +# unrelated edit failing while citing #143 — just moved from "any step in the +# file" to "this step plus the head of the next job". mono_step_block() { awk '/^ - name: no shipped changelog heading/ {f=1; print; next} - f && /^ - name: / {exit} + f && (/^ - / || /^ [^ ]/) {exit} f {print}' "$ROOT/.github/workflows/ci.yml" } -mono_step_gated() { mono_step_block | grep -q 'if:'; } +# Anchored: an `if:` appearing inside a `run:` line is not a step condition. +mono_step_gated() { mono_step_block | grep -q '^ if:'; } check "ci.yml: the monotonic step itself is not pull_request-gated (#143)" 1 "" mono_step_gated check "ci.yml: ...and the block was actually found (guards the awk above)" 0 "changelog-monotonic" mono_step_block check "ci.yml: ...and falls back to ref_name, so a push has a base to resolve" 0 "" \