name: Test Windows on: push: paths-ignore: - ".github/workflows/docs.yml" - "docs/**" pull_request: paths-ignore: - ".github/workflows/docs.yml" - "docs/**" workflow_dispatch: permissions: contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: runs-on: windows-latest strategy: fail-fast: false matrix: python-version: ["pypy3.10", "pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12-dev"] timeout-minutes: 30 name: Python ${{ matrix.python-version }} steps: - name: Checkout Pillow uses: actions/checkout@v4 - name: Checkout cached dependencies uses: actions/checkout@v4 with: repository: python-pillow/pillow-depends path: winbuild\depends - name: Checkout extra test images uses: actions/checkout@v4 with: repository: python-pillow/test-images path: Tests\test-images # sets env: pythonLocation - name: Set up Python uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} cache: pip cache-dependency-path: ".github/workflows/test-windows.yml" - name: Print build system information run: python3 .github/workflows/system-info.py - name: python3 -m pip install pytest pytest-cov pytest-timeout defusedxml run: python3 -m pip install pytest pytest-cov pytest-timeout defusedxml - name: Install dependencies id: install run: | 7z x winbuild\depends\nasm-2.16.01-win64.zip "-o$env:RUNNER_WORKSPACE\" echo "$env:RUNNER_WORKSPACE\nasm-2.16.01" >> $env:GITHUB_PATH choco install ghostscript --version=10.0.0.20230317 echo "C:\Program Files\gs\gs10.00.0\bin" >> $env:GITHUB_PATH # Install extra test images xcopy /S /Y Tests\test-images\* Tests\images # make cache key depend on VS version & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" ` | find """catalog_buildVersion""" ` | ForEach-Object { $a = $_.split(" ")[1]; echo "vs=$a" >> $env:GITHUB_OUTPUT } shell: pwsh - name: Cache build id: build-cache uses: actions/cache@v3 with: path: winbuild\build key: ${{ hashFiles('winbuild\build_prepare.py') }}-${{ hashFiles('.github\workflows\test-windows.yml') }}-${{ env.pythonLocation }}-${{ steps.install.outputs.vs }} - name: Prepare build if: steps.build-cache.outputs.cache-hit != 'true' run: | & python.exe winbuild\build_prepare.py -v shell: pwsh - name: Build dependencies / libjpeg-turbo if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libjpeg.cmd" - name: Build dependencies / zlib if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_zlib.cmd" - name: Build dependencies / xz if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_xz.cmd" - name: Build dependencies / WebP if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libwebp.cmd" - name: Build dependencies / LibTiff if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libtiff.cmd" # for FreeType CBDT/SBIX font support - name: Build dependencies / libpng if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libpng.cmd" # for FreeType WOFF2 font support - name: Build dependencies / brotli if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_brotli.cmd" - name: Build dependencies / FreeType if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_freetype.cmd" - name: Build dependencies / LCMS2 if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_lcms2.cmd" - name: Build dependencies / OpenJPEG if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_openjpeg.cmd" # GPL licensed - name: Build dependencies / libimagequant if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_libimagequant.cmd" # Raqm dependencies - name: Build dependencies / HarfBuzz if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_harfbuzz.cmd" # Raqm dependencies - name: Build dependencies / FriBidi if: steps.build-cache.outputs.cache-hit != 'true' run: "& winbuild\\build\\build_dep_fribidi.cmd" # trim ~150MB for each job - name: Optimize build cache if: steps.build-cache.outputs.cache-hit != 'true' run: rmdir /S /Q winbuild\build\src shell: cmd - name: Build Pillow run: | $FLAGS="-C raqm=vendor -C fribidi=vendor" if ('${{ github.event_name }}' -ne 'pull_request') { $FLAGS+=" -C imagequant=disable" } cmd /c "winbuild\build\build_env.cmd && $env:pythonLocation\python.exe -m pip install -v $FLAGS ." & $env:pythonLocation\python.exe selftest.py --installed shell: pwsh # skip PyPy for speed - name: Enable heap verification if: "!contains(matrix.python-version, 'pypy')" run: | & reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\python.exe" /v "GlobalFlag" /t REG_SZ /d "0x02000000" /f - name: Test Pillow run: | path %GITHUB_WORKSPACE%\\winbuild\\build\\bin;%PATH% python.exe -m pytest -vx -W always --cov PIL --cov Tests --cov-report term --cov-report xml Tests shell: cmd - name: Prepare to upload errors if: failure() run: | mkdir -p Tests/errors shell: bash - name: Upload errors uses: actions/upload-artifact@v3 if: failure() with: name: errors path: Tests/errors - name: After success run: | .ci/after_success.sh shell: pwsh - name: Upload coverage uses: codecov/codecov-action@v3 with: file: ./coverage.xml flags: GHA_Windows name: ${{ runner.os }} Python ${{ matrix.python-version }} - name: Build wheel id: wheel if: "github.event_name != 'pull_request'" run: | mkdir fribidi copy winbuild\build\bin\fribidi* fribidi setlocal EnableDelayedExpansion for %%f in (winbuild\build\license\*) do ( set x=%%~nf rem Skip FriBiDi license, it is not included in the wheel. set fribidi=!x:~0,7! if NOT !fribidi!==fribidi ( rem Skip imagequant license, it is not included in the wheel. set libimagequant=!x:~0,13! if NOT !libimagequant!==libimagequant ( echo. >> LICENSE echo ===== %%~nf ===== >> LICENSE echo. >> LICENSE type %%f >> LICENSE ) ) ) for /f "tokens=3 delims=/" %%a in ("${{ github.ref }}") do echo dist=dist-%%a >> %GITHUB_OUTPUT% call winbuild\\build\\build_env.cmd %pythonLocation%\python.exe -m pip wheel -v -C raqm=vendor -C fribidi=vendor -C imagequant=disable . shell: cmd - name: Upload wheel uses: actions/upload-artifact@v3 if: "github.event_name != 'pull_request'" with: name: ${{ steps.wheel.outputs.dist }} path: "*.whl" - name: Upload fribidi.dll if: "github.event_name != 'pull_request' && matrix.python-version == 3.11" uses: actions/upload-artifact@v3 with: name: fribidi path: fribidi\* success: permissions: contents: none needs: build runs-on: ubuntu-latest name: Windows Test Successful steps: - name: Success run: echo Windows Test Successful