Skip to content

ci: read the class file version from a file, not a pipe into od -N1 (defensive) - #61

Merged
tomasr78 merged 1 commit into
mainfrom
ci/fix-sigpipe-race
Nov 9, 2026
Merged

tomasr78 merged 1 commit into
mainfrom
ci/fix-sigpipe-race

Conversation

@tomasr78

@tomasr78 tomasr78 commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Why

The Package step in build.yml reads the class file version with unzip -p … ConvertApi.class | od -An -j7 -N1 -tu1 under set -euo pipefail. od -N1 stops reading after byte 8 (yes | od -N1 returns 141), so this has the shape of the tar | grep -q check that failed at random in convertapi-library-js's main build on 2026-11-09: the reader leaves early, and if the writer is still writing, pipefail fails the step.

It cannot fail on GitHub's runners today:

  • unzip writes the 15.8 KB ConvertApi.class in one write() (strace), so od cannot exit while unzip is still writing. unzip writes 64 KB at a time.
  • With SIGPIPE ignored, as on the runner, unzip -p ignores EPIPE and exits 0 when its reader leaves early. With the default SIGPIPE disposition, as in a terminal, unzip is killed and the pipeline returns 141.

This change removes both conditions and uses the same pattern as the other SDK workflows. It is defensive: nothing fails today. It turned up while checking every SDK workflow for producers piped into early-exiting readers (grep -q, head, od -N and similar). The only other ones are in convertapi-library-js, -node and -python.

Change

The class goes to $RUNNER_TEMP/ConvertApi.class, and od reads byte 8 from that file. The error message is unchanged. A jar without the class now stops the step with unzip's caution: filename not matched instead of od's cannot skip past end of combined input.

Tested

In an Ubuntu 24.04 container (unzip 6.0, GNU od 9.4, bash 5.2) with SIGPIPE ignored, as on the runner. The step's run: script was read from build.yml and run with bash -euo pipefail against the jars built from main (./mvnw package -DskipTests, version 0.0.0-ci.1.g2cdfce7), with ./mvnw stubbed to hand over those jars:

Case main this branch
Real jar (class file version 52), 500 runs 0 failed 0 failed
Class padded to 116 KB, 500 runs 0 failed 0 failed
Class patched to version 61 exit 1, ::error::The classes are compiled for class file version 61, not 52 (Java 8) same
Jar without ConvertApi.class exit 1, od: cannot skip past end of combined input exit 11, caution: filename not matched: com/convertapi/client/ConvertApi.class

This PR's own Build runs the changed Package step.

The fix for the real race: ConvertAPI/convertapi-library-js#31 and ConvertAPI/convertapi-library-node#128. The same defensive change for Python: ConvertAPI/convertapi-library-python#65.

🤖 Generated with Claude Code

od -N1 stops reading after byte 8, so `unzip -p ... | od` under pipefail
has the shape of the tar | grep -q check that failed at random in
convertapi-library-js's build on 2026-11-09. It cannot fail on GitHub's
runners today: unzip writes the 16 KB class in one write(), and with
SIGPIPE ignored, as on the runner, unzip -p ignores EPIPE and exits 0.
With a class over 64 KB and the default SIGPIPE disposition it could, so
the check now reads a file and depends on neither.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the packaging workflow’s Java 8 compatibility-check update.

No open issues 🎉

What changed in this PR

This PR defensively updates the packaging workflow’s Java 8 compatibility check to avoid a potential broken-pipe failure when od stops reading early.

Changes:

  • Extracts ConvertApi.class to $RUNNER_TEMP before reading its class-file version.
  • Preserves the version check and mismatch error message while documenting why the intermediate file is used.
File Description
.github/​workflows/​build.yml Replaces the unzip-to-od pipe with an intermediate file for the class-version check.

Review effort: Balanced

@tomasr78
tomasr78 merged commit 7e48f07 into main Nov 9, 2026
5 checks passed
@tomasr78
tomasr78 deleted the ci/fix-sigpipe-race branch November 9, 2026 15:42
Sign up for free to 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