Repository navigation
Update to Python 3.15, other maintenance, and allocator stuff #226
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: Python wheel package build and publish | |
| on: | |
| release: | |
| types: [published] | |
| # Enable Run Workflow button in GitHub UI | |
| workflow_dispatch: | |
| inputs: | |
| # Manual dispatch allows optional upload of wheels to PyPI | |
| upload_dest: | |
| type: choice | |
| description: Upload wheels to | |
| options: | |
| - No Upload | |
| - PyPI | |
| - Test PyPI | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| # Cancel superseded runs of a PR only. Keying on `github.ref` would also let a | |
| # push to main cancel a running release or manual (workflow_dispatch) upload. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| build_sdist: | |
| name: Build SDist | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Build SDist | |
| run: pipx run build --sdist | |
| - name: Check metadata | |
| run: pipx run twine check dist/* | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: sdist | |
| path: dist/*.tar.gz | |
| build_wheels: | |
| name: Wheels - ${{ matrix.cibw_archs }} ${{ matrix.arch_note}} - ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| cibw_archs: "auto64" | |
| # Linux x86_64 manylinux | |
| - os: ubuntu-latest | |
| cibw_archs: "x86_64" | |
| # manylinux_2_28 uses dnf (not yum). libffi-devel needed for Python 3.12+ cffi. | |
| cibw_before_build_linux: "dnf install -y libffi-devel || yum install -y libffi-devel || true" | |
| # skip musllinux | |
| cibw_skip: "*musl*" | |
| # Linux x86_64 musllinux | |
| # Separate runner for a Musl build of graphblas. The glibc build is not guaranteed to be compatible. | |
| - os: ubuntu-latest | |
| cibw_archs: "x86_64" | |
| arch_note: "musl" | |
| # skip manylinux (built elsewhere) | |
| cibw_skip: "*many*" | |
| # Linux aarch64 — native ARM runner (no QEMU emulation needed) | |
| - os: ubuntu-24.04-arm | |
| cibw_archs: "auto" | |
| # numpy wheels not available for aarch64 musllinux | |
| cibw_skip: "*musl*" | |
| # macOS x86_64 — macos-15-intel is the last Intel macOS runner. | |
| # libomp from Homebrew determines the minimum supported macOS version. | |
| - os: macos-15-intel | |
| cibw_archs: "x86_64" | |
| # macOS Apple Silicon | |
| # Keep runner version as old as possible: libomp determines minimum macOS version. | |
| - os: macos-14 | |
| cibw_archs: "arm64" | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup for testing | |
| if: github.event_name == 'push' || github.event_name == 'pull_request' | |
| # Ask suitesparse.sh to compile in the fastest way possible and provide a GB version to build | |
| run: | | |
| echo "SUITESPARSE_FASTEST_BUILD=1" >> "$GITHUB_ENV" | |
| shell: bash | |
| - name: Setup GraphBLAS version from GB_VERSION.txt | |
| # Use GraphBLAS version specified in GB_VERSION.txt unless specified in a git tag (next workflow step). | |
| # Git tag method required for uploads to PyPI. | |
| if: github.event_name != 'release' && github.event.inputs.upload_dest != 'PyPI' | |
| run: echo "GB_VERSION_REF=refs/tags/$(cat GB_VERSION.txt).0" >> "$GITHUB_ENV" | |
| shell: bash | |
| - name: Setup GraphBLAS version from git tag | |
| if: ${{ startsWith(github.ref, 'refs/tags/') }} | |
| # If this is a tagged ref, like a release, then use the tag for the graphblas version | |
| run: echo "GB_VERSION_REF=$GITHUB_REF" >> "$GITHUB_ENV" | |
| shell: bash | |
| - name: Install tools (macOS) | |
| if: contains(matrix.os, 'macos') | |
| # Install coreutils which includes `nproc` used by `make -j` in suitesparse.sh | |
| # | |
| # Explicitly install libomp to be clear about the dependency. | |
| # | |
| # libomp determines the minimum macOS version that we can build for | |
| run: | | |
| brew fetch --retry coreutils && brew install coreutils | |
| brew fetch --retry libomp && brew reinstall libomp | |
| echo "MACOSX_DEPLOYMENT_TARGET=$(otool -l "$(brew --prefix libomp)/lib/libomp.dylib" | grep minos | awk '{print $2}')" >> "$GITHUB_ENV" | |
| - uses: pypa/cibuildwheel@e090b81e30c4d855ea63bf4b6e59204c09a101ae # v4.2.1 | |
| with: | |
| output-dir: wheelhouse | |
| env: | |
| # very verbose | |
| CIBW_BUILD_VERBOSITY: 3 | |
| # PyPy is not built by default (since cibuildwheel v3); enable explicitly. | |
| # Free-threaded wheels (cp314t, cp315t) are built and tested by default. | |
| # cibuildwheel v4 dropped cp313t (and its "cpython-freethreading" | |
| # enable option) entirely. | |
| CIBW_ENABLE: "pypy" | |
| # Build SuiteSparse | |
| CIBW_BEFORE_ALL: bash suitesparse.sh ${{ env.GB_VERSION_REF }} | |
| CIBW_BEFORE_BUILD_LINUX: ${{ matrix.cibw_before_build_linux }} | |
| CIBW_ENVIRONMENT_PASS_LINUX: SUITESPARSE_FASTEST_BUILD | |
| # CMAKE_GNUtoMS=ON asks suitesparse.sh to build libraries in MSVC style on Windows. | |
| CIBW_ENVIRONMENT_WINDOWS: CMAKE_GNUtoMS=ON GRAPHBLAS_PREFIX="C:/GraphBLAS" | |
| # macOS libomp requires special configs. BREW_LIBOMP=1 asks suitesparse.sh to include them. | |
| # SUITESPARSE_MACOS_ARCH asks to build a particular architecture. Either x86 or arm64. | |
| CIBW_ENVIRONMENT_MACOS: BREW_LIBOMP="1" SUITESPARSE_MACOS_ARCH=${{ matrix.cibw_archs }} | |
| # Uncomment to only build CPython wheels | |
| # CIBW_BUILD: "cp*" | |
| # Architectures to build specified in matrix | |
| CIBW_ARCHS: ${{ matrix.cibw_archs }} | |
| CIBW_SKIP: "${{ matrix.cibw_skip }}" | |
| # Use delvewheel on Windows. | |
| # This copies graphblas.dll into the wheel. "repair" in cibuildwheel parlance includes copying any shared | |
| # libraries from the build host into the wheel to make the wheel self-contained. | |
| # cibuildwheel v4 installs delvewheel and uses it by default; this overrides its command so it can | |
| # find graphblas.dll and to apply a workaround: --no-mangle instead of stripping graphblas.dll | |
| # see https://github.com/adang1345/delvewheel/issues/33 | |
| CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel repair --add-path \"C:\\GraphBLAS\\bin\" --no-mangle \"libgomp-1.dll;libgcc_s_seh-1.dll\" -w {dest_dir} {wheel}" | |
| # make cibuildwheel install test dependencies from pyproject.toml | |
| CIBW_TEST_EXTRAS: "test" | |
| # run tests. They run from a temporary directory, so pyproject.toml's pytest | |
| # config doesn't apply; -W error restores its `filterwarnings = ["error"]`. | |
| CIBW_TEST_COMMAND: "pytest --pyargs suitesparse_graphblas -s -k test_print_jit_config && pytest -v -W error --pyargs suitesparse_graphblas" | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: wheels-${{ matrix.os }}-${{ matrix.cibw_archs }}${{ matrix.arch_note}} | |
| path: wheelhouse/*.whl | |
| if-no-files-found: error | |
| # Uploads use PyPI Trusted Publishing (no API token). Each index trusts this workflow | |
| # (wheels.yml) only when it runs in the GitHub environment registered with it. | |
| upload_pypi: | |
| name: Upload to PyPI | |
| needs: [build_wheels, build_sdist] | |
| runs-on: ubuntu-latest | |
| # only upload releases (or an explicit manual request) to PyPI | |
| if: github.repository == 'GraphBLAS/python-suitesparse-graphblas' && ((github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'workflow_dispatch' && github.event.inputs.upload_dest == 'PyPI')) | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/suitesparse-graphblas | |
| permissions: | |
| id-token: write # for Trusted Publishing (and its attestations) | |
| steps: | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 | |
| with: | |
| # PyPI does not allow replacing a file. Without this flag the entire action fails if even a single duplicate exists. | |
| skip-existing: true | |
| upload_test_pypi: | |
| name: Upload to Test PyPI | |
| needs: [build_wheels, build_sdist] | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'GraphBLAS/python-suitesparse-graphblas' && github.event_name == 'workflow_dispatch' && github.event.inputs.upload_dest == 'Test PyPI' | |
| environment: | |
| name: test-pypi | |
| url: https://test.pypi.org/p/suitesparse-graphblas | |
| permissions: | |
| id-token: write # for Trusted Publishing (and its attestations) | |
| steps: | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| # PyPI does not allow replacing a file. Without this flag the entire action fails if even a single duplicate exists. | |
| skip-existing: true |