name: Release

# Two ways in:
#   * push a tag `v0.1.0`  → build installers and attach them to a draft
#     GitHub Release.
#   * run manually (workflow_dispatch, on any branch) → build the same
#     installers and upload them as **workflow artifacts** only, with no tag
#     and no release. This is how you test the pipeline without burning a tag.
on:
  push:
    tags: ["v*"]
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always

jobs:
  release:
    permissions:
      contents: write # create the release + upload assets (tag runs only)
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: macos-latest
            rust_targets: aarch64-apple-darwin,x86_64-apple-darwin
            tauri_args: --target universal-apple-darwin
            cli_asset: tutabridge-macos-arm64
            bundle_path: target/universal-apple-darwin/release/bundle
          - platform: ubuntu-latest
            rust_targets: ""
            tauri_args: ""
            cli_asset: tutabridge-linux-x86_64
            bundle_path: target/release/bundle
          - platform: windows-latest
            rust_targets: ""
            tauri_args: ""
            cli_asset: tutabridge-windows-x86_64.exe
            bundle_path: target/release/bundle
    runs-on: ${{ matrix.platform }}
    steps:
      - name: Checkout (with vendored SDK submodule)
        uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0

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

      - name: Cache cargo build
        uses: Swatinem/rust-cache@v2

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
          cache-dependency-path: ui/package-lock.json

      # Linux: Tauri's webkit/gtk stack + our build deps (aws-lc-sys, the
      # keyring Secret Service backend's libdbus).
      - name: Install Linux deps
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            libwebkit2gtk-4.1-dev \
            libgtk-3-dev \
            librsvg2-dev \
            libsoup-3.0-dev \
            libjavascriptcoregtk-4.1-dev \
            libayatana-appindicator3-dev \
            cmake nasm libdbus-1-dev pkg-config

      # Windows: NASM for aws-lc-sys's assembly.
      - name: Install NASM (Windows)
        if: runner.os == 'Windows'
        uses: ilammy/setup-nasm@v1

      - name: Install frontend deps
        working-directory: ui
        run: npm ci

      # Builds the GUI bundles (.dmg / .msi+.exe / .deb+.AppImage). On a tag it
      # also creates/updates a draft Release and uploads them; on a manual run
      # `tagName` is empty so it only builds (no release).
      - name: Build GUI bundles
        id: tauri
        uses: tauri-apps/tauri-action@v0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tagName: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || '' }}
          releaseName: ${{ startsWith(github.ref, 'refs/tags/') && format('TutaBridge {0}', github.ref_name) || '' }}
          releaseDraft: true
          prerelease: false
          args: ${{ matrix.tauri_args }}

      - name: Build CLI
        run: cargo build --release -p tutabridge

      # --- Tag run: attach the CLI binary to the draft release ---
      - name: Attach CLI to release
        if: startsWith(github.ref, 'refs/tags/')
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          src=target/release/tutabridge
          [ "${{ runner.os }}" = "Windows" ] && src=target/release/tutabridge.exe
          cp "$src" "${{ matrix.cli_asset }}"
          gh release upload "${{ github.ref_name }}" "${{ matrix.cli_asset }}" --clobber

      # tauri-action names the GUI installers with the version (e.g.
      # TutaBridge_0.1.0_universal.dmg), which would break any fixed download
      # link on the next release. Upload version-less aliases alongside them so
      # `releases/latest/download/TutaBridge-macOS.dmg` (and friends) always
      # resolve to the current build. The CLI assets are already version-less.
      - name: Attach version-less GUI installer aliases
        if: startsWith(github.ref, 'refs/tags/')
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          bp="${{ matrix.bundle_path }}"
          tag="${{ github.ref_name }}"
          alias() { # $1 = glob, $2 = stable name
            f=$(ls $1 2>/dev/null | head -n1)
            if [ -n "$f" ]; then
              cp "$f" "$2"
              gh release upload "$tag" "$2" --clobber
            else
              echo "::warning::no installer matched $1"
            fi
          }
          case "${{ runner.os }}" in
            macOS)
              alias "$bp/dmg/*.dmg" "TutaBridge-macOS.dmg" ;;
            Linux)
              alias "$bp/appimage/*.AppImage" "TutaBridge-Linux.AppImage"
              alias "$bp/deb/*.deb"           "TutaBridge-Linux.deb"
              alias "$bp/rpm/*.rpm"           "TutaBridge-Linux.rpm" ;;
            Windows)
              alias "$bp/nsis/*-setup.exe" "TutaBridge-Windows-setup.exe"
              alias "$bp/msi/*.msi"        "TutaBridge-Windows.msi" ;;
          esac

      # --- Manual run: publish everything as downloadable workflow artifacts ---
      - name: Upload GUI bundles as artifacts
        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
        uses: actions/upload-artifact@v4
        with:
          name: gui-bundles-${{ matrix.platform }}
          path: ${{ matrix.bundle_path }}/**
          if-no-files-found: warn

      - name: Upload CLI as artifact
        if: ${{ !startsWith(github.ref, 'refs/tags/') }}
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.cli_asset }}
          path: |
            target/release/tutabridge
            target/release/tutabridge.exe
          if-no-files-found: warn
