Skip to content

ci: release a prebuilt x86_64 Linux binary for every published version - #7

Merged
0xfinetuned merged 2 commits into
mainfrom
release-binaries
Oct 12, 2026
Merged

0xfinetuned merged 2 commits into
mainfrom
release-binaries

Conversation

@0xfinetuned

@0xfinetuned 0xfinetuned commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Why

Every Arch program repo installs arch-kit with cargo install arch-kit --locked, which compiles it from source on each job. In the last real deploy-stage-v2 run (arch-infrastructure run 38264455030, 89 min):

Job arch-kit install Whole job
ausd-bridge treasury-mint (×5, back to back) 254s each ~5 min each
ausd-bridge arch-deploy 214s (with SBF tools) 6.3 min
arch-lend arch-program 326s (with SBF tools) 15 min
arch-vaults arch-markets 339s (with SBF tools) 11 min

About 16 workflows across 7 repos do this, and none caches it.

What

New .github/workflows/release-binary.yml:

  1. Reads the commit crates.io packaged the version from (.cargo_vcs_info.json in the published .crate), checks it out, and checks that Cargo.toml says that version.
  2. Runs cargo build --locked --release, then a smoke test: arch-kit --version must print arch-kit <version>.
  3. Attaches arch-kit-<version>-x86_64-unknown-linux-gnu.tar.gz and its .sha256 to the GitHub release v<version>. If the release doesn't exist, it creates the release and its tag at that commit, and the release notes give the SHA-256.
  4. Assets are never replaced. An identical asset is skipped, so re-running a failed release job works. A different asset fails the run, and so does an existing tag at another commit. A checksum someone has pinned stays valid.
  5. Triggers:
    • workflow_call, from Publish Crate after cargo publish
    • workflow_dispatch, to backfill a version published earlier
    • pull_request on crate changes: build and smoke test only, no release

Platform: x86_64-unknown-linux-gnu, built on ubuntu-24.04. It needs glibc 2.39+ and OpenSSL 3, linked dynamically (readelf NEEDED: libssl.so.3, libcrypto.so.3, libgcc_s, libm, libc). A static musl build isn't possible as-is: arch_sdk pulls in reqwest with native-tls, so OpenSSL comes along. Every current consumer runs on ubuntu-24.04 or ubuntu-latest.

publish-crate.yml: new binary job (needs: publish) that calls the workflow above.

README:

  • an install snippet for the prebuilt binary, pinning its SHA-256
  • the publishing section now says the release and tag are created automatically

Verification

  • actionlint clean.
  • Build steps run locally against the real crates.io:
    • 0.1.8 resolves to 02377c4 (the current main, which 0.1.8 was published from) and the version check passes
    • the binary prints arch-kit 0.1.8, and the archive contains only arch-kit and passes sha256sum -c
    • an unpublished version fails with "not on crates.io"
    • a malformed version is rejected
  • Release job run against a stub gh:
    • new release → created, both assets attached
    • re-run with the same bytes → "already attached"
    • different bytes → fails
    • tag at another commit → fails
  • This PR's own pull_request run builds and smoke-tests the binary on ubuntu-24.04.

After merge

Run Release binary with version=0.1.8 to publish v0.1.8. Program repos can then swap cargo install arch-kit for the download and pin the SHA-256 from the release notes.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Every Arch program repo installs arch-kit with `cargo install`, which takes
about four minutes per job; a stage deploy runs it in some twenty jobs, five
of them back to back for aUSD funding alone.

`Release binary` builds arch-kit from the exact commit crates.io packaged a
version from (the crate's .cargo_vcs_info.json), smoke-tests `--version`, and
attaches `arch-kit-<version>-x86_64-unknown-linux-gnu.tar.gz` and its SHA-256
to the GitHub release `v<version>`, creating the release and tag at that
commit. The binary needs glibc 2.39+ and OpenSSL 3 (arch_sdk's reqwest uses
native-tls), i.e. ubuntu-24.04 / ubuntu-latest runners.

- Publish Crate calls it after `cargo publish`; run it by hand to backfill a
  version published earlier (0.1.8 next).
- Published assets are never replaced: an identical asset is skipped, a
  different one, or a tag at another commit, fails the run.
- Pull requests touching the crate build and smoke-test without releasing.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-12T20:11:48.264465Z 9d08cff PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d08cff81e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +174 to +175
gh release create "${tag}" -R "${REPO}" --target "${COMMIT}" \
--title "arch-kit ${VERSION}" --notes "${notes}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Validate an existing tag before creating its release

When v${VERSION} already exists without a GitHub Release, as can happen during a historical backfill, this branch skips the tag-commit check and relies on --target. However, gh release create --help states that --target controls the automatic tag creation when the matching tag does not yet exist, so an existing tag is not retargeted. The workflow can therefore attach a binary built from COMMIT to a release whose tag points to a different commit; resolve and validate the tag independently of whether the release exists.

Useful? React with 👍 / 👎.

@0xfinetuned 0xfinetuned Oct 12, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 91b002b: the tag is now checked whenever it exists, before anything is created. Existence comes from git/matching-refs with an exact-name filter, which answers [] when the tag is absent, so a failed lookup can't pass for "no tag". A tag at another commit fails the run.

Comment thread .github/workflows/release-binary.yml Outdated
Comment on lines +159 to +164
if gh release view "${tag}" -R "${REPO}" > /dev/null 2>&1; then
tag_commit="$(gh api "repos/${REPO}/commits/${tag}" --jq .sha)"
test "${tag_commit}" = "${COMMIT}" || {
echo "::error::tag ${tag} points at ${tag_commit}, but ${VERSION} was published from ${COMMIT}" >&2
exit 1
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add the checksum to existing release notes

When backfilling a version that already has a GitHub Release, this branch only validates the tag and leaves the existing notes unchanged; the checksum-bearing notes are constructed exclusively in the else branch. Such a backfill successfully uploads the assets but does not put the SHA-256 in the release notes, even though the new installation instructions tell consumers to pin the checksum from those notes. Update or append to existing notes while preserving their current content.

Useful? React with 👍 / 👎.

@0xfinetuned 0xfinetuned Oct 12, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 91b002b: once the assets are in place, a release whose notes lack SHA-256 <checksum> gets the checksum section appended, and its existing content is kept. This happens once; a re-run doesn't touch the notes again.

… checksum in old notes

Review follow-ups:
- A tag v<version> that exists without a release skipped the commit check,
  and `gh release create --target` does not move an existing tag, so a
  binary could land on a tag at another commit. The tag is now checked
  whenever it exists (git/matching-refs answers [] for an absent tag, so a
  failed lookup cannot pass for "no tag"), before anything is created.
- Backfilling into a release that already existed left its notes without
  the SHA-256 the README tells consumers to pin. Its notes now gain the
  checksum section once, keeping their content.
@0xfinetuned
0xfinetuned merged commit dc6dcc9 into main Oct 12, 2026
4 checks passed
@0xfinetuned
0xfinetuned deleted the release-binaries branch October 12, 2026 20:35
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.

1 participant