name: Release

on:
  push:
    tags:
      - "v*.*.*"
  workflow_dispatch:
    inputs:
      version:
        description: "Version to release, for example 0.1.0"
        required: true
        type: string

permissions:
  contents: write

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
  linux-service-binary:
    name: Build dune-server-service (musl)
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: x86_64-unknown-linux-musl

      - name: Install Zig
        uses: mlugg/setup-zig@v1
        with:
          version: 0.13.0

      - name: Install cargo-zigbuild
        run: cargo install --locked cargo-zigbuild

      - name: Resolve release version
        shell: bash
        env:
          WORKFLOW_VERSION: ${{ inputs.version }}
        run: |
          version="$WORKFLOW_VERSION"
          if [ -z "$version" ]; then
            version="${GITHUB_REF_NAME#v}"
          fi
          if [ -z "$version" ]; then
            echo "could not resolve release version" >&2
            exit 1
          fi
          echo "RELEASE_VERSION=$version" >> "$GITHUB_ENV"
          echo "RELEASE_TAG=v$version" >> "$GITHUB_ENV"

      - name: Build musl binary
        run: |
          cargo zigbuild -p dune-server-service --release --target x86_64-unknown-linux-musl
          strip target/x86_64-unknown-linux-musl/release/dune-server-service

      - name: Stage release artifacts
        run: |
          mkdir -p release-artifacts
          cp target/x86_64-unknown-linux-musl/release/dune-server-service release-artifacts/dune-server-service
          cp crates/dune-server-service/systemd/dune-server-service.service release-artifacts/dune-server-service.service
          cp crates/dune-server-service/openrc/dune-server-service release-artifacts/dune-server-service.openrc

      - name: Upload artifact for desktop bundle
        uses: actions/upload-artifact@v4
        with:
          name: dune-server-service-musl
          path: release-artifacts/
          retention-days: 7

      - name: Resolve release notes
        if: startsWith(github.ref, 'refs/tags/v')
        shell: bash
        run: |
          notes_path="release-notes/${RELEASE_VERSION}.md"
          if [ -f "$notes_path" ]; then
            echo "RELEASE_BODY_PATH=$notes_path" >> "$GITHUB_ENV"
          else
            tmp=$(mktemp)
            printf 'Release v%s. No release-notes/%s.md was provided — see the commit log for details.\n' \
              "$RELEASE_VERSION" "$RELEASE_VERSION" > "$tmp"
            echo "RELEASE_BODY_PATH=$tmp" >> "$GITHUB_ENV"
          fi

      - name: Attach to GitHub release
        if: startsWith(github.ref, 'refs/tags/v')
        uses: softprops/action-gh-release@v2
        with:
          tag_name: ${{ env.RELEASE_TAG }}
          body_path: ${{ env.RELEASE_BODY_PATH }}
          files: |
            release-artifacts/dune-server-service
            release-artifacts/dune-server-service.service
            release-artifacts/dune-server-service.openrc

  desktop-app:
    name: Build ${{ matrix.name }} app
    needs: linux-service-binary
    runs-on: ${{ matrix.platform }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: Windows
            platform: windows-latest
            args: --bundles nsis
          - name: Linux
            platform: ubuntu-22.04
            args: --bundles appimage,deb
          - name: macOS Apple Silicon
            platform: macos-latest
            args: --target aarch64-apple-darwin --bundles dmg
          - name: macOS Intel
            platform: macos-latest
            args: --target x86_64-apple-darwin --bundles dmg

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ startsWith(matrix.name, 'macOS') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}

      - name: Install Node
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
          cache-dependency-path: app/package-lock.json

      - name: Install Linux Tauri dependencies
        if: matrix.platform == 'ubuntu-22.04'
        run: |
          sudo apt-get update
          sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf pkg-config libssl-dev

      - name: Install frontend dependencies
        working-directory: app
        run: npm ci

      - name: Download bundled dune-server-service binary
        uses: actions/download-artifact@v4
        with:
          name: dune-server-service-musl
          path: app/src-tauri/binaries/

      - name: Resolve release version
        shell: pwsh
        env:
          WORKFLOW_VERSION: ${{ inputs.version }}
        run: |
          $version = $env:WORKFLOW_VERSION
          if ([string]::IsNullOrWhiteSpace($version)) {
            $version = "${{ github.ref_name }}".TrimStart("v")
          }
          if ([string]::IsNullOrWhiteSpace($version)) {
            throw "Release version could not be resolved."
          }
          "RELEASE_VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Append
          "RELEASE_TAG=v$version" | Out-File -FilePath $env:GITHUB_ENV -Append

      - name: Prepare release config
        shell: pwsh
        run: |
          $version = $env:RELEASE_VERSION

          Push-Location app
          npm version --no-git-tag-version --allow-same-version $version
          Pop-Location

          $tauriConfigPath = "app/src-tauri/tauri.conf.json"
          $config = Get-Content $tauriConfigPath -Raw
          $config = $config -replace '"version":\s*"[^"]+"', ('"version": "' + $version + '"')
          # Release builds publish signed updater artifacts; the checked-in
          # default keeps this off so local debug builds do not require
          # TAURI_SIGNING_PRIVATE_KEY.
          $config = $config -replace '"createUpdaterArtifacts":\s*false', '"createUpdaterArtifacts": true'
          Set-Content -Path $tauriConfigPath -Value $config -NoNewline

      # The body is set by the linux-service-binary job's softprops step.
      # tauri-action only uploads desktop bundles + the signed updater
      # artifacts here; we don't pass releaseBody to avoid clobbering.
      - name: Build and publish Tauri release
        uses: tauri-apps/tauri-action@v0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
          TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
          VITE_ENABLE_STARTUP_UPDATE_CHECK: "true"
        with:
          projectPath: app
          tagName: ${{ env.RELEASE_TAG }}
          releaseName: "Dune Dedicated Server Manager ${{ env.RELEASE_TAG }}"
          releaseDraft: false
          prerelease: false
          args: ${{ matrix.args }}
