diff --git a/.github/workflows/build-cassandra-driver.yml b/.github/workflows/build-cassandra-driver.yml new file mode 100644 index 0000000000..a4bf15e7a5 --- /dev/null +++ b/.github/workflows/build-cassandra-driver.yml @@ -0,0 +1,136 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on: https://github.com/datastax/python-driver-wheels/blob/master/.github/workflows/build_wheels_linux.yml +name: Build cassandra-driver wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/cassandra-driver.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-cassandra-driver.yml' + - 'docs/packages/cassandra-driver.yaml' + push: + branches: [main] + paths: + - '.github/workflows/build-cassandra-driver.yml' + - 'docs/packages/cassandra-driver.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 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: cassandra-driver + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build cassandra-driver ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 240 + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + # Per-interpreter (not abi3): the Cython extensions link the version-specific ABI. + python: + - "cp312" + - "cp313" + - "cp314" + - "cp314t" + + env: + CASSANDRA_DRIVER_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout cassandra-driver ${{ env.CASSANDRA_DRIVER_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: apache/cassandra-python-driver + ref: ${{ env.CASSANDRA_DRIVER_VERSION }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + # auditwheel bundles the image's libev, whose notice the explicit + # pyproject license-files list would otherwise drop (gotcha 105). + - name: Patch cassandra-driver source + run: git apply python-wheels/patches/cassandra-driver/${{ env.CASSANDRA_DRIVER_VERSION }}/00*.patch + + - name: Build wheels + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + output-dir: wheelhouse/ + only: ${{ matrix.python }}-manylinux_riscv64 + env: + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + CIBW_BEFORE_ALL: yum install -y libev libev-devel + CIBW_ENVIRONMENT: >- + CFLAGS='-s -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall' + PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ + # tox.ini's [base] deps, minus kerberos (needs krb5 headers and only gates + # integration tests) and minus gevent on cp314t, which it has no build for. + # setuptools is what gives pyximport a distutils on 3.12+ (gotcha 211). + CIBW_TEST_REQUIRES: >- + pytest packaging setuptools cython>=3.0 eventlet twisted[tls] pure-sasl lz4 + cryptography>=42.0 numpy + ${{ matrix.python == 'cp314t' && '' || 'gevent' }} + # cassandra/ would shadow the installed wheel, so only the two .pyx files + # tests/unit/cython/types_testhelper.pyx includes by relative path are staged. + CIBW_TEST_SOURCES: tests cassandra/ioutils.pyx cassandra/cython_marshal.pyx + # VERIFY_CYTHON is how the Jenkinsfile makes the Cython and numpy tests fail + # instead of skip when the extensions are missing. PIP_PREFER_BINARY keeps pip + # on our registry's gevent instead of compiling PyPI's newer release. + CIBW_TEST_ENVIRONMENT: VERIFY_CYTHON=True PIP_PREFER_BINARY=1 + # The extension check is config.sh's run_tests verification from upstream's + # wheels repo: setup.py swallows every Cython failure, so without it a degraded + # pure-Python wheel passes the suite under a manylinux_riscv64 tag. + CIBW_TEST_COMMAND: >- + python -c "import importlib.metadata as m; f=[str(p) for p in m.files('cassandra-driver')]; assert any(s.endswith('licenses/LICENSE.libev') for s in f), f" && + python -c "import importlib; mods=[importlib.import_module('cassandra.'+m) for m in ('cluster','concurrent','connection','cqltypes','metadata','pool','protocol','query','util','bytesio','cython_marshal','cython_utils','deserializers','ioutils','numpy_parser','obj_parser','parsing','row_parser')]; bad=[m.__name__ for m in mods if not m.__file__.endswith('.so')]; assert not bad, bad; from cassandra.cmurmur3 import murmur3; assert murmur3('key') == -6847573755651342660; import cassandra.io.libevwrapper as libev; libev.Loop(); from cassandra.protocol import cython_protocol_handler; from cassandra.obj_parser import ListParser, LazyParser; from cassandra.numpy_parser import NumpyParser; [cython_protocol_handler(p()) for p in (ListParser, LazyParser, NumpyParser)]" && + python -m pytest tests/unit + --deselect tests/unit/advanced/cloud/test_cloud.py::CloudTests::test_use_default_tempdir + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: cassandra-driver-${{ env.CASSANDRA_DRIVER_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish cassandra-driver ${{ matrix.version }} + needs: [setup, build_wheels] + 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: cassandra-driver-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/cassandra-driver.yaml b/docs/packages/cassandra-driver.yaml new file mode 100644 index 0000000000..bfbe9c572c --- /dev/null +++ b/docs/packages/cassandra-driver.yaml @@ -0,0 +1,6 @@ +package-name: cassandra-driver +source-code: https://github.com/apache/cassandra-python-driver/ +license: Apache-2.0 +versions: +- version: 3.30.1 + patched: true diff --git a/patches/cassandra-driver/3.30.1/0001-Ship-the-licence-of-the-bundled-libev-in-the-wheel.patch b/patches/cassandra-driver/3.30.1/0001-Ship-the-licence-of-the-bundled-libev-in-the-wheel.patch new file mode 100644 index 0000000000..b5d94ede47 --- /dev/null +++ b/patches/cassandra-driver/3.30.1/0001-Ship-the-licence-of-the-bundled-libev-in-the-wheel.patch @@ -0,0 +1,88 @@ +From d9f275bd09f4dd4c26c23cc2c09008abe8b13cf1 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Sat, 19 Sep 2026 08:43:20 +0000 +Subject: [PATCH] Ship the licence of the bundled libev in the wheel + +cassandra.io.libevwrapper links libev dynamically, so auditwheel copies the +system libev.so.4 into cassandra_driver.libs/ and rewrites the extension's +RPATH to it: every manylinux wheel redistributes libev in binary form. libev +is dual-licensed BSD-2-Clause OR GPL-2.0-or-later and its BSD terms require +the copyright notice to travel with the binary, but the wheel carries only the +driver's own Apache-2.0 LICENSE. + +pyproject.toml sets an explicit license-files = ["LICENSE"], which turns off +setuptools' default LICEN[CS]E* root glob, so adding the file alone is not +enough - the list is the complete set once the key is present (CLAUDE.md +gotcha 105/57). Add LICENSE.libev with the notice from libev 4.33, the version +the manylinux images package, and extend the list to cover it. + +Upstream-Status: To upstream [not yet submitted; this port may only touch riseproject-dev/python-wheels] +--- + LICENSE.libev | 41 +++++++++++++++++++++++++++++++++++++++++ + pyproject.toml | 2 +- + 2 files changed, 42 insertions(+), 1 deletion(-) + create mode 100644 LICENSE.libev + +diff --git a/LICENSE.libev b/LICENSE.libev +new file mode 100644 +index 00000000..04b35e78 +--- /dev/null ++++ b/LICENSE.libev +@@ -0,0 +1,41 @@ ++The libev shared library the cassandra.io.libevwrapper extension links against ++is redistributed inside the binary wheel. libev is not part of this project and ++carries the licence below; the driver's own licence is in LICENSE. ++ ++All files in libev are ++Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are ++met: ++ ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ ++ * 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. ++ ++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 ++OWNER 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. ++ ++Alternatively, the contents of this package may be used under the terms ++of the GNU General Public License ("GPL") version 2 or any later version, ++in which case the provisions of the GPL are applicable instead of the ++above. If you wish to allow the use of your version of this package only ++under the terms of the GPL and not to allow others to use your version of ++this file under the BSD license, indicate your decision by deleting the ++provisions above and replace them with the notice and other provisions ++required by the GPL in this and the other files of this package. If you do ++not delete the provisions above, a recipient may use your version of this ++file under either the BSD or the GPL. +diff --git a/pyproject.toml b/pyproject.toml +index 0af1e770..55592882 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -10,7 +10,7 @@ dependencies = ['geomet>=1.1', "Deprecated>=1.3.1"] + readme = "README.rst" + authors = [{name = "DataStax"}] + license = "Apache-2.0" +-license-files = ["LICENSE"] ++license-files = ["LICENSE", "LICENSE.libev"] + requires-python = ">= 3.10" + keywords = ["cassandra","cql","orm","dse","graph"] + classifiers = [ +-- +2.43.0 +