diff --git a/.github/workflows/build-faust-cchardet.yml b/.github/workflows/build-faust-cchardet.yml new file mode 100644 index 000000000..d024ce0a2 --- /dev/null +++ b/.github/workflows/build-faust-cchardet.yml @@ -0,0 +1,99 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# Based on the `build_wheels` job of +# https://github.com/faust-streaming/cChardet/blob/v3.2.0/.github/workflows/build-and-upload-to-pypi.yml +name: Build faust-cchardet wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'faust-cchardet version to build (e.g. 3.2.0)' + required: true + default: '3.2.0' + pull_request: + paths: + - '.github/workflows/build-faust-cchardet.yml' + - 'patches/faust-cchardet/**' + +concurrency: + group: ${{ github.workflow }}-${{ inputs.version || '3.2.0' }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + FAUST_CCHARDET_VERSION: ${{ inputs.version || '3.2.0' }} + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + + build_wheels: + needs: [setup] + name: Build faust-cchardet ${{ inputs.version || '3.2.0' }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 90 + strategy: + fail-fast: false + matrix: + python: ["cp312", "cp313", "cp314", "cp314t"] + + steps: + - name: Checkout cChardet v${{ env.FAUST_CCHARDET_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: faust-streaming/cChardet + ref: v${{ env.FAUST_CCHARDET_VERSION }} + submodules: recursive + 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 COPYING/LICENSE glob, so + # every wheel upstream publishes ships with none. See + # patches/faust-cchardet/3.2.0 for details. + - name: Patch cChardet source + run: git apply python-wheels/patches/faust-cchardet/${{ env.FAUST_CCHARDET_VERSION }}/*.patch + + - name: Build and test wheels + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + only: ${{ matrix.python }}-manylinux_riscv64 + env: + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + + - name: Verify the wheel ships the compiled extension and licence + run: | + python3 - wheelhouse/*.whl <<'EOF' + import sys, zipfile + for whl in sys.argv[1:]: + names = zipfile.ZipFile(whl).namelist() + assert any(n.startswith("cchardet/_cchardet") and n.endswith(".so") for n in names), names + assert any(n.endswith(".dist-info/licenses/COPYING") for n in names), names + print(whl, "ok") + EOF + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: faust-cchardet-${{ env.FAUST_CCHARDET_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: ./wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish faust-cchardet ${{ inputs.version || '3.2.0' }} + needs: [setup, build_wheels] + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + with: + artifact-pattern: faust-cchardet-${{ inputs.version || '3.2.0' }}-*-manylinux_riscv64 diff --git a/patches/faust-cchardet/3.2.0/0001-ship-the-tri-license-COPYING-in-the-wheel-s-dist-info.patch b/patches/faust-cchardet/3.2.0/0001-ship-the-tri-license-COPYING-in-the-wheel-s-dist-info.patch new file mode 100644 index 000000000..3888d2529 --- /dev/null +++ b/patches/faust-cchardet/3.2.0/0001-ship-the-tri-license-COPYING-in-the-wheel-s-dist-info.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 10 Sep 2026 07:43:01 +0200 +Subject: [PATCH] ship the MPL-1.1/GPL-2.0-or-later/LGPL-2.1-or-later COPYING + in the wheel's dist-info + +pyproject.toml declares the tri-license as a legacy `license = { text = ... }` +table, which two things break: + +- meson-python's build backend has no default LICEN[CS]E*/COPYING* glob + (pyproject-metadata only ever includes files named in `license-files`), + so every wheel upstream publishes (verified against the real + faust_cchardet-3.2.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl + from PyPI) carries no licence file at all. +- pyproject-metadata refuses `license-files` outright unless `license` is + itself a PEP 639 SPDX expression string, not the old table form: + "project.license-files" must not be used when "project.license" is not + a SPDX license expression. + +The fix is two coupled edits: turn `license` into the plain SPDX string +(the text was already valid SPDX, just wrapped in the deprecated table), +and add `license-files = ["COPYING"]`. meson-python then copies the +repository's root COPYING into dist-info/licenses/COPYING. The vendored +uchardet submodule under src/ext/uchardet ships its own COPYING that is +byte-identical to the root one (both are the MPL 1.1 text uchardet itself +is tri-licensed under), so one file covers both. + +Upstream-Status: To upstream [not yet submitted; no fork of faust-streaming/cChardet to push from] +--- + pyproject.toml | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/pyproject.toml b/pyproject.toml +index 3f750f9..6d910a9 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -18,7 +18,8 @@ name = "faust-cchardet" + description = "cChardet is high speed universal character encoding detector." + readme = "README.md" + authors = [{ name = "PyYoshi", email = "myoshi321go@gmail.com" }] +-license = { text = "MPL-1.1 OR GPL-2.0-or-later OR LGPL-2.1-or-later" } ++license = "MPL-1.1 OR GPL-2.0-or-later OR LGPL-2.1-or-later" ++license-files = ["COPYING"] + keywords = ["cython", "chardet", "charsetdetect"] + # meson-python (the build backend) requires Python >= 3.8. Python 3.9 is no + # longer supported; the floor is 3.10.