# This workflow will build a Java project with Gradle
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle

name: SlimeVR Server

on:
  push:
    branches:
      - main
  pull_request:
  workflow_dispatch:
  create:

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
      - name: Get tags
        run: git fetch --tags origin --recurse-submodules=no

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: "17"
          distribution: "adopt"

      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2

      - run: mkdir ./gui/dist && touch ./gui/dist/somefile
        shell: bash

      - name: Check code formatting
        run: ./gradlew spotlessCheck

      - name: Test with Gradle
        run: ./gradlew test


  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
      - name: Get tags
        run: git fetch --tags origin --recurse-submodules=no

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: "17"
          distribution: "adopt"

      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2

      - name: Build with Gradle
        run: ./gradlew shadowJar

      - name: Upload the Server JAR as a Build Artifact
        uses: actions/upload-artifact@v3
        with:
          # Artifact name
          name: "SlimeVR-Server" # optional, default is artifact
          # A file, directory or wildcard pattern that describes what to upload
          path: server/desktop/build/libs/*

      - name: Upload to draft release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          draft: true
          generate_release_notes: true
          files: |
            server/desktop/build/libs/*


  bundle-linux:
    runs-on: ubuntu-22.04
    needs: [build, test]
    if: contains(fromJSON('["workflow_dispatch", "create"]'), github.event_name)
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - uses: actions/download-artifact@v3
        with:
          name: "SlimeVR-Server"
          path: server/desktop/build/libs/

      - name: Set up Linux dependencies
        uses: awalsh128/cache-apt-pkgs-action@latest
        with:
          packages: libgtk-3-dev webkit2gtk-4.1 libappindicator3-dev librsvg2-dev patchelf libfuse2
          # Increment to invalidate the cache
          version: 1.0
          # Enables a workaround to attempt to run pre and post install scripts
          execute_install_scripts: true
          # Disables uploading logs as a build artifact
          debug: false

      - name: Cache cargo dependencies
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: "ubuntu-22.04"

      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version-file: '.node-version'
          cache: 'npm'

      - name: Build
        run: |
          npm ci
          npm run tauri build

      - uses: actions/upload-artifact@v3.1.0
        with:
          name: SlimeVR-GUI-Deb
          path: target/release/bundle/deb/slimevr*.deb

      - name: Install appimage-builder
        run: |
          wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
          chmod a+x appimagetool-x86_64.AppImage
          sudo mv appimagetool-x86_64.AppImage /usr/local/bin/appimagetool

      - name: Modify and Build AppImage
        run: |
          cd target/release/bundle/appimage
          chmod a+x slimevr*.AppImage
          ./slimevr*.AppImage --appimage-extract
          cp $( git rev-parse --show-toplevel )/server/desktop/build/libs/slimevr.jar squashfs-root/slimevr.jar
          chmod 644 squashfs-root/slimevr.jar
          appimagetool squashfs-root slimevr*.AppImage

      - uses: actions/upload-artifact@v3.1.0
        with:
          name: SlimeVR-GUI-AppImage
          path: target/release/bundle/appimage/slimevr*.AppImage

      - name: Prepare for release
        if: startsWith(github.ref, 'refs/tags/')
        run: |
          cp target/release/bundle/appimage/slimevr*.AppImage ./SlimeVR-amd64.appimage
          cp target/release/bundle/deb/slimevr*.deb ./SlimeVR-amd64.deb

      - name: Upload to draft release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          draft: true
          generate_release_notes: true
          files: |
            ./SlimeVR-amd64.appimage
            ./SlimeVR-amd64.deb


  bundle-mac:
    runs-on: macos-latest
    needs: [build, test]
    if: contains(fromJSON('["workflow_dispatch", "create"]'), github.event_name)
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - uses: actions/download-artifact@v3
        with:
          name: "SlimeVR-Server"
          path: server/desktop/build/libs/

      - name: Cache cargo dependencies
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: "macos-latest"

      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version-file: '.node-version'
          cache: 'npm'

      - name: Build
        run: |
          npm ci
          npm run tauri build -- "--target universal-apple-darwin"

      - name: Modify Application
        run: |
          cd target/release/bundle/macos/slimevr.app/Contents/MacOS
          cp $( git rev-parse --show-toplevel )/server/desktop/build/libs/slimevr.jar ./
          cd ../../../../dmg/
          ./bundle_dmg.sh --volname slimevr --icon slimevr 180 170 --app-drop-link 480 170 \
          --window-size 660 400 --hide-extension ../macos/slimevr.app \
          --volicon ../macos/slimevr.app/Contents/Resources/icon.icns --skip-jenkins \
          --eula ../../../../LICENSE-MIT slimevr.dmg ../macos/slimevr.app

      - uses: actions/upload-artifact@v3.1.0
        with:
          name: SlimeVR-GUI-MacApp
          path: target/release/bundle/macos/slimevr*.app

      - uses: actions/upload-artifact@v3.1.0
        with:
          name: SlimeVR-GUI-MacDmg
          path: target/release/bundle/dmg/slimevr.dmg

      - name: Prepare for release
        if: startsWith(github.ref, 'refs/tags/')
        run: |
          cp target/release/bundle/dmg/slimevr.dmg ./SlimeVR-mac.dmg

      - name: Upload to draft release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          draft: true
          generate_release_notes: true
          files: |
            ./SlimeVR-mac.dmg


  bundle-windows:
    runs-on: windows-latest
    needs: [build, test]
    if: contains(fromJSON('["workflow_dispatch", "create"]'), github.event_name)
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - uses: actions/download-artifact@v3
        with:
          name: "SlimeVR-Server"
          path: server/desktop/build/libs/

      - name: Cache cargo dependencies
        uses: Swatinem/rust-cache@v2
        with:
          shared-key: "windows-latest"

      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version-file: '.node-version'
          cache: 'npm'

      - name: Build
        run: |
          npm ci
          npm run skipbundler

      - name: Bundle to zips
        shell: bash
        run: |
          mkdir SlimeVR
          cp gui/src-tauri/icons/icon.ico ./SlimeVR/run.ico
          cp server/desktop/build/libs/slimevr.jar ./SlimeVR/slimevr.jar
          cp server/core/resources/* ./SlimeVR/
          cp target/release/slimevr.exe ./SlimeVR/
          7z a -tzip SlimeVR-win64.zip ./SlimeVR/

          mv ./SlimeVR/slimevr.exe ./SlimeVR/slimevr-ui.exe
          7z a -tzip SlimeVR.zip ./SlimeVR/

      - uses: actions/upload-artifact@v3.1.0
        with:
          name: SlimeVR-GUI-Windows
          path: ./SlimeVR*.zip

      - name: Upload to draft release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          draft: true
          generate_release_notes: true
          files: |
            ./SlimeVR-win64.zip
            ./SlimeVR.zip
