diff --git a/.github/workflows/release-performance.yml b/.github/workflows/release-performance.yml index aaf705d6ed..a02c75e8d9 100644 --- a/.github/workflows/release-performance.yml +++ b/.github/workflows/release-performance.yml @@ -62,7 +62,9 @@ jobs: - name: Install dependencies run: uv sync --locked --all-groups --all-extras - name: Build candidate wheel - run: uv build --wheel --out-dir "${RUNNER_TEMP}/candidate" + run: | + uv build --wheel --out-dir "${RUNNER_TEMP}/candidate" + uv build --wheel crates/sqlbuild-cli --out-dir "${RUNNER_TEMP}/candidate" # Temporary: one-model edit compiles use MAX_EDIT_COMPILE_TIME_RATIO (1.35x) because an edited # model recompiles uncached; tighten it back to 1.15x once native rendering is the default. - name: Compare candidate and previous release on this runner diff --git a/scripts/release_performance/_helpers/versions.py b/scripts/release_performance/_helpers/versions.py index 2c9ddeeefe..5d66ce8cbe 100644 --- a/scripts/release_performance/_helpers/versions.py +++ b/scripts/release_performance/_helpers/versions.py @@ -196,7 +196,8 @@ def install_wheel(*, wheel: Path, venv_dir: Path, python: str) -> Path: _create_venv(venv_dir=venv_dir, python=python) completed: subprocess.CompletedProcess[str] = _uv_pip_install( - venv_dir=venv_dir, requirements=(str(wheel.resolve()),) + venv_dir=venv_dir, + requirements=("--find-links", str(wheel.resolve().parent), str(wheel.resolve())), ) if completed.returncode != 0: raise ReleasePerformanceError(f"Installing {wheel} failed: {_tail(completed.stderr)}") diff --git a/tests/integration/scripts/__init__.py b/tests/integration/scripts/__init__.py new file mode 100644 index 0000000000..66c5503022 --- /dev/null +++ b/tests/integration/scripts/__init__.py @@ -0,0 +1 @@ +"""Integration checks for repository tooling.""" diff --git a/tests/integration/scripts/release_performance/__init__.py b/tests/integration/scripts/release_performance/__init__.py new file mode 100644 index 0000000000..0946f1f325 --- /dev/null +++ b/tests/integration/scripts/release_performance/__init__.py @@ -0,0 +1 @@ +"""Release candidate installation integration checks.""" diff --git a/tests/integration/scripts/release_performance/_test_types.py b/tests/integration/scripts/release_performance/_test_types.py new file mode 100644 index 0000000000..9cf297cd37 --- /dev/null +++ b/tests/integration/scripts/release_performance/_test_types.py @@ -0,0 +1,12 @@ +"""Local candidate installation cases.""" + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class LocalWheelTestCase: + """A synchronized candidate and companion version.""" + + description: str + version: str + expected_version: str diff --git a/tests/integration/scripts/release_performance/test_local_wheels.py b/tests/integration/scripts/release_performance/test_local_wheels.py new file mode 100644 index 0000000000..3c77848d5b --- /dev/null +++ b/tests/integration/scripts/release_performance/test_local_wheels.py @@ -0,0 +1,53 @@ +"""Exercise candidate installation with an unpublished companion wheel.""" + +import sys +from pathlib import Path +from zipfile import ZipFile + +import pytest + +from scripts.release_performance._helpers.versions import install_wheel, installed_version +from tests.integration.scripts.release_performance._test_types import LocalWheelTestCase + + +@pytest.mark.skipif(sys.platform == "win32", reason="Release comparison uses POSIX environments") +@pytest.mark.parametrize( + "test_case", + [ + LocalWheelTestCase( + description="unpublished companion installs offline beside its candidate", + version="0.1.0", + expected_version="0.1.0", + ) + ], + ids=lambda case: case.description, +) +def test_given_unpublished_companion_when_installing_candidate_then_resolves_local_wheel( + test_case: LocalWheelTestCase, tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + monkeypatch.setenv("UV_NO_INDEX", "1") + wheels: Path = tmp_path / "wheels" + wheels.mkdir() + version: str = test_case.version + for name, dependency, entry_points in ( + ("sqlbuild", f"Requires-Dist: sqlbuild-cli=={version}\n", ""), + ("sqlbuild_cli", "", "[console_scripts]\nsqb = sqlbuild_cli_probe:main\n"), + ): + metadata: str = f"Metadata-Version: 2.1\nName: {name}\nVersion: {version}\n{dependency}" + with ZipFile(wheels / f"{name}-{version}-py3-none-any.whl", "w") as wheel: + info: str = f"{name}-{version}.dist-info" + wheel.writestr(f"{info}/METADATA", metadata) + wheel.writestr( + f"{info}/WHEEL", + "Wheel-Version: 1.0\nGenerator: release-probe\n" + "Root-Is-Purelib: true\nTag: py3-none-any\n", + ) + wheel.writestr(f"{info}/RECORD", "") + wheel.writestr(f"{name}_probe.py", f"def main():\n print('sqlbuild {version}')\n") + wheel.writestr(f"{info}/entry_points.txt", entry_points) + sqb: Path = install_wheel( + wheel=wheels / f"sqlbuild-{version}-py3-none-any.whl", + venv_dir=tmp_path / "candidate", + python=sys.executable, + ) + assert installed_version(sqb=sqb) == test_case.expected_version