Skip to content

release: the signed-tag check reads the tag object before searching it - #648

Merged
apostasie merged 1 commit into
mainfrom
claudio/20261110-grep-pipe
Nov 10, 2026
Merged

apostasie merged 1 commit into
mainfrom
claudio/20261110-grep-pipe

Conversation

@closer-claudio

Copy link
Copy Markdown
Contributor

release.just's reuse of a tag on HEAD piped git cat-file tag into
grep -qE for the signature block, under pipefail. grep -q closes the
pipe at its match; a producer still writing after that is killed by
SIGPIPE, and pipefail turns its exit 141 into the pipeline's failure, so
a signed tag can read as unsigned and the release refuse it. The
signature block opens near the end of a tag object and lines follow it,
so the window exists; forkcloser/openssh's release of v10.6.1.5 was
refused by the same shape on codesign's output
(forkcloser/openssh#99). The object is captured
first and searched after, as every other grep -q in the recipes already
reads from a variable. limen's own .justfile had the one other live
producer, utmctl's status line, and takes the same form; its message now
carries the status it read.

Measured on this machine against the newest tag, 200 runs each:
the piped form failed 0 of 200 and the captured form 0 of 200 on a
499-byte tag object, which git writes at once; the window is the
producer's second write, which codesign makes and this git call rarely
does. The change makes the shape uniform rather than closes a failure
seen here.

just lint and just test green.

release.just's reuse of a tag on HEAD piped `git cat-file tag` into
`grep -qE` for the signature block, under pipefail. grep -q closes the
pipe at its match; a producer still writing after that is killed by
SIGPIPE, and pipefail turns its exit 141 into the pipeline's failure, so
a signed tag can read as unsigned and the release refuse it. The
signature block opens near the end of a tag object and lines follow it,
so the window exists; forkcloser/openssh's release of v10.6.1.5 was
refused by the same shape on codesign's output
(forkcloser/openssh#99). The object is captured
first and searched after, as every other grep -q in the recipes already
reads from a variable. limen's own .justfile had the one other live
producer, utmctl's status line, and takes the same form; its message now
carries the status it read.

Measured on this machine against the newest tag, 200 runs each:
the piped form failed 0 of 200 and the captured form 0 of 200 on a
499-byte tag object, which git writes at once; the window is the
producer's second write, which codesign makes and this git call rarely
does. The change makes the shape uniform rather than closes a failure
seen here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: closer-claudio <claudio@farcloser.world>
@closer-claudio closer-claudio added the internal Changes nothing for a consumer; left out of release notes label Nov 10, 2026
@apostasie
apostasie merged commit ab446ca into main Nov 10, 2026
14 checks passed
@apostasie
apostasie deleted the claudio/20261110-grep-pipe branch November 10, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Changes nothing for a consumer; left out of release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants