name: EasyTier GUI

on:
  push:
    branches: ["develop", "main", "releases/**"]
  pull_request:
    branches: ["develop", "main"]
      
env:
  CARGO_TERM_COLOR: always

defaults:
  run:
    # necessary for windows
    shell: bash

jobs:
  pre_job:
    # continue-on-error: true # Uncomment once integration is finished
    runs-on: ubuntu-latest
    # Map a step output to a job output
    outputs:
      should_skip: ${{ steps.skip_check.outputs.should_skip == 'true' && !startsWith(github.ref_name, 'releases/') }}
    steps:
      - id: skip_check
        uses: fkirc/skip-duplicate-actions@v5
        with:
          # All of these options are optional, so you can remove them if you are happy with the defaults
          concurrent_skipping: 'same_content_newer'
          skip_after_successful_duplicate: 'true'
          cancel_others: 'true'
          paths: '["Cargo.toml", "Cargo.lock", "easytier/**", "easytier-gui/**", ".github/workflows/gui.yml", ".github/workflows/install_rust.sh", ".github/workflows/install_gui_dep.sh"]'
  build-gui:
    strategy:
      fail-fast: false
      matrix:
        include:
          - TARGET: aarch64-unknown-linux-musl
            OS: ubuntu-22.04
            GUI_TARGET: aarch64-unknown-linux-gnu
            ARTIFACT_NAME: linux-aarch64
          - TARGET: x86_64-unknown-linux-musl
            OS: ubuntu-22.04
            GUI_TARGET: x86_64-unknown-linux-gnu
            ARTIFACT_NAME: linux-x86_64

          - TARGET: x86_64-apple-darwin
            OS: macos-latest
            GUI_TARGET: x86_64-apple-darwin
            ARTIFACT_NAME: macos-x86_64
          - TARGET: aarch64-apple-darwin
            OS: macos-latest
            GUI_TARGET: aarch64-apple-darwin
            ARTIFACT_NAME: macos-aarch64

          - TARGET: x86_64-pc-windows-msvc
            OS: windows-latest
            GUI_TARGET: x86_64-pc-windows-msvc
            ARTIFACT_NAME: windows-x86_64

          - TARGET: aarch64-pc-windows-msvc
            OS: windows-latest
            GUI_TARGET: aarch64-pc-windows-msvc
            ARTIFACT_NAME: windows-arm64

          - TARGET: i686-pc-windows-msvc
            OS: windows-latest
            GUI_TARGET: i686-pc-windows-msvc
            ARTIFACT_NAME: windows-i686

    runs-on: ${{ matrix.OS }}
    env:
      NAME: easytier
      TARGET: ${{ matrix.TARGET }}
      OS: ${{ matrix.OS }}
      GUI_TARGET: ${{ matrix.GUI_TARGET }}
      OSS_BUCKET: ${{ secrets.ALIYUN_OSS_BUCKET }}
    needs: pre_job
    if: needs.pre_job.outputs.should_skip != 'true'    
    steps:
      - uses: actions/checkout@v3

      - name: Install GUI dependencies (x86 only)
        if: ${{ matrix.TARGET == 'x86_64-unknown-linux-musl' }}
        run: bash ./.github/workflows/install_gui_dep.sh

      - name: Install GUI cross compile (aarch64 only)
        if: ${{ matrix.TARGET == 'aarch64-unknown-linux-musl' }}
        run: |
          # see https://tauri.app/v1/guides/building/linux/
          echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted" | sudo tee /etc/apt/sources.list
          echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy universe" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates universe" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy multiverse" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security main restricted" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security universe" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security multiverse" | sudo tee -a /etc/apt/sources.list

          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy universe" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates universe" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy multiverse" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security universe" | sudo tee -a /etc/apt/sources.list
          echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security multiverse" | sudo tee -a /etc/apt/sources.list

          sudo dpkg --add-architecture arm64
          sudo apt update
          sudo apt install aptitude
          sudo aptitude install -y libgstreamer1.0-0:arm64 gstreamer1.0-plugins-base:arm64 gstreamer1.0-plugins-good:arm64 \
            libgstreamer-gl1.0-0:arm64 libgstreamer-plugins-base1.0-0:arm64 libgstreamer-plugins-good1.0-0:arm64 libwebkit2gtk-4.1-0:arm64 \
            libwebkit2gtk-4.1-dev:arm64 libssl-dev:arm64 gcc-aarch64-linux-gnu
          echo "PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/" >> "$GITHUB_ENV"
          echo "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/" >> "$GITHUB_ENV"

      - name: Set current ref as env variable
        run: |
          echo "GIT_DESC=$(git log -1 --format=%cd.%h --date=format:%Y-%m-%d_%H:%M:%S)" >> $GITHUB_ENV

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10
          run_install: false

      - name: Get pnpm store directory
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

      - name: Setup pnpm cache
        uses: actions/cache@v4
        with:
          path: ${{ env.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-

      - name: Install frontend dependencies
        run: |
          pnpm -r install
          pnpm -r build

      - uses: Swatinem/rust-cache@v2
        with:
          # The prefix cache key, this can be changed to start a new cache manually.
          # default: "v0-rust"
          prefix-key: ""

      - name: Install rust target
        run: bash ./.github/workflows/install_rust.sh

      - name: Setup protoc
        uses: arduino/setup-protoc@v3
        with:
          # GitHub repo token to use to avoid rate limiter
          repo-token: ${{ secrets.GITHUB_TOKEN }}

      - name: copy correct DLLs
        if: ${{ matrix.OS == 'windows-latest' }}
        run: |
          if [[ $GUI_TARGET =~ ^aarch64.*$ ]]; then
            cp ./easytier/third_party/arm64/*.dll ./easytier-gui/src-tauri/
          elif [[ $GUI_TARGET =~ ^i686.*$ ]]; then
            cp ./easytier/third_party/i686/*.dll ./easytier-gui/src-tauri/
          else
            cp ./easytier/third_party/*.dll ./easytier-gui/src-tauri/
          fi

      - name: Build GUI
        if: ${{ matrix.GUI_TARGET != '' }}
        uses: tauri-apps/tauri-action@v0
        with:
          projectPath: ./easytier-gui
          # https://tauri.app/v1/guides/building/linux/#cross-compiling-tauri-applications-for-arm-based-devices
          args: --verbose --target ${{ matrix.GUI_TARGET }} ${{ matrix.OS == 'ubuntu-22.04' && contains(matrix.TARGET, 'aarch64') && '--bundles deb' || ''  }}

      - name: Compress
        run: |
          mkdir -p ./artifacts/objects/
          
          if [[ $GITHUB_REF_TYPE =~ ^tag$ ]]; then
            TAG=$GITHUB_REF_NAME
          else
            TAG=$GITHUB_SHA
          fi
          # copy gui bundle, gui is built without specific target
          if [[ $OS =~ ^windows.*$ ]]; then
              mv ./target/$GUI_TARGET/release/bundle/nsis/*.exe ./artifacts/objects/
          elif [[ $OS =~ ^macos.*$ ]]; then
              mv ./target/$GUI_TARGET/release/bundle/dmg/*.dmg ./artifacts/objects/
          elif [[ $OS =~ ^ubuntu.*$ && ! $TARGET =~ ^mips.*$ ]]; then
              mv ./target/$GUI_TARGET/release/bundle/deb/*.deb ./artifacts/objects/
              if [[ $GUI_TARGET =~ ^x86_64.*$ ]]; then
                # currently only x86 appimage is supported
                mv ./target/$GUI_TARGET/release/bundle/appimage/*.AppImage ./artifacts/objects/
              fi
          fi

          mv ./artifacts/objects/* ./artifacts/
          rm -rf ./artifacts/objects/

      - name: Archive artifact
        uses: actions/upload-artifact@v4
        with:
          name: easytier-gui-${{ matrix.ARTIFACT_NAME }}
          path: |
            ./artifacts/*

  gui-result:
    if: needs.pre_job.outputs.should_skip != 'true' && always()
    runs-on: ubuntu-latest
    needs:
      - pre_job
      - build-gui
    steps:
      - name: Mark result as failed
        if: needs.build-gui.result != 'success'
        run: exit 1
