# Builds AdGuardian for all supported targets and drafts a GitHub release
# with the compiled binaries, a SHA256 checksum and provenance attestations
# The release is created as a draft, then human can review and hit publish
#
# Triggered by:
# - Push of any minor/major (X.Y.0) git tag (patch tags just rebuild Docker)
# - Manual dispatch with any existing tag (any version)

name: 🚀 Release

on:
  push:
    tags: ['*.*.0']
  workflow_dispatch:
    inputs:
      tag:
        description: 'Existing git tag to release (e.g. 1.7.0)'
        required: true

concurrency:
  group: ${{ github.workflow }}-${{ inputs.tag || github.ref_name }}
  cancel-in-progress: false

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    name: 🏗️ Build ${{ matrix.name }}
    runs-on: ${{ matrix.os }}
    timeout-minutes: 30
    env:
      TAG: ${{ inputs.tag || github.ref_name }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: adguardian-linux
            os: ubuntu-latest
            target: x86_64-unknown-linux-musl
            cross: false
            apt: musl-tools
          - name: adguardian-linux-arm64
            os: ubuntu-latest
            target: aarch64-unknown-linux-gnu
            cross: true
          - name: adguardian-linux-armv7
            os: ubuntu-latest
            target: armv7-unknown-linux-gnueabihf
            cross: true
          - name: adguardian-macos
            os: macos-latest
            target: aarch64-apple-darwin
            cross: false
          - name: adguardian-macos-x86_64
            os: macos-latest
            target: x86_64-apple-darwin
            cross: false
          - name: adguardian-windows.exe
            os: windows-latest
            target: x86_64-pc-windows-msvc
            cross: false
    steps:
      - name: 🛎️ Checkout tag
        uses: actions/checkout@v6
        with:
          ref: refs/tags/${{ env.TAG }}
          persist-credentials: false

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

      - name: 📦 Install apt dependencies
        if: matrix.apt != ''
        run: sudo apt-get update -y && sudo apt-get install -y ${{ matrix.apt }}

      - name: 🔧 Install cross
        if: matrix.cross
        uses: taiki-e/install-action@v2
        with:
          tool: cross

      - name: 🏗️ Build with cargo
        if: ${{ !matrix.cross }}
        run: cargo build --release --locked --target ${{ matrix.target }}

      - name: 🏗️ Build with cross
        if: matrix.cross
        run: cross build --release --locked --target ${{ matrix.target }}

      - name: 📤 Stage binary as ${{ matrix.name }}
        shell: bash
        run: |
          set -euo pipefail
          SRC="target/${{ matrix.target }}/release/adguardian"
          [ -f "${SRC}.exe" ] && SRC="${SRC}.exe"
          cp "$SRC" "${{ matrix.name }}"

      - name: ⬆️ Upload build artifact
        uses: actions/upload-artifact@v7
        with:
          name: ${{ matrix.name }}
          path: ${{ matrix.name }}
          if-no-files-found: error
          retention-days: 1

  release:
    name: 🚀 Draft Release
    needs: build
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: write
      id-token: write
      attestations: write
    env:
      TAG: ${{ inputs.tag || github.ref_name }}
    steps:
      - name: 🛎️ Checkout tag
        uses: actions/checkout@v6
        with:
          ref: refs/tags/${{ env.TAG }}
          fetch-depth: 0
          persist-credentials: false

      - name: 📥 Download all binaries
        uses: actions/download-artifact@v8
        with:
          path: artifacts
          merge-multiple: true

      - name: 🔢 Generate SHA256 checksums
        run: |
          set -euo pipefail
          cd artifacts
          sha256sum adguardian-* > SHA256SUMS
          cat SHA256SUMS

      - name: 🪪 Generate build provenance attestation
        uses: actions/attest-build-provenance@v4
        with:
          subject-path: 'artifacts/adguardian-*'

      - name: 🔎 Find previous release tag
        id: prev
        env:
          CURRENT_TAG: ${{ env.TAG }}
        run: |
          set -euo pipefail
          git fetch --tags --force
          PREV=$({ echo "$CURRENT_TAG"; git tag | grep -E '^[0-9]+\.[0-9]+\.0$' || true; } \
            | sort -uV \
            | awk -v cur="$CURRENT_TAG" '$0 == cur { print prev; exit } { prev = $0 }')
          echo "tag=$PREV" >> "$GITHUB_OUTPUT"

      - name: 📝 Create draft release
        id: release
        uses: softprops/action-gh-release@v3 # zizmor: ignore[superfluous-actions]
        with:
          tag_name: ${{ env.TAG }}
          name: Release ${{ env.TAG }}
          draft: true
          prerelease: false
          generate_release_notes: true
          previous_tag: ${{ steps.prev.outputs.tag }}
          fail_on_unmatched_files: true
          files: |
            artifacts/adguardian-*
            artifacts/SHA256SUMS
          token: ${{ secrets.BOT_TOKEN || secrets.GITHUB_TOKEN }}

      - name: 📋 Job summary
        if: always()
        env:
          REPO_URL: ${{ github.server_url }}/${{ github.repository }}
          PREV_TAG: ${{ steps.prev.outputs.tag }}
          RELEASE_URL: ${{ steps.release.outputs.url }}
        run: |
          set -euo pipefail
          {
            echo "## 🚀 Release Draft"
            echo ""
            echo "| Item | Value |"
            echo "|------|-------|"
            echo "| Tag | [\`${TAG}\`](${REPO_URL}/releases/tag/${TAG}) |"
            if [ -n "$PREV_TAG" ]; then
              echo "| Notes since | [\`${PREV_TAG}\`](${REPO_URL}/releases/tag/${PREV_TAG}) |"
            fi
            echo "| Assets | $(find artifacts -maxdepth 1 -type f -printf '%f ') |"
            if [ -n "$RELEASE_URL" ]; then
              echo "| Draft release | ✅ [Review and publish](${RELEASE_URL}) |"
            else
              echo "| Draft release | ❌ Failed |"
            fi
          } >> "$GITHUB_STEP_SUMMARY"
