From 5db808045f28190e5a56b6ddc421fba07525f14b Mon Sep 17 00:00:00 2001 From: AlpinDale Date: Fri, 31 Jul 2026 09:03:06 +0430 Subject: [PATCH] fix(release): apply manylinux tag before PyPI upload Signed-off-by: AlpinDale --- .github/scripts/detect_manylinux_tag.py | 90 +++++++++++++++++++++++++ .github/workflows/release-wheel.yml | 16 ++++- 2 files changed, 103 insertions(+), 3 deletions(-) create mode 100755 .github/scripts/detect_manylinux_tag.py diff --git a/.github/scripts/detect_manylinux_tag.py b/.github/scripts/detect_manylinux_tag.py new file mode 100755 index 0000000000..70d2ee15e1 --- /dev/null +++ b/.github/scripts/detect_manylinux_tag.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project + +"""Detect and apply the manylinux tag supported by a wheel's binaries. + +This changes only the wheel filename. CUDA libraries remain external, so +``auditwheel repair`` cannot be used to graft dependencies into the wheel. +""" + +from __future__ import annotations + +import argparse +import sys +from pathlib import Path + +from auditwheel.error import ( + AuditwheelError, + NonPlatformWheelError, + WheelToolsError, +) +from auditwheel.wheel_abi import analyze_wheel_abi +from auditwheel.wheeltools import get_wheel_architecture, get_wheel_libc + + +def detect_platform_tag(wheel: Path) -> str: + """Return the most precise manylinux tag supported by the wheel.""" + try: + architecture = get_wheel_architecture(wheel.name) + except (WheelToolsError, NonPlatformWheelError): + architecture = None + + try: + libc = get_wheel_libc(wheel.name) + except WheelToolsError: + libc = None + + wheel_info = analyze_wheel_abi( + libc, + architecture, + wheel, + frozenset(), + disable_isa_ext_check=False, + allow_graft=False, + ) + return wheel_info.sym_policy.name + + +def rename_wheel(wheel: Path, platform_tag: str) -> Path: + """Replace the platform component of a wheel filename.""" + parts = wheel.stem.split("-") + if len(parts) < 5: + raise ValueError(f"Unrecognized wheel filename: {wheel.name}") + parts[-1] = platform_tag + destination = wheel.with_name("-".join(parts) + ".whl") + if destination != wheel: + wheel.rename(destination) + return destination + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("wheel", type=Path) + args = parser.parse_args() + + if not args.wheel.is_file(): + parser.error(f"wheel does not exist: {args.wheel}") + + try: + platform_tag = detect_platform_tag(args.wheel) + destination = rename_wheel(args.wheel, platform_tag) + except (AuditwheelError, OSError, ValueError) as error: + print( + f"Failed to retag {args.wheel.name}: {type(error).__name__}: {error}", + file=sys.stderr, + ) + return 1 + + print(f"Detected platform tag: {platform_tag}", file=sys.stderr) + if destination != args.wheel: + print( + f"Renamed {args.wheel.name} to {destination.name}", + file=sys.stderr, + ) + print(destination) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/workflows/release-wheel.yml b/.github/workflows/release-wheel.yml index ea73d0050b..85f7a1b7c3 100644 --- a/.github/workflows/release-wheel.yml +++ b/.github/workflows/release-wheel.yml @@ -35,6 +35,19 @@ jobs: - name: Build release wheel run: ./docker/export_wheels.sh + - name: Install uv + uses: astral-sh/setup-uv@v7 + + - name: Apply manylinux platform tag + shell: bash + run: | + set -euo pipefail + wheel="$(find wheels/main -maxdepth 1 -type f -name '*.whl' -print -quit)" + test -n "$wheel" + uv run --isolated --no-project \ + --with auditwheel==6.6.0 \ + python .github/scripts/detect_manylinux_tag.py "$wheel" + - name: Verify release version shell: bash run: | @@ -50,9 +63,6 @@ jobs: --tag "$GITHUB_REF_NAME" \ --output release-notes.md - - name: Install uv - uses: astral-sh/setup-uv@v7 - - name: Publish wheel to PyPI run: | uv publish \