Defect
scripts/check-changelog-parity.sh --check-bump reports UNDOCUMENTED BUMP for a bump whose ## [<version>] entry is present, rendered, and at column one — a false FAIL in a required merge gate.
First observed on PR #2130 (markdown-format 0.11.3 -> 0.11.4, entry at line 6 of a 43 KB changelog): failed twice in CI, passed locally on Windows.
Root cause
has_heading is a pipeline under the script's set -o pipefail:
rendered_lines - | awk -v h="$heading" '
index($0, h) == 1 { found = 1; exit }
END { exit !found }
'
The reader exits on first match. A real changelog puts the newest heading near the top of a file larger than one stdio buffer, so rendered_lines (awk) is still writing when the reader exits, takes SIGPIPE (exit 141), and pipefail reports the pipeline — and therefore has_heading — as failed. The found heading is misread as missing.
Reproduced deterministically in an ubuntu:24.04 container at the exact CI merge commit ba4b72fb: under gawk (the runner image's /usr/bin/awk) the gate exits 1 with the exact CI error and PIPESTATUS=141 0; under mawk it passes (different write buffering wins the race), which is also why the Windows-local runs passed. The suite's 55 fixtures all fit in one buffer and can never trip it — hence PASS=55 in the same failing CI job.
Fix
Scan the whole input (drop the early exit); add a large-changelog regression fixture that fails against the early-exit reader under gawk.
Defect
scripts/check-changelog-parity.sh --check-bumpreports UNDOCUMENTED BUMP for a bump whose## [<version>]entry is present, rendered, and at column one — a false FAIL in a required merge gate.First observed on PR #2130 (
markdown-format0.11.3 -> 0.11.4, entry at line 6 of a 43 KB changelog): failed twice in CI, passed locally on Windows.Root cause
has_headingis a pipeline under the script'sset -o pipefail:The reader
exits on first match. A real changelog puts the newest heading near the top of a file larger than one stdio buffer, sorendered_lines(awk) is still writing when the reader exits, takes SIGPIPE (exit 141), andpipefailreports the pipeline — and thereforehas_heading— as failed. The found heading is misread as missing.Reproduced deterministically in an
ubuntu:24.04container at the exact CI merge commitba4b72fb: under gawk (the runner image's/usr/bin/awk) the gate exits 1 with the exact CI error andPIPESTATUS=141 0; under mawk it passes (different write buffering wins the race), which is also why the Windows-local runs passed. The suite's 55 fixtures all fit in one buffer and can never trip it — hencePASS=55in the same failing CI job.Fix
Scan the whole input (drop the early
exit); add a large-changelog regression fixture that fails against the early-exit reader under gawk.