name: Release

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    name: Build (${{ matrix.target }})
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            binary: sessionguard
          - target: x86_64-apple-darwin
            os: macos-latest
            binary: sessionguard
          - target: aarch64-apple-darwin
            os: macos-latest
            binary: sessionguard
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2

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

      - name: Package
        run: |
          cd target/${{ matrix.target }}/release
          tar czf ../../../sessionguard-${{ matrix.target }}.tar.gz ${{ matrix.binary }}

      - name: Upload artifact
        uses: actions/upload-artifact@v7
        with:
          name: sessionguard-${{ matrix.target }}
          path: sessionguard-${{ matrix.target }}.tar.gz

  release:
    name: Create Release
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Generate changelog
        uses: orhun/git-cliff-action@v4
        with:
          config: cliff.toml
          args: --latest --strip header
        env:
          OUTPUT: RELEASE_NOTES.md

      - name: Download artifacts
        uses: actions/download-artifact@v8
        with:
          path: artifacts

      - name: Create release
        uses: softprops/action-gh-release@v2
        with:
          body_path: RELEASE_NOTES.md
          files: artifacts/**/*.tar.gz

  publish:
    name: Publish to crates.io
    needs: release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      - name: Publish
        run: cargo publish --allow-dirty
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

  homebrew:
    # Update PilotDevo/homebrew-tap with the new version + SHA256s.
    # Lives here (not a separate workflow on release.published) because
    # GitHub's anti-recursion rule prevents GITHUB_TOKEN-triggered
    # releases from firing release events in other workflows.
    #
    # Requires repo secret HOMEBREW_TAP_TOKEN (fine-grained PAT scoped
    # to PilotDevo/homebrew-tap with Contents:write). Preflight fails
    # loud if it's missing, before writing anything.
    #
    # Security: all github.* values captured into env: before use in
    # run: scripts — never interpolated directly into command lines.
    name: Update Homebrew tap
    needs: release
    runs-on: ubuntu-latest
    steps:
      - name: Preflight — ensure tap token is configured
        env:
          TAP_TOKEN_PRESENT: ${{ secrets.HOMEBREW_TAP_TOKEN != '' }}
        run: |
          if [ "$TAP_TOKEN_PRESENT" != "true" ]; then
            echo "::error::HOMEBREW_TAP_TOKEN secret is not set"
            exit 1
          fi

      - name: Checkout tap
        uses: actions/checkout@v6
        with:
          repository: PilotDevo/homebrew-tap
          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
          path: tap

      - name: Download release assets
        env:
          VERSION_TAG: ${{ github.ref_name }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          REPO: ${{ github.repository }}
        run: |
          mkdir -p assets
          gh release download "$VERSION_TAG" \
            --repo "$REPO" \
            --pattern '*.tar.gz' \
            --dir assets
          ls -la assets

      - name: Compute SHA256s
        id: sha
        run: |
          sha_aarch64_darwin=$(sha256sum assets/sessionguard-aarch64-apple-darwin.tar.gz   | awk '{print $1}')
          sha_x86_64_darwin=$( sha256sum assets/sessionguard-x86_64-apple-darwin.tar.gz    | awk '{print $1}')
          sha_x86_64_linux=$(  sha256sum assets/sessionguard-x86_64-unknown-linux-gnu.tar.gz | awk '{print $1}')
          {
            echo "aarch64_darwin=$sha_aarch64_darwin"
            echo "x86_64_darwin=$sha_x86_64_darwin"
            echo "x86_64_linux=$sha_x86_64_linux"
          } >> "$GITHUB_OUTPUT"

      - name: Render formula
        env:
          VERSION_TAG: ${{ github.ref_name }}
          SHA_AARCH64_DARWIN: ${{ steps.sha.outputs.aarch64_darwin }}
          SHA_X86_64_DARWIN: ${{ steps.sha.outputs.x86_64_darwin }}
          SHA_X86_64_LINUX: ${{ steps.sha.outputs.x86_64_linux }}
        run: |
          version="${VERSION_TAG#v}"
          mkdir -p tap/Formula
          cat > tap/Formula/sessionguard.rb <<EOF
          class Sessionguard < Formula
            desc "System-level daemon that keeps AI coding sessions intact when projects move"
            homepage "https://github.com/PilotDevo/sessionguard"
            version "$version"
            license "MIT"

            on_macos do
              on_arm do
                url "https://github.com/PilotDevo/sessionguard/releases/download/v#{version}/sessionguard-aarch64-apple-darwin.tar.gz"
                sha256 "$SHA_AARCH64_DARWIN"
              end
              on_intel do
                url "https://github.com/PilotDevo/sessionguard/releases/download/v#{version}/sessionguard-x86_64-apple-darwin.tar.gz"
                sha256 "$SHA_X86_64_DARWIN"
              end
            end

            on_linux do
              url "https://github.com/PilotDevo/sessionguard/releases/download/v#{version}/sessionguard-x86_64-unknown-linux-gnu.tar.gz"
              sha256 "$SHA_X86_64_LINUX"
            end

            def install
              bin.install "sessionguard"
            end

            test do
              assert_match "sessionguard #{version}", shell_output("#{bin}/sessionguard version")
            end
          end
          EOF
          echo "--- rendered formula ---"
          cat tap/Formula/sessionguard.rb

      - name: Commit and push to tap
        env:
          VERSION_TAG: ${{ github.ref_name }}
        run: |
          cd tap
          git config user.name  "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add Formula/sessionguard.rb
          if git diff --cached --quiet; then
            echo "no formula changes — skipping push"
            exit 0
          fi
          git commit -m "sessionguard ${VERSION_TAG}"
          git push
