Skip to content

Add release.yml — wohl-hub binaries with SBOM, sums, sig, attestation#22

Merged
avrabe merged 1 commit into
mainfrom
add/release-workflow
May 24, 2026
Merged

Add release.yml — wohl-hub binaries with SBOM, sums, sig, attestation#22
avrabe merged 1 commit into
mainfrom
add/release-workflow

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 24, 2026

Summary

First release pipeline for wohl. Adopts the pulseengine release-standardization brief (synth pattern as reference). No release has been cut yet — this PR adds the machinery; the first git tag v0.1.0 && git push --tags exercises it end-to-end.

Adopted from the brief

Asset Source
wohl-hub-vX.Y.Z-<triple>.tar.gz cargo build --release -p wohl-hub per target
wohl-hub-X.Y.Z.cdx.json cargo cyclonedx --manifest-path crates/wohl-hub/Cargo.toml --format json --spec-version 1.5
SHA256SUMS.txt sha256sum ./* over the directory after SBOM is generated
SHA256SUMS.txt.sig / .pem / .cosign.bundle keyless OIDC cosign sign-blob (cosign v2.4.1)
build-env.txt rustc / cargo / cosign / runner versions
SLSA v1 provenance actions/attest-build-provenance@v2, subject-path: release-assets/*.tar.gz

Permissions on the create-release job: contents: write, id-token: write, attestations: write (per the brief).

Targets

  • x86_64-unknown-linux-gnu — MiniPC / generic Linux hub
  • aarch64-unknown-linux-gnuRaspberry Pi 4/5 (primary deployment per spar/wohl_nodes.aadl)
  • x86_64-apple-darwin, aarch64-apple-darwin — dev convenience

aarch64-linux uses the native ubuntu-24.04-arm runner instead of cross-rs. wohl-hub has path = "../relay/..." sibling deps and cross's docker container doesn't mount the parent dir — a native runner sidesteps that friction.

relay sibling

Same RELAY_REF SHA as ci.yml (kept in lock-step; bump together), with fetch-depth: 0 so relay force-pushes don't break release builds (lesson from #21).

Verification one-liner — paste into release notes

cosign verify-blob \
  --certificate-identity-regexp 'https://github.com/pulseengine/wohl/.github/workflows/release.yml@.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  --bundle SHA256SUMS.txt.cosign.bundle \
  SHA256SUMS.txt
gh attestation verify wohl-hub-vX.Y.Z-<triple>.tar.gz --repo pulseengine/wohl

Notes

  • Triggers on push: tags: ['v*'] and workflow_dispatch (manual re-run for partially-failed releases).
  • Concurrency group is per-tag, cancel-in-progress: false — never cancels mid-publish.
  • Idempotent: re-runs upload with --clobber instead of failing.
  • This PR merging does not fire the release workflow (tag trigger only). First exercise is when you cut v0.1.0.

🤖 Generated with Claude Code

First release pipeline for wohl. Adapts pulseengine/synth's
release.yml (the cross-repo reference per the release-standardization
brief), tailored for wohl-hub's specifics:

Targets
  - x86_64-unknown-linux-gnu    (MiniPC / generic Linux hub)
  - aarch64-unknown-linux-gnu   (Raspberry Pi 4/5; primary deployment
                                 per spar/wohl_nodes.aadl)
  - x86_64-apple-darwin         (dev convenience)
  - aarch64-apple-darwin        (dev convenience)

aarch64-linux uses the native `ubuntu-24.04-arm` runner instead of
cross-rs — cross's docker container doesn't mount the parent dir,
which would break wohl-hub's `path = "../relay/..."` sibling-path
workspace deps; a native runner sidesteps that friction.

relay sibling checked out with fetch-depth: 0 at the pinned
RELAY_REF (kept in lock-step with ci.yml).

Required release assets (matches the standardization brief exactly):
    wohl-hub-vX.Y.Z-<triple>.tar.gz   binary archives (x 4 targets)
    wohl-hub-X.Y.Z.cdx.json           CycloneDX SBOM (CDX 1.5)
    SHA256SUMS.txt                    sha256sum over every asset
    SHA256SUMS.txt.sig                cosign detached signature
    SHA256SUMS.txt.pem                Fulcio certificate
    SHA256SUMS.txt.cosign.bundle      cosign verifier bundle
    build-env.txt                     rustc/cargo/cosign/runner

SBOM is generated *before* SHA256SUMS so its digest is in the
manifest; the cosign signature over SHA256SUMS.txt transitively
covers the SBOM.

Provenance + signing
  - actions/attest-build-provenance@v2 generates SLSA v1 build
    provenance for every .tar.gz (GitHub-native; consumers verify
    with `gh attestation verify <file> --repo pulseengine/wohl`).
  - sigstore/cosign-installer@v3 cosign v2.4.1; keyless OIDC
    sign-blob over SHA256SUMS.txt producing the
    .sig / .pem / .cosign.bundle triple.

Triggers
  - push: tags: ['v*']  (the primary path)
  - workflow_dispatch  (manual re-run for a partially-failed release;
    requires the existing tag as input)
  - Concurrency group per-tag, never cancels in flight.
  - Idempotent on re-run via gh release upload --clobber.

Permissions
  - Workflow-level: contents: read.
  - create-release job: contents: write + id-token: write +
    attestations: write (minimum for asset upload + keyless signing
    + SLSA attestation).

No release has been cut yet — `gh release list` is empty. Merging
this PR does NOT fire the workflow (tag trigger only). First
exercise is `git tag v0.1.0 && git push --tags`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avrabe avrabe merged commit b10659e into main May 24, 2026
5 checks passed
@avrabe avrabe deleted the add/release-workflow branch May 24, 2026 19:29
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