Repository navigation
CI: reproducible arm64 and armv7 release binaries; publish without overwriting signatures - #9602
Merged
Merged
Conversation
nGoline
force-pushed
the
ci/arm-release-binaries
branch
from
October 6, 2026 15:07
db520a5 to
a0b9d13
Compare
RELEASEDIR is hardcoded to release/, and the zip block runs on the host before any builder container starts, so an ARM build would write into the amd64 release directory whichever builder image it used. That block also removes release/clightning-$VERSION.zip before rebuilding it from the current HEAD. For an ARM build there is nothing to rebuild it from, so the file is simply lost. Send -arm64 targets to release-arm64/ and -armv7 targets to release-armv7/, and skip the zip for them: the zip is the source archive and carries no architecture, so one copy serves every build. Targets without a suffix keep their current behaviour. Suffix arm64 builder images in cl-repro.sh so both architectures can be present at once, and so bin-Ubuntu-<dist>-arm64 resolves to the right one. amd64 images keep their existing names. Changelog-None Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every pinned .deb in repro-build.sh is _amd64, so sha256sum -c fails outright on an arm64 builder. Add tools/repro-build.arm64.sh: the same script with the same packages at the same upstream versions, built for arm64. Keeping it separate leaves the amd64 path isolated, so work on one architecture cannot disturb the other. Pass VERSION to the install step as well as the build step. The Makefile falls back to git describe, which inside the builder reports the commit that was checked out rather than the release tag, so without this --force-version names the tarball but leaves the binaries stamped with the branch version. Pick the script from the image's own architecture, so one Dockerfile still serves both. bin-Ubuntu-<dist>-arm64 already resolves to cl-repro-<dist>-arm64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cln-rpc/Makefile names the example target/$(RUST_PROFILE)/..., while plugins/Makefile lists the same file under $(RUST_TARGET_DIR) in DEFAULT_TARGETS. The two only agree when TARGET is unset: with a cross TARGET, cargo writes to target/<triple>/<profile>/, and make stops with "No rule to make target 'target/<triple>/release/examples/cln-rpc-getinfo'". Use $(RUST_TARGET_DIR) like the other Rust targets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
armv7 cannot build natively like arm64: cln-grpc's build script takes protoc from protoc-bin-vendored, which ships no armv7 binary, so the build panics there. Add tools/repro-build.armv7.sh, which cross-compiles instead. It runs in the amd64 cl-repro-<dist> image, adds armhf from ports.ubuntu.com (same release pocket, updates and security still disabled), and pins the arm-linux-gnueabihf toolchain and armhf libraries the same way the other scripts pin theirs. The Rust plugins build for armv7-unknown-linux-gnueabihf. The build runs a few armv7 programs (configure tests, tools/headerversions), so the host needs qemu-arm registered with binfmt_misc. bin-Ubuntu-<dist>-armv7 runs the amd64 image with REPRO_ARCH=armv7, and the tarball lands in release-armv7/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
build-release.sh's sign target cannot be used for the ARM tarballs: it hardcodes `cd release/` rather than honouring RELEASEDIR, and globs the zip, so running it for an ARM build would rewrite the amd64 manifest. Checksum one architecture's tarballs, from release-arm64/ or release-armv7/, into SHA256SUMS-<version>-<arch> and sign it. arm64 and armv7 keep separate manifests: arm64 builds natively and armv7 is cross-compiled, so they are reproduced and co-signed separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add arm64 and armv7 targets for every Ubuntu release to the release build. arm64 builds natively on GitHub's ubuntu-24.04-arm runners; armv7 cross-compiles on the amd64 runners, with qemu registered for the few armv7 programs the build runs. The arm64 and armv7 tarballs go into their own artifacts, are checksummed and signed per architecture with tools/sign-release-arm.sh, and are attached to the draft release with SHA256SUMS-<version>-arm64 and SHA256SUMS-<version>-armv7 and their .asc files, next to the amd64 manifest. Document how to reproduce the ARM builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release job uploaded release/* with action-gh-release, which replaces any asset of the same name. Re-running it after the release captains had added their signatures to SHA256SUMS-<version>.asc replaced that file with one carrying only the CI signature, so users verifying the release found the maintainers' signatures gone. Upload with tools/publish-release-assets.sh instead: - files the release does not have yet are uploaded; - files it already has must be identical, otherwise the job stops before touching anything (the builds disagree, and nothing should be signed); - an .asc it already has gets our signature appended, after normalising the armor so gpg reads every block; one that already carries our signature is left alone, so re-runs are harmless. The draft release is created with gh when it does not exist yet, with the same title and pre-release flag as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nGoline
force-pushed
the
ci/arm-release-binaries
branch
from
October 6, 2026 15:29
a0b9d13 to
9a663cf
Compare
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 release job now builds arm64 and armv7 tarballs for Ubuntu 22.04, 24.04 and 26.04 alongside the amd64 ones, and it no longer replaces files that are already on the GitHub release.
ARM builds
ubuntu-24.04-armrunners, usingtools/repro-build.arm64.sh(the same pinned package set as the amd64 script, built for arm64).protoc-bin-vendored, which cln-grpc's build script uses, has no armv7 binary.tools/repro-build.armv7.shcross-compiles instead, in the amd64cl-repro-<dist>image, with Ubuntu'sarm-linux-gnueabihftoolchain and armhf libraries from ports.ubuntu.com, all pinned by sha256 like the other scripts. The build runs a few armv7 programs (configure tests,tools/headerversions), so the runner registers qemu-arm first.SHA256SUMS-<version>-arm64/.ascandSHA256SUMS-<version>-armv7/.asc, next to the existing amd64SHA256SUMS-<version>. Output goes torelease-arm64/andrelease-armv7/, so the manifests never mix;tools/sign-release-arm.sh <version> arm64|armv7creates and signs them.doc/getting-started/advanced-setup/repro.mdexplains how to reproduce both.Publishing
The draft-release step used
softprops/action-gh-release, which replaces any asset with the same name. Re-running the job after the release captains had added their signatures toSHA256SUMS-<version>.ascreplaced that file with one carrying only the CI signature.tools/publish-release-assets.shreplaces it:.ascgets the CI signature appended (armor normalised so gpg reads every block), and one that already carries it is left alone, so re-runs are harmless.Also fixed
cln-rpc/Makefilenamed thecln-rpc-getinfoexample undertarget/$(RUST_PROFILE)whileDEFAULT_TARGETSlists it under$(RUST_TARGET_DIR), so any build withTARGETset (any cross build) stopped with "No rule to make target". It now uses$(RUST_TARGET_DIR).Testing
lightningd --versionreports the forced version.lightningd --versionruns inarm32v7/ubuntu:noble.cl-repro-{jammy,noble,resolute}images.tools/publish-release-assets.shexercised against a stubghwith throwaway keys: fresh release, a release with two co-signatures (ends with three), a re-run (no-op), a mismatched tarball (aborts, nothing touched), and a co-signed.ascwith a malformed armor block (repaired, all signatures verify).make check-sourcepasses.Changelog-None
Written by Claude (AI assistant) on behalf of Níckolas.
🤖 Generated with Claude Code