From bb3f5a9a490bcac8a53e410eaf4c73e017260649 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 3 Sep 2026 22:49:49 +0200 Subject: [PATCH 1/4] deptry: add build-deptry.yml for riscv64 wheels Drives upstream's maturin/pyo3 build (release.yml's linux job) through cibuildwheel, narrowed to riscv64. abi3-py310 is unconditional in Cargo.toml, so one cp310 build covers cp310-cp314; musllinux is dropped (no riscv64 musl rustup target). Includes a small patch to tests/functional/conftest.py so the functional suite reuses the wheel cibuildwheel already built instead of rebuilding deptry from scratch a second time via `uv build`. --- .github/workflows/build-deptry.yml | 113 ++++++++++++++++++ ...tional-tests-to-reuse-a-prebuilt-whe.patch | 50 ++++++++ 2 files changed, 163 insertions(+) create mode 100644 .github/workflows/build-deptry.yml create mode 100644 patches/deptry/0.25.1/0001-tests-allow-functional-tests-to-reuse-a-prebuilt-whe.patch diff --git a/.github/workflows/build-deptry.yml b/.github/workflows/build-deptry.yml new file mode 100644 index 000000000..afb4c0176 --- /dev/null +++ b/.github/workflows/build-deptry.yml @@ -0,0 +1,113 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow drives upstream's own wheel build (release.yml `linux` job, which calls +# PyO3/maturin-action) through cibuildwheel, narrowed to riscv64. +name: Build deptry wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'deptry version/tag to build (e.g. 0.25.1)' + required: true + default: '0.25.1' + pull_request: + paths: + - '.github/workflows/build-deptry.yml' + +concurrency: + group: ${{ github.workflow }}-${{ inputs.version || '0.25.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.25.1 there. + DEPTRY_VERSION: ${{ inputs.version || '0.25.1' }} + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + + build_wheels: + needs: [setup] + name: Build deptry ${{ inputs.version || '0.25.1' }} cp310-abi3-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 360 + + steps: + - name: Checkout deptry ${{ env.DEPTRY_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: osprey-oss/deptry + ref: ${{ env.DEPTRY_VERSION }} + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + sparse-checkout: patches/deptry + persist-credentials: false + + - name: Apply patches + run: git apply -v python-wheels/patches/deptry/${{ env.DEPTRY_VERSION }}/*.patch + + # pyproject.toml carries a stale placeholder version; upstream's own release + # job stamps the real one from the tag the same way (release.yml set-version). + - name: Set version from tag + run: | + sed -i "s/^version = \".*\"/version = \"${DEPTRY_VERSION}\"/" pyproject.toml + grep -qx "version = \"${DEPTRY_VERSION}\"" pyproject.toml + + - name: Build wheels + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + output-dir: wheelhouse/ + env: + # Cargo.toml's pyo3 dependency carries abi3-py310 unconditionally + # (gotcha 181), so every interpreter below reuses the cp310 build + # ("Found previously built wheel ... Skipping build step"). + CIBW_BUILD: >- + cp310-manylinux_riscv64 cp311-manylinux_riscv64 cp312-manylinux_riscv64 + cp313-manylinux_riscv64 cp314-manylinux_riscv64 + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + # deptry ships no [tool.cibuildwheel]; the Rust toolchain its maturin + # backend needs is installed in-container here (gotcha 10). + CIBW_BEFORE_ALL_LINUX: >- + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + CIBW_ENVIRONMENT_LINUX: >- + PATH="$PATH:$HOME/.cargo/bin" + PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ + CIBW_TEST_ENVIRONMENT: PYTHONIOENCODING=utf-8 + CIBW_TEST_SOURCES: tests + CIBW_TEST_REQUIRES: >- + pytest==9.0.2 pytest-cov==7.0.0 "pytest-xdist[psutil]==3.8.0" + inline-snapshot==0.32.5 pdm==2.26.6 poetry==2.3.2 uv + # tests/functional's conftest normally rebuilds its own wheel with `uv + # build` to install into the poetry/pdm/uv/pip venv fixtures; our patch + # points it at the wheel cibuildwheel already built and repaired + # instead of paying for a second from-scratch native Rust compile. + CIBW_TEST_COMMAND: >- + python -c "import deptry.rust as m; assert m.__file__.endswith('.so'), m.__file__" && + python -m pytest tests/unit -v && + DEPTRY_PREBUILT_WHEEL={wheel} python -m pytest tests/functional -n auto --dist loadgroup -v + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: deptry-${{ env.DEPTRY_VERSION }}-cp310-abi3-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish deptry ${{ inputs.version || '0.25.1' }} + needs: [setup, build_wheels] + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + with: + artifact-pattern: deptry-${{ inputs.version || '0.25.1' }}-*-manylinux_riscv64 diff --git a/patches/deptry/0.25.1/0001-tests-allow-functional-tests-to-reuse-a-prebuilt-whe.patch b/patches/deptry/0.25.1/0001-tests-allow-functional-tests-to-reuse-a-prebuilt-whe.patch new file mode 100644 index 000000000..87a19337a --- /dev/null +++ b/patches/deptry/0.25.1/0001-tests-allow-functional-tests-to-reuse-a-prebuilt-whe.patch @@ -0,0 +1,50 @@ +From 872146c4bced3cb8e45a41d830f5068ca8b1f582 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 3 Sep 2026 22:38:19 +0200 +Subject: [PATCH] tests: allow functional tests to reuse a prebuilt wheel + +pytest_sessionstart always runs `uv build --wheel` to produce the wheel the +venv factories install into their poetry/pdm/uv/pip environments. In a +cibuildwheel job the interpreter's own wheel has already been built (and +repaired) once; rebuilding it a second time from scratch to run the +functional suite roughly doubles an already multi-minute native riscv64 +Rust compile for no functional benefit; the produced wheel is identical. + +DEPTRY_PREBUILT_WHEEL lets the caller point at that already-built wheel and +skip the redundant rebuild; unset, behaviour is unchanged. + +Upstream-Status: Inappropriate [avoids a second from-scratch Rust compile inside a cibuildwheel test step; CI-infra only, nothing to fix in the project] +--- + tests/functional/conftest.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py +index c2f8034..33dac90 100644 +--- a/tests/functional/conftest.py ++++ b/tests/functional/conftest.py +@@ -1,6 +1,8 @@ + from __future__ import annotations + ++import os + import shlex ++import shutil + import subprocess + import sys + from pathlib import Path +@@ -22,6 +24,13 @@ def pytest_sessionstart(session: pytest.Session) -> None: + + deptry_wheel_path = Path(DEPTRY_WHEEL_DIRECTORY) + ++ prebuilt_wheel = os.environ.get("DEPTRY_PREBUILT_WHEEL") ++ if prebuilt_wheel: ++ print(f"Reusing prebuilt `deptry` wheel {prebuilt_wheel} for functional tests...") # noqa: T201 ++ deptry_wheel_path.mkdir(parents=True, exist_ok=True) ++ shutil.copy2(prebuilt_wheel, deptry_wheel_path) ++ return None ++ + print(f"Building `deptry` wheel in {deptry_wheel_path} to use it on functional tests...") # noqa: T201 + + try: +-- +2.50.1 (Apple Git-155) + From c1a76592ece24b6948bdf5ea2dd9871ee4e7e45c Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 3 Sep 2026 23:18:00 +0200 Subject: [PATCH 2/4] deptry: pin cryptography to a binary install in the test env poetry pulls keyring -> SecretStorage -> cryptography on Linux. Without PIP_ONLY_BINARY=cryptography, pip resolves whatever cryptography release is newest on PyPI, which is newer than what pypi.riseproject.dev has a riscv64 wheel for, and tries to build it from source -- failing on a missing OpenSSL dev install (openssl-sys can't find openssl.pc). --- .github/workflows/build-deptry.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-deptry.yml b/.github/workflows/build-deptry.yml index afb4c0176..568bd7a01 100644 --- a/.github/workflows/build-deptry.yml +++ b/.github/workflows/build-deptry.yml @@ -82,7 +82,10 @@ jobs: CIBW_ENVIRONMENT_LINUX: >- PATH="$PATH:$HOME/.cargo/bin" PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ - CIBW_TEST_ENVIRONMENT: PYTHONIOENCODING=utf-8 + # poetry pulls keyring -> SecretStorage -> cryptography on Linux; without + # this pip resolves a cryptography release newer than our registry has a + # riscv64 wheel for and tries (and fails) to build it from source. + CIBW_TEST_ENVIRONMENT: PYTHONIOENCODING=utf-8 PIP_ONLY_BINARY=cryptography CIBW_TEST_SOURCES: tests CIBW_TEST_REQUIRES: >- pytest==9.0.2 pytest-cov==7.0.0 "pytest-xdist[psutil]==3.8.0" From c7860958fb3c0625e5c1a501d33e421cf3cb6b62 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 3 Sep 2026 23:45:15 +0200 Subject: [PATCH 3/4] deptry: stage pyproject.toml for tests/unit's self-scan tests test_text_reporter_only/test_all_reporters run deptry against cwd's own pyproject.toml (mirrors upstream's `uv run deptry python` quality-job step); without it staged, the dependency getter builder finds nothing and raises DependencySpecificationNotFoundError instead of the expected SystemExit. Verified locally: 179 passed (was 177 passed, 2 failed). --- .github/workflows/build-deptry.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-deptry.yml b/.github/workflows/build-deptry.yml index 568bd7a01..f00341203 100644 --- a/.github/workflows/build-deptry.yml +++ b/.github/workflows/build-deptry.yml @@ -86,7 +86,10 @@ jobs: # this pip resolves a cryptography release newer than our registry has a # riscv64 wheel for and tries (and fails) to build it from source. CIBW_TEST_ENVIRONMENT: PYTHONIOENCODING=utf-8 PIP_ONLY_BINARY=cryptography - CIBW_TEST_SOURCES: tests + # tests/unit/test_core.py's test_text_reporter_only/test_all_reporters + # run deptry against cwd's own pyproject.toml (mirroring upstream's + # `uv run deptry python` quality-job step), so it has to be staged too. + CIBW_TEST_SOURCES: tests pyproject.toml CIBW_TEST_REQUIRES: >- pytest==9.0.2 pytest-cov==7.0.0 "pytest-xdist[psutil]==3.8.0" inline-snapshot==0.32.5 pdm==2.26.6 poetry==2.3.2 uv From bdacaa99b31d02293e8e112cbbc133dc741473f0 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 4 Sep 2026 01:38:43 +0200 Subject: [PATCH 4/4] deptry: add patch to upgrade pip in each functional-test fixture venv ensurepip's bundled pip on the manylinux_riscv64 image doesn't recognize the riscv64 wheel tag, so the poetry/pdm/uv/pip fixture venvs functional tests create with venv.EnvBuilder fail to install our own riscv64 wheel with "... is not a supported wheel on this platform" even though the outer cibuildwheel test venv's own pip installs the identical wheel without complaint. Verified locally (doesn't reproduce off riscv64, but the extra `pip install --upgrade pip` step is a no-op there and the functional suite still passes: 38 passed, 1 skipped). --- ...p-in-each-throwaway-venv-before-inst.patch | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 patches/deptry/0.25.1/0002-tests-upgrade-pip-in-each-throwaway-venv-before-inst.patch diff --git a/patches/deptry/0.25.1/0002-tests-upgrade-pip-in-each-throwaway-venv-before-inst.patch b/patches/deptry/0.25.1/0002-tests-upgrade-pip-in-each-throwaway-venv-before-inst.patch new file mode 100644 index 000000000..fe7c84f4a --- /dev/null +++ b/patches/deptry/0.25.1/0002-tests-upgrade-pip-in-each-throwaway-venv-before-inst.patch @@ -0,0 +1,36 @@ +From cba283a56f34d6ace2bcad4c3cbcce5791aa6cb3 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Fri, 4 Sep 2026 01:36:29 +0200 +Subject: [PATCH] tests: upgrade pip in each throwaway venv before installing + the wheel + +VirtualEnvironment.setup creates each poetry/pdm/uv/pip fixture venv with +venv.EnvBuilder(with_pip=True), which provisions whatever pip ensurepip +bundled for that Python build. On the manylinux_riscv64 cibuildwheel image +that bundled pip predates riscv64 wheel-tag support, so `pip install +--no-cache-dir ` against our own riscv64 wheel fails with "... is +not a supported wheel on this platform" even though the outer test venv's +own (newer) pip installs the identical wheel without complaint moments +earlier. + +Upstream-Status: Inappropriate [ensurepip's bundled pip on the manylinux_riscv64 image predates riscv64 wheel-tag support; not reproducible off riscv64] +--- + tests/utils.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/utils.py b/tests/utils.py +index 10b22a0..7320630 100644 +--- a/tests/utils.py ++++ b/tests/utils.py +@@ -101,6 +101,8 @@ class VirtualEnvironment: + ) + virtual_env.create(self.project_path) + ++ self.run("pip install --upgrade pip", check=True) ++ + shutil.copytree(deptry_directory / "tests/fixtures" / self.project, self.project_path / "project") + + self.run( +-- +2.50.1 (Apple Git-155) +