Skip to content

feat(TRI-1118): add --release-version + PEP 440/817 wheel scheme (cherry-pick) - #505

Merged
mc-nv merged 1 commit into
mainfrom
mchornyi/TRI-1431/advance-default-branch
Jun 29, 2026
Merged

feat(TRI-1118): add --release-version + PEP 440/817 wheel scheme (cherry-pick)#505
mc-nv merged 1 commit into
mainfrom
mchornyi/TRI-1431/advance-default-branch

Conversation

@mc-nv

@mc-nv mc-nv commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

What does the PR do?

Cherry-picks 84ee799 from r26.06 to advance main post-26.05 toward the 26.07dev_user container train (tracks upstream 26.06).

Adds --release-version flag and a PEP 440 / PEP 817-compliant wheel naming scheme.

Related PRs:

Test plan:

  • Build wheel locally with python setup.py bdist_wheel (or equivalent) and confirm output filename obeys PEP 440 / 817.
  • CI Pipeline ID: TBD

Related Issues:

  • Resolves: TRI-1431

* feat(TRI-1118): add --release-version + PEP 440/817 wheel scheme

Adds a --release-version CLI flag with a TRITON_RELEASE_VERSION env-var
fallback to build_wheel.py. Precedence: CLI flag > env var >
in-tree TRITON_VERSION file. CI can now pin a release tag without
editing the source-tree TRITON_VERSION.

Classifies the base version by regex:
  - X.Y.Z (release-semantic) -> PEP 440 normalized output: no PEP 440
    local segment, no PEP 427 build tag, no variant label. PyPI-clean.
  - anything else (.devN, aN, rcN, etc.) -> PEP 817 variant: keeps the
    PEP 427 build tag (CI_PIPELINE_ID) and appends a PEP 817 variant
    label (nv<container>.cu<major><minor>) to the wheel filename after
    the platform tag. Backward-compatible -- pre-PEP 817 installers
    ignore variants and fall back to a non-variant wheel.

ANSI-colored info lines surface the chosen path in CI logs.

Refs TRI-1118.

* feat(TRI-1118): encode CI_PIPELINE_ID via PEP 440 dev counter, drop PEP 427 build tag

Pre-this-commit, dev wheels carried the CI pipeline id as a PEP 427
build tag between version and python-tag:
    tritonserver-2.70.0.dev0-12345-cp310-cp310-...-nv26.05.cu132.whl

PEP 427 build tags are rejected by public PyPI and duplicate the
identity that already belongs in the version string.

Switch to PEP 440 .dev<N> counter semantics. When the resolved base
version matches X.Y.Z.devN and CI_PIPELINE_ID is a positive integer,
replace the dev counter with the pipeline id:
    2.70.0.dev0 + CI_PIPELINE_ID=12345 -> 2.70.0.dev12345

Resulting filename:
    tritonserver-2.70.0.dev12345-cp310-cp310-...-nv26.05.cu132.whl

This is PyPI-uploadable, PEP 440-sortable across reruns
(dev12346 > dev12345), and removes the need for any PEP 427 build-tag
injection in `python -m build`.

The PEP 817 variant label path is untouched: dev versions still
classify as non-release and get the nv/cu label appended. Release
wheels (X.Y.Z) remain PyPI-clean. Local dev builds without
CI_PIPELINE_ID keep their in-tree .dev0.

Refs TRI-1118.

* fix(TRI-1118): auditwheel writes to dist_dir; relax dev-counter regex

Two related fixes for the wheel-build / install pipeline:

1) auditwheel manylinux wheel was never installed.
   _repair_wheel_with_auditwheel() was passing --wheel-dir=<dest_dir>,
   which writes the manylinux wheel one directory above where the
   CMake `install(DIRECTORY ${WHEEL_OUT_DIR})` line reads from
   (<dest>/wheel/dist/). Result: the manylinux wheel was produced but
   never copied to /opt/tritonserver/python/ in the base image -- the
   publish job uploaded only the pre-repair linux_<arch> wheel.

   Switch --wheel-dir to dist_dir so auditwheel writes alongside the
   pre-repair wheel; on success, remove the original linux_<arch>
   wheel so dist_dir carries a single canonical manylinux artifact.

2) Dev-counter rewrite didn't match the in-tree TRITON_VERSION.
   The previous regex required canonical PEP 440 X.Y.Z.devN; in-tree
   `TRITON_VERSION` files use the legacy `X.Y.Zdev` shape (no period,
   no counter). Relax to ^(\d+\.\d+\.\d+)\.?dev\d*$ so both forms
   match and CI_PIPELINE_ID gets substituted as the dev counter.

Refs TRI-1118.

* fix(TRI-1118): route wheel tagging per PEP 425, omit manylinux when no .so

Previous logic hardcoded `manylinux_2_28_<arch>` for any wheel auditwheel
reported as "no ELF". Result: pure-Python wheels (e.g. downstream builds
that disabled bindings) carried a false manylinux compatibility promise.

New routing inspects the wheel zip for native `.so` members up front:

  Has `.so`  -> auditwheel repair. auditwheel chooses the lowest
                `manylinux_<X>_<Y>_<arch>` policy that covers the .so's
                glibc symbol requirements, per PEP 513 / PEP 599 / PEP 600.
                Original `linux_<arch>` wheel is removed on success.
  No `.so`   -> `python -m wheel tags --python-tag py3 --abi-tag none
                --platform-tag any --remove` -> emit a canonical
                `py3-none-any` pure-Python wheel per PEP 425. The
                manylinux tag is OMITTED -- claiming manylinux on a wheel
                with no glibc-bound code would be a false promise.

PEP 656 musllinux is not produced here (build containers are glibc-based;
auditwheel-musl would be needed on musl distros). PEP 440 version
normalization still happens upstream of this function in the dev-counter
rewrite.

Add `_wheel_has_so()` helper using zipfile + basename inspection
(matches `*.so` and `*.so.<ver>`), the same classification heuristic
auditwheel and pip use.

Refs TRI-1118.

* fix(TRI-1118): prevent compressed manylinux tag set from double-repair

Symptom (job 342953964 / pipeline 55073480):
  tritonserver-2.70.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
  tritonserver-2.70.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl

Cause: CMake's add_custom_command for the wheel target runs twice
(build phase + install phase). The first run produces a manylinux wheel
in `wheel/dist/` and removes the linux_<arch> input. The second run's
`python -m build` re-creates the linux_<arch> wheel; dist/ now contains
both. _repair_wheel_with_auditwheel iterates over `os.listdir(dist_dir)`
and invokes auditwheel on each, including the already-manylinux leftover.
auditwheel applied to an already-tagged wheel emits a compressed PEP 425
tag set (e.g. manylinux_2_27_x86_64.manylinux_2_28_x86_64) -- valid but
noisy.

Two-belt fix:
  1. Clean wheel/dist/ before `python -m build` runs so leftovers from
     a previous CMake pass can't accumulate.
  2. In _repair_wheel_with_auditwheel, skip wheels whose filename
     already carries a manylinux or musllinux tag (defensive guard for
     any other source of stale wheels).

Together these make the script idempotent across repeated CMake
invocations and ensure each wheel carries exactly one platform tag.

Refs TRI-1118.

* fix(TRI-1118): normalize compressed manylinux tag sets to highest version

If auditwheel emits (or has emitted) a wheel whose PEP 425 platform-tag
component is a compressed set of manylinux entries -- e.g.
manylinux_2_27_x86_64.manylinux_2_28_x86_64 -- collapse to the highest
version (manylinux_2_28_x86_64). The lower-version entry is redundant
(higher version is the strictest applicable glibc baseline, aligned
with the build container's manylinux policy).

Implementation: scan dist/ after _repair_wheel_with_auditwheel completes;
parse each wheel filename; if the platform-tag component contains
multiple manylinux_X_Y_<arch> entries, sort by (X, Y) and rewrite the
tag via `python -m wheel tags --platform-tag <highest> --remove`.

Single-tag wheels and pure-Python (py3-none-any) wheels are no-ops.
Non-manylinux entries in a compressed set (rare) are preserved.

Refs TRI-1118.
@mc-nv
mc-nv merged commit 449af13 into main Jun 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants