Skip to content

changelog-parity gate: has_heading's early-exit reader SIGPIPEs rendered_lines under pipefail, failing correctly documented bumps #2158

Description

@kyle-sexton

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions