Skip to content

Epic: Phase 2 — Multi-platform binary release artifacts #63

@jh-lee-cryptolab

Description

@jh-lee-cryptolab

Context

rune-vault currently ships only as a GHCR Docker image. The next phase's docker-free installer (#64) needs native binaries, so this phase produces signed GitHub Release assets for four Unix target platforms (Linux and macOS — Windows is out of scope for rune-vault).

flowchart LR
  Tag[GitHub release published] --> WF[release-binaries.yml]
  WF --> L1[ubuntu-latest<br/>linux/amd64 native]
  WF --> L2[ubuntu-24.04-arm<br/>linux/arm64 native]
  WF --> M1[macos-14<br/>darwin/arm64 native]
  WF --> M2[macos-14<br/>darwin/amd64 cross<br/>-arch x86_64]
  L1 & L2 & M1 & M2 --> Pack[tar.gz<br/>+ LICENSE + README]
  Pack --> Sign[cosign keyless<br/>+ SHA256SUMS<br/>+ SBOM]
  Sign --> Rel[GitHub Release assets]
Loading

Linux targets use native runners per SDK guidance. macOS targets both build on macos-14 — arm64 natively, amd64 via Apple clang -arch x86_64 cross-compile. Apple's toolchain supports both archs in one host (universal-binary heritage), and envector-go-sdk vendors both darwin_amd64 and darwin_arm64 libevi slices, so no external sysroot is required. macos-13 is avoided because GitHub is sunsetting Intel-host mac runners.

Non-goals

  • Package-manager distribution (brew / apt / scoop)
  • In-binary auto-update

Design

Workflow: .github/workflows/release-binaries.yml, triggered on release: [published] and workflow_dispatch (dry-run).

Per-matrix build steps:

checkout
→ setup-go (go-version-file=vault-go/go.mod, pinned 1.25.9)
→ install OpenSSL 3 + C toolchain for this target
→ CGO_ENABLED=1 GOOS=$goos GOARCH=$goarch [CC / CGO_CFLAGS / CGO_LDFLAGS for cross] \
    go build -trimpath \
    -ldflags "-s -w -X main.version=$TAG -X main.commit=$SHA" \
    -o runevault ./cmd/runevault
→ smoke: ./runevault version  (run under Rosetta 2 for darwin/amd64 on macos-14)
→ package: tar.gz
→ upload-artifact

For darwin/amd64 on macos-14:

export SDKROOT=$(xcrun -sdk macosx --show-sdk-path)
export CC="clang -arch x86_64 -isysroot $SDKROOT"
export CGO_CFLAGS="-arch x86_64 -I/usr/local/opt/openssl@3/include"
export CGO_LDFLAGS="-arch x86_64 -L/usr/local/opt/openssl@3/lib"

Publish job: download all four artifacts → cosign sign-blob keyless (OIDC) → consolidated SHA256SUMSgh release upload.

OpenSSL sourcing:

Runner / target Command
ubuntu-latest / ubuntu-24.04-arm apt install libssl-dev
macos-14 → darwin/arm64 brew install openssl@3 (arm64 slice at /opt/homebrew/opt/openssl@3)
macos-14 → darwin/amd64 (cross) Rosetta 2 + Intel Homebrew (/usr/local/bin/brew install openssl@3) → x86_64 slice at /usr/local/opt/openssl@3. Rosetta 2 is pre-installed on Apple-silicon GitHub runners.

Artifact naming:

runevault_<ver>_<os>_<arch>.tar.gz        (os ∈ {linux, darwin}, arch ∈ {amd64, arm64})
runevault_<ver>_<os>_<arch>.tar.gz.{sig,pem}
SHA256SUMS / SHA256SUMS.sig
sbom/<archive>.spdx.json       (anchore/sbom-action)

Verification recipe (shipped with release notes):

cosign verify-blob \
  --certificate-identity-regexp 'https://github.com/CryptoLabInc/rune-admin/\.github/workflows/release-binaries\.yml@.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --signature runevault_X.Y.Z_linux_amd64.tar.gz.sig \
  --certificate runevault_X.Y.Z_linux_amd64.tar.gz.pem \
  runevault_X.Y.Z_linux_amd64.tar.gz

Acceptance

  • A workflow_dispatch run produces four archives + sig/pem + SBOM + consolidated checksums as workflow artifacts
  • A published GitHub release uploads those assets automatically
  • Cosign verification succeeds on a clean Linux and macOS host
  • The downloaded binary reports its stamped version and commit via runevault version
  • Linux amd64 boots on Ubuntu 22.04 and 24.04; linux/arm64 on Ubuntu 24.04 arm; darwin/arm64 on macOS 14; darwin/amd64 cross-built on macOS 14 runs cleanly on a fresh Intel Mac (and passes runevault version under Rosetta 2 at CI time)

Open questions

  • Link OpenSSL statically (preferred) or dynamically on Linux — decided during the skeleton PR.

Sequencing

Phase 2 of 3. Depends on Phase 1 (#61) — the unified binary with version subcommand is already part of Phase 1. Feeds Phase 3 (#64).

Metadata

Metadata

Labels

ciCI/CD pipelineepicLarge work item spanning multiple PRs / tasksmigrationPlatform / stack migration work

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions