---
name: 🎁 Package with vcpkg
on:
  push:
    branches:
      - master
      - release-**
  pull_request:
  release:
    types: ['published', 'released']


jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - triplet: 'x64-windows'
            os: 'windows-2019'

          - triplet: 'x64-linux'
            os: 'ubuntu-20.04'

          - triplet: 'x64-osx'
            os: 'macos-10.15'

    steps:
# Avoid that we run out of disk space
#      - name: Free additional space
#        uses: easimon/maximize-build-space@master
#        if: ${{ matrix.triplet == 'x64-linux' }}
#        with:
#          remove-haskell: true # 9G
#          remove-android: true # 18G
#          remove-dotnet: true # 30G

      - name: 🐣 Checkout
        uses: actions/checkout@v2
        with:
          submodules: recursive

      - name: 🌾 Prepare vars
        id: vars
        shell: bash
        run: |
          ./scripts/ci/env_gh.sh

          case ${{ matrix.triplet }} in
            x64-windows)
              BUILD_ROOT="C:"
              echo "::set-output name=MONO::"
              echo "::set-output name=PATHCONVERT::cygpath -u"
              echo "::set-output name=EXCLUDE_TESTS::(smoke_test)"
              ;;

            x64-linux)
              BUILD_ROOT="/home/runner"
              echo "::set-output name=MONO::mono"
              echo "::set-output name=OVERLAY::vcpkg/overlay_system_qt"
              echo "::set-output name=PATHCONVERT::echo"
              echo "::set-output name=INSTALL_QT::true"
              echo "::set-output name=QT_TARGET::desktop"
              echo "::set-output name=QT_ARCH::"
              ;;

            x64-osx)
              BUILD_ROOT="/Users/runner"
              echo "::set-output name=MONO::mono"
              echo "::set-output name=OVERLAY::vcpkg/overlay_system_qt"
              echo "::set-output name=PATHCONVERT::echo"
              echo "::set-output name=INSTALL_QT::true"
              echo "::set-output name=QT_TARGET::desktop"
              echo "::set-output name=QT_ARCH::"
              ;;
          esac

          echo "::set-output name=VCPKG_ROOT::${BUILD_ROOT}/src"
          echo "::set-output name=BUILD_TYPE::Release"
          echo "::set-output name=BUILD_ROOT::${BUILD_ROOT}"

          echo "VCPKG_ROOT=${BUILD_ROOT}/src" >> $GITHUB_ENV
          echo "CMAKE_BUILD_DIR=${BUILD_ROOT}/builddir" >> $GITHUB_ENV
          echo "VCPKG_DEFAULT_BINARY_CACHE=${BUILD_ROOT}/vcpkg_cache" >> $GITHUB_ENV

      - name: 🐩 Install CMake and Ninja
        uses: lukka/get-cmake@latest

      - name: 📪 Clone vcpkg
        shell: bash
        run: |
          VCPKG_SHA=$(head -1 .git/modules/vcpkg/HEAD)
          mkdir -p "${{ env.VCPKG_DEFAULT_BINARY_CACHE }}"
          mkdir -p "${{ steps.vars.outputs.VCPKG_ROOT }}"
          cd "${{ steps.vars.outputs.VCPKG_ROOT }}"
          git init
          git remote add origin https://github.com/microsoft/vcpkg.git
          git fetch --depth 1 origin $VCPKG_SHA
          git checkout FETCH_HEAD

      - name: 📫 Cache vcpkg
        id: cache-vcpkg-tool
        uses: pat-s/always-upload-cache@v2.1.5
        with:
          path: |
            ${{ steps.vars.outputs.VCPKG_ROOT }}/vcpkg
            ${{ steps.vars.outputs.VCPKG_ROOT }}/vcpkg.exe
          key: ${{ runner.os }}-${{ hashFiles('.git/modules/vcpkg/HEAD') }}-x

      - name: 📬 Bootstrap vcpkg
        if: steps.cache-vcpkg-tool.outputs.cache-hit != 'true'
        shell: bash
        working-directory: ${{ steps.vars.outputs.VCPKG_ROOT }}
        run: |
          if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null ; then
            ./bootstrap-vcpkg.bat
          else
            ./bootstrap-vcpkg.sh
          fi

      - name: 🔐 Setup NuGet Credentials
        shell: bash
        run: |
          ${{ steps.vars.outputs.VCPKG_ROOT }}/vcpkg fetch nuget
          ${{ steps.vars.outputs.MONO }} $(${{ steps.vars.outputs.VCPKG_ROOT }}/vcpkg fetch nuget | tail -n 1) \
          sources add \
          -source "https://nuget.pkg.github.com/opengisch/index.json" \
          -storepasswordincleartext \
          -name "GitHub" \
          -username "opengisch" \
          -password "${{ secrets.GITHUB_TOKEN }}"

          ${{ steps.vars.outputs.MONO }} $(${{ steps.vars.outputs.VCPKG_ROOT }}/vcpkg fetch nuget | tail -n 1) \
          setapikey ${{ secrets.GITHUB_TOKEN }} -src "https://nuget.pkg.github.com/opengisch/index.json"

      - name: 🧽 Developer Command Prompt for Microsoft Visual C++
        uses: ilammy/msvc-dev-cmd@v1
        if: ${{ matrix.os == 'windows-2019' }}

      - name: 🔥 Free additional space
        if: ${{ matrix.triplet == 'x64-linux' }}
        run: |
          df -h
          sudo rm -rf /usr/share/dotnet/sdk
          sudo rm -rf /usr/share/rust
          sudo rm -rf /usr/share/swift
          sudo rm -rf /usr/local/lib/android
          sudo apt remove llvm-* ghc-* google-chrome-* dotnet-sdk-* azure-cli google-cloud-sdk google-chrome-stable firefox
          dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -n | tail -n 100
          du -a /usr/share | sort -n -r | head -n 10
          du -a /usr/local/share | sort -n -r | head -n 10
          df -h
          sudo apt clean
          df -h

      - name: 💐 Install Qt
        if: ${{ steps.vars.outputs.INSTALL_QT }}
        uses: jurplel/install-qt-action@v2
        with:
          version: 5.15.2
          modules: 'qtcharts'
          target: ${{ steps.vars.outputs.QT_TARGET }}
          arch: ${{ steps.vars.outputs.QT_ARCH }}

      - name: 🐧 Prepare linux build env
        if: ${{ matrix.triplet == 'x64-linux' }}
        run: |
          sudo apt-get update
          sudo apt-get install -y gperf autopoint '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
          sudo apt-get remove -y libopenexr-dev # Avoid gdal picking this system lib up
          # Required to run unit tests on linux
          echo "QT_QPA_PLATFORM=offscreen" >> $GITHUB_ENV
          echo "TESTWRAPPER=xvfb-run" >> $GITHUB_ENV
          echo "EXTRA_CMAKE_ARGS=-GNinja -DCMAKE_INSTALL_PREFIX=/usr -DLINUXDEPLOY_EXECUTABLE=${{ steps.vars.outputs.BUILD_ROOT }}/linuxdeploy-x86_64.AppImage" >> $GITHUB_ENV

      - name: Install linuxdeploy
        if: ${{ matrix.triplet == 'x64-linux' }}
        uses: miurahr/install-linuxdeploy-action@v1
        with:
          dir: ${{ steps.vars.outputs.BUILD_ROOT }}
          plugins: qt appimage

      # transifex-client is not compatible with py >= 3.10
      # temporary band aid
      - uses: actions/setup-python@v2
        with:
          python-version: '3.9'

      - name: 🌍 Pull Translations
        shell: bash
        env:
          TX_TOKEN: ${{ secrets.TX_TOKEN }}
        run: |
          if [[ -z "${TX_TOKEN}" ]]; then
            echo "TX_TOKEN not set, skip tx pull"
          else
            pip install transifex-client>=0.14.3
            ./scripts/ci/pull_translations.sh
          fi

      - name: Prepare osx build env
        if: ${{ matrix.os == 'macos-10.15' }}
        run: |
          brew install automake bison flex
          echo $(brew --prefix bison)/bin >> $GITHUB_PATH
          echo $(brew --prefix flex)/bin >> $GITHUB_PATH
          echo "EXTRA_CMAKE_ARGS=-GXcode -DUSE_MAC_BUNDLING=OFF" >> $GITHUB_ENV
          sudo xcode-select -s /Applications/Xcode_12.app/Contents/Developer

      - name: 🌱 Install dependencies and generate project files
        shell: bash
        env:
          WORKSPACE: ${{ github.workspace }}
          VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite'
        run: |
          # Convert paths to bash compatible ones. Thanks to whoever decided to use drive letters and backslashes.
          CMAKE_BUILD_DIR=$( ${{ steps.vars.outputs.PATHCONVERT }} "${CMAKE_BUILD_DIR}" )
          VCPKG_ROOT=$( ${{ steps.vars.outputs.PATHCONVERT }} "${VCPKG_ROOT}" )
          SOURCE_DIR=$( ${{ steps.vars.outputs.PATHCONVERT }} "${WORKSPACE}" )

          source ./scripts/version_number.sh
          source ./scripts/ci/generate-version-details.sh

          overlay_ports=(${WORKSPACE}/${{ steps.vars.outputs.OVERLAY }} ${WORKSPACE}/vcpkg/overlay)
          echo "Building with $(IFS=\; ; echo "${overlay_ports[*]}")"
          cmake -S "${SOURCE_DIR}" \
                -B "${CMAKE_BUILD_DIR}" \
                -DCMAKE_BUILD_TYPE=${{ steps.vars.outputs.BUILD_TYPE }} \
                -DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" \
                -DVCPKG_OVERLAY_PORTS=$(IFS=\; ; echo "${overlay_ports[*]}") \
                -DVCPKG_TARGET_TRIPLET="${{ matrix.triplet }}" \
                -DWITH_VCPKG=ON \
                -DWITH_SPIX=ON \
                -DAPP_VERSION="${APP_VERSION}" \
                -DAPP_VERSION_STR="${APP_VERSION_STR}" \
                -DAPP_PACKAGE_NAME="${APP_PACKAGE_NAME}" \
                -DENABLE_TESTS=ON \
                ${EXTRA_CMAKE_ARGS}

      - name: 📑 Upload Build Logs
        uses: actions/upload-artifact@v2
        if: failure()
        with:
          name: build-logs-${{ matrix.triplet }}
          path: ${{ steps.vars.outputs.VCPKG_ROOT }}/buildtrees/**/*.log

      - name: 🌋 Build
        run: |
          cmake --build "${{ env.CMAKE_BUILD_DIR }}" --config ${{ steps.vars.outputs.BUILD_TYPE }} # --target qfield

      - name: 🧫 Test
        shell: bash
        env:
          WORKSPACE: ${{ github.workspace }}
        run: |
          SOURCE_DIR=$( ${{ steps.vars.outputs.PATHCONVERT }} "${WORKSPACE}" )
          pip install -r "${SOURCE_DIR}/test/spix/requirements.txt"
          cd "${{ env.CMAKE_BUILD_DIR }}"
          ${TESTWRAPPER} ctest --output-on-failure -E '${{ steps.vars.outputs.EXCLUDE_TESTS }}' -C ${{ steps.vars.outputs.BUILD_TYPE }}

      - name: Package
        shell: bash
        run: |
          export LD_LIBRARY_PATH="${{ env.CMAKE_BUILD_DIR }}/vcpkg_installed/${{ matrix.triplet }}/lib/":${LD_LIBRARY_PATH}
          cmake --build  "${{ env.CMAKE_BUILD_DIR }}" --target bundle --config Release
          case ${{ matrix.triplet }} in
            x64-linux)
              echo "ARTIFACT_PATHNAME=${{ env.CMAKE_BUILD_DIR }}/QField-x86_64.AppImage" >> $GITHUB_ENV
              echo "ARTIFACT_NAME=${{ steps.vars.outputs.CI_PACKAGE_FILE_BASENAME }}-linux-x64.AppImage" >> $GITHUB_ENV
              ;;

            x64-windows)
              ARTIFACT_PATHNAME=$(ls ${{ env.CMAKE_BUILD_DIR }}/QField-*-win64.* | head -n 1)
              ARTIFACT_NAME=$(basename $ARTIFACT_PATHNAME)
              echo "ARTIFACT_PATHNAME=${ARTIFACT_PATHNAME}" >> $GITHUB_ENV
              echo "ARTIFACT_NAME=${{ steps.vars.outputs.CI_PACKAGE_FILE_BASENAME }}-windows-x64.exe" >> $GITHUB_ENV
              ;;
          esac

      - name: 📑 Upload Package Logs
        uses: actions/upload-artifact@v2
        if: failure()
        with:
          name: package-logs-${{ matrix.triplet }}
          path: ${{ steps.vars.outputs.BUILD_ROOT }}/builddir/_CPack_Packages/**/*.log

      - name: 📦 Upload package
        if: ${{ env.ARTIFACT_NAME != null }}
        uses: actions/upload-artifact@v2
        with:
          name: "QField-dev-${{ matrix.triplet }}-${{ steps.vars.outputs.BUILD_TYPE }}"
          path: ${{ env.ARTIFACT_PATHNAME }}

      - name: 📊 Upload test report
        uses: actions/upload-artifact@v2
        with:
          name: "test-report-${{ matrix.triplet }}-${{ steps.vars.outputs.BUILD_TYPE }}"
          path: "${{ env.CMAKE_BUILD_DIR }}/report"

      - name: 🪔 Get the current release version
        id: get_version
        shell: bash
        run: |
          echo "::set-output name=version::${GITHUB_REF##*/}"

      - name: 🚀 Upload Release Asset
        if: github.event_name == 'release' && startsWith(github.ref, 'refs/tags/v') && env.ARTIFACT_NAME != null
        uses: shogo82148/actions-upload-release-asset@v1
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: ${{ env.ARTIFACT_PATHNAME }}
          asset_name: ${{ env.ARTIFACT_NAME }}
          overwrite: true
