name: 🖥️ Windows Builds

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches:
      - master
    tags:
      - v*
  pull_request:
    branches:
      - master
    paths-ignore:
      - '**/*.md'
      - '.clang-format'
      - '.codacy.yaml'
      - '.github/*'
      - '.github/workflows/lint-gamedb.yml'
      - '.github/workflows/linux-workflow.yml'
      - '.github/workflows/macos-workflow.yml'
      - '.github/workflows/scripts/linux/**'
      - '.github/workflows/scripts/validation/**'
      - '.gitignore'
      - 'bin/PCSX2_keys.ini.default'
      - 'build.sh'
      - 'buildbot.xml'
      - 'linux_various/**'
      - 'mscompile.cmd'
      - 'pcsx2/CDVD/Linux/**'
      - 'pcsx2/DEV9/Linux/**'
      - 'pcsx2/Linux/**'
      - 'pcsx2/PAD/Linux/**'
      - 'pcsx2/SPU2/Linux/**'
      - 'pcsx2/USB/linux/**'

jobs:
  build:
    strategy:
      # Prevent one build from failing everything (although maybe those should be included as experimental builds instead)
      fail-fast: false
      matrix:
        os: [windows-2019]
        platform: [x64]
        configuration: [Release, Release AVX2, CMake, Qt]
        experimental: [false]

    name: ${{ matrix.configuration }}
    runs-on: ${{ matrix.os }}
    continue-on-error: ${{ matrix.experimental }}
    # Set some sort of timeout in the event of run-away builds.  We are limited on concurrent jobs so, get rid of them.
    timeout-minutes: 60

    env:
      POWERSHELL_TELEMETRY_OPTOUT: 1
      BUILDCACHE_COMPRESS_FORMAT: ZSTD
      BUILDCACHE_COMPRESS_LEVEL: 9
      BUILDCACHE_MAX_CACHE_SIZE: 536870912 # 512MB
      BUILDCACHE_DIRECT_MODE: true
      BUILDCACHE_LOG_FILE: ${{ github.workspace }}\buildcache.log

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v3

      - name: Checkout Submodules
        run: git submodule update --init --recursive -j $env:NUMBER_OF_PROCESSORS

      - name: Setup Buildcache
        if: matrix.configuration == 'CMake' # TODO: buildcache on VS
        uses: mikehardy/buildcache-action@v1.2.2
        with:
          cache_key: ${{ matrix.os }} ${{ matrix.platform }} ${{ matrix.configuration }}

      - name: Verify VS Project Files
        if: matrix.configuration != 'CMake'
        run: .github\workflows\scripts\windows\validate-vs-filters.ps1

      - name: Setup msbuild
        if: matrix.configuration != 'CMake'
        uses: microsoft/setup-msbuild@v1

      - name: Download Qt build files
        if: matrix.configuration == 'Qt'
        shell: cmd
        run: |
          cd 3rdparty\qt
          aria2c https://github.com/PCSX2/pcsx2-windows-dependencies/releases/download/2022-01-20/qt-6.2.2-x64.7z
          7z x qt-6.2.2-x64.7z
          del qt-6.2.2-x64.7z

      - name: Generate CMake
        if: matrix.configuration == 'CMake'
        id: cmake
        shell: cmd
        run: |
          if "${{ github.event.inputs.retainDebugArtifacts }}"=="true" (SET type=RelWithDebInfo) else (SET type=Release)
          if "${{ matrix.platform }}"=="Win32" (SET vcvars=vcvarsamd64_x86.bat) else (SET vcvars=vcvars64.bat)
          call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\%vcvars%"
          echo ::set-output name=buildtype::%type%
          echo ::set-output name=vcvars::%vcvars%
          cmake . -B build -DCMAKE_BUILD_TYPE=%type% -DLTO_PCSX2_CORE=ON -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_CXX_COMPILER_LAUNCHER=..\buildcache\bin\buildcache.exe -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON

      - name: Build PCSX2
        shell: cmd
        env:
          # Set to 'true' to retain the .pdb / .exp / .lib, etc files which can be useful for repro'ing issues that only occur in the compiled .exe
          RetainDebuggingArtifacts: ${{ github.event.inputs.retainDebugArtifacts == 'true' }}
        run: |
          if "${{ matrix.configuration }}"=="CMake" (
            call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
            cmake --build build --config ${{ steps.cmake.outputs.buildtype }}
          ) else (
              if "${{ matrix.configuration }}"=="Qt" (
                rem This is hardcoded to Release AVX2 for now, because of the artifact naming below.
                msbuild "PCSX2_qt.sln" /m /v:m /p:Configuration="Release AVX2" /p:Platform="${{ matrix.platform }}"
              ) else (
                msbuild "PCSX2_suite.sln" /m /v:m /p:Configuration="${{ matrix.configuration }}" /p:Platform="${{ matrix.platform }}"
              )
          )

      - name: Run Tests
        if: matrix.configuration == 'CMake'
        shell: cmd
        run: |
          call "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\${{ steps.cmake.outputs.vcvars }}"
          cmake --build build --config ${{ steps.cmake.outputs.buildtype }} --target unittests

      - name: Prepare Artifact Metadata
        id: artifact-metadata
        shell: bash
        run: |
          ARCH=$([ "${{ matrix.platform }}" == Win32 ] && echo "32bit" || echo "64bit")
          case "${{ matrix.configuration }}" in
            Release) SIMD="SSE4";;
            *AVX2)   SIMD="AVX2";;
            Qt)      SIMD="QT";;
            CMake)   SIMD="CMake"
                     cp build/pcsx2/pcsx2* bin/ ;;
            *)       SIMD="UNKNOWN";;
          esac
          if [ ${{ github.event_name }} == "pull_request" ]; then
            PR_SHA=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")
            ARTIFACT_NAME="PCSX2-${ARCH}-${SIMD}"
            if [ ! -z "${{ github.event.pull_request.number }}" ]; then
              PR_NUM=${{ github.event.pull_request.number }}
              ARTIFACT_NAME="${ARTIFACT_NAME}-pr[${PR_NUM}]"
            fi
            ARTIFACT_NAME="${ARTIFACT_NAME}-sha[${PR_SHA}]"
            if [ ! -z "${{ github.event.pull_request.title }}" ]; then
              PR_TITLE=$(echo "${{ github.event.pull_request.title }}" | tr -cd '[a-zA-Z0-9[:space:]]_-')
              ARTIFACT_NAME="${ARTIFACT_NAME}-title["${PR_TITLE}""
            fi
          else
            SHA=$(git rev-parse --short "$GITHUB_SHA")
            ARTIFACT_NAME="PCSX2-${ARCH}-${SIMD}-sha[${SHA}"
          fi
          TRIMMED_ARTIFACT_NAME=$(printf "%.199s]" "$ARTIFACT_NAME")
          echo "name=$TRIMMED_ARTIFACT_NAME"
          echo "##[set-output name=name;]${TRIMMED_ARTIFACT_NAME}"
          echo "##[set-output name=arch;]${ARCH}"
          echo "##[set-output name=simd;]${SIMD}"

      - name: Upload artifact
        uses: actions/upload-artifact@v2
        continue-on-error: true
        with:
          name: ${{ steps.artifact-metadata.outputs.name }}
          path: |
            ./bin
            !./bin/**/*.bsc
            !./bin/**/*.exp
            !./bin/**/*.ilk
            !./bin/**/*.iobj
            !./bin/**/*.ipdb
            !./bin/**/*.pdb
            !./bin/**/*.lib

      - name: Upload artifact - with symbols
        if: matrix.configuration != 'CMake'
        uses: actions/upload-artifact@v2
        continue-on-error: true
        with:
          name: ${{ steps.artifact-metadata.outputs.name }}-symbols
          path: ./bin/**/*.pdb

      # ---- Release / Tagging related steps ----
      - name: Prepare Build Artifacts
        if: github.repository == 'PCSX2/pcsx2' && startsWith(github.ref, 'refs/tags/') && matrix.configuration != 'CMake' && matrix.configuration != 'Qt'
        run: |
          mkdir -p ./ci-artifacts/
          7z a ./ci-artifacts/windows-${{ steps.artifact-metadata.outputs.arch }}-${{ steps.artifact-metadata.outputs.simd }}.7z ./bin/* '-xr!*bsc' '-xr!*.exp' '-xr!*.ilk' '-xr!*.iobj' '-xr!*.ipdb' '-xr!*.pdb' '-xr!*.lib'
          7z a ./ci-artifacts/windows-${{ steps.artifact-metadata.outputs.arch }}-${{ steps.artifact-metadata.outputs.simd }}-symbols.7z ./bin/*.pdb
          ls ./ci-artifacts/

      - name: Upload Assets and Potential Publish Release
        if: github.repository == 'PCSX2/pcsx2' && startsWith(github.ref, 'refs/tags/') && matrix.configuration != 'CMake' && matrix.configuration != 'Qt'
        env:
          GITHUB_TOKEN: ${{ secrets.BOT_PAT }}
          ASSET_DIR: ${{ github.WORKSPACE }}/ci-artifacts
          ASSET_EXTENSION: 7z
          TAG_TO_SEARCH_FOR: ${{ github.REF }}
        run: |
          cd ./.github/workflows/scripts/releases/upload-release-artifacts
          npm ci
          node index.js
