Skip to content

ci: stop the clang-format report dying on SIGPIPE for large diffs - #161

Open
balbasty wants to merge 1 commit into
mainfrom
ci/fix-clang-format-sigpipe
Open

ci: stop the clang-format report dying on SIGPIPE for large diffs#161
balbasty wants to merge 1 commit into
mainfrom
ci/fix-clang-format-sigpipe

Conversation

@balbasty

Copy link
Copy Markdown
Collaborator

The informational clang-format job introduced in #156 still goes red on any PR whose diff exceeds the 64 KiB pipe buffer — which is most real PRs. #147 hit it with 12 files.

Cause

The step runs under set -euo pipefail and builds its capped step-summary diff with:

shown=$(printf '%s\n'"$out"| head -n "$max")

Once head has taken its 400 lines it closes the pipe. If $out is larger than the 64 KiB pipe buffer, printf has not finished writing, takes SIGPIPE, and the pipeline reports 141. pipefail propagates it, set -e kills the step — before the exit 0 at the end that makes this job informational.

So the job printed its findings, emitted ::notice::clang-format … this job does not fail, and then failed anyway.

Reproduced

$ bash -c 'set -euo pipefail; out=$(seq 1 5000);
shown=$(printf "%s\n" "$out" | head -n 400); echo REACHED'
REACHED → exit 0
$ bash -c 'set -euo pipefail; out=$(for i in $(seq 1 40000); do echo "+ line $i"; done);
shown=$(printf "%s\n" "$out" | head -n 400); echo REACHED'
→ exit 141

5,000 short lines is ~25 KiB and fits the pipe buffer, so it passes. That is exactly why #156's verification PR — a single added file — came back green while a real PR does not: the bug is invisible below 64 KiB.

Fix

sed -n "1,${max}p" reads all of its input rather than closing the pipe early, so printf is never signalled. Verified at 40,000 lines: exits 0 and captures exactly 400 lines.

Note

This is the same shape as the bug #156 set out to fix (#89): a set -e interaction with a pipeline whose failure path was never exercised. Worth remembering that the reporting path of a lint needs testing at realistic size, not just at all.

The other | head in this workflow — the FFMEM peak-RSS table in build-cuda — is not affected: that step has no pipefail, so head's exit status is the pipeline's and sort being signalled is harmless.


Generated by Claude Code

The informational clang-format job still went red on any PR whose diff
exceeded the 64 KiB pipe buffer. Under `set -euo pipefail`,
`printf ... | head -n 400` makes printf take SIGPIPE once head closes,
pipefail propagates 141, and set -e kills the step before its `exit 0`.
Reproduced: a 40,000-line payload exits 141; 5,000 lines (under the pipe
buffer) exits 0 -- which is why the one-file verification PR passed and
PR #147, with 12 files, did not.
This is the same shape as #89: a set -e interaction with a pipeline that
was never exercised at scale. sed reads all of its input, so it cannot
signal printf.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@balbasty@claude