diff --git a/.github/workflows/build-impit.yml b/.github/workflows/build-impit.yml new file mode 100644 index 000000000..93434ec5b --- /dev/null +++ b/.github/workflows/build-impit.yml @@ -0,0 +1,100 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on the `linux-build`/`linux-test` jobs of +# https://github.com/apify/impit/blob/master/.github/workflows/python-test.yaml +name: Build impit wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'impit version to build (git tag without the leading py-, e.g. 0.14.1)' + required: true + default: '0.14.1' + pull_request: + paths: + - '.github/workflows/build-impit.yml' + +concurrency: + group: ${{ github.workflow }}-${{ inputs.version || '0.14.1' }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + # `inputs.version` is empty on pull_request events; default to 0.14.1 there. + IMPIT_VERSION: ${{ inputs.version || '0.14.1' }} + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + + build_wheels: + needs: [setup] + name: Build impit ${{ inputs.version || '0.14.1' }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 360 + strategy: + fail-fast: false + matrix: + python: [cp312, cp313, cp314, cp314t] + + steps: + - name: Checkout impit py-${{ env.IMPIT_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: apify/impit + ref: py-${{ env.IMPIT_VERSION }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Patch impit source + run: git apply python-wheels/patches/impit/${{ env.IMPIT_VERSION }}/*.patch + + - name: Build wheels + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + package-dir: impit-python + output-dir: wheelhouse/ + env: + # musllinux is dropped: rustup.rs ships no riscv64 musl toolchain. + CIBW_BUILD: ${{ matrix.python }}-manylinux_riscv64 + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + # impit-python ships no [tool.cibuildwheel], so the Rust toolchain its + # maturin backend needs is installed in-container here. + CIBW_BEFORE_ALL_LINUX: >- + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + CIBW_ENVIRONMENT_LINUX: PATH="$PATH:$HOME/.cargo/bin" + CIBW_TEST_REQUIRES: pytest pytest-asyncio pytest-rerunfailures pproxy + CIBW_TEST_SOURCES: >- + impit-python/test impit-python/pyproject.toml + CIBW_TEST_COMMAND: >- + cd impit-python && + python -c "import impit.impit as m, importlib.metadata as md; + assert m.__file__.endswith('.so'), m.__file__; + assert any(str(p).endswith('licenses/LICENSE.md') for p in md.files('impit'))" && + python -m pytest -v + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: impit-${{ env.IMPIT_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish impit ${{ inputs.version || '0.14.1' }} + needs: [setup, build_wheels] + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + with: + artifact-pattern: impit-${{ inputs.version || '0.14.1' }}-*-manylinux_riscv64 diff --git a/patches/impit/0.14.1/0001-impit-python-Cargo.toml-drop-pyo3-auto-initialize.patch b/patches/impit/0.14.1/0001-impit-python-Cargo.toml-drop-pyo3-auto-initialize.patch new file mode 100644 index 000000000..4de094e48 --- /dev/null +++ b/patches/impit/0.14.1/0001-impit-python-Cargo.toml-drop-pyo3-auto-initialize.patch @@ -0,0 +1,41 @@ +From 4d8ff5017201b92ef9fdfb62cbec05ca448e4f1c Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Tue, 8 Sep 2026 17:13:42 +0200 +Subject: [PATCH] impit-python/Cargo.toml: drop pyo3's auto-initialize feature + +pyo3-build-config's build script hard-errors when auto-initialize is +enabled against a Python installation that only supports static +embedding: 'The auto-initialize feature is enabled, but your python +installation only supports embedding the Python interpreter +statically.' manylinux_2_39_riscv64's bundled CPythons are built this +way, so every interpreter leg fails at the pyo3 build step before +compiling a single impit source file. + +auto-initialize only matters for embedding a Python interpreter in a +Rust binary (or cargo test); impit-python builds a cdylib extension +module loaded into an already-running interpreter, which never calls +it, and pyo3-async-runtimes' own pyo3 dependency (version = "0.29", +no features) does not request it either. Dropping the feature changes +no runtime behaviour and clears the build error. + +Upstream-Status: Inappropriate [manylinux_2_39_riscv64-specific: its CPython builds lack a shared libpython, unlike upstream's own maturin-action manylinux images, which build the same Cargo.toml with this feature enabled without issue] +--- + impit-python/Cargo.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/impit-python/Cargo.toml b/impit-python/Cargo.toml +index bf15c00..91c679b 100644 +--- a/impit-python/Cargo.toml ++++ b/impit-python/Cargo.toml +@@ -15,7 +15,7 @@ h2 = "0.4.7" + reqwest = "0.13.1" + tokio-stream = "0.1.17" + bytes = "1.9.0" +-pyo3 = { version = "0.29", features = ["extension-module", "auto-initialize", "either"] } ++pyo3 = { version = "0.29", features = ["extension-module", "either"] } + pyo3-async-runtimes = { version = "0.29", features = ["attributes", "async-std-runtime", "tokio-runtime"] } + urlencoding = "2.1.3" + encoding = "0.2.33" +-- +2.50.1 (Apple Git-155) +