diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..490efc7d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,134 @@ +name: Release + +# MUS-14: prebuilt muster-shim and muster-daemon for macOS arm64 and Linux x86_64, so neither +# needs a Rust toolchain to install. scripts/install-codex.sh fetches +# releases/latest/download/muster-shim-, so the assets are raw binaries with those names. +# +# - workflow_dispatch builds everything and uploads it as a workflow artifact only: a dry run that +# touches no release and no tag. +# - Pushing a `v*` tag does the same, then creates a DRAFT release with the files attached. Nothing +# is public until someone publishes the draft by hand. +on: + push: + tags: ["v*"] + workflow_dispatch: + +permissions: + contents: read + +# Every action is pinned to a full commit SHA (version in the comment), so a moved tag can't change +# what builds a release, and the build restores no cache, so a poisoned cache entry can't reach a +# shipped binary. Releases are rare; the cold build's extra minutes don't matter. + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + name: build (${{ matrix.target }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + include: + - os: macos-15 # Apple silicon, pinned so the image doesn't drift under a release + target: aarch64-apple-darwin + # The oldest supported Ubuntu image, so the binaries need the oldest glibc we can give + # them (2.35). They link OpenSSL 3 (native-tls) dynamically: Ubuntu 22.04+, Debian 12+, + # Fedora 36+ and other distributions with libssl.so.3. + - os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - name: Install build dependencies (Linux) + if: runner.os == 'Linux' + timeout-minutes: 8 + run: sudo apt-get update && sudo apt-get install -y build-essential pkg-config libssl-dev + - uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable branch, 2026-10-16 + with: + # Pinned to a SHA, the action can't read the toolchain from its ref, so name it. + toolchain: stable + targets: ${{ matrix.target }} + - name: Build + run: cargo build --release --locked --target ${{ matrix.target }} -p muster-shim -p muster-daemon + - name: Name the binaries for the release + run: | + mkdir dist + for bin in muster-shim muster-daemon; do + cp "target/${{ matrix.target }}/release/$bin" "dist/$bin-${{ matrix.target }}" + done + ls -l dist + # Neither binary has --version; both answer an unknown flag with an error or their usage. + # Getting that text back shows the binary loads its libraries and runs on this runner. + - name: Smoke test + # In case a binary ever ignores the unknown flag and keeps running. + timeout-minutes: 2 + run: | + for bin in muster-shim muster-daemon; do + out=$("./dist/$bin-${{ matrix.target }}" --release-smoke-test 2>&1 || true) + echo "$bin: $out" | head -3 + echo "$out" | grep -qiE "usage|unknown argument" || { echo "::error::$bin didn't run"; exit 1; } + done + file dist/* + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: bin-${{ matrix.target }} + path: dist/* + if-no-files-found: error + + # One SHA256SUMS over every asset, made and checked in one place. + package: + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + pattern: bin-* + path: dist + merge-multiple: true + - name: Checksums + working-directory: dist + run: | + cp ../scripts/install-codex.sh . + chmod +x muster-* + sha256sum muster-* install-codex.sh > SHA256SUMS + sha256sum -c SHA256SUMS + cat SHA256SUMS + # Every asset scripts/install-codex.sh can ask for is here. + for target in aarch64-apple-darwin x86_64-unknown-linux-gnu; do + for bin in muster-shim muster-daemon; do + grep -q " $bin-$target\$" SHA256SUMS || { echo "::error::missing $bin-$target"; exit 1; } + done + done + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: muster-release + path: dist/* + if-no-files-found: error + + release: + needs: package + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write + steps: + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: muster-release + path: dist + - name: Create a draft release + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.ref_name }} + run: | + gh release create "$TAG" dist/* \ + --repo "$GITHUB_REPOSITORY" \ + --draft \ + --verify-tag \ + --title "muster $TAG" \ + --notes "Prebuilt muster-shim and muster-daemon for macOS (Apple silicon) and Linux (x86_64, glibc 2.35+ with OpenSSL 3). Check downloads against SHA256SUMS: \`sha256sum -c SHA256SUMS --ignore-missing\`." diff --git a/docs/roadmap.md b/docs/roadmap.md index 614d4439..4bb8e8bb 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -395,6 +395,10 @@ Merged and needing a live run: MUS-36 and MUS-37. - [ ] **MUS-14: Publish prebuilt binaries.** There are no releases yet, so `scripts/install-codex.sh` can't work and the plugins aren't on npm. Done when: macOS and Linux can install without a Rust toolchain. + `.github/workflows/release.yml` now builds muster-shim and muster-daemon for macOS arm64 and + Linux x86_64 under the names install-codex.sh asks for, with one SHA256SUMS. workflow_dispatch + is a dry run that only uploads artifacts; a `v*` tag also makes a draft release, which stays + unpublished until Josh publishes it. Left: a tag and a published release, on Josh's word. - [ ] **MUS-91: Keep `windows-cross-check` from timing out.** It hit its 20-minute limit on #110, #113 and #124, and a re-run passed each time. Every time it was the apt step: `mingw-w64` pulls 278 MB (the i686 and x86_64 toolchains, C and C++), which normally takes 7 s, but the Azure