Binary Release #1
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
| name: Binary Release | |
| # Attaches cross-compiled `bashrs` binaries to a GitHub Release as tar.gz + | |
| # sha256. Decoupled from `cargo publish` and from the existing self-hosted | |
| # clean-room `release.yml` — downstream consumers can `curl` the prebuilt | |
| # binary instead of `cargo install bashrs --locked` (which compiles from | |
| # source and is slow on cold caches). | |
| # | |
| # Triggered by: | |
| # - `release: published` — fires automatically when a release is published | |
| # - `workflow_dispatch` — manual re-run / backfill, takes a tag input | |
| # | |
| # Targets: 4 Linux (x86_64/aarch64 × musl/gnu). musl variants are static | |
| # and ideal for Docker / scratch / Alpine; gnu variants are smaller and | |
| # match typical Linux distributions. aarch64 builds use `cross`. | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Release tag to attach binaries to (e.g. v6.65.0)' | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write # upload assets to the release | |
| concurrency: | |
| group: binary-release-${{ github.event.release.tag_name || inputs.tag }} | |
| cancel-in-progress: false | |
| env: | |
| CROSS_VERSION: v0.2.5 | |
| jobs: | |
| build: | |
| name: ${{ matrix.target }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-musl | |
| cross: false | |
| - target: x86_64-unknown-linux-gnu | |
| cross: false | |
| - target: aarch64-unknown-linux-musl | |
| cross: true | |
| - target: aarch64-unknown-linux-gnu | |
| cross: true | |
| steps: | |
| - name: Resolve release tag | |
| id: tag | |
| run: | | |
| TAG="${{ github.event.release.tag_name || inputs.tag }}" | |
| if [ -z "$TAG" ]; then | |
| echo "::error::No tag resolved (release event missing tag_name and no dispatch input)" | |
| exit 1 | |
| fi | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "Building bashrs for $TAG → ${{ matrix.target }}" | |
| - name: Checkout at tag | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ steps.tag.outputs.tag }} | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install musl tools | |
| if: matrix.target == 'x86_64-unknown-linux-musl' | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y --no-install-recommends musl-tools | |
| # Cross is used for aarch64 targets — pinned to v0.2.5 (matches the | |
| # legacy self-hosted release.yml; later cross releases have broken | |
| # CI in the past, ripgrep lesson). | |
| - name: Install cross | |
| if: matrix.cross | |
| run: | | |
| dir="$RUNNER_TEMP/cross" | |
| mkdir -p "$dir" | |
| curl -sL "https://github.com/cross-rs/cross/releases/download/${CROSS_VERSION}/cross-x86_64-unknown-linux-musl.tar.gz" \ | |
| | tar xz -C "$dir" | |
| echo "$dir" >> "$GITHUB_PATH" | |
| - name: Cache cargo | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: binary-${{ matrix.target }} | |
| - name: Build bashrs | |
| run: | | |
| if [ "${{ matrix.cross }}" = "true" ]; then | |
| cross build --release --bin bashrs --target ${{ matrix.target }} --locked | |
| else | |
| cargo build --release --bin bashrs --target ${{ matrix.target }} --locked | |
| fi | |
| - name: Strip binary | |
| run: | | |
| TARGET="${{ matrix.target }}" | |
| BIN_PATH="target/${TARGET}/release/bashrs" | |
| # Each cross image ships the matching ${triple}-strip; the | |
| # gnu image does NOT carry the musl variant and vice-versa. | |
| case "$TARGET" in | |
| aarch64-unknown-linux-musl) STRIP=aarch64-linux-musl-strip ;; | |
| aarch64-unknown-linux-gnu) STRIP=aarch64-linux-gnu-strip ;; | |
| *) STRIP="" ;; | |
| esac | |
| if [ -n "$STRIP" ]; then | |
| docker run --rm -v "$PWD/target:/target:Z" \ | |
| "ghcr.io/cross-rs/${TARGET}:main" \ | |
| "$STRIP" "/$BIN_PATH" | |
| else | |
| strip "$BIN_PATH" | |
| fi | |
| ls -la "$BIN_PATH" | |
| - name: Package archive | |
| id: package | |
| run: | | |
| VERSION="${{ steps.tag.outputs.tag }}" | |
| TARGET="${{ matrix.target }}" | |
| ARCHIVE="bashrs-${VERSION}-${TARGET}" | |
| mkdir -p "$ARCHIVE" | |
| cp "target/${TARGET}/release/bashrs" "$ARCHIVE/" | |
| for f in README.md LICENSE LICENSE-MIT LICENSE-APACHE; do | |
| [ -f "$f" ] && cp "$f" "$ARCHIVE/" | |
| done | |
| tar czf "${ARCHIVE}.tar.gz" "$ARCHIVE" | |
| shasum -a 256 "${ARCHIVE}.tar.gz" > "${ARCHIVE}.tar.gz.sha256" | |
| echo "archive=${ARCHIVE}.tar.gz" >> "$GITHUB_OUTPUT" | |
| echo "sha=${ARCHIVE}.tar.gz.sha256" >> "$GITHUB_OUTPUT" | |
| du -h "${ARCHIVE}.tar.gz" | |
| - name: Upload assets to release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release upload "${{ steps.tag.outputs.tag }}" \ | |
| "${{ steps.package.outputs.archive }}" \ | |
| "${{ steps.package.outputs.sha }}" \ | |
| --clobber | |
| summary: | |
| name: Summary | |
| needs: build | |
| runs-on: ubuntu-latest | |
| if: always() | |
| steps: | |
| - name: Write summary | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| TAG="${{ github.event.release.tag_name || inputs.tag }}" | |
| STATUS="${{ needs.build.result }}" | |
| { | |
| echo "### Binary Release: $TAG" | |
| echo "" | |
| if [ "$STATUS" = "success" ]; then | |
| echo "- Build matrix: **4/4 targets succeeded**" | |
| else | |
| echo "- Build matrix: **partial** (status=$STATUS)" | |
| fi | |
| echo "- Targets:" | |
| echo " - x86_64-unknown-linux-musl" | |
| echo " - x86_64-unknown-linux-gnu" | |
| echo " - aarch64-unknown-linux-musl" | |
| echo " - aarch64-unknown-linux-gnu" | |
| } >> "$GITHUB_STEP_SUMMARY" |