rayfish 0.1.4

P2P mesh VPN powered by iroh — connect peers by cryptographic identity, not IP address
name: Release

# Continuous releases: pushing a tag like `v0.1.0` cuts a release with
# Linux + macOS binaries. Can also be run manually from the Actions tab.
# Windows support: TODO.
on:
  push:
    tags:
      - "v*"
  workflow_dispatch:
    inputs:
      tag:
        description: "Release tag (e.g. v0.1.0)"
        required: false
        type: string

env:
  CARGO_TERM_COLOR: always

jobs:
  create-release:
    runs-on: ubuntu-22.04
    permissions:
      contents: write
    outputs:
      tag: ${{ steps.extract_version.outputs.tag }}
    steps:
      - uses: actions/checkout@v4
        with:
          # Full history + tags so git-cliff can diff against the previous tag.
          fetch-depth: 0

      - name: Extract version
        id: extract_version
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ github.event.inputs.tag }}" ]; then
            TAG="${{ github.event.inputs.tag }}"
          elif [ "${{ github.event_name }}" = "push" ]; then
            TAG="${GITHUB_REF#refs/tags/}"
          else
            VERSION=$(grep '^version = ' Cargo.toml | head -1 | cut -d'"' -f2)
            TAG="v${VERSION}"
          fi
          echo "tag=$TAG" >> "$GITHUB_OUTPUT"

      - name: Create Git tag
        if: github.event_name == 'workflow_dispatch'
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git tag -a "${{ steps.extract_version.outputs.tag }}" -m "Release ${{ steps.extract_version.outputs.tag }}" 2>/dev/null || true
          git push origin "${{ steps.extract_version.outputs.tag }}" 2>/dev/null || true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      # Grouped changelog for this tag (since the previous vX.Y.Z) + a compare
      # link, rendered from the conventional commit messages by cliff.toml.
      - name: Generate release notes
        id: notes
        uses: orhun/git-cliff-action@v4
        with:
          config: cliff.toml
          # --latest (not --current): pick the newest tag matching cliff.toml's
          # tag_pattern from the full timeline, instead of relying on "the tag at
          # HEAD". On a tag-push the runner checks out a detached HEAD and the
          # rolling `nightly` tag also sits on the commit, which breaks
          # --current's HEAD-tag detection ("No tag exists for the current commit").
          args: --latest --strip all
        env:
          OUTPUT: CHANGELOG.md

      - name: Create release
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ steps.extract_version.outputs.tag }}
          name: ${{ steps.extract_version.outputs.tag }}
          body: ${{ steps.notes.outputs.content }}
          draft: false
          prerelease: ${{ contains(steps.extract_version.outputs.tag, '-') }}

  build:
    needs: create-release
    permissions:
      contents: write
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            runner: ubuntu-22.04
            name: ray-linux-x86_64
          - target: aarch64-unknown-linux-gnu
            runner: ubuntu-22.04-arm
            name: ray-linux-aarch64
          - target: aarch64-apple-darwin
            runner: macos-latest
            name: ray-macos-aarch64
          - target: x86_64-apple-darwin
            # Cross-compiled on Apple Silicon (universal SDK); macos-13 Intel
            # runners are being retired and leave the job queued indefinitely.
            runner: macos-latest
            name: ray-macos-x86_64

    runs-on: ${{ matrix.runner }}

    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Rust cache
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: "release"
          cache-on-failure: true

      - name: Build binary
        run: cargo build --release --locked --target ${{ matrix.target }}

      - name: Package for release
        run: |
          BINARY=target/${{ matrix.target }}/release/ray
          cp "$BINARY" ${{ matrix.name }}
          if command -v sha256sum &>/dev/null; then
            sha256sum ${{ matrix.name }} > ${{ matrix.name }}.sha256
          else
            shasum -a 256 ${{ matrix.name }} > ${{ matrix.name }}.sha256
          fi

      - name: Upload release assets
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ needs.create-release.outputs.tag }}
          files: |
            ${{ matrix.name }}
            ${{ matrix.name }}.sha256