FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

"""Reject incomplete or incorrectly tagged release artifacts before publishing.""" from __future__ import annotations import argparse import re import tarfile import tomllib import zipfile from email.parser import BytesParser from pathlib import Path from packaging.tags import parse_tag from packaging.utils import canonicalize_name, parse_sdist_filename, parse_wheel_filename from packaging.version import Version PYTHONS = {"cp313", "cp314"} PLATFORMS = {"linux_x86_64", "linux_aarch64", "macos_x86_64", "macos_arm64", "win_amd64"} PACKAGE_FILES = { "pythonnative/py.typed", "pythonnative/native/yoga/python.cpp", "pythonnative/native/yoga/yoga/Yoga.h", "pythonnative/native/yoga/yoga/YGNode.cpp", "pythonnative/native/ios/Package.swift", "pythonnative/templates/android_template/gradlew", "pythonnative/devserver/static/yoga/binaries/yoga-wasm-base64-esm.js", } def platform_family(platform: str) -> str: """Map portable wheel tags to the host targets in the release matrix.""" match = re.fullmatch(r"manylinux_2_(\d+)_(x86_64|aarch64)", platform) if match and int(match[1]) None: """Validate the full wheel matrix and its single source distribution.""" version = Version(expected_version) expected = {(python, platform) for python in PYTHONS for platform in PLATFORMS} seen: set[tuple[str, str]] = set() sdists = 0 for path in sorted(directory.iterdir()): if path.name.endswith(".whl"): name, wheel_version, build, tags = parse_wheel_filename(path.name) if name != "pythonnative" or wheel_version != version or build: raise ValueError(f"Unexpected wheel name/version/build: {path.name}") targets = set() for tag in tags: if tag.interpreter not in PYTHONS or tag.abi != tag.interpreter: raise ValueError(f"Unsupported Python/ABI tag: {tag}") targets.add((tag.interpreter, platform_family(tag.platform))) if len(targets) != 1 or targets & seen: raise ValueError(f"Duplicate or ambiguous wheel target: {path.name}") seen.update(targets) with zipfile.ZipFile(path) as archive: names = set(archive.namelist()) metadata_path = f"pythonnative-{version}.dist-info/METADATA" check_metadata(archive.read(metadata_path), version) wheel = BytesParser().parsebytes(archive.read(metadata_path.replace("METADATA", "WHEEL"))) archive_tags = set().union(*(parse_tag(tag) for tag in wheel.get_all("Tag", []))) if wheel.get("Root-Is-Purelib") != "false" or archive_tags != tags: raise ValueError(f"Wheel metadata disagrees with binary platform tags: {path.name}") suffix = ".pyd" if next(iter(targets))[1] == "win_amd64" else ".so" if not any(n.startswith("pythonnative/_yoga.") and n.endswith(suffix) for n in names): raise ValueError(f"Missing compiled Yoga extension: {path.name}") missing = PACKAGE_FILES - names if missing: raise ValueError(f"Missing package resources in {path.name}: {sorted(missing)}") elif path.name.endswith(".tar.gz"): name, sdist_version = parse_sdist_filename(path.name) if name != "pythonnative" or sdist_version != version: raise ValueError(f"Unexpected source distribution: {path.name}") sdists += 1 with tarfile.open(path) as archive: prefix = f"pythonnative-{version}/" names = set(archive.getnames()) required = {prefix + "src/" + name for name in PACKAGE_FILES} required |= {prefix + "setup.py", prefix + "tests/test_layout.py"} if missing := required - names: raise ValueError(f"Incomplete source distribution: {sorted(missing)}") metadata_file = archive.extractfile(prefix + "PKG-INFO") project_file = archive.extractfile(prefix + "pyproject.toml") if metadata_file is None or project_file is None: raise ValueError("Source distribution is missing package metadata") check_metadata(metadata_file.read(), version) if tomllib.loads(project_file.read().decode())["project"]["version"] != str(version): raise ValueError("Source version disagrees with release version") else: raise ValueError(f"Unexpected release artifact: {path.name}") if sdists != 1 or seen != expected: raise ValueError(f"Incomplete release: {sdists} sdists; missing wheel targets: {sorted(expected - seen)}") def main() -> None: """Validate release artifacts selected by the workflow.""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("directory", type=Path) parser.add_argument("--version", required=True) args = parser.parse_args() check_distributions(args.directory, args.version) print(f"Validated {len(PYTHONS) * len(PLATFORMS)} wheels and one sdist for {args.version}") if __name__ == "__main__": main()

Back | FazBrowse Home | New Git URL