diff --git a/.github/workflows/build-memory-allocator.yml b/.github/workflows/build-memory-allocator.yml new file mode 100644 index 000000000..bd7bc684a --- /dev/null +++ b/.github/workflows/build-memory-allocator.yml @@ -0,0 +1,106 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# Based on the `build_wheels` job of +# https://github.com/sagemath/memory_allocator/blob/879b51b922d0ef31ef7bbc6c9d287f600a20bfbd/.github/workflows/dist.yml +name: Build memory-allocator wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'memory-allocator version to build (e.g. 0.2.0)' + required: true + default: '0.2.0' + pull_request: + paths: + - '.github/workflows/build-memory-allocator.yml' + - 'patches/memory-allocator/**' + +concurrency: + group: ${{ github.workflow }}-${{ inputs.version || '0.2.0' }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + MEMORY_ALLOCATOR_VERSION: ${{ inputs.version || '0.2.0' }} + # The v0.2.0 tag was left behind by a history rewrite around the meson + # migration and predates the version bump (pyproject.toml there still + # reads 0.1.4); this commit's tree is byte-identical to the released + # 0.2.0 PyPI sdist. Update alongside MEMORY_ALLOCATOR_VERSION. + MEMORY_ALLOCATOR_REF: 879b51b922d0ef31ef7bbc6c9d287f600a20bfbd + 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 + + build_wheels: + needs: [setup] + name: Build memory-allocator ${{ inputs.version || '0.2.0' }} ${{ matrix.python }}-${{ matrix.libc }}_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + python: ["cp312", "cp313", "cp314", "cp314t"] + libc: [manylinux, musllinux] + + steps: + - name: Checkout memory_allocator ${{ env.MEMORY_ALLOCATOR_REF }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: sagemath/memory_allocator + ref: ${{ env.MEMORY_ALLOCATOR_REF }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + # pyproject.toml declares `license` but no `license-files`, and + # meson-python's build backend has no default LICENSE glob, so every + # wheel upstream publishes ships with none. See + # patches/memory-allocator/0.2.0 for details. + - name: Patch memory_allocator source + run: git apply python-wheels/patches/memory-allocator/${{ env.MEMORY_ALLOCATOR_VERSION }}/*.patch + + - uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + only: ${{ matrix.python }}-${{ matrix.libc }}_riscv64 + env: + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + CIBW_MUSLLINUX_RISCV64_IMAGE: ${{ env.MUSLLINUX_RISCV64_IMAGE }} + + - name: Check the extensions and LICENSE 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("memory_allocator/memory_allocator") and n.endswith(".so") for n in names), names + assert any(n.startswith("memory_allocator/test") and n.endswith(".so") for n in names), names + assert any(n.endswith(".dist-info/licenses/LICENSE") for n in names), names + print(whl, "ok") + EOF + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: memory-allocator-${{ env.MEMORY_ALLOCATOR_VERSION }}-${{ matrix.python }}-${{ matrix.libc }}_riscv64 + path: ./wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish memory-allocator ${{ inputs.version || '0.2.0' }} + needs: [setup, build_wheels] + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + with: + artifact-pattern: memory-allocator-${{ inputs.version || '0.2.0' }}-*riscv64 diff --git a/patches/memory-allocator/0.2.0/0001-ship-the-GPL-3.0-or-later-LICENSE-in-the-wheel-s-dis.patch b/patches/memory-allocator/0.2.0/0001-ship-the-GPL-3.0-or-later-LICENSE-in-the-wheel-s-dis.patch new file mode 100644 index 000000000..ea5ef52bc --- /dev/null +++ b/patches/memory-allocator/0.2.0/0001-ship-the-GPL-3.0-or-later-LICENSE-in-the-wheel-s-dis.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Mon, 7 Sep 2026 16:06:57 +0200 +Subject: [PATCH] ship the GPL-3.0-or-later LICENSE in the wheel's dist-info + +pyproject.toml declares `license = "GPL-3.0-or-later"` (PEP 639 SPDX +expression) but never lists a `license-files` glob, and pyproject-metadata +(the library meson-python's build backend uses to assemble wheel metadata) +only ever includes files named in that key: there is no implicit +LICEN[CS]E*/COPYING*/NOTICE* fallback the way some other backends provide. +As a result every wheel upstream publishes (verified against the real +memory_allocator-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl from PyPI) +carries no LICENSE file at all. + +Declaring `license-files = ["LICENSE"]` makes meson-python copy the +repository's root LICENSE into dist-info/licenses/LICENSE. + +Upstream-Status: To upstream [not yet submitted; no fork of sagemath/memory_allocator to push from] +--- + pyproject.toml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/pyproject.toml b/pyproject.toml +index 680ae1c..d019ac5 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -12,6 +12,7 @@ authors = [ + requires-python = ">=3.12" + readme = "README.md" + license = "GPL-3.0-or-later" ++license-files = ["LICENSE"] + classifiers = [ + "Development Status :: 6 - Mature", + "Intended Audience :: Science/Research",