name: Release

on:
  pull_request:
    types: [closed]
    branches: [main]

jobs:
  build:
    if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/')
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            ext: ""
          - os: ubuntu-24.04-arm
            target: aarch64-unknown-linux-gnu
            ext: ""
          - os: macos-latest
            target: aarch64-apple-darwin
            ext: ""
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            ext: ".exe"
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.merge_commit_sha }}

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

      - uses: Swatinem/rust-cache@v2

      - name: Install dependencies (Linux)
        if: runner.os == 'Linux'
        run: sudo apt-get update && sudo apt-get install -y protobuf-compiler cmake

      - name: Install dependencies (macOS)
        if: runner.os == 'macOS'
        run: brew install protobuf

      - name: Install dependencies (Windows)
        if: runner.os == 'Windows'
        run: choco install protoc

      - name: Build
        run: cargo build -p sapphire-workspace-cli --release --target ${{ matrix.target }}

      - name: Stage binary
        shell: bash
        run: |
          mkdir -p dist
          cp target/${{ matrix.target }}/release/sapphire-workspace${{ matrix.ext }} \
             dist/sapphire-workspace-${{ matrix.target }}${{ matrix.ext }}

      - uses: actions/upload-artifact@v4
        with:
          name: sapphire-workspace-${{ matrix.target }}
          path: dist/

  publish:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.merge_commit_sha }}

      - name: Extract version from branch name
        id: version
        run: |
          BRANCH="${{ github.event.pull_request.head.ref }}"
          VERSION="${BRANCH#release/}"
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      - name: Install protoc
        run: sudo apt-get update && sudo apt-get install -y protobuf-compiler cmake

      - name: Publish sapphire-retrieve
        run: |
          VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "sapphire-retrieve") | .version')
          if curl -sf "https://crates.io/api/v1/crates/sapphire-retrieve/$VERSION" > /dev/null; then
            echo "sapphire-retrieve $VERSION already published, skipping"
          else
            cargo publish -p sapphire-retrieve
          fi
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Publish sapphire-sync
        run: |
          VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "sapphire-sync") | .version')
          if curl -sf "https://crates.io/api/v1/crates/sapphire-sync/$VERSION" > /dev/null; then
            echo "sapphire-sync $VERSION already published, skipping"
          else
            cargo publish -p sapphire-sync
          fi
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Publish sapphire-workspace
        run: |
          VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "sapphire-workspace") | .version')
          if curl -sf "https://crates.io/api/v1/crates/sapphire-workspace/$VERSION" > /dev/null; then
            echo "sapphire-workspace $VERSION already published, skipping"
          else
            cargo publish -p sapphire-workspace
          fi
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts/
          merge-multiple: true

      - name: Create tag and GitHub release
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git tag v${{ steps.version.outputs.version }}
          git push origin v${{ steps.version.outputs.version }}
          gh release create v${{ steps.version.outputs.version }} \
            --title "v${{ steps.version.outputs.version }}" \
            --generate-notes \
            artifacts/*
        env:
          GH_TOKEN: ${{ github.token }}
