name: Build Artifacts (Windows+VS2022)
on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'
        type: choice
        options:
        - info
        - warning
        - debug
      tags:
        description: 'Test scenario tags'
        required: false
        type: boolean
  pull_request:
    branches: [master, develop]
    paths-ignore:
    - '**/*.md'
    - '.circleci/**'
    - '.cirrus.yml'
  push:
    branches: [master, develop, vs2022]
    paths-ignore:
    - '**/*.md'
    - '.circleci/**'
    - '.cirrus.yml'
  release:
    types: [published]
  schedule:
    - cron: '0 16 * * *'
concurrency:
  group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.run_id }}
  cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
defaults:
  run:
    shell: cmd
env:
  CACHE_EPOCH: 148-2
  GOPROXY: direct
jobs:
  windows-release:
    runs-on: windows-2025
    permissions:
      contents: write
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: x86
            crt-linkage: dynamic
            build_type: Release
            winsdk_version: 10.0.26100.0
            build_options: -use-allocator=tbbmalloc -component-build
          - arch: x86
            crt-linkage: dynamic
            build_type: Debug
            winsdk_version: 10.0.26100.0
            build_options: -use-allocator=tbbmalloc -component-build
          - arch: x64
            crt-linkage: dynamic
            build_type: Release
            winsdk_version: 10.0.26100.0
            build_options: -use-allocator=tbbmalloc -component-build
          - arch: x64
            crt-linkage: dynamic
            build_type: Debug
            winsdk_version: 10.0.26100.0
            build_options: -use-allocator=tbbmalloc -component-build
          - arch: arm64
            crt-linkage: dynamic
            build_type: Release
            winsdk_version: 10.0.26100.0
            build_options: -component-build
    env:
      BUILD_TYPE: '${{ matrix.build_type }}'
    steps:
      - uses: actions/checkout@v5
      - name: Checkout with shallow submodules
        run: |
          # unshallow must come first otherwise submodule may be get unshallowed
          git fetch --tags --unshallow
          git submodule update --init --depth 1
      - name: Cache toolchain, nasm, nsis and wixtoolset 3
        id: toolchain-cache
        uses: actions/cache@v5
        with:
          path: |
            third_party/nasm
            third_party/llvm-build/Release+Asserts
            third_party/wix314
            third_party/nsis
          key: ${{ runner.os }}-toolchain-nsis-${{ hashFiles('CLANG_REVISION') }}-v${{ env.CACHE_EPOCH }}-v2
      - name: Cache msvc curl
        id: curl-cache
        uses: actions/cache@v5
        with:
          path: |
            third_party/libcurl-vc16-arm64-release-static-ipv6-sspi-schannel
            third_party/libcurl-vc16-x64-release-static-ipv6-sspi-schannel
            third_party/libcurl-vc16-x86-release-static-ipv6-sspi-schannel
          key: ${{ runner.os }}-msvc-dynamic-curl-vc16-${{ matrix.arch }}-v2
      - uses: actions/setup-go@v6
        with:
          go-version: '>=1.20.0'
          cache-dependency-path: |
            tools/go.sum
            third_party/boringssl/src/go.sum
      - name: Build build tool
        run: |
          cd tools
          go build
      - name: "Install dependency: clang, nasm, nsis and wixtoolset 3"
        if: ${{ steps.toolchain-cache.outputs.cache-hit != 'true' }}
        run: |
          scripts\download-toolchain.bat
      - name: "Install dependency: curl"
        if: ${{ steps.curl-cache.outputs.cache-hit != 'true' }}
        run: |
          scripts\download-curl-msvc.bat ${{ matrix.arch }}
      - name: Build Binary
        run: |
          set VCToolsVersion=
          set Winsdk=${{ matrix.winsdk_version }}
          set "WindowsSDKVersion=%Winsdk%\"
          if "${{ matrix.arch }}" == "arm64" (call :SetNewVCToolsVersion)
          set vsdevcmd=C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat
          set "VSCMD_START_DIR=%CD%"
          set Platform=${{ matrix.arch }}

          call "%vsdevcmd%" -arch=%Platform% -host_arch=amd64 -winsdk=%Winsdk% -no_logo -vcvars_ver=%VCToolsVersion%

          tools\build --variant cli -msvc-tgt-arch=${{ matrix.arch }} -msvc-crt-linkage=${{ matrix.crt-linkage }} -nc -build-benchmark -build-test ${{ matrix.build_options }} || exit /b
          tools\build --variant gui -msvc-tgt-arch=${{ matrix.arch }} -msvc-crt-linkage=${{ matrix.crt-linkage }} -nc ${{ matrix.build_options }} || exit /b
          tools\build --variant dylib -msvc-tgt-arch=${{ matrix.arch }} -msvc-crt-linkage=${{ matrix.crt-linkage }} -nc ${{ matrix.build_options }} || exit /b

          exit /b 0

          :SetNewVCToolsVersion
          set VCToolsVersion=
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-gui
          path: |
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/yass.exe
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/*.dll
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/LICENSE
            !build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/YASS-C.dll
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-nsis-installer
          path: |
            *.exe
          compression-level: 0 # no compression
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-msi-installer
          path: |
            *.msi
          compression-level: 0 # no compression
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-cli
          path: |
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/yass_cli.exe
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/*.dll
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/LICENSE
            !build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/YASS-C.dll
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-dylib
          path: |
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/devel
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/yass.py
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/*.dll
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/LICENSE
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-test
          path: |
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/yass_test.exe
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/*.dll
            !build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/YASS-C.dll
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-benchmark
          path: |
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/yass_benchmark.exe
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/*.dll
            !build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/YASS-C.dll
      - uses: actions/upload-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-pdb
          path: |
            build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}/*.pdb
          compression-level: 9 # maximum compression
      - name: Run tests (dummy)
        if: ${{ matrix.arch == 'x64' || matrix.arch == 'x86' }}
        run: |
          build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}\yass_cli --version || exit /b
          build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}\yass --version || exit /b
      - name: Run tests (python)
        if: ${{ matrix.arch == 'x64' }}
        run: |
          python build-msvc-${{ matrix.arch }}-${{ matrix.crt-linkage }}\yass.py --version || exit /b
      - name: Upload dist tarball (including debuginfo)
        if: ${{ github.event_name == 'release' && matrix.build_type == 'Release' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        shell: bash
        run: |
          gh release upload ${{ github.event.release.tag_name }} *.zip *.exe *.msi
  windows-release-native-test:
    runs-on: windows-2022
    needs: windows-release
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: x86
            crt-linkage: dynamic
            build_type: Release
            gtest_repeat_times: 10
          - arch: x86
            crt-linkage: dynamic
            build_type: Debug
            gtest_repeat_times: 2
          - arch: x64
            crt-linkage: dynamic
            build_type: Release
            gtest_repeat_times: 10
          - arch: x64
            crt-linkage: dynamic
            build_type: Debug
            gtest_repeat_times: 2
    steps:
      - name: Download built executables
        uses: actions/download-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-test
      - name: Run tests
        if: ${{ matrix.arch == 'x86' || matrix.arch == 'x64' }}
        run: |
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type socks4 || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type socks4a || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type socks5 || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type socks5h || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type http || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type socks4a --ipv6_mode || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type socks5 --ipv6_mode || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type socks5h --ipv6_mode || exit /b
          yass_test --gtest_shuffle --gtest_repeat=${{ matrix.gtest_repeat_times }} --gtest_throw_on_failure --proxy_type http --ipv6_mode || exit /b
  windows-release-native-benchmark:
    runs-on: windows-2022
    needs: windows-release
    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: x86
            crt-linkage: dynamic
            build_type: Release
          - arch: x64
            crt-linkage: dynamic
            build_type: Release
    steps:
      - name: Download built executables
        uses: actions/download-artifact@v6
        with:
          name: msvc-release-${{ matrix.build_type }}-${{ matrix.arch }}-${{ matrix.crt-linkage }}-${{ github.run_id }}-benchmark
      - name: Run benchmarks
        if: ${{ matrix.arch == 'x86' || matrix.arch == 'x64' }}
        run: |
          yass_benchmark || exit /b
