name: Windows x86_64

on:
  pull_request:
    branches:
      - master
      - 3.4
      - 4.x
      - 5.x
    paths-ignore:
      - '.github/workflows/build_wheels_linux*'
      - '.github/workflows/build_wheels_macos*'
  release:
    types: [published, edited]
  schedule:
    - cron: '0 3 * * 6'
  workflow_dispatch:


jobs:
  Build:
    runs-on: windows-2019
    strategy:
      fail-fast: false
      matrix:
        python-version: ['3.9']
        platform: [x86, x64]
        with_contrib: [0, 1]
        without_gui: [0, 1]
        build_sdist: [0]
    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
      SDIST: ${{ matrix.build_sdist || 0 }}
      ENABLE_HEADLESS: ${{ matrix.without_gui }}
      ENABLE_CONTRIB: ${{ matrix.with_contrib }}
      OPENCV_TEST_DATA_PATH: ${{ github.workspace }}\opencv_extra\testdata
    steps:
    - name: Cleanup
      shell: bash
      run: |
        rm -rf ./* || true
        rm -rf ./.??* || true
      working-directory: ${{ github.workspace }}
    - name: Setup environment
      shell: bash
      run: |
        if [[ "${{ github.event_name }}" == "schedule" || "${{ github.event_name }}" == "workflow_dispatch" ]]; then
          echo "ENABLE_ROLLING=1" >> $GITHUB_ENV
        fi
    - name: Checkout
      uses: actions/checkout@v3
      with:
        submodules: false
        fetch-depth: 0
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
        architecture: ${{ matrix.platform }}
    - name: Setup MSBuild.exe
      uses: microsoft/setup-msbuild@v1.1
    - name: Setup NASM
      uses: ilammy/setup-nasm@v1
    - name: Build a package
      # CMake 3.25 regression fix. See https://stackoverflow.com/questions/74162633/problem-compiling-from-source-opencv-with-mvsc2019-in-64-bit-version
      run: |
        python --version
        python -m pip install --upgrade pip
        python -m pip install --upgrade setuptools
        python -m pip install cmake==3.24.2
        python -m pip install toml && python -c "import toml; c = toml.load('pyproject.toml'); print('\n'.join(c['build-system']['requires']))" >> requirements.txt | python -m pip install -r requirements.txt
        set "CI_BUILD=1" && python setup.py bdist_wheel --py-limited-api=cp37 --dist-dir=%cd%\wheelhouse -v
      shell: cmd
    - name: Saving all wheels
      uses: actions/upload-artifact@v3
      with:
        name: wheels
        path: wheelhouse/opencv*.whl
    - name: Saving a wheel accordingly to matrix
      uses: actions/upload-artifact@v3
      with:
        name: wheel-${{ matrix.with_contrib }}-${{ matrix.without_gui }}-${{ matrix.build_sdist }}-${{ matrix.platform }}
        path: wheelhouse/opencv*

  Test:
    needs: [Build]
    runs-on: windows-2019
    defaults:
      run:
        shell: cmd
    strategy:
      fail-fast: false
      matrix:
        python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
        platform: [x86, x64]
        with_contrib: [0, 1]
        without_gui: [0, 1]
        build_sdist: [0]
    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
      OPENCV_TEST_DATA_PATH: ${{ github.workspace }}\opencv_extra\testdata
      PYLINT_TEST_FILE: ${{ github.workspace }}\opencv\samples\python\squares.py
    steps:
    - name: Cleanup
      shell: bash
      run: |
        rm -rf ./* || true
        rm -rf ./.??* || true
      working-directory: ${{ github.workspace }}
    - name: Checkout
      uses: actions/checkout@v3
      with:
        submodules: true
        fetch-depth: 0
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
        architecture: ${{ matrix.platform }}
    - name: Download a wheel accordingly to matrix
      uses: actions/download-artifact@v3
      with:
        name: wheel-${{ matrix.with_contrib }}-${{ matrix.without_gui }}-${{ matrix.build_sdist }}-${{ matrix.platform }}
        path: wheelhouse/
    - name: Package installation
      run: |
        cd ${{ github.workspace }}/tests
        &python -m pip install --user --no-warn-script-location (ls "../wheelhouse/opencv*.whl")
        if ($LastExitCode -ne 0) {throw $LastExitCode}
        python get_build_info.py
      shell: powershell
    - name: Run tests
      run: |
        cd ${{ github.workspace }}/opencv
        python modules\python\test\test.py -v --repo .
    - name: Pylint test
      run: |
        python -m pip install pylint==2.15.9
        cd ${{ github.workspace }}\tests
        python -m pylint $PYLINT_TEST_FILE

  Release_rolling:
    if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
    needs: [Build, Test]
    runs-on: ubuntu-20.04
    environment: opencv-python-rolling-release
    defaults:
      run:
        shell: bash
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: wheels
          path: wheelhouse/
      - name: Upload wheels for opencv_python_rolling
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_PYTHON_ROLLING_USERNAME }} -p ${{ secrets.OPENCV_PYTHON_ROLLING_PASSWORD }} --skip-existing wheelhouse/opencv_python_rolling-*
      - name: Upload wheels for opencv_contrib_python_rolling
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_CONTRIB_PYTHON_ROLLING_USERNAME }} -p ${{ secrets.OPENCV_CONTRIB_PYTHON_ROLLING_PASSWORD }} --skip-existing wheelhouse/opencv_contrib_python_rolling-*
      - name: Upload wheels for opencv_python_headless_rolling
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_PYTHON_HEADLESS_ROLLING_USERNAME }} -p ${{ secrets.OPENCV_PYTHON_HEADLESS_ROLLING_PASSWORD }} --skip-existing wheelhouse/opencv_python_headless_rolling-*
      - name: Upload wheels for opencv_contrib_python_headless_rolling
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_CONTRIB_PYTHON_HEADLESS_ROLLING_USERNAME }} -p ${{ secrets.OPENCV_CONTRIB_PYTHON_HEADLESS_ROLLING_PASSWORD }} --skip-existing wheelhouse/opencv_contrib_python_headless_rolling-*

  Pre-release:
    if: github.event_name == 'release' && github.event.release.prerelease
    needs: [Build, Test]
    runs-on: ubuntu-20.04
    environment: test-opencv-python-release
    defaults:
      run:
        shell: bash
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: wheels
          path: wheelhouse/
      - name: Upload all wheels
        run: |
          python -m pip install twine
          python -m twine upload --repository testpypi -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_PASSWORD }} --skip-existing wheelhouse/opencv_*

  Release:
    if: github.event_name == 'release' && !github.event.release.prerelease
    needs: [Build, Test]
    runs-on: ubuntu-20.04
    environment: opencv-python-release
    defaults:
      run:
        shell: bash
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: wheels
          path: wheelhouse/
      - name: Upload wheels for opencv_python
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_PYTHON_USERNAME }} -p ${{ secrets.OPENCV_PYTHON_PASSWORD }} --skip-existing wheelhouse/opencv_python-*
      - name: Upload wheels for opencv_contrib_python
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_CONTRIB_PYTHON_USERNAME }} -p ${{ secrets.OPENCV_CONTRIB_PYTHON_PASSWORD }} --skip-existing wheelhouse/opencv_contrib_python-*
      - name: Upload wheels for opencv_python_headless
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_PYTHON_HEADLESS_USERNAME }} -p ${{ secrets.OPENCV_PYTHON_HEADLESS_PASSWORD }} --skip-existing wheelhouse/opencv_python_headless-*
      - name: Upload wheels for opencv_contrib_python_headless
        run: |
          python -m pip install twine
          python -m twine upload -u ${{ secrets.OPENCV_CONTRIB_PYTHON_HEADLESS_USERNAME }} -p ${{ secrets.OPENCV_CONTRIB_PYTHON_HEADLESS_PASSWORD }} --skip-existing wheelhouse/opencv_contrib_python_headless-*