name: Release

on:
  push:
    tags:
      - "*"
      - "!nightly"
      - "!nightly*"
  workflow_dispatch:
    inputs:
      tag_name:
        description: "Release Tag name (optional, defaults to Cargo.toml version)"
        required: false
        type: string

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-Dwarnings"

jobs:
  build_release:
    name: Build & Sign Release
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          [
            ubuntu-latest,
            ubuntu-26.04-arm,
            windows-latest,
            windows-11-arm,
            macos-latest,
          ]
        toolchain:
          - stable
    steps:
      - uses: actions/checkout@v7
        with:
          submodules: recursive

      - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
      - uses: Swatinem/rust-cache@v2

      - name: Install musl-tools (Linux only)
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y musl-tools

      - name: Build Release
        shell: bash
        run: |
          cargo build --verbose --release
          if [ "${{ runner.os }}" == "Linux" ]; then
            if [ "${{ runner.arch }}" == "X64" ]; then
              TARGET="x86_64-unknown-linux-musl"
            elif [ "${{ runner.arch }}" == "ARM64" ]; then
              TARGET="aarch64-unknown-linux-musl"
            fi
            rustup target add "$TARGET"
            cargo build --verbose --release --target "$TARGET"
          fi

      - name: Prepare artifacts
        shell: bash
        run: |
          mkdir -p dist
          EXT=""
          if [ "${{ runner.os }}" == "Windows" ]; then EXT=".exe"; fi
          cp "target/release/pumpkin$EXT" "dist/pumpkin-${{ runner.arch }}-${{ runner.os }}$EXT"
          if [ "${{ runner.os }}" == "Linux" ]; then
            if [ "${{ runner.arch }}" == "X64" ]; then
              TARGET="x86_64-unknown-linux-musl"
            elif [ "${{ runner.arch }}" == "ARM64" ]; then
              TARGET="aarch64-unknown-linux-musl"
            fi
            cp "target/$TARGET/release/pumpkin" "dist/pumpkin-${{ runner.arch }}-${{ runner.os }}-musl"
          fi

      - name: Upload unsigned executable for SignPath (Windows only)
        if: runner.os == 'Windows'
        id: upload_unsigned
        uses: actions/upload-artifact@v7
        with:
          name: unsigned-${{ runner.arch }}-${{ runner.os }}
          path: dist/pumpkin-*
          retention-days: 1

      - name: Submit SignPath signing request (Windows only)
        if: runner.os == 'Windows'
        uses: signpath/github-action-submit-signing-request@v2
        with:
          api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
          organization-id: '${{ secrets.SIGNPATH_ORGANIZATION_ID }}'
          project-slug: '${{ secrets.SIGNPATH_PROJECT_SLUG }}'
          signing-policy-slug: '${{ secrets.SIGNPATH_RELEASE_SIGNING_POLICY_SLUG || secrets.SIGNPATH_SIGNING_POLICY_SLUG }}'
          github-artifact-id: '${{ steps.upload_unsigned.outputs.artifact-id }}'
          wait-for-completion: true
          output-artifact-directory: dist/signed/

      - name: Overwrite with signed version (Windows only)
        if: runner.os == 'Windows'
        shell: bash
        run: |
          cp dist/signed/* dist/
          rm -rf dist/signed/

      - name: Export executable
        uses: actions/upload-artifact@v7
        with:
          name: pumpkin-${{ runner.arch }}-${{ runner.os }}
          compression-level: 9
          path: dist/pumpkin-*

  build_android_release:
    name: Build project in release for Android (AArch64)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          submodules: recursive
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: aarch64-linux-android
      - uses: nttld/setup-ndk@v1
        with:
          ndk-version: r27c
      - name: Install cargo-ndk
        run: cargo install cargo-ndk
      - uses: Swatinem/rust-cache@v2
      - name: Build Release with cargo ndk
        env:
          CARGO_NDK_PLATFORM: 24
        run: cargo ndk -t arm64-v8a build --release --locked
      - name: Prepare artifacts
        shell: bash
        run: |
          mkdir -p dist
          cp "target/aarch64-linux-android/release/pumpkin" "dist/pumpkin-aarch64-android"
      - name: Export executable
        uses: actions/upload-artifact@v7
        with:
          name: pumpkin-aarch64-android
          compression-level: 9
          path: dist/pumpkin-aarch64-android

  publish_release:
    name: Publish GitHub Release
    permissions:
      contents: write
    needs: [build_release, build_android_release]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          submodules: recursive

      - name: Determine tag name
        id: tag
        shell: bash
        run: |
          if [ -n "${{ github.event.inputs.tag_name }}" ]; then
            TAG="${{ github.event.inputs.tag_name }}"
          elif [ "${{ github.ref_type }}" == "tag" ]; then
            TAG="${{ github.ref_name }}"
          else
            VERSION=$(awk -F '"' '/^version/ {print $2}' Cargo.toml)
            TAG="${VERSION}"
          fi
          echo "tag_name=${TAG}" >> $GITHUB_OUTPUT
          echo "Determined release tag: ${TAG}"

      - name: Download prebuilt binary artifacts
        uses: actions/download-artifact@v8
        with:
          pattern: "pumpkin-*"
          path: dist/
          merge-multiple: true

      - name: Generate Checksums
        shell: bash
        run: |
          cd dist
          sha256sum pumpkin-* > checksums.sha256
          cat checksums.sha256

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v3
        with:
          tag_name: ${{ steps.tag.outputs.tag_name }}
          name: Release ${{ steps.tag.outputs.tag_name }}
          files: |
            dist/pumpkin*
            dist/checksums.sha256
          generate_release_notes: true
