diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..465effd --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,102 @@ +name: release + +# Publishes per-platform `furrow` binaries so callers can install it without a +# Rust toolchain. Windows is absent on purpose: 13 source files use +# `std::os::unix` with no `cfg(windows)` guards, so a native Windows build needs +# a source port, not a build target. Windows users reach furrow through WSL, +# which uses the linux asset. + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + tag: + description: "Existing tag to build and publish (e.g. v0.1.0)" + required: true + type: string + +permissions: + contents: write + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + name: ${{ matrix.asset }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - asset: furrow-linux-amd64 + target: x86_64-unknown-linux-gnu + os: ubuntu-latest + native: true + - asset: furrow-darwin-arm64 + target: aarch64-apple-darwin + os: macos-14 + native: true + # Cross-compiled on the arm64 runner; Apple's toolchain ships both + # slices, so this needs no extra SDK. It cannot be smoke-tested here. + - asset: furrow-darwin-amd64 + target: x86_64-apple-darwin + os: macos-14 + native: false + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.tag || github.ref }} + + - name: Install toolchain + run: | + rustup toolchain install stable --profile minimal --no-self-update + rustup target add ${{ matrix.target }} + + - name: Build + run: cargo +stable build --release --locked --target ${{ matrix.target }} + + - name: Smoke test + if: matrix.native + run: ./target/${{ matrix.target }}/release/furrow --version + + - name: Stage asset + run: | + mkdir -p dist + install -m 755 "target/${{ matrix.target }}/release/furrow" "dist/${{ matrix.asset }}" + + - uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.asset }} + path: dist/${{ matrix.asset }} + if-no-files-found: error + + publish: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + path: dist + merge-multiple: true + + - name: Checksums + working-directory: dist + run: sha256sum furrow-* > SHA256SUMS + + - name: Publish release + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ inputs.tag || github.ref_name }} + run: | + if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then + gh release upload "$TAG" dist/* --repo "$GITHUB_REPOSITORY" --clobber + else + gh release create "$TAG" dist/* \ + --repo "$GITHUB_REPOSITORY" \ + --title "furrow $TAG" \ + --generate-notes \ + --verify-tag + fi