From 41f14724c05fd09702d3092d7310863e0dcce32b Mon Sep 17 00:00:00 2001 From: John McGrath Date: Fri, 4 Sep 2026 00:46:48 -0500 Subject: [PATCH] fix: ship abi3 manylinux wheels for py3.10+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the 5×4 Python matrix. One cp310-abi3 wheel per manylinux/musllinux arch, and install protoc in the maturin container so the build.rs can run. --- .github/workflows/release.yml | 43 +++++++++++++++++++++++++++-------- AGENTS.md | 2 +- CONTRIBUTING.md | 2 +- sdk/python/Cargo.toml | 2 +- sdk/python/pyproject.toml | 3 +-- tests/e2e_sdk_python.rs | 4 ++-- 6 files changed, 40 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index baaf45a..4dea6a4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ # - builds + publishes a Helm chart to OCI on GHCR # - creates a GitHub Release and attaches binaries + chart # - publishes conproxy + conproxy-sdk to crates.io -# - builds manylinux2014 + musllinux_1_2 wheels (py3.9–3.13, x86_64 + aarch64) +# - builds manylinux2014 + musllinux_1_2 abi3 wheels (py3.10+, x86_64 + aarch64) # and publishes to PyPI (trusted publishing) # # All testing (fmt, clippy, lib tests, mcp_test, integration, integration- @@ -311,7 +311,7 @@ jobs: retention-days: 30 pypi-build: - name: pypi (${{ matrix.platform.target }} py${{ matrix.python }}) + name: pypi (${{ matrix.platform.name }}) needs: version-check if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: ${{ matrix.platform.runner }} @@ -319,18 +319,21 @@ jobs: strategy: fail-fast: false matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] platform: - - target: x86_64-unknown-linux-gnu + - name: manylinux2014-x86_64 + target: x86_64 runner: ubuntu-latest manylinux: '2014' - - target: aarch64-unknown-linux-gnu + - name: manylinux2014-aarch64 + target: aarch64 runner: ubuntu-24.04-arm manylinux: '2014' - - target: x86_64-unknown-linux-musl + - name: musllinux_1_2-x86_64 + target: x86_64-unknown-linux-musl runner: ubuntu-latest manylinux: musllinux_1_2 - - target: aarch64-unknown-linux-musl + - name: musllinux_1_2-aarch64 + target: aarch64-unknown-linux-musl runner: ubuntu-24.04-arm manylinux: musllinux_1_2 steps: @@ -339,12 +342,34 @@ jobs: with: target: ${{ matrix.platform.target }} manylinux: ${{ matrix.platform.manylinux }} - args: --release --out dist --interpreter ${{ matrix.python }} + args: --release --out dist working-directory: sdk/python sccache: 'true' + before-script-linux: | + set -euo pipefail + PROTOC_VERSION=28.3 + ARCH=$(uname -m) + case "$ARCH" in + x86_64) ZIP="protoc-${PROTOC_VERSION}-linux-x86_64.zip" ;; + aarch64) ZIP="protoc-${PROTOC_VERSION}-linux-aarch64.zip" ;; + *) echo "unsupported arch ${ARCH}"; exit 1 ;; + esac + if command -v yum >/dev/null 2>&1; then + yum install -y unzip + elif command -v apk >/dev/null 2>&1; then + apk add --no-cache unzip curl + elif command -v apt-get >/dev/null 2>&1; then + apt-get update + apt-get install -y --no-install-recommends unzip curl + fi + curl -sSL -o "/tmp/${ZIP}" \ + "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/${ZIP}" + unzip -o "/tmp/${ZIP}" -d /usr/local + rm -f "/tmp/${ZIP}" + protoc --version - uses: actions/upload-artifact@v4 with: - name: pypi-wheel-${{ matrix.platform.target }}-py${{ matrix.python }} + name: pypi-wheel-${{ matrix.platform.name }} path: sdk/python/dist/* if-no-files-found: error retention-days: 30 diff --git a/AGENTS.md b/AGENTS.md index 621de9b..cdb36d0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -128,7 +128,7 @@ Published artifacts per `v*` tag: | Helm chart | `oci://ghcr.io/jmcgrath207/charts/conproxy` + `.tgz` on GH Release | `version` + `appVersion` stamped from tag | | Binaries | GH Release + workflow artifacts | x86_64-musl, aarch64-gnu | | crates.io | `conproxy`, `conproxy-sdk` | tag version | -| PyPI | `conproxy` wheels + sdist | manylinux2014 + musllinux_1_2, py3.9–3.13, x86_64 + aarch64 | +| PyPI | `conproxy` wheels + sdist | manylinux2014 + musllinux_1_2, abi3 py3.10+, x86_64 + aarch64 | ### Coverage (weekly, not a PR gate) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9876c38..36d1be7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ Thanks for your interest in conproxy! This guide covers building, testing, and c - **Security:** `cargo-audit`, `cargo-deny`, `cargo-tarpaulin`, `cargo-cyclonedx`, `cargo-geiger`, `cargo-mutants`, `cargo-fuzz` (nightly) - **Eval:** Ollama running locally, OR Claude API key - **Profiling (Linux):** `bpftrace`, `perf` -- **Python SDK:** Python 3.9+, `maturin` +- **Python SDK:** Python 3.10+, `maturin` Install cargo tools: diff --git a/sdk/python/Cargo.toml b/sdk/python/Cargo.toml index 50f9bcb..83c1b4e 100644 --- a/sdk/python/Cargo.toml +++ b/sdk/python/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["cdylib"] [dependencies] conproxy = { path = "../..", default-features = false } conproxy-sdk = { path = "../rust" } -pyo3 = { version = "0.29", features = ["extension-module"] } +pyo3 = { version = "0.29", features = ["extension-module", "abi3-py310"] } pyo3-async-runtimes = { version = "0.29", features = ["tokio-runtime"] } tokio = { version = "1", features = ["rt-multi-thread"] } serde_json = "1" diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index 62c375a..423c971 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -5,10 +5,9 @@ build-backend = "maturin" [project] name = "conproxy" description = "Python SDK for conproxy cache proxy (native Rust bindings)" -requires-python = ">=3.9" +requires-python = ">=3.10" classifiers = [ "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/tests/e2e_sdk_python.rs b/tests/e2e_sdk_python.rs index 86af044..fad4cf3 100644 --- a/tests/e2e_sdk_python.rs +++ b/tests/e2e_sdk_python.rs @@ -6,7 +6,7 @@ //! Run with: `cargo test --test e2e_sdk_python --features e2e -- --ignored --nocapture` //! //! Prerequisites: -//! - Python 3.9+ with `pip` available +//! - Python 3.10+ with `pip` available //! - `maturin` installed (`pip install maturin`) //! - Running proxy on 127.0.0.1:8080 (for client tests) @@ -94,7 +94,7 @@ fn run_python(script: &str) -> (bool, String, String) { } #[test] -#[ignore = "E2E: requires Python 3.9+ and maturin (no running proxy needed; client ops skip gracefully)"] +#[ignore = "E2E: requires Python 3.10+ and maturin (no running proxy needed; client ops skip gracefully)"] fn python_sdk_import_test() { eprintln!(); eprintln!("\x1b[1mPython SDK E2E Tests\x1b[0m");