Merge pull request #92 from m96-chan/feature/v0.2.10 #28
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: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| test_only: | |
| description: 'Test build without publishing' | |
| type: boolean | |
| default: false | |
| jobs: | |
| # Build source distribution | |
| build-sdist: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| fetch-depth: 1 # Shallow clone for faster checkout | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build | |
| - name: Build sdist | |
| run: python -m build --sdist | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sdist | |
| path: dist/*.tar.gz | |
| # Build CUDA wheel for Linux (Python 3.12) | |
| build-linux: | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| fetch-depth: 1 # Shallow clone for faster checkout | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Set up Rust | |
| uses: actions-rust-lang/setup-rust-toolchain@v1 | |
| with: | |
| toolchain: stable | |
| - name: Install CUDA Toolkit | |
| uses: Jimver/cuda-toolkit@v0.2.29 | |
| with: | |
| cuda: "13.0.2" | |
| method: "network" | |
| linux-local-args: '["--toolkit"]' | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build scikit-build-core pybind11 ninja cmake auditwheel patchelf maturin | |
| - name: Build Rust module | |
| run: | | |
| cd rust/pygpukit-python | |
| maturin build --release --interpreter python | |
| # Extract and copy the Rust extension to src/pygpukit/ | |
| cd ../target/wheels | |
| unzip -o *.whl -d ../rust-extracted | |
| find ../rust-extracted -name "_pygpukit_rust*.so" -exec cp {} ../../../src/pygpukit/ \; | |
| ls -la ../../../src/pygpukit/*.so || true | |
| env: | |
| RUSTFLAGS: "" # Override -D warnings from setup-rust-toolchain | |
| - name: Build wheel (C++ + Rust) | |
| run: | | |
| python -m build --wheel | |
| env: | |
| # PyGPUkit requires SM >= 80 (Ampere and newer) | |
| # SM100/120 (Blackwell) supported with CUDA 13.x | |
| CMAKE_CUDA_ARCHITECTURES: "80;86;89;90;100;120" | |
| - name: Show wheel info before repair | |
| run: | | |
| ls -la dist/ | |
| echo "=== Extension modules in wheel ===" | |
| python -m zipfile -l dist/*.whl | grep -E '\.so|\.pyd' | |
| - name: Repair wheel with auditwheel | |
| run: | | |
| # Repair the wheel, excluding CUDA libraries (user must have CUDA driver) | |
| auditwheel repair dist/*.whl \ | |
| --wheel-dir dist-repaired \ | |
| --exclude libcudart.so.12 \ | |
| --exclude libcuda.so.1 \ | |
| --exclude libnvrtc.so.12 \ | |
| --exclude libnvrtc-builtins.so.13.0 \ | |
| --plat manylinux_2_35_x86_64 | |
| # Replace original wheel with repaired one | |
| rm dist/*.whl | |
| mv dist-repaired/*.whl dist/ | |
| - name: Show wheel info after repair | |
| run: | | |
| ls -la dist/ | |
| echo "=== Extension modules in wheel ===" | |
| python -m zipfile -l dist/*.whl | grep -E '\.so|\.pyd' | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheel-linux-py312 | |
| path: dist/*.whl | |
| # Build CUDA wheel for Windows (Python 3.12) | |
| build-windows: | |
| runs-on: [self-hosted, Windows, X64, cuda] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| fetch-depth: 1 # Shallow clone for faster checkout | |
| - name: Set up Python 3.12 | |
| shell: pwsh | |
| run: | | |
| pyenv install 3.12 --skip-existing | |
| pyenv local 3.12 | |
| python --version | |
| - name: Set up Rust | |
| shell: pwsh | |
| run: | | |
| # Install rustup if not present | |
| if (-not (Get-Command rustup -ErrorAction SilentlyContinue)) { | |
| Write-Host "Installing rustup..." | |
| Invoke-WebRequest -Uri https://win.rustup.rs/x86_64 -OutFile rustup-init.exe | |
| .\rustup-init.exe -y --default-toolchain stable | |
| Remove-Item rustup-init.exe | |
| $env:PATH = "$env:USERPROFILE\.cargo\bin;$env:PATH" | |
| } | |
| rustup default stable | |
| rustup update | |
| rustc --version | |
| cargo --version | |
| - name: Clean previous builds | |
| shell: pwsh | |
| run: | | |
| if (Test-Path dist) { Remove-Item -Recurse -Force dist } | |
| if (Test-Path build) { Remove-Item -Recurse -Force build } | |
| if (Test-Path rust/target) { Remove-Item -Recurse -Force rust/target } | |
| Get-ChildItem -Filter "*.egg-info" -Directory | Remove-Item -Recurse -Force | |
| - name: Install build dependencies | |
| shell: pwsh | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build scikit-build-core pybind11 ninja cmake maturin | |
| - name: Build Rust module | |
| shell: pwsh | |
| run: | | |
| cd rust/pygpukit-python | |
| maturin build --release --interpreter python | |
| # Copy the built extension to src/pygpukit/ | |
| $wheel = Get-ChildItem ../target/wheels/*.whl | Select-Object -First 1 | |
| Expand-Archive -Path $wheel.FullName -DestinationPath ../target/rust-extracted -Force | |
| $ext = Get-ChildItem ../target/rust-extracted/_pygpukit_rust*.pyd -Recurse | Select-Object -First 1 | |
| if ($ext) { | |
| Copy-Item $ext.FullName ../../src/pygpukit/ | |
| Write-Host "Copied Rust extension: $($ext.Name)" | |
| } | |
| Get-ChildItem ../../src/pygpukit/*.pyd | |
| - name: Build wheel (C++ + Rust) | |
| shell: cmd | |
| run: | | |
| @REM Set up VS environment for cl.exe | |
| call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" | |
| @REM Use CUDA 13.1 for CUTLASS 4.x (SM100/SM120 Blackwell support) | |
| @REM CUTLASS 4.3.3 requires CUDA 12.8+ due to constexpr dim3 usage | |
| set "CUDA_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.1" | |
| set "PATH=%CUDA_PATH%\bin;%PATH%" | |
| python -m build --wheel | |
| env: | |
| # PyGPUkit requires SM >= 80 (Ampere and newer) | |
| # CUDA 13.1+ required for CUTLASS 4.x (constexpr dim3 support) | |
| CMAKE_CUDA_ARCHITECTURES: "80;86;89;90;100;120" | |
| - name: Verify wheel contents | |
| shell: pwsh | |
| run: | | |
| Get-ChildItem dist/*.whl | ForEach-Object { | |
| Write-Host "Built: $($_.Name)" | |
| Write-Host "=== Wheel contents ===" | |
| python -m zipfile -l $_.FullName | Select-String -Pattern "\.pyd|\.so" | |
| } | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheel-windows-py312 | |
| path: dist/*.whl | |
| # NOTE: Driver-only mode is now the default (v0.2.4+) | |
| # All wheels are single-binary distribution - no separate driver-only test needed | |
| # Publish to TestPyPI first | |
| publish-testpypi: | |
| runs-on: ubuntu-latest | |
| needs: [build-linux, build-windows, build-sdist] | |
| if: github.event_name == 'push' || !inputs.test_only | |
| environment: testpypi | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Download sdist | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: sdist | |
| path: dist | |
| - name: Download Linux wheel | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: wheel-linux-py312 | |
| path: dist | |
| - name: Download Windows wheel | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: wheel-windows-py312 | |
| path: dist | |
| - name: List dist contents | |
| run: | | |
| echo "=== Artifacts to publish ===" | |
| ls -la dist/ | |
| - name: Publish to TestPyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| skip-existing: true | |
| # Publish to PyPI after TestPyPI succeeds | |
| publish-pypi: | |
| runs-on: ubuntu-latest | |
| needs: publish-testpypi | |
| if: github.event_name == 'push' || !inputs.test_only | |
| environment: pypi | |
| permissions: | |
| id-token: write | |
| steps: | |
| - name: Download sdist | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: sdist | |
| path: dist | |
| - name: Download Linux wheel | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: wheel-linux-py312 | |
| path: dist | |
| - name: Download Windows wheel | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: wheel-windows-py312 | |
| path: dist | |
| - name: List dist contents | |
| run: | | |
| echo "=== Artifacts to publish ===" | |
| ls -la dist/ | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@release/v1 | |
| with: | |
| skip-existing: true | |
| # Create GitHub Release | |
| github-release: | |
| runs-on: ubuntu-latest | |
| needs: [build-sdist, build-linux, build-windows, publish-pypi] | |
| if: github.event_name == 'push' | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| fetch-depth: 1 # Shallow clone for faster checkout | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| files: dist/* | |
| generate_release_notes: true |