run on matrix #24
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Test PyPi Wheels on Windows | |
| on: | |
| push: | |
| branches: [ "main", "feat/win-compilation-test" ] | |
| workflow_call: | |
| inputs: | |
| publish_target: | |
| description: 'Publish Destination' | |
| required: true | |
| default: 'testpypi' | |
| type: string | |
| workflow_dispatch: | |
| inputs: | |
| publish_target: | |
| description: 'Publish Destination' | |
| required: true | |
| default: 'testpypi' | |
| type: choice | |
| options: | |
| - testpypi | |
| - pypi | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref || '' }}-${{ github.base_ref || '' }}-${{ github.ref != 'refs/heads/main' || github.sha }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| compute_matrix: | |
| name: Determine matrix to run on | |
| runs-on: linux_x64 | |
| outputs: | |
| matrix: ${{ steps.main.outputs.matrix }} | |
| steps: | |
| - id: main | |
| run: | | |
| PLATFORMS=("windows-g9i" "windows-amd" "windows-2025" "windows-2022") | |
| PYTHON_VERSIONS=("3.10" "3.11" "3.12" "3.13" "3.14") | |
| JSON_ARRAY="[" | |
| for p in "${PLATFORMS[@]}"; do | |
| for v in "${PYTHON_VERSIONS[@]}"; do | |
| JSON_ARRAY+="{\"platform\":\"$p\",\"python-version\":\"$v\"}," | |
| done | |
| done | |
| # Remove the trailing comma and close the bracket | |
| JSON_ARRAY="${JSON_ARRAY%,}]" | |
| # Wrap in the "include" key and send to GITHUB_OUTPUT | |
| RESULT="{\"include\":$JSON_ARRAY}" | |
| echo "matrix=$RESULT" >> "$GITHUB_OUTPUT" | |
| build_wheels_windows_2025: | |
| name: Build wheels on windows-2025 (x64) | |
| runs-on: windows-g9i | |
| steps: | |
| - name: Show env info | |
| run: | | |
| Get-CimInstance -ClassName Win32_Processor | |
| where cl | |
| & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -all -products * -prerelease -format json | |
| shell: powershell | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: recursive | |
| - name: Cleanup left marker files | |
| run: | | |
| git submodule foreach --recursive 'git reset --hard && git clean -ffdx' | |
| - name: Set up Python (for cibuildwheel controller) | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: Install cibuildwheel | |
| run: | | |
| pip install --upgrade pip | |
| pip install cibuildwheel==3.4.0 | |
| # Cache the directory where cibuildwheel outputs the .whl files | |
| - name: Cache built wheels | |
| id: cache-wheels | |
| uses: actions/cache@v4 | |
| with: | |
| path: wheelhouse | |
| # IMPORTANT: Update these file extensions/paths to match the source files | |
| # that actually affect your compiled wheel (e.g., .c, .cpp, .rs, .py) | |
| key: ${{ runner.os }}-wheels-${{ hashFiles('**/pyproject.toml', '**/setup.py', '**/*.py', '**/*.c', '**/*.cpp') }} | |
| - name: Build wheels using cibuildwheel | |
| if: steps.cache-wheels.outputs.cache-hit != 'true' | |
| shell: powershell | |
| run: | | |
| python -m cibuildwheel --output-dir wheelhouse | |
| # - name: Install and test wheel | |
| # shell: powershell | |
| # run: | | |
| # # cp11 | |
| # $wheels = Get-ChildItem wheelhouse/*.whl | Select-Object -First 2 | |
| # $wheelPath = $wheels.FullName | |
| # | |
| # python -m venv test_env | |
| # $venvPython = "test_env/Scripts/python.exe" | |
| # & $venvPython -m pip install --upgrade pip | |
| # & $venvPython -m pip install $wheelPath | |
| # & $venvPython -c "import zvec; print('Import OK:', zvec.__version__)" | |
| - name: Log wheel variables | |
| shell: powershell | |
| run: | | |
| $wheels = Get-ChildItem wheelhouse/*.whl | Select-Object -ExpandProperty FullName | |
| if ($env:GITHUB_STEP_SUMMARY) { | |
| $wheels | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append | |
| } | |
| "wheels=$($wheels -join ' ')" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| $wheels = Get-ChildItem wheelhouse/*.whl | Select-Object -ExpandProperty FullName | |
| if ($env:GITHUB_STEP_SUMMARY) { | |
| $wheels | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append | |
| } | |
| "wheels=$($wheels -join ' ')" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| - name: Upload built wheels | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-wheels | |
| path: wheelhouse/*.whl | |
| publish_wheels: | |
| name: Publish wheels | |
| runs-on: windows-g9i | |
| needs: build_wheels_windows_2025 | |
| steps: | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: Publish to PyPI/TestPyPI | |
| env: | |
| TWINE_USERNAME: __token__ | |
| TWINE_PASSWORD: ${{ inputs.publish_target == 'pypi' && secrets.PYPI_API_TOKEN || secrets.TEST_PYPI_API_TOKEN }} | |
| TWINE_REPOSITORY_URL: ${{ inputs.publish_target == 'pypi' && 'https://upload.pypi.org/legacy/' || 'https://test.pypi.org/legacy/' }} | |
| run: | | |
| pip install twine | |
| twine upload --skip-existing --verbose wheelhouse/*.whl | |
| smoke_test: | |
| needs: [ publish_wheels, compute_matrix ] | |
| strategy: | |
| fail-fast: false | |
| max-parallel: 4 | |
| matrix: ${{ fromJson(needs.compute_matrix.outputs.matrix) }} | |
| runs-on: ${{ matrix.platform }} | |
| steps: | |
| - name: Smoke test from PyPI | |
| shell: powershell | |
| env: | |
| PUBLISH_TARGET: ${{ inputs.publish_target || 'testpypi' }} | |
| run: | | |
| $wheel = (Get-ChildItem wheelhouse/zvec-*.whl)[1] # cp311 | |
| $filename = $wheel.Name | |
| $version = [regex]::Match($filename, '^zvec-([^-]+)-').Groups[1].Value | |
| if ($env:PUBLISH_TARGET -eq 'testpypi') { | |
| $indexArgs = @("--index-url", "https://test.pypi.org/simple/", "--extra-index-url", "https://pypi.org/simple/") | |
| Write-Host "Waiting for zvec==$version to become available on TestPyPI..." | |
| } else { | |
| $indexArgs = @() | |
| Write-Host "Waiting for zvec==$version to become available on PyPI..." | |
| } | |
| $ErrorActionPreference = 'Continue' | |
| $PSNativeCommandUseErrorActionPreference = $false | |
| $found = $false | |
| for ($i = 1; $i -le 30; $i++) { | |
| python -m pip install @indexArgs --dry-run "zvec==$version" 1>$null 2>$null | |
| if ($LASTEXITCODE -eq 0) { | |
| Write-Host "Version $version is available." | |
| $found = $true | |
| break | |
| } | |
| Write-Host "Attempt $i/30: not yet available, retrying in 10s..." | |
| Start-Sleep -Seconds 10 | |
| } | |
| if (-not $found) { | |
| Write-Host "ERROR: Timed out waiting for zvec==$version." | |
| exit 1 | |
| } | |
| python -m venv test_env | |
| $venvPython = "test_env/Scripts/python.exe" | |
| & $venvPython -m pip install --upgrade pip | |
| & $venvPython -m pip install @indexArgs "zvec==$version" | |
| & $venvPython -c "import zvec; print('Import OK:', zvec.__version__)" |