From fdba92ed9db3f935f711508c655e865c369894e9 Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Wed, 16 Sep 2026 17:40:40 +0530 Subject: [PATCH 1/8] Add s390x wheels to the build and verification matrix --- .semaphore/semaphore.yml | 42 ++++++++++++++++++++++++++++++ tools/wheels/build-wheels.sh | 1 + tools/wheels/install-librdkafka.sh | 6 +++-- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 46e56d14b..ad2ffeaed 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -131,6 +131,27 @@ blocks: - ./tools/wheels/build-wheels.sh "${LIBRDKAFKA_VERSION#v}" wheelhouse - tar -czf wheelhouse-linux-${ARCH}.tgz wheelhouse - artifact push workflow wheelhouse-linux-${ARCH}.tgz --destination artifacts/wheels-${OS_NAME}-${ARCH}.tgz/ + - name: "Wheels: Linux s390x" + run: + when: "tag =~ '.*'" + dependencies: + - "Pre-release Validation" + task: + agent: + machine: + type: s1-ubuntu-24-s390x-4 + env_vars: + - name: OS_NAME + value: linux + jobs: + - name: Build + commands: + - export ARCH=s390x + - sem-version python 3.13 + - pip install uv + - ./tools/wheels/build-wheels.sh "${LIBRDKAFKA_VERSION#v}" wheelhouse + - tar -czf wheelhouse-linux-${ARCH}.tgz wheelhouse + - artifact push workflow wheelhouse-linux-${ARCH}.tgz --destination artifacts/wheels-${OS_NAME}-${ARCH}.tgz/ - name: "Wheels: Linux x64" run: when: "tag =~ '.*'" @@ -431,6 +452,26 @@ blocks: - artifact pull workflow artifacts - cd artifacts && ls *.tgz |xargs -n1 tar -xvf && cd .. - tools/test-wheels.sh artifacts/wheelhouse + - name: "Wheel Verification: Linux s390x" + run: + when: "tag =~ '.*'" + dependencies: + - "Wheels: Linux s390x" + task: + agent: + machine: + type: s1-ubuntu-24-s390x-4 + env_vars: + - name: OS_NAME + value: linux + jobs: + - name: Verify + commands: + - export ARCH=s390x + - sem-version python 3.9 + - artifact pull workflow artifacts + - cd artifacts && ls *.tgz |xargs -n1 tar -xvf && cd .. + - tools/test-wheels.sh artifacts/wheelhouse - name: "Wheel Verification: OSX x64" run: when: "tag =~ '.*'" @@ -546,6 +587,7 @@ blocks: dependencies: - "Wheel Verification: Linux x64" - "Wheel Verification: Linux arm64" + - "Wheel Verification: Linux s390x" - "Wheel Verification: OSX x64" - "Wheel Verification: OSX arm64" - "Wheel Verification: Windows" diff --git a/tools/wheels/build-wheels.sh b/tools/wheels/build-wheels.sh index b6cdfe46c..fe73452ec 100755 --- a/tools/wheels/build-wheels.sh +++ b/tools/wheels/build-wheels.sh @@ -13,6 +13,7 @@ export CIBW_TEST_REQUIRES="pytest" export CIBW_TEST_COMMAND="pytest {project}/tests/test_error.py" export CIBW_MANYLINUX_X86_64_IMAGE="manylinux_2_28" export CIBW_MANYLINUX_AARCH64_IMAGE="manylinux_2_28" +export CIBW_MANYLINUX_S390X_IMAGE="manylinux_2_28" librdkafka_version=$1 wheeldir=$2 diff --git a/tools/wheels/install-librdkafka.sh b/tools/wheels/install-librdkafka.sh index 3a772a2ae..1e4ac33df 100755 --- a/tools/wheels/install-librdkafka.sh +++ b/tools/wheels/install-librdkafka.sh @@ -28,8 +28,10 @@ ARCH=${ARCH:-x64} if [[ $OSTYPE == linux* ]]; then # Linux - # Copy the librdkafka build with least dependencies to librdkafka.so.1 - if [[ $ARCH == arm64* ]]; then + # Copy the librdkafka build with least dependencies to librdkafka.so.1. + # arm64 and s390x redist runtimes ship only the plain librdkafka.so (no + # centos8- variant), so both use it directly; x64 uses the centos8 build. + if [[ $ARCH == arm64* || $ARCH == s390x* ]]; then cp -v runtimes/linux-$ARCH/native/{librdkafka.so,librdkafka.so.1} else cp -v runtimes/linux-$ARCH/native/{centos8-librdkafka.so,librdkafka.so.1} From 79242d55beb781e1c2b200749bed23650172cca1 Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Mon, 21 Sep 2026 13:06:44 +0530 Subject: [PATCH 2/8] Scope the s390x smoke-test deps to avoid no-wheel source builds --- .../requirements-tests-install-s390x.txt | 22 +++++++++++++++++++ tools/smoketest.sh | 11 +++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 requirements/requirements-tests-install-s390x.txt diff --git a/requirements/requirements-tests-install-s390x.txt b/requirements/requirements-tests-install-s390x.txt new file mode 100644 index 000000000..31962f542 --- /dev/null +++ b/requirements/requirements-tests-install-s390x.txt @@ -0,0 +1,22 @@ +# Reduced test-install set for s390x (IBM Z). +# +# Same as requirements-tests-install.txt but WITHOUT requirements-schemaregistry.txt +# and requirements-rules.txt, whose transitive deps (cryptography, google-re2, +# tink) publish no s390x wheels and would fall back to slow/failing source builds +# on the s390x agent (e.g. google-re2 needs the abseil C++ headers). +# +# This is only the smoke-test dependency set: tools/smoketest.sh installs and +# exercises the core client plus the [avro], [protobuf] and [json] extras (all of +# which have s390x wheels or build with gcc) and runs the top-level unit tests, +# which do not import the rules/schema-registry crypto stack. Drop this file and +# use requirements-tests-install.txt once cryptography/google-re2/tink ship s390x +# wheels. +# +# trivup is also omitted: it is only used by tests/integration (not exercised by +# the smoke test) and it pulls jwcrypto -> cryptography, reintroducing the same +# no-s390x-wheel source build this file exists to avoid. +-r requirements-tests.txt +-r requirements-avro.txt +-r requirements-protobuf.txt +-r requirements-json.txt +-r requirements-oauthbearer-aws.txt diff --git a/tools/smoketest.sh b/tools/smoketest.sh index db0a98245..630c39b3b 100755 --- a/tools/smoketest.sh +++ b/tools/smoketest.sh @@ -60,7 +60,16 @@ for py in 3.9 ; do hash -r uv pip install pkginfo - uv pip install -r requirements/requirements-tests-install.txt + # On s390x, use the reduced test-install set: cryptography, google-re2 and + # tink (pulled by the schemaregistry/rules extras) have no s390x wheels and + # would fall back to slow/failing source builds. The smoke test only + # exercises core + [avro]/[protobuf]/[json] and the top-level unit tests, + # none of which need those deps. + tests_install_reqs="requirements/requirements-tests-install.txt" + if [[ "$(uname -m)" == "s390x" ]]; then + tests_install_reqs="requirements/requirements-tests-install-s390x.txt" + fi + uv pip install -r "$tests_install_reqs" # Get the packages version so we can pin the install # command to this version (which hopefully loads it from the wheeldir From 4e962f4674f7bd2b4d32a9ec7fe0e259be21ae62 Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Wed, 23 Sep 2026 21:24:18 +0530 Subject: [PATCH 3/8] Verify the free-threaded (cp314t) wheel on s390x Since the free-threading work, build-wheels.sh builds a cp314t wheel on every arch, s390x included, but verify-free-threaded-job.sh only handled x64 and arm64, so the s390x cp314t wheel would have been published without verification. - tools/verify-free-threaded-job.sh: add a linux-s390x case. On s390x, install requirements-tests-install-nogil-s390x.txt and skip tests/schema_registry: the schema-registry stack pulls cryptography (via authlib and trivup's jwcrypto), which publishes no s390x wheels. Same scoping as the s390x smoke test. - requirements/requirements-tests-install-nogil-s390x.txt: the nogil test set minus schemaregistry and trivup. - .semaphore/semaphore.yml: add the "Verify free threaded" job to the Linux s390x Wheel Verification block, mirroring arm64. --- .semaphore/semaphore.yml | 7 +++++ ...requirements-tests-install-nogil-s390x.txt | 15 +++++++++++ tools/verify-free-threaded-job.sh | 27 ++++++++++++++----- 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 requirements/requirements-tests-install-nogil-s390x.txt diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index c01f32d84..4a9d8140a 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -518,6 +518,13 @@ blocks: - artifact pull workflow artifacts - cd artifacts && ls *.tgz |xargs -n1 tar -xvf && cd .. - tools/test-wheels.sh artifacts/wheelhouse + - name: Verify free threaded + commands: + - export ARCH=s390x + # sem-version only provides a pip to bootstrap uv; the wheel runs in the 3.14t venv uv creates. + - sem-version python 3.9 + - pip install uv + - tools/verify-free-threaded-job.sh - name: "Wheel Verification: OSX x64" run: when: "tag =~ '.*'" diff --git a/requirements/requirements-tests-install-nogil-s390x.txt b/requirements/requirements-tests-install-nogil-s390x.txt new file mode 100644 index 000000000..e235a924c --- /dev/null +++ b/requirements/requirements-tests-install-nogil-s390x.txt @@ -0,0 +1,15 @@ +# Free-threaded (no-GIL) variant of requirements-tests-install-s390x.txt, used by +# the "Verify free threaded" job of the Linux s390x Wheel Verification block +# (tools/verify-free-threaded-job.sh). +# +# Same as requirements-tests-install-nogil.txt but WITHOUT +# requirements-schemaregistry.txt and trivup, for the reason given in +# requirements-tests-install-s390x.txt: they pull cryptography (via authlib and +# jwcrypto), which publishes no s390x wheels. The job skips tests/schema_registry +# to match. +# Keep in sync with requirements-tests-install-nogil.txt when adding new includes. +-r requirements-tests.txt +-r requirements-avro-nogil.txt +-r requirements-protobuf.txt +-r requirements-json.txt +-r requirements-oauthbearer-aws.txt diff --git a/tools/verify-free-threaded-job.sh b/tools/verify-free-threaded-job.sh index bd13000a6..e4aa6d4b0 100755 --- a/tools/verify-free-threaded-job.sh +++ b/tools/verify-free-threaded-job.sh @@ -5,28 +5,40 @@ # run the free-threaded wheel checks (tools/verify-free-threaded-wheel.sh) and then the unit suite. # # Run from the repo root with uv on PATH. Expects OS_NAME (linux|osx) and ARCH -# (x64|arm64) as the Wheel blocks set them, and LIBRDKAFKA_VERSION for the wheel -# checks. +# (x64|arm64, or s390x on linux) as the Wheel blocks set them, and +# LIBRDKAFKA_VERSION for the wheel checks. set -eu : "${OS_NAME:?set OS_NAME to linux or osx}" -: "${ARCH:?set ARCH to x64 or arm64}" +: "${ARCH:?set ARCH to x64, arm64 or s390x}" -# cibuildwheel tags Linux wheels manylinux_*_{x86_64,aarch64} and macOS wheels -# macosx_*_{x86_64,arm64}. +# cibuildwheel tags Linux wheels manylinux_*_{x86_64,aarch64,s390x} and macOS +# wheels macosx_*_{x86_64,arm64}. case "$OS_NAME-$ARCH" in linux-x64) wheel_glob='*-cp314t-manylinux*x86_64.whl' ;; linux-arm64) wheel_glob='*-cp314t-manylinux*aarch64.whl' ;; + linux-s390x) wheel_glob='*-cp314t-manylinux*s390x.whl' ;; osx-x64) wheel_glob='*-cp314t-macosx*x86_64.whl' ;; osx-arm64) wheel_glob='*-cp314t-macosx*arm64.whl' ;; *) echo "$0: unsupported OS_NAME-ARCH '$OS_NAME-$ARCH'" >&2; exit 1 ;; esac echo "Verifying the free-threaded wheel matching $wheel_glob for $OS_NAME-$ARCH" +# s390x: the schema-registry stack's deps (cryptography, via authlib and trivup's +# jwcrypto) publish no s390x wheels, so install the reduced set and skip the +# schema-registry tests, as the s390x smoke test does (see +# requirements/requirements-tests-install-nogil-s390x.txt). +tests_install_reqs=requirements/requirements-tests-install-nogil.txt +ignore_sr_tests= +if [[ $ARCH == s390x ]]; then + tests_install_reqs=requirements/requirements-tests-install-nogil-s390x.txt + ignore_sr_tests=--ignore=tests/schema_registry +fi + uv venv _venv314t --python 3.14t source _venv314t/bin/activate -uv pip install -r requirements/requirements-tests-install-nogil.txt +uv pip install -r "$tests_install_reqs" artifact pull workflow artifacts # Fail fast, with a clear message, if the pull brought no wheel tarballs at all. @@ -37,4 +49,5 @@ ls artifacts/wheelhouse/$wheel_glob uv pip install --no-index --find-links artifacts/wheelhouse confluent-kafka tools/verify-free-threaded-wheel.sh -python -m pytest tests/ --ignore=tests/integration --ignore=tests/test_unasync.py --timeout 1200 +# Unquoted on purpose: an empty $ignore_sr_tests must expand to no argument. +python -m pytest tests/ --ignore=tests/integration --ignore=tests/test_unasync.py $ignore_sr_tests --timeout 1200 From 7dfaf229786075e23655f04bb0782434515bead1 Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Wed, 23 Sep 2026 23:06:39 +0530 Subject: [PATCH 4/8] Give the s390x smoke-test containers a build toolchain The container stage of the wheel verification (tools/test-manylinux.sh) runs the smoke test on bare ubuntu images. On s390x several test and extra dependencies publish no s390x wheels and are built from source: fastavro, psutil, librt (via mypy) and cryptography (via the schema-registry deps of the [avro]/[protobuf]/[json] extras). The bare images have no compiler or headers, so the s390x verification failed there. x64 and arm64 are unaffected: these all have wheels there. - On s390x, install gcc, python3.9-dev, libssl-dev and pkg-config in the container before the smoke test. - On s390x, test on ubuntu:22.04 and 24.04 instead of 20.04: cryptography needs OpenSSL >= 3.0 to build and ubuntu:20.04 ships 1.1.1. - Correct the comments in smoketest.sh and requirements-tests-install-s390x.txt: the extras do pull the schema-registry deps, so cryptography is still built from source. --- requirements/requirements-tests-install-s390x.txt | 12 ++++++------ tools/smoketest.sh | 10 ++++++---- tools/test-manylinux.sh | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/requirements/requirements-tests-install-s390x.txt b/requirements/requirements-tests-install-s390x.txt index 31962f542..e3a9a1d2f 100644 --- a/requirements/requirements-tests-install-s390x.txt +++ b/requirements/requirements-tests-install-s390x.txt @@ -5,12 +5,12 @@ # tink) publish no s390x wheels and would fall back to slow/failing source builds # on the s390x agent (e.g. google-re2 needs the abseil C++ headers). # -# This is only the smoke-test dependency set: tools/smoketest.sh installs and -# exercises the core client plus the [avro], [protobuf] and [json] extras (all of -# which have s390x wheels or build with gcc) and runs the top-level unit tests, -# which do not import the rules/schema-registry crypto stack. Drop this file and -# use requirements-tests-install.txt once cryptography/google-re2/tink ship s390x -# wheels. +# This is only the smoke-test dependency set: tools/smoketest.sh runs the +# top-level unit tests, which do not import the rules/schema-registry crypto +# stack. (It then also installs the [avro], [protobuf] and [json] extras, which +# pull the schema-registry deps, so cryptography is still built from source +# there.) Drop this file and use requirements-tests-install.txt once +# cryptography/google-re2/tink ship s390x wheels. # # trivup is also omitted: it is only used by tests/integration (not exercised by # the smoke test) and it pulls jwcrypto -> cryptography, reintroducing the same diff --git a/tools/smoketest.sh b/tools/smoketest.sh index 630c39b3b..cf95b69a9 100755 --- a/tools/smoketest.sh +++ b/tools/smoketest.sh @@ -61,10 +61,12 @@ for py in 3.9 ; do uv pip install pkginfo # On s390x, use the reduced test-install set: cryptography, google-re2 and - # tink (pulled by the schemaregistry/rules extras) have no s390x wheels and - # would fall back to slow/failing source builds. The smoke test only - # exercises core + [avro]/[protobuf]/[json] and the top-level unit tests, - # none of which need those deps. + # tink (pulled by the schemaregistry/rules requirements) have no s390x + # wheels and would fall back to slow/failing source builds. The top-level + # unit tests don't need them. The [avro]/[protobuf]/[json] extras + # installed below do pull the schema-registry deps, so on s390x + # cryptography is built from source there (needs a C compiler and + # OpenSSL >= 3.0 headers). tests_install_reqs="requirements/requirements-tests-install.txt" if [[ "$(uname -m)" == "s390x" ]]; then tests_install_reqs="requirements/requirements-tests-install-s390x.txt" diff --git a/tools/test-manylinux.sh b/tools/test-manylinux.sh index df4f93953..49ad209c0 100755 --- a/tools/test-manylinux.sh +++ b/tools/test-manylinux.sh @@ -41,6 +41,13 @@ function setup_ubuntu { apt-get install -y -q python3.9 apt-get install -y -q python3.9-distutils apt-get install -y -q curl + # s390x: several test and extra dependencies (fastavro, psutil, librt via + # mypy, and cryptography via the schema-registry deps of the extras the + # smoke test installs) publish no s390x wheels and are built from source, + # which needs a C compiler plus the Python and OpenSSL headers. + if [[ $(uname -m) == s390x ]]; then + apt-get install -y -q gcc python3.9-dev libssl-dev pkg-config + fi } @@ -78,6 +85,13 @@ function run_all_with_docker { exit 1 fi + # s390x: test on ubuntu:22.04 and 24.04 rather than 20.04. cryptography has + # no s390x wheel, so it is built against the system OpenSSL, and it needs + # OpenSSL >= 3.0 (ubuntu:20.04 ships 1.1.1). + if [[ -z $DOCKER_IMAGES && $(uname -m) == s390x ]]; then + DOCKER_IMAGES="ubuntu:22.04 ubuntu:24.04" + fi + [[ ! -z $DOCKER_IMAGES ]] || \ # LTS and stable release of popular Linux distros. DOCKER_IMAGES="ubuntu:20.04 ubuntu:22.04" From 44e9c64ce6ca8614f4a6bbea19e7a5804844e3b4 Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Thu, 24 Sep 2026 16:58:21 +0530 Subject: [PATCH 5/8] Skip tests/schema_registry on s390x from tests/conftest.py --- .../requirements-tests-install-nogil-s390x.txt | 4 ++-- tests/conftest.py | 18 ++++++++++++++++++ tools/verify-free-threaded-job.sh | 11 ++++------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/requirements/requirements-tests-install-nogil-s390x.txt b/requirements/requirements-tests-install-nogil-s390x.txt index e235a924c..50ed99bd2 100644 --- a/requirements/requirements-tests-install-nogil-s390x.txt +++ b/requirements/requirements-tests-install-nogil-s390x.txt @@ -5,8 +5,8 @@ # Same as requirements-tests-install-nogil.txt but WITHOUT # requirements-schemaregistry.txt and trivup, for the reason given in # requirements-tests-install-s390x.txt: they pull cryptography (via authlib and -# jwcrypto), which publishes no s390x wheels. The job skips tests/schema_registry -# to match. +# jwcrypto), which publishes no s390x wheels. tests/conftest.py skips collecting +# tests/schema_registry on s390x to match. # Keep in sync with requirements-tests-install-nogil.txt when adding new includes. -r requirements-tests.txt -r requirements-avro-nogil.txt diff --git a/tests/conftest.py b/tests/conftest.py index d2abf2d91..5131917cc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,13 +16,31 @@ # limitations under the License. # +import platform import sys import sysconfig +import warnings import pytest FREE_THREADED_BUILD = bool(sysconfig.get_config_var("Py_GIL_DISABLED")) +# s390x: the schema-registry stack's deps (cryptography, via authlib) publish +# no s390x wheels, so the s390x test installs leave them out (see +# requirements/requirements-tests-install-s390x.txt). Everything under +# tests/schema_registry needs them: its conftest.py imports the +# schema-registry client, and with it authlib, at import time. So skip +# collecting that directory on s390x. The exclusion lives here because that +# conftest.py would fail to import before it could exclude anything itself. +collect_ignore = [] +if platform.machine() == "s390x": + collect_ignore = ["schema_registry"] + warnings.warn( + "s390x: skipping collection of tests/schema_registry, whose " + "schema-registry deps (cryptography via authlib) ship no s390x wheels", + RuntimeWarning, + ) + if FREE_THREADED_BUILD: diff --git a/tools/verify-free-threaded-job.sh b/tools/verify-free-threaded-job.sh index e4aa6d4b0..c6eed2f0e 100755 --- a/tools/verify-free-threaded-job.sh +++ b/tools/verify-free-threaded-job.sh @@ -26,14 +26,12 @@ esac echo "Verifying the free-threaded wheel matching $wheel_glob for $OS_NAME-$ARCH" # s390x: the schema-registry stack's deps (cryptography, via authlib and trivup's -# jwcrypto) publish no s390x wheels, so install the reduced set and skip the -# schema-registry tests, as the s390x smoke test does (see -# requirements/requirements-tests-install-nogil-s390x.txt). +# jwcrypto) publish no s390x wheels, so install the reduced set (see +# requirements/requirements-tests-install-nogil-s390x.txt). tests/conftest.py +# skips collecting tests/schema_registry on s390x to match. tests_install_reqs=requirements/requirements-tests-install-nogil.txt -ignore_sr_tests= if [[ $ARCH == s390x ]]; then tests_install_reqs=requirements/requirements-tests-install-nogil-s390x.txt - ignore_sr_tests=--ignore=tests/schema_registry fi uv venv _venv314t --python 3.14t @@ -49,5 +47,4 @@ ls artifacts/wheelhouse/$wheel_glob uv pip install --no-index --find-links artifacts/wheelhouse confluent-kafka tools/verify-free-threaded-wheel.sh -# Unquoted on purpose: an empty $ignore_sr_tests must expand to no argument. -python -m pytest tests/ --ignore=tests/integration --ignore=tests/test_unasync.py $ignore_sr_tests --timeout 1200 +python -m pytest tests/ --ignore=tests/integration --ignore=tests/test_unasync.py --timeout 1200 From 9851dc2d0225e9dcf3cc6ae91fde9561553d9efd Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Wed, 30 Sep 2026 11:28:19 +0530 Subject: [PATCH 6/8] Shorten the s390x comments --- tests/conftest.py | 9 ++------- tools/verify-free-threaded-job.sh | 7 +++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 5131917cc..8a7d5b109 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,13 +25,8 @@ FREE_THREADED_BUILD = bool(sysconfig.get_config_var("Py_GIL_DISABLED")) -# s390x: the schema-registry stack's deps (cryptography, via authlib) publish -# no s390x wheels, so the s390x test installs leave them out (see -# requirements/requirements-tests-install-s390x.txt). Everything under -# tests/schema_registry needs them: its conftest.py imports the -# schema-registry client, and with it authlib, at import time. So skip -# collecting that directory on s390x. The exclusion lives here because that -# conftest.py would fail to import before it could exclude anything itself. +# s390x: tests/schema_registry needs cryptography (via authlib), which ships no +# s390x wheels, and its conftest.py imports it at load time, so skip it here. collect_ignore = [] if platform.machine() == "s390x": collect_ignore = ["schema_registry"] diff --git a/tools/verify-free-threaded-job.sh b/tools/verify-free-threaded-job.sh index c6eed2f0e..6bff90ab4 100755 --- a/tools/verify-free-threaded-job.sh +++ b/tools/verify-free-threaded-job.sh @@ -25,10 +25,9 @@ case "$OS_NAME-$ARCH" in esac echo "Verifying the free-threaded wheel matching $wheel_glob for $OS_NAME-$ARCH" -# s390x: the schema-registry stack's deps (cryptography, via authlib and trivup's -# jwcrypto) publish no s390x wheels, so install the reduced set (see -# requirements/requirements-tests-install-nogil-s390x.txt). tests/conftest.py -# skips collecting tests/schema_registry on s390x to match. +# s390x: cryptography (via authlib, trivup's jwcrypto) ships no s390x wheels, +# so this installs the reduced requirements-tests-install-nogil-s390x.txt; +# tests/conftest.py skips tests/schema_registry there to match. tests_install_reqs=requirements/requirements-tests-install-nogil.txt if [[ $ARCH == s390x ]]; then tests_install_reqs=requirements/requirements-tests-install-nogil-s390x.txt From d15b154809ce88665f2b8d0d1a594517ee610fa4 Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Wed, 30 Sep 2026 11:36:11 +0530 Subject: [PATCH 7/8] Add the s390x wheels to the CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb77a1d66..7e60378e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ v2.16.0 is a feature release with the following features, fixes and enhancements ### Enhancements - `confluent_kafka` now declares itself GIL-safe, enabling real multi-core parallelism on free-threaded CPython builds. See the [Multithreading Guide](docs/multithreading-guide.md) for thread-safety details and free-threaded caveats. (#2347) - Add Python 3.14t wheels (#2352) +- Add Linux s390x (IBM Z) wheels, including Python 3.14t (#2360) - Producer `close()` now aborts any open transaction (#2347) - Async IO Consumer's default worker pool size has been increased from 2 to 100 (#2347) - Add support for saving Azure key version with DEK (#2306) From 20ae9089c5bc11ad73a6180abdd26e26167a8e4c Mon Sep 17 00:00:00 2001 From: Devarsh Patel Date: Thu, 1 Oct 2026 17:30:45 +0530 Subject: [PATCH 8/8] Address review: if/else, quoting, newer Ubuntu and Python --- .semaphore/semaphore.yml | 2 +- tools/smoketest.sh | 3 ++- tools/test-manylinux.sh | 13 +++---------- tools/verify-free-threaded-job.sh | 5 +++-- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index f64221978..c1834697b 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -522,7 +522,7 @@ blocks: commands: - export ARCH=s390x # sem-version only provides a pip to bootstrap uv; the wheel runs in the 3.14t venv uv creates. - - sem-version python 3.9 + - sem-version python 3.13 - pip install uv - tools/verify-free-threaded-job.sh - name: "Wheel Verification: OSX x64" diff --git a/tools/smoketest.sh b/tools/smoketest.sh index cf95b69a9..d68e2adb9 100755 --- a/tools/smoketest.sh +++ b/tools/smoketest.sh @@ -67,9 +67,10 @@ for py in 3.9 ; do # installed below do pull the schema-registry deps, so on s390x # cryptography is built from source there (needs a C compiler and # OpenSSL >= 3.0 headers). - tests_install_reqs="requirements/requirements-tests-install.txt" if [[ "$(uname -m)" == "s390x" ]]; then tests_install_reqs="requirements/requirements-tests-install-s390x.txt" + else + tests_install_reqs="requirements/requirements-tests-install.txt" fi uv pip install -r "$tests_install_reqs" diff --git a/tools/test-manylinux.sh b/tools/test-manylinux.sh index 49ad209c0..b3c648441 100755 --- a/tools/test-manylinux.sh +++ b/tools/test-manylinux.sh @@ -45,7 +45,7 @@ function setup_ubuntu { # mypy, and cryptography via the schema-registry deps of the extras the # smoke test installs) publish no s390x wheels and are built from source, # which needs a C compiler plus the Python and OpenSSL headers. - if [[ $(uname -m) == s390x ]]; then + if [[ $(uname -m) == "s390x" ]]; then apt-get install -y -q gcc python3.9-dev libssl-dev pkg-config fi } @@ -85,16 +85,9 @@ function run_all_with_docker { exit 1 fi - # s390x: test on ubuntu:22.04 and 24.04 rather than 20.04. cryptography has - # no s390x wheel, so it is built against the system OpenSSL, and it needs - # OpenSSL >= 3.0 (ubuntu:20.04 ships 1.1.1). - if [[ -z $DOCKER_IMAGES && $(uname -m) == s390x ]]; then - DOCKER_IMAGES="ubuntu:22.04 ubuntu:24.04" - fi - [[ ! -z $DOCKER_IMAGES ]] || \ - # LTS and stable release of popular Linux distros. - DOCKER_IMAGES="ubuntu:20.04 ubuntu:22.04" + # Supported LTS releases of popular Linux distros. + DOCKER_IMAGES="ubuntu:22.04 ubuntu:24.04 ubuntu:26.04" _wheels="$wheelhouse/*manylinux*.whl" diff --git a/tools/verify-free-threaded-job.sh b/tools/verify-free-threaded-job.sh index 6bff90ab4..4ebe4207a 100755 --- a/tools/verify-free-threaded-job.sh +++ b/tools/verify-free-threaded-job.sh @@ -28,9 +28,10 @@ echo "Verifying the free-threaded wheel matching $wheel_glob for $OS_NAME-$ARCH" # s390x: cryptography (via authlib, trivup's jwcrypto) ships no s390x wheels, # so this installs the reduced requirements-tests-install-nogil-s390x.txt; # tests/conftest.py skips tests/schema_registry there to match. -tests_install_reqs=requirements/requirements-tests-install-nogil.txt -if [[ $ARCH == s390x ]]; then +if [[ $ARCH == "s390x" ]]; then tests_install_reqs=requirements/requirements-tests-install-nogil-s390x.txt +else + tests_install_reqs=requirements/requirements-tests-install-nogil.txt fi uv venv _venv314t --python 3.14t