ci(release): build, sign and publish wallet bundles for linux/darwin × amd64/arm64 - #41
Merged
Merged
Conversation
…forms
The catalogue ships io.pilot.wallet as a single darwin/arm64 Mach-O: the
top-level bundle_url of the wallet-v0.3.3 release on pilotprotocol, built
by hand with CGO. As a result:
- pilotctl before v1.13.10 installs it on every platform, and it cannot
exec on linux/amd64, linux/arm64 or Intel Macs ("exec format error",
"Bad CPU type in executable").
- v1.13.10 refuses it with platform_mismatch.
This repo has no release pipeline.
release.yml runs on a v* tag (or workflow_dispatch with a tag). It:
1. Runs the tests.
2. Builds CGO_ENABLED=0 binaries natively on ubuntu-latest,
ubuntu-24.04-arm, macos-15-intel and macos-15, and asserts `file` output
and `wallet -version` == tag.
3. Pins the sha256 into manifest.json and signs it with
`pilotctl appstore sign`, using the PILOT_APP_PUBLISHER_KEY secret.
Publisher must equal the catalogue pin ed25519:VF8f…/os=. pilotctl is
built from the pinned tag v1.13.10, not from main, because this step
holds the private key.
4. Packs io.pilot.wallet-<ver>-<os>-<arch>.tar.gz with
scripts/pack-bundle.py. The packing is deterministic (0:0, fixed mtime,
no AppleDouble/xattr entries from macOS tar).
5. Publishes the four bundles with checksums.txt and build provenance.
The workflow is based on the WIP commit eb261f2, with three changes: the
pilotctl ref is pinned, packing is deterministic, and it has a README
section.
Checked locally:
- actionlint passes.
- The build job's steps, run against pilotctl v1.13.10 with a throwaway
key, produce a bundle whose signature, publisher pin, binary sha256 and
Mach-O arm64 format all verify.
Before the first release, a maintainer must add the PILOT_APP_PUBLISHER_KEY
secret. `gh secret list -R pilot-protocol/wallet` is empty today.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
Problem
The catalogue's
io.pilot.wallet0.3.3 entry has a single top-levelbundle_url:wallet-v0.3.3on pilot-protocol/pilotprotocol. It contains a darwin/arm64 Mach-O built by hand on a Mac (CGO_ENABLED=1, go1.25.3) and has nobundlesmap.debian:bookworm-slim):exec /b/bin/wallet: exec format errorarch -x86_64):Bad CPU type in executableThis repo has no releases, no Actions secrets and no release workflow.
Change
.github/workflows/release.ymlruns on av*tag, or onworkflow_dispatchwith an existing tag:go test -race ./...CGO_ENABLED=0 go build -trimpath -ldflags='-s -w'onubuntu-latest,ubuntu-24.04-arm,macos-15-intelandmacos-15. Each job asserts thefileoutput for its target and requireswallet -versionto equal the tag.manifest.jsonand signs it withpilotctl appstore sign, using thePILOT_APP_PUBLISHER_KEYsecret. It asserts that the publisher is the catalogue pined25519:VF8fdEP/Oe2aWN3ozQ7Ar22137tHb7dkSw0hlzlk/os=.main, because this step holds the private key.io.pilot.wallet-<ver>-<os>-<arch>.tar.gzwith the newscripts/pack-bundle.py:manifest.json+bin/wallet, the same entries as the 0.3.3 bundle..sha256files,checksums.txtand build provenance (actions/attest-build-provenance@v3).The workflow is based on the unpushed WIP commit
eb261f2, with three changes: the pilotctl ref is pinned, packing is deterministic, and the README has a Release section.Verified locally
actionlintpasses.fileand-version.pack-bundle.py.sha256_ok,signature_ok,publisher_pin_ok, Mach-O arm64, native.CGO_ENABLED=0, pure-Go sqlite) give Mach-O arm64, Mach-O x86_64, ELF x86-64 and ELF aarch64.go-version: '1.25'picks the latest 1.25 patch.Before the first release (maintainer)
PILOT_APP_PUBLISHER_KEY(the private key fored25519:VF8f…/os=).gh secret list -R pilot-protocol/walletis empty today.v0.4.0:cmd/walletVersionandmanifest.jsonapp_versionare both 0.4.0).bundlesentry for each platform.catalogue/stateful-apps.json.catalogue-lintblocks wallet updates until the fleet runs a pilotctl with the app-state fix, v1.13.10.catalogue.json.🤖 Generated with Claude Code