wheelripe

Configuration

There is no config file. Everything is a flag, an Action input or an environment variable, and the defaults describe a typical 2026 deployment.

Target Python

-p / --python, env WHEELRIPE_PYTHON, default 3.15. Accepts 3.15, 3.15t, cp315, 315t. The t suffix means the free-threaded build, which has its own ABI: a cp315 or abi3 wheel does not load there, a cp315t or abi3t one does.

Platforms

--platform (repeat or comma-separate), or --all-platforms. Default linux-x86_64, macos-arm64, windows-amd64. Keys are listed in the reference.

Floors: glibc, musl, macOS

A wheel tagged manylinux_2_39_x86_64 needs glibc 2.39; on a 2.34 host pip skips it. Set the oldest system you deploy on and wheelripe judges with that floor, and tells you when the only wheels are for newer systems.

FlagDefaultApplies to
--glibc2.34linux-* (manylinux tags, including manylinux1/2010/2014)
--musl1.2musllinux-*
--macos14macos-* (arm64 also accepts universal2)

Failing

--fail-on sets the exit-1 threshold: bump (default: anything you have to change), blocked (only upstream blockers — useful for a "tell me when" job), build (also sdist-only packages), never (report only).

Pre-releases

--pre lets the suggested bump be a pre-release. Early in a CPython cycle, many projects ship wheels in an rc first.

Indexes

By default wheelripe asks the PyPI JSON API. For anything else — PyTorch's download.pytorch.org, Artifactory, Nexus, devpi, GitLab — give it the simple-API URL you would give pip. It asks for PEP 691 JSON (Accept: application/vnd.pypi.simple.v1+json) and reads PEP 503 HTML when that is what comes back.

WhereEffect
-i / --index-url URLReplaces PyPI for every package, including ones a lockfile pinned to another registry. PyPI is not asked about your package names unless you list it.
--extra-index-url URLRepeatable. Files from every index are pooled, as pip does, so a newer release on any of them counts.
requirements files-i, --index-url and --extra-index-url lines, also inside -r includes, with pip's ${VAR} expansion. The last -i wins, as in pip.
lockfilesEach package is checked on the registry it was locked from: source = { registry = … } in uv.lock, a legacy source in poetry.lock, index in pylock.toml, _meta.sources in Pipfile.lock.
environmentPIP_INDEX_URL, UV_DEFAULT_INDEX or UV_INDEX_URL for the main index; PIP_EXTRA_INDEX_URL, UV_INDEX and UV_EXTRA_INDEX_URL (space-separated) for extras.
--index URLA mirror of the PyPI JSON API (<index>/<name>/json), env WHEELRIPE_INDEX.

Order: --index-url > the lockfile's registry for that package > -i in requirements files > environment > PyPI. Extra indexes from all of them are added together. https://pypi.org/simple anywhere in the list means PyPI's JSON API, which also gives wheelripe the upstream links for BLOCKED packages.

Local versions

Versions come from file names (packaging.utils), so torch-2.14.0+cpu-cp315-cp315-win_amd64.whl is version 2.14.0+cpu. Matching follows PEP 440, like pip: torch==2.14.0 accepts 2.14.0+cpu on Linux and Windows and plain 2.14.0 on macOS; torch==2.14.0+cpu accepts only the +cpu builds, so on macOS it reports the first release that has one. CI compares these verdicts with pip on the live PyTorch index for 3.15 and 3.15t.

Credentials

Put them in the URL (https://USER:TOKEN@host/simple; percent-encode an @ or : inside the token) or in ~/.netrc (or the file named by NETRC). They are sent as HTTP Basic auth to that host only — including lockfile registries on the same host, which uv records without credentials — and are dropped on a redirect to another host. wheelripe never prints them: every URL in the report, warnings, annotations, MCP results and error messages is redacted.

When an index says no

AnswerWhat wheelripe does
404 / 410The package is not on that index. If no index has it, it is MISSING and the note says what each index answered. An index that has none of your packages gets a warning: is the URL the /simple root?
401As in pip, that index adds no files for the package; a warning says whether credentials were missing or rejected.
403The same, but a warning appears only when the index refused every package (download.pytorch.org answers 403 for projects it does not host).
a web page, XML, the PyPI JSON API or websiteExit code 2, with the URL and a hint. A login page or web UI is not a simple index, and a verdict built from it would be wrong.
5xx, timeoutsThree attempts, then exit code 2.

Warnings go to stderr, into the JSON report (warnings), the Markdown summary and, with --annotations, a ::warning annotation.

Environment variables

VariableEffect
WHEELRIPE_PYTHONDefault for --python.
WHEELRIPE_INDEXDefault for --index.
PIP_INDEX_URL, UV_DEFAULT_INDEX, UV_INDEX_URLMain simple index when neither --index-url nor a requirements-file -i is given.
PIP_EXTRA_INDEX_URL, UV_INDEX, UV_EXTRA_INDEX_URLExtra simple indexes (space-separated; UV_INDEX entries may be name=url).
NETRCnetrc file with index credentials (default ~/.netrc).
NO_COLORPlain text output.
HTTPS_PROXYStandard proxy support.
SSL_CERT_FILECA bundle for an index behind a private certificate authority.

What gets read

FileNotes
uv.lockRegistry packages only, each checked on its own registry; git, path and URL sources are skipped.
pylock.tomlPEP 751 lockfiles.
poetry.lock, Pipfile.lockAll locked packages.
requirements*.txtFollows -r, handles continuations and hashes, honours -i / --extra-index-url; skips other options, URLs and -e.
pyproject.toml[project] dependencies, optional dependencies and dependency groups.

Environment markers are evaluated per target, so pywin32; sys_platform == "win32" is only checked for Windows and shows as skipped elsewhere.

Reference →