name: CI and release

on:
  pull_request:
  push:
    branches:
      - '**'
    tags:
      - '*'

permissions:
  contents: read

jobs:
  validate:
    name: Validate (${{ matrix.label }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: windows-latest
            label: Windows
          - os: macos-13
            label: macOS
          - os: ubuntu-latest
            label: Linux

    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Set up Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: 1.3.6

      - name: Set up .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 9.0.x

      - name: Install Linux native dependencies
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y libsecret-1-dev

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Run web tests
        run: bun run test

      - name: Run sidecar tests
        run: bun run sidecar:test

      - name: Build the application
        run: bun run build

  create-release:
    name: Create GitHub release
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    needs: validate
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Create release if needed
        env:
          GH_TOKEN: ${{ github.token }}
          TAG_NAME: ${{ github.ref_name }}
        run: |
          if gh release view "$TAG_NAME" >/dev/null 2>&1; then
            echo "Release $TAG_NAME already exists."
          else
            gh release create "$TAG_NAME" --title "$TAG_NAME" --generate-notes
          fi

  publish-release-assets:
    name: Publish release asset (${{ matrix.label }})
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    needs: create-release
    runs-on: ${{ matrix.os }}
    permissions:
      contents: write
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: windows-latest
            label: Windows
            asset_path: release/Aryx-windows-x64.zip
          - os: macos-13
            label: macOS
            asset_path: release/Aryx-macos-x64.zip
          - os: ubuntu-latest
            label: Linux
            asset_path: release/Aryx-linux-x64.tar.gz

    steps:
      - name: Check out repository
        uses: actions/checkout@v4

      - name: Set up Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: 1.3.6

      - name: Set up .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 9.0.x

      - name: Install Linux native dependencies
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y libsecret-1-dev

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Package current platform
        run: bun run package

      - name: Ad-hoc sign macOS app bundle
        if: runner.os == 'macOS'
        run: codesign --force --deep --sign - release/Aryx-macos-x64/Aryx.app

      - name: Create Windows release archive
        if: runner.os == 'Windows'
        shell: pwsh
        run: Compress-Archive -Path 'release\Aryx-windows-x64\*' -DestinationPath 'release\Aryx-windows-x64.zip' -Force

      - name: Create macOS release archive
        if: runner.os == 'macOS'
        run: ditto -c -k --sequesterRsrc --keepParent release/Aryx-macos-x64/Aryx.app release/Aryx-macos-x64.zip

      - name: Create Linux release archive
        if: runner.os == 'Linux'
        run: tar -czf release/Aryx-linux-x64.tar.gz -C release Aryx-linux-x64

      - name: Upload asset to GitHub release
        shell: bash
        env:
          GH_TOKEN: ${{ github.token }}
          TAG_NAME: ${{ github.ref_name }}
          ASSET_PATH: ${{ matrix.asset_path }}
        run: gh release upload "$TAG_NAME" "$ASSET_PATH" --clobber
