name: build-packages

on:
  workflow_dispatch:
    inputs:
      publish_release:
        description: "Publish GitHub Release after build"
        type: boolean
        default: false
  push:
    tags:
      - "v*"

jobs:
  build:
    name: build-${{ matrix.name }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: macos
            os: macos-latest
            pack_script: pack:mac
          - name: windows
            os: windows-latest
            pack_script: pack:win
    env:
      VITE_SYNC_GITHUB_CLIENT_ID: ${{ secrets.VITE_SYNC_GITHUB_CLIENT_ID }}
      VITE_SYNC_GOOGLE_CLIENT_ID: ${{ secrets.VITE_SYNC_GOOGLE_CLIENT_ID }}
      VITE_SYNC_GOOGLE_CLIENT_SECRET: ${{ secrets.VITE_SYNC_GOOGLE_CLIENT_SECRET }}
      VITE_SYNC_ONEDRIVE_CLIENT_ID: ${{ secrets.VITE_SYNC_ONEDRIVE_CLIENT_ID }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: Install deps
        run: npm ci

      - name: Set version
        shell: bash
        run: |
          if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
            # Tag release: use version from tag
            VERSION="${GITHUB_REF_NAME#v}"
          else
            # workflow_dispatch: use short commit ID
            VERSION="${GITHUB_SHA:0:7}"
          fi
          echo "Setting version to ${VERSION}"
          npm pkg set version="${VERSION}"

      - name: Build package
        env:
          ELECTRON_BUILDER_PUBLISH: "never"
          # macOS code signing & notarization (only for macOS builds)
          CSC_LINK: ${{ matrix.name == 'macos' && secrets.MAC_CSC_LINK || '' }}
          CSC_KEY_PASSWORD: ${{ matrix.name == 'macos' && secrets.MAC_CSC_KEY_PASSWORD || '' }}
          APPLE_ID: ${{ matrix.name == 'macos' && secrets.APPLE_ID || '' }}
          APPLE_APP_SPECIFIC_PASSWORD: ${{ matrix.name == 'macos' && secrets.APPLE_APP_SPECIFIC_PASSWORD || '' }}
          APPLE_TEAM_ID: ${{ matrix.name == 'macos' && secrets.APPLE_TEAM_ID || '' }}
        run: npm run ${{ matrix.pack_script }}

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: netcatty-${{ matrix.name }}
          path: |
            release/*.dmg
            release/*.zip
            release/*.exe
            release/*.msi
            release/*.AppImage
            release/*.deb
            release/*.rpm
            release/*.tar.gz
            release/*.yml
            release/*.blockmap
          if-no-files-found: ignore

  # Linux x64 — pin to ubuntu-22.04 for broader glibc compatibility.
  # ubuntu-latest (24.04) links native modules against glibc 2.39 which
  # can cause dlopen failures on some distros. 22.04 uses glibc 2.35,
  # compatible with most current Linux distributions including Arch.
  # See #264.
  build-linux-x64:
    name: build-linux-x64
    runs-on: ubuntu-22.04
    env:
      VITE_SYNC_GITHUB_CLIENT_ID: ${{ secrets.VITE_SYNC_GITHUB_CLIENT_ID }}
      VITE_SYNC_GOOGLE_CLIENT_ID: ${{ secrets.VITE_SYNC_GOOGLE_CLIENT_ID }}
      VITE_SYNC_GOOGLE_CLIENT_SECRET: ${{ secrets.VITE_SYNC_GOOGLE_CLIENT_SECRET }}
      VITE_SYNC_ONEDRIVE_CLIENT_ID: ${{ secrets.VITE_SYNC_ONEDRIVE_CLIENT_ID }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: Install deps
        run: npm ci

      - name: Set version
        shell: bash
        run: |
          if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
            VERSION="${GITHUB_REF_NAME#v}"
          else
            VERSION="${GITHUB_SHA:0:7}"
          fi
          echo "Setting version to ${VERSION}"
          npm pkg set version="${VERSION}"

      - name: Build package
        env:
          ELECTRON_BUILDER_PUBLISH: "never"
        run: npm run pack:linux-x64

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: netcatty-linux-x64
          path: |
            release/*.AppImage
            release/*.deb
            release/*.rpm
            release/*.yml
            release/*.blockmap
          if-no-files-found: ignore

  # Dedicated job for Linux ARM64 — builds inside Debian Bullseye (GLIBC 2.31)
  # to ensure compatibility with older distros like UOS/Deepin (GLIBC 2.28).
  # Key: GLIBC < 2.34 avoids the libpthread-merge symbol requirement.
  build-linux-arm64:
    name: build-linux-arm64
    runs-on: ubuntu-24.04-arm
    container:
      image: debian:bullseye
    env:
      VITE_SYNC_GITHUB_CLIENT_ID: ${{ secrets.VITE_SYNC_GITHUB_CLIENT_ID }}
      VITE_SYNC_GOOGLE_CLIENT_ID: ${{ secrets.VITE_SYNC_GOOGLE_CLIENT_ID }}
      VITE_SYNC_GOOGLE_CLIENT_SECRET: ${{ secrets.VITE_SYNC_GOOGLE_CLIENT_SECRET }}
      VITE_SYNC_ONEDRIVE_CLIENT_ID: ${{ secrets.VITE_SYNC_ONEDRIVE_CLIENT_ID }}
    steps:
      - name: Install build dependencies
        run: |
          apt-get update
          apt-get install -y curl build-essential python3 git libfuse2 file rpm
          curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
          apt-get install -y nodejs

      - name: Checkout
        uses: actions/checkout@v4

      - name: Install deps
        run: npm ci

      - name: Set version
        shell: bash
        run: |
          if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
            VERSION="${GITHUB_REF_NAME#v}"
          else
            VERSION="${GITHUB_SHA:0:7}"
          fi
          echo "Setting version to ${VERSION}"
          npm pkg set version="${VERSION}"

      - name: Build package
        env:
          npm_config_arch: arm64
          ELECTRON_BUILDER_PUBLISH: "never"
        run: npm run pack:linux-arm64

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: netcatty-linux-arm64
          path: |
            release/*.AppImage
            release/*.deb
            release/*.rpm
            release/*.yml
            release/*.blockmap
          if-no-files-found: ignore

  release:
    name: release
    runs-on: ubuntu-latest
    needs: [build, build-linux-x64, build-linux-arm64]
    if: startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && inputs.publish_release)
    permissions:
      contents: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: List artifacts
        run: ls -la artifacts/

      - name: Generate Release Body
        run: node .github/scripts/generate-release-note.js
        env:
          GITHUB_REF_NAME: ${{ github.ref_name }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_SHA: ${{ github.sha }}

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          body_path: release_notes.md
          files: |
            artifacts/*.dmg
            artifacts/*.zip
            artifacts/*.exe
            artifacts/*.AppImage
            artifacts/*.deb
            artifacts/*.rpm
            artifacts/*.yml
            artifacts/*.blockmap
          generate_release_notes: true
          fail_on_unmatched_files: false
          token: ${{ secrets.RELEASE_TOKEN }}
