This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 0df38ffed97 Breeze: ensure generated Dockerfile.pmc upgrades uv to the
required floor (#65774)
0df38ffed97 is described below
commit 0df38ffed97e1798db246da704b1a9772cec4f59
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sat Apr 25 00:24:37 2026 +0200
Breeze: ensure generated Dockerfile.pmc upgrades uv to the required floor
(#65774)
`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.
---
.pre-commit-config.yaml | 1 +
.../airflow_breeze/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 67a08139591..f4e1fd64753 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -245,6 +245,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 e4fb0f5b022..50e60cb6dea 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 pathlib import Path
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.11.7" # 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 44e4269e641..107788ebed5 100644
--- a/dev/breeze/tests/test_check_release_files.py
+++ b/dev/breeze/tests/test_check_release_files.py
@@ -19,6 +19,7 @@ from __future__ import annotations
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