fix(jpeg): unbreak the arm64 build; add a publish-nothing Docker dry run - #613
Merged
Conversation
The Docker layer cache and the image build were only ever exercised by a real release, which is the worst place to find out the cache backend is misconfigured -- and the WarpBuild proxy settings this repo now uses (127.0.0.1:49160 plus the network=host buildx driver-opt) had never executed at all. workflow_dispatch now builds both architectures exactly as a release does, and publishes nothing: push=false on the build output, and the Docker Hub login, smoke test, digest export/upload and the whole manifest-list job are skipped. The ancestry gate is short-circuited for dispatch on purpose rather than by accident -- it exists to keep an unreviewed commit off Docker Hub, and a run that cannot push has nothing to gate. Everything above the outputs line is identical between a dry run and a release, so the dry run measures the real build and populates the real cache. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
perl_sprintf_g declared its snprintf buffer as [0_i8; 32]. c_char is
signed on x86_64 but UNSIGNED on aarch64, so passing *mut i8 where the
target expects *mut u8 is a hard type error: this never compiled for
aarch64-unknown-linux-musl.
error[E0308]: mismatched types
--> src/core/jpeg_helpers.rs:1725:33
| expected `*mut u8`, found `*mut i8`
Every arm64 Docker image build failed on it, and release.yml builds the
same target. It went unnoticed because arm64 is built only by those two
workflows, both of which run solely on a version tag -- so the failure
would first appear during a release.
Found by the Docker dry run added in the previous commit, which is the
only way to exercise an arm64 build without cutting a release.
The `as u8` on the read side is left as is: it is a no-op where c_char
is unsigned and a reinterpret where it is signed, and both are correct
for the ASCII that %g emits.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
perl_sprintf_gdeclared itssnprintfbuffer as[0_i8; 32].c_charissigned on x86_64 but unsigned on aarch64-linux, so this never compiled for
aarch64-unknown-linux-musl:Every arm64 Docker image build failed on it, and
release.ymlbuilds thesame target. It survived because arm64 is built only by those two workflows,
both of which run solely on a version tag — so it would first surface during a
release.
It also can't be caught on an arm64 Mac: signedness follows the platform ABI,
not the CPU.
aarch64-apple-darwinis signed (verified locally),aarch64-unknown-linux-muslis unsigned. Same chip, opposite sign.Fixed by using
libc::c_charinstead of hardcoding either side.The dry run that found it
docker.ymltriggered only onv*tags, so the layer cache and the image buildwere exercised only by a real release — a bad place to discover a broken
build or a misconfigured cache backend. The WarpBuild proxy settings this repo
now uses had never executed at all.
workflow_dispatchnow builds both architectures exactly as a release does andpublishes nothing:
push=false, and the Docker Hub login, smoke test, digestexport/upload and the entire manifest-list job are skipped. The ancestry gate is
short-circuited for dispatch deliberately — it exists to keep unreviewed commits
off Docker Hub, and a run that cannot push has nothing to gate.
Measured
The WarpBuild layer cache works (
importing cache manifest from gha:…):Where the build time actually goes, measured, since it rules out the obvious
"cache dependencies in their own layer" tweak:
RUN cargo buildoxidex-tags-*oxidexitselfA dependency-layer split would save ~12s — the build is dominated by compiling
oxidexunder[profile.release]'slto = true+codegen-units = 1. That isthe shipped binary, so it is not changed here.
.dockerignorealready excludesdocs/,tests/and.github/so doc-only commits don't bust the layer.🤖 Generated with Claude Code