From 780aa8a417e2152e99b8e865a86d87fae0668c5c Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Wed, 14 Oct 2026 11:18:19 +0000 Subject: [PATCH] pymetis: Add version 2025.2.2 --- .github/workflows/build-pymetis.yml | 158 ++++++++++++++++++ docs/packages/pymetis.yaml | 6 + ...he-METIS-and-pybind11-licences-in-th.patch | 73 ++++++++ 3 files changed, 237 insertions(+) create mode 100644 .github/workflows/build-pymetis.yml create mode 100644 docs/packages/pymetis.yaml create mode 100644 patches/pymetis/2025.2.2/0001-pyproject-ship-the-METIS-and-pybind11-licences-in-th.patch diff --git a/.github/workflows/build-pymetis.yml b/.github/workflows/build-pymetis.yml new file mode 100644 index 000000000000..60457eede160 --- /dev/null +++ b/.github/workflows/build-pymetis.yml @@ -0,0 +1,158 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# Based on the `build_wheels` job of +# https://github.com/inducer/pymetis/blob/v2025.2.2/.github/workflows/wheels.yml +name: Build pymetis wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/pymetis.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-pymetis.yml' + - 'docs/packages/pymetis.yaml' + push: + branches: [main] + paths: + - '.github/workflows/build-pymetis.yml' + - 'docs/packages/pymetis.yaml' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + MUSLLINUX_RISCV64_IMAGE: quay.io/pypa/musllinux_1_2_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: pymetis + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build pymetis ${{ matrix.version }} ${{ matrix.python }}-${{ matrix.libc }}_riscv64 + runs-on: ubuntu-24.04-riscv + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + python: ["cp312", "cp313", "cp314", "cp314t"] + libc: [manylinux, musllinux] + + env: + PYMETIS_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout pymetis v${{ env.PYMETIS_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: inducer/pymetis + ref: v${{ env.PYMETIS_VERSION }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Patch pymetis source + run: git apply python-wheels/patches/pymetis/${{ env.PYMETIS_VERSION }}/*.patch + + - uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + output-dir: wheelhouse/ + only: ${{ matrix.python }}-${{ matrix.libc }}_riscv64 + env: + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + CIBW_MUSLLINUX_RISCV64_IMAGE: ${{ env.MUSLLINUX_RISCV64_IMAGE }} + CIBW_ENVIRONMENT: PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ PIP_ONLY_BINARY=numpy + # upstream's wheels.yml tests nothing; run the pytest suite its ci.yml runs + CIBW_TEST_REQUIRES: numpy pytest + CIBW_TEST_SOURCES: test + CIBW_TEST_COMMAND: python -m pytest -v test + # numpy has no riscv64 musllinux wheel in our registry. + CIBW_TEST_SKIP: "*-musllinux*" + + - name: Check the extension and licences made it into the wheel + run: | + python3 - wheelhouse/*.whl <<'EOF' + import sys, zipfile + for whl in sys.argv[1:]: + names = zipfile.ZipFile(whl).namelist() + assert any(n.startswith("pymetis/_internal.") and n.endswith(".so") for n in names), names + licences = {n.split(".dist-info/licenses/", 1)[1] for n in names if ".dist-info/licenses/" in n and not n.endswith("/")} + assert licences == {"LICENSE", "LICENSE.pybind11", "src/metis/LICENSE.txt"}, (whl, licences) + print(whl, "ok") + EOF + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: pymetis-${{ env.PYMETIS_VERSION }}-${{ matrix.python }}-${{ matrix.libc }}_riscv64 + path: ./wheelhouse/*.whl + if-no-files-found: error + + gpl_sources: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + name: Collect GPL sources for pymetis ${{ matrix.version }} + runs-on: ubuntu-24.04-riscv + + env: + PYMETIS_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + # The musllinux wheel vendors the image's libstdc++ and libgcc_s (gotcha 409). + - uses: ./actions/collect-gpl-sources + with: + image: ${{ env.MANYLINUX_RISCV64_IMAGE }} + packages: gcc + output: gpl-sources.tar + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: pymetis-${{ env.PYMETIS_VERSION }}-gpl-sources + path: gpl-sources.tar + if-no-files-found: error + + publish: + name: Publish pymetis ${{ matrix.version }} + needs: [setup, build_wheels, gpl_sources] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: pymetis-${{ matrix.version }}-*riscv64 + gpl-sources-artifact: pymetis-${{ matrix.version }}-gpl-sources + gpl-sources-description: gcc diff --git a/docs/packages/pymetis.yaml b/docs/packages/pymetis.yaml new file mode 100644 index 000000000000..6946c732972a --- /dev/null +++ b/docs/packages/pymetis.yaml @@ -0,0 +1,6 @@ +package-name: pymetis +source-code: https://github.com/inducer/pymetis +license: MIT AND Apache-2.0 +versions: +- version: 2025.2.2 + patched: true diff --git a/patches/pymetis/2025.2.2/0001-pyproject-ship-the-METIS-and-pybind11-licences-in-th.patch b/patches/pymetis/2025.2.2/0001-pyproject-ship-the-METIS-and-pybind11-licences-in-th.patch new file mode 100644 index 000000000000..16f6a35e0429 --- /dev/null +++ b/patches/pymetis/2025.2.2/0001-pyproject-ship-the-METIS-and-pybind11-licences-in-th.patch @@ -0,0 +1,73 @@ +From 5290f985605abfb79f008e7bcfeb59a5682dc109 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Wed, 14 Oct 2026 11:02:42 +0000 +Subject: [PATCH] pyproject: ship the METIS and pybind11 licences in the wheel + +meson-python only writes dist-info/licenses/ entries for files named in +`[project] license-files`, and has no PEP 639 default glob behind it, so +every wheel built from this tree ships no licence text at all -- not +pymetis' own MIT LICENSE, not the Apache-2.0 notice of the METIS/GKlib +sources compiled into _internal, and not the BSD-3-Clause notice of the +pybind11 headers instantiated into it. Upstream's PyPI wheels carry the +same gap. + +List the three explicitly; LICENSE.pybind11 is pybind11's own LICENSE, +verbatim from its v3.1.0 tag. + +Upstream-Status: To upstream [not yet submitted; python-wheels does not open issues/PRs on third-party repos] +--- + LICENSE.pybind11 | 29 +++++++++++++++++++++++++++++ + pyproject.toml | 1 + + 2 files changed, 30 insertions(+) + create mode 100644 LICENSE.pybind11 + +diff --git a/LICENSE.pybind11 b/LICENSE.pybind11 +new file mode 100644 +index 0000000..e466b0d +--- /dev/null ++++ b/LICENSE.pybind11 +@@ -0,0 +1,29 @@ ++Copyright (c) 2016 Wenzel Jakob , All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ ++1. Redistributions of source code must retain the above copyright notice, this ++ list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright notice, ++ this list of conditions and the following disclaimer in the documentation ++ and/or other materials provided with the distribution. ++ ++3. Neither the name of the copyright holder nor the names of its contributors ++ may be used to endorse or promote products derived from this software ++ without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ++CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of ++external contributions to this project including patches, pull requests, etc. +diff --git a/pyproject.toml b/pyproject.toml +index 69aac21..3a5b2f7 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -11,6 +11,7 @@ version = "2025.2.2" + description = "A graph partitioning package" + readme = "README.rst" + license = "MIT AND Apache-2.0" ++license-files = ["LICENSE", "LICENSE.pybind11", "src/metis/LICENSE.txt"] + maintainers = [ { name = "Andreas Kloeckner", email = "inform@tiker.net" } ] + authors = [ { name = "Andreas Kloeckner", email = "inform@tiker.net" } ] + requires-python = ">=3.10" +-- +2.43.0 +