diff --git a/.github/workflows/test-windows-trampolines.yml b/.github/workflows/test-windows-trampolines.yml index b84640531f..20029f1daf 100644 --- a/.github/workflows/test-windows-trampolines.yml +++ b/.github/workflows/test-windows-trampolines.yml @@ -10,6 +10,21 @@ env: RUSTUP_MAX_RETRIES: 10 jobs: + # Verify windows crate version matches between workspaces + windows-version-check: + timeout-minutes: 5 + runs-on: ubuntu-latest + name: "check windows crate version" + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + + - uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6 + + - name: "Check windows crate versions match" + run: uv run scripts/check-trampoline-version-consistency.py + # Separate jobs for the nightly crate windows-trampoline-check: timeout-minutes: 15 diff --git a/scripts/check-trampoline-version-consistency.py b/scripts/check-trampoline-version-consistency.py new file mode 100644 index 0000000000..1b1bc83657 --- /dev/null +++ b/scripts/check-trampoline-version-consistency.py @@ -0,0 +1,56 @@ +"""Check that the `windows` crate version matches between workspaces. + +The uv-trampoline crate is excluded from the main workspace (it requires nightly), +so this script verifies that the `windows` crate version is kept in sync by +comparing the locked versions in both Cargo.lock files. +""" + +# /// script +# requires-python = ">=3.12" +# /// + +from __future__ import annotations + +import sys +import tomllib +from pathlib import Path + +ROOT = Path(__file__).parent.parent + + +def get_locked_windows_version(lockfile_path: Path) -> str | None: + """Get the windows crate version from a Cargo.lock file.""" + with open(lockfile_path, "rb") as f: + lockfile = tomllib.load(f) + + for package in lockfile.get("package", []): + if package.get("name") == "windows": + return package.get("version") + + return None + + +def main() -> int: + main_lockfile = ROOT / "Cargo.lock" + trampoline_lockfile = ROOT / "crates" / "uv-trampoline" / "Cargo.lock" + + main_version = get_locked_windows_version(main_lockfile) + trampoline_version = get_locked_windows_version(trampoline_lockfile) + + print(f"workspace: windows {main_version}") + print(f"uv-trampoline: windows {trampoline_version}") + + if main_version != trampoline_version: + print( + f"\n::error::windows crate version mismatch! " + f"workspace uses {main_version} but uv-trampoline uses {trampoline_version}", + file=sys.stderr, + ) + return 1 + + print("\nVersions match.") + return 0 + + +if __name__ == "__main__": + sys.exit(main())