From 2f48d99ce93b0b9a5d433be4c819c3b03b63ca75 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Sat, 25 Apr 2026 00:24:37 +0200 Subject: [PATCH] [v3-2-test] Breeze: ensure generated Dockerfile.pmc upgrades uv to the required floor (#65774) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `breeze release-management check-release-files providers` generates a Dockerfile.pmc that copies the root `pyproject.toml` into the CI image and then runs `uv pip install`. If the CI image ships an older uv than `[tool.uv] required-version`, that install step fails with: error: Required uv version `>=X.Y.Z` does not match the running version `A.B.C`. Update `uv` by running `uv self update`. This is reproducible today: the current `ghcr.io/apache/airflow/main/ci/ python3.10` ships uv 0.11.6 while the pin is `>=0.11.7`, so every PMC Dockerfile.pmc verification breaks out of the box. Inject a `pip install --upgrade 'uv>=X.Y.Z'` before the `uv pip install` step so the install works regardless of when the CI image was last rebuilt. The floor is a module constant with the existing `# sync-uv-min-version` marker so the `sync-uv-min-version-markers` prek hook keeps it in lockstep with the `[tool.uv] required-version` bump going forward — drop `check_release_files.py` into that hook's file list and add a belt-and-braces test that the two values match. (cherry picked from commit 0df38ffed97e1798db246da704b1a9772cec4f59) Co-authored-by: Jarek Potiuk --- .pre-commit-config.yaml | 1 + .../utils/check_release_files.py | 14 ++++++-- dev/breeze/tests/test_check_release_files.py | 33 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9a427824a2148..042d192a22285 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -246,6 +246,7 @@ repos: files: > (?x) ^pyproject\.toml$| + ^dev/breeze/src/airflow_breeze/utils/check_release_files\.py$| ^dev/breeze/tests/test_environment_check\.py$ require_serial: true - id: check-distribution-gitignore diff --git a/dev/breeze/src/airflow_breeze/utils/check_release_files.py b/dev/breeze/src/airflow_breeze/utils/check_release_files.py index e4fb0f5b0226c..07afdf2d5e3f0 100644 --- a/dev/breeze/src/airflow_breeze/utils/check_release_files.py +++ b/dev/breeze/src/airflow_breeze/utils/check_release_files.py @@ -22,13 +22,23 @@ from airflow_breeze.utils.console import get_console -PROVIDERS_DOCKER = """\ +# Must satisfy the `[tool.uv] required-version` floor in the root pyproject.toml +# that gets COPY'd into the PMC image. Kept in lockstep with that floor by the +# `sync-uv-min-version-markers` prek hook. +_PROVIDERS_DOCKER_UV_MIN_VERSION = "0.9.17" # sync-uv-min-version + +PROVIDERS_DOCKER = f"""\ FROM ghcr.io/apache/airflow/main/ci/python3.10 RUN cd airflow-core; uv sync --no-sources # Install providers with providers pre-releases allowed COPY pyproject.toml . -{} +# The CI image may ship an older uv than the copied pyproject.toml's +# `[tool.uv] required-version` floor; `uv pip install` would then refuse with +# a version-pin error. Upgrade uv first so the install step works regardless +# of when the CI image was last rebuilt. +RUN pip install --upgrade 'uv>={_PROVIDERS_DOCKER_UV_MIN_VERSION}' +{{}} """ AIRFLOW_DOCKER = """\ diff --git a/dev/breeze/tests/test_check_release_files.py b/dev/breeze/tests/test_check_release_files.py index 44e4269e641bc..107788ebed57d 100644 --- a/dev/breeze/tests/test_check_release_files.py +++ b/dev/breeze/tests/test_check_release_files.py @@ -19,6 +19,7 @@ from pathlib import Path from airflow_breeze.utils.check_release_files import ( + PROVIDERS_DOCKER, check_airflow_ctl_release, check_airflow_release, check_providers, @@ -220,3 +221,35 @@ def test_check_python_client_release_fail(): "apache_airflow_client-2.5.0.tar.gz.sha512", "apache_airflow_python_client-2.5.0-source.tar.gz.asc", ] + + +def test_providers_docker_upgrades_uv_before_install(): + """The generated Dockerfile.pmc must upgrade uv to satisfy the copied + pyproject.toml's [tool.uv] required-version floor before `uv pip install` + runs, otherwise the install step fails with a version-pin error when the + CI image ships an older uv. + """ + install_cmd = "RUN uv pip install --pre --system 'apache-airflow-providers-amazon==9.26.0rc1'" + rendered = PROVIDERS_DOCKER.format(install_cmd) + + assert "pip install --upgrade 'uv>=" in rendered + upgrade_idx = rendered.index("pip install --upgrade 'uv>=") + install_idx = rendered.index(install_cmd) + assert upgrade_idx < install_idx, "uv upgrade must precede uv pip install" + + +def test_providers_docker_uv_version_matches_required_version(): + """The hard-coded uv floor in PROVIDERS_DOCKER must equal the current + [tool.uv] required-version from the root pyproject.toml. The + `sync-uv-min-version-markers` prek hook enforces this at commit time; + this test is a belt-and-braces guard for accidental drift. + """ + from airflow_breeze.utils.check_release_files import _PROVIDERS_DOCKER_UV_MIN_VERSION + from airflow_breeze.utils.path_utils import AIRFLOW_ROOT_PATH + + pyproject = (AIRFLOW_ROOT_PATH / "pyproject.toml").read_text() + import re + + match = re.search(r'required-version\s*=\s*"\s*>=\s*([0-9]+(?:\.[0-9]+){0,2})\s*"', pyproject) + assert match, "Could not find [tool.uv] required-version in root pyproject.toml" + assert match.group(1) == _PROVIDERS_DOCKER_UV_MIN_VERSION