This is an automated email from the ASF dual-hosted git repository.
ashb 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 efb49f5e36d Stop prek hooks changing uv.lock and fail CI when it is
stale (#74803)
efb49f5e36d is described below
commit efb49f5e36df9f580b1eaf62a6080cf8b38709be
Author: Ash Berlin-Taylor <[email protected]>
AuthorDate: Thu Oct 15 20:10:53 2026 +0100
Stop prek hooks changing uv.lock and fail CI when it is stale (#74803)
Several hooks ran uv without --frozen, so a commit could re-lock with
whichever uv was on PATH (seen: lock format revision and environment
markers rewritten by an unrelated commit). Set UV_FROZEN=1 through prek's
default_env (needs prek 0.4.8); the manual upgrade hooks set UV_FROZEN=0
because they need real resolution. default_env only applies to hooks in
the root config, so check-provider-yaml-valid, which runs `uv sync` inside
breeze against the bind-mounted host uv.lock, now passes --frozen itself.
update-uv-lock ran `uv lock --frozen`, which exits 0 on a stale lock, and
CI always skipped it, so the 2026-10-14 providers release merged with
version bumps that were never re-locked. Run `uv lock --check` with
UV_FROZEN=0 and stop skipping it in CI.
The breeze shim passes --locked, which older uv rejects together with an
inherited UV_FROZEN. Unset UV_FROZEN in the shim and bump SHIM_VERSION to 3
so existing installs are told to re-run setup_breeze.
test_get_expected_shim_version_reads_real_setup_script asserted the exact
SHIM_VERSION, so it failed on every bump without saying what broke. It now
only asserts that the real setup_breeze still yields an integer version,
which is what ties the parser to the real file.
---
.pre-commit-config.yaml | 20 ++++++---
contributing-docs/07_local_virtualenv.rst | 8 +++-
.../src/airflow_breeze/utils/selective_checks.py | 1 -
dev/breeze/tests/test_selective_checks.py | 50 +++++++++++-----------
dev/breeze/tests/test_shim_version_check.py | 4 +-
.../in_container/run_provider_yaml_files_check.py | 10 ++++-
scripts/tools/setup_breeze | 5 ++-
7 files changed, 58 insertions(+), 40 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 79b45df6646..5bb9518083d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -17,11 +17,15 @@
---
default_stages: [pre-commit, pre-push]
default_install_hook_types: [pre-commit, commit-msg]
-minimum_prek_version: '0.3.4'
+minimum_prek_version: '0.4.8'
default_language_version:
python: python3
node: 22.19.0
golang: 1.25.0
+default_env:
+ # Unless overridden, no hook defined in this file should change the
resolutions in uv.lock; they use
+ # the committed ones. Hooks in nested configs do not inherit this and must
pass --frozen to uv themselves.
+ UV_FROZEN: "1"
exclude: ^.*/.*_vendor/
repos:
- repo: meta
@@ -565,6 +569,7 @@ repos:
name: Upgrade important versions (manual)
entry: ./scripts/ci/prek/upgrade_important_versions.py
stages: ['manual']
+ env: {UV_FROZEN: "0"}
language: python
files: >
(?x)
@@ -577,6 +582,7 @@ repos:
name: Upgrade curated dependency floors (manual)
entry: ./scripts/ci/prek/upgrade_dependency_floors.py
stages: ['manual']
+ env: {UV_FROZEN: "0"}
language: python
files: >
(?x)
@@ -1585,13 +1591,15 @@ repos:
files: ^dev/breeze/src/airflow_breeze/global_constants\.py$
require_serial: true
# This is a fast regular hook that runs when any pyproject.toml
changes.
- # It runs locally with `--frozen` so the lock is only verified against
pyproject.toml,
- # never silently rewritten during a commit. If a pyproject.toml change
makes the lock
- # stale, the hook fails and the contributor must run `uv lock`
explicitly and commit
- # the refreshed uv.lock — which keeps lock updates intentional and
reviewable.
+ # It runs `uv lock --check`, so the lock is verified against
pyproject.toml but never
+ # rewritten during a commit. If a pyproject.toml change makes the lock
stale, the hook
+ # fails and the contributor must run `uv lock` explicitly and commit
the refreshed
+ # uv.lock — which keeps lock updates intentional and reviewable.
UV_FROZEN is disabled
+ # because under it `--check` only validates the lock, it does not
detect staleness.
- id: update-uv-lock
name: Update uv.lock
- entry: uv lock --frozen
+ entry: uv lock --check
+ env: {UV_FROZEN: "0"}
language: system
files: >
(?x)
diff --git a/contributing-docs/07_local_virtualenv.rst
b/contributing-docs/07_local_virtualenv.rst
index 7577e74b71c..fc73068ac4a 100644
--- a/contributing-docs/07_local_virtualenv.rst
+++ b/contributing-docs/07_local_virtualenv.rst
@@ -287,8 +287,12 @@ or when running tests), you can pass the ``--frozen`` flag:
uv sync --frozen
-This will fail if the lock file is out of date with respect to
``pyproject.toml``, rather than
-silently updating it. This is useful when you want to guarantee fully
reproducible environments.
+This never resolves or writes to the lock file, even when it is out of date
with respect to
+``pyproject.toml``. Use ``--locked`` (or ``uv lock --check``) to fail on a
stale lock file instead.
+
+A change to a ``pyproject.toml`` (including a workspace member's version) must
be committed together
+with the refreshed ``uv.lock``: run ``uv lock``. The ``update-uv-lock`` prek
hook, which also runs in CI,
+fails otherwise. All other prek hooks run ``uv`` frozen and never change
``uv.lock``.
Cooldown via ``exclude-newer``
..............................
diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
index 246107a835d..511ebc96e01 100644
--- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
+++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
@@ -1925,7 +1925,6 @@ class SelectiveChecks:
def skip_prek_hooks(self) -> str:
prek_hooks_to_skip = set()
prek_hooks_to_skip.add("identity")
- prek_hooks_to_skip.add("update-uv-lock")
if self._default_branch != "main":
# Skip those tests on all "release" branches
prek_hooks_to_skip.update(
diff --git a/dev/breeze/tests/test_selective_checks.py
b/dev/breeze/tests/test_selective_checks.py
index 5533390a721..a4846a09756 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -121,10 +121,10 @@ ALL_SKIPPED_COMMITS_ON_NO_CI_IMAGE = (
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
-ALL_SKIPPED_COMMITS_BY_DEFAULT_ON_ALL_TESTS_NEEDED = "identity,update-uv-lock"
+ALL_SKIPPED_COMMITS_BY_DEFAULT_ON_ALL_TESTS_NEEDED = "identity"
ALL_SKIPPED_COMMITS_IF_ONLY_UI_OPENAPI_CHANGED = (
"check-java-sdk-serialization-conformance,check-provider-yaml-valid,check-ts-sdk-supervisor-schema,flynt,identity,ktlint,"
@@ -135,7 +135,7 @@ ALL_SKIPPED_COMMITS_IF_ONLY_UI_OPENAPI_CHANGED = (
"mypy-shared-observability,mypy-shared-plugins_manager,mypy-shared-providers_discovery,"
"mypy-shared-secrets_backend,mypy-shared-secrets_masker,mypy-shared-serialization,"
"mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,"
-
"mypy-task-sdk-integration-tests,regenerate-java-sdk-verification-metadata,update-uv-lock"
+ "mypy-task-sdk-integration-tests,regenerate-java-sdk-verification-metadata"
)
ALL_SKIPPED_COMMITS_IF_NO_UI = (
@@ -146,7 +146,7 @@ ALL_SKIPPED_COMMITS_IF_NO_UI = (
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_HELM_TESTS = (
"check-java-sdk-serialization-conformance,check-ts-sdk-supervisor-schema,identity,ktlint,lint-helm-chart,"
@@ -156,7 +156,7 @@ ALL_SKIPPED_COMMITS_IF_NO_HELM_TESTS = (
"mypy-shared-configuration,mypy-shared-dagnode,mypy-shared-listeners,mypy-shared-logging,"
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
-
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,regenerate-java-sdk-verification-metadata,update-uv-lock"
+
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,regenerate-java-sdk-verification-metadata"
)
ALL_SKIPPED_COMMITS_IF_NO_UI_AND_HELM_TESTS = (
@@ -168,7 +168,7 @@ ALL_SKIPPED_COMMITS_IF_NO_UI_AND_HELM_TESTS = (
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
# API source/test change with NO OpenAPI spec change: the full matrix is no
longer
@@ -184,7 +184,7 @@ ALL_SKIPPED_COMMITS_IF_ONLY_API_SOURCE_CHANGED = (
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,"
"mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS_AND_UI = (
@@ -196,7 +196,7 @@ ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS_AND_UI = (
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS = (
@@ -208,7 +208,7 @@ ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS = (
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
@@ -221,7 +221,7 @@ ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS_UI_AND_HELM_TESTS = (
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_CODE_PROVIDERS_AND_HELM_TESTS = (
@@ -232,7 +232,7 @@ ALL_SKIPPED_COMMITS_IF_NO_CODE_PROVIDERS_AND_HELM_TESTS = (
"mypy-shared-configuration,mypy-shared-dagnode,mypy-shared-listeners,mypy-shared-logging,"
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
-
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,regenerate-java-sdk-verification-metadata,update-uv-lock"
+
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,regenerate-java-sdk-verification-metadata"
)
ALL_SKIPPED_COMMITS_IF_NOT_IMPORTANT_FILES_CHANGED = (
@@ -244,7 +244,7 @@ ALL_SKIPPED_COMMITS_IF_NOT_IMPORTANT_FILES_CHANGED = (
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
@@ -252,7 +252,7 @@ All_SKIPPED_COMMITS_IF_NON_MAIN_BRANCH = (
"check-airflow-provider-compatibility,check-airflow-providers-bug-report-template,"
"check-extra-packages-references,check-provider-yaml-valid,"
"compile-fab-assets,generate-openapi-spec-fab,identity,"
- "lint-helm-chart,update-uv-lock,validate-operators-init"
+ "lint-helm-chart,validate-operators-init"
)
@@ -489,7 +489,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str,
str], stderr: str):
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"upgrade-to-newer-dependencies": "false",
"core-test-types-list-as-strings-in-json": json.dumps(
@@ -536,7 +536,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str,
str], stderr: str):
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,"
"mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"upgrade-to-newer-dependencies": "false",
"core-test-types-list-as-strings-in-json": json.dumps(
@@ -790,7 +790,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str,
str], stderr: str):
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"skip-providers-tests": "false",
"upgrade-to-newer-dependencies": "false",
@@ -828,7 +828,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str,
str], stderr: str):
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"skip-providers-tests": "true",
"upgrade-to-newer-dependencies": "false",
@@ -891,7 +891,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str,
str], stderr: str):
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"skip-providers-tests": "true",
"upgrade-to-newer-dependencies": "false",
@@ -927,7 +927,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str,
str], stderr: str):
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"skip-providers-tests": "true",
"upgrade-to-newer-dependencies": "false",
@@ -1276,7 +1276,7 @@ def assert_outputs_are_printed(expected_outputs:
dict[str, str], stderr: str):
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"upgrade-to-newer-dependencies": "false",
"core-test-types-list-as-strings-in-json": json.dumps(
@@ -1483,7 +1483,7 @@ def assert_outputs_are_printed(expected_outputs:
dict[str, str], stderr: str):
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"upgrade-to-newer-dependencies": "false",
"core-test-types-list-as-strings-in-json": None,
@@ -1971,7 +1971,7 @@ def assert_outputs_are_printed(expected_outputs:
dict[str, str], stderr: str):
"mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,"
"mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
},
id=("Shared logging change keeps only mypy-shared-logging
among the mypy-shared-* hooks"),
@@ -2958,7 +2958,7 @@ def test_expected_output_push(
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"upgrade-to-newer-dependencies": "false",
"core-test-types-list-as-strings-in-json": json.dumps(
@@ -2999,7 +2999,7 @@ def test_expected_output_push(
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"run-kubernetes-tests": "true",
"upgrade-to-newer-dependencies": "false",
@@ -3045,7 +3045,7 @@ def test_expected_output_push(
"mypy-shared-module_loading,mypy-shared-observability,mypy-shared-plugins_manager,"
"mypy-shared-providers_discovery,mypy-shared-secrets_backend,mypy-shared-secrets_masker,"
"mypy-shared-serialization,mypy-shared-state,mypy-shared-template_rendering,mypy-shared-timezones,mypy-task-sdk,mypy-task-sdk-integration-tests,"
-
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui,update-uv-lock"
+
"regenerate-java-sdk-verification-metadata,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
),
"run-kubernetes-tests": "false",
"upgrade-to-newer-dependencies": "false",
diff --git a/dev/breeze/tests/test_shim_version_check.py
b/dev/breeze/tests/test_shim_version_check.py
index 953852419e1..3364ddf951d 100644
--- a/dev/breeze/tests/test_shim_version_check.py
+++ b/dev/breeze/tests/test_shim_version_check.py
@@ -60,9 +60,7 @@ def test_parse_shim_version(version_line, expected):
def test_get_expected_shim_version_reads_real_setup_script():
- # The real setup_breeze in the sources is the source of truth — keep this
test in sync
- # with the SHIM_VERSION it declares.
- assert get_expected_shim_version(ACTUAL_AIRFLOW_SOURCES) == 2
+ assert isinstance(get_expected_shim_version(ACTUAL_AIRFLOW_SOURCES), int)
def test_get_expected_shim_version_from_fake_sources(tmp_path):
diff --git a/scripts/in_container/run_provider_yaml_files_check.py
b/scripts/in_container/run_provider_yaml_files_check.py
index 2363ffbaeae..ab88b9ebd83 100755
--- a/scripts/in_container/run_provider_yaml_files_check.py
+++ b/scripts/in_container/run_provider_yaml_files_check.py
@@ -125,7 +125,15 @@ def sync_dependencies_without_dev() -> None:
"""
console.print("[magenta]Running uv sync --no-dev to strip development
dependencies...[/]")
result = subprocess.run(
- ["uv", "sync", "--no-dev", "--all-packages", "--no-python-downloads",
"--no-managed-python"],
+ [
+ "uv",
+ "sync",
+ "--frozen",
+ "--no-dev",
+ "--all-packages",
+ "--no-python-downloads",
+ "--no-managed-python",
+ ],
capture_output=True,
text=True,
cwd=AIRFLOW_ROOT_PATH,
diff --git a/scripts/tools/setup_breeze b/scripts/tools/setup_breeze
index 85eef32cd04..54e8e759b1f 100755
--- a/scripts/tools/setup_breeze
+++ b/scripts/tools/setup_breeze
@@ -41,7 +41,7 @@ SHIM_MARKER="# Apache Airflow breeze shim — managed by
scripts/tools/setup_bre
# into the installed shim; if the installed shim is older it warns the user to
# re-run this script. See warn_if_shim_outdated() in
# dev/breeze/src/airflow_breeze/utils/path_utils.py.
-SHIM_VERSION="2"
+SHIM_VERSION="3"
# The shim itself. Runs breeze via 'uv run' against the dev/breeze folder of
the
# *current* git worktree, so multiple checkouts / agentic worktrees never
@@ -84,7 +84,8 @@ else
echo "breeze: not inside an Airflow worktree, AIRFLOW_REPO_ROOT is unset
or not an Airflow worktree, and the install-time fallback
'\${fallback_root}/dev/breeze' is missing — re-run scripts/tools/setup_breeze"
>&2
exit 1
fi
-exec env AIRFLOW_ROOT_PATH="\${breeze_root}" SKIP_BREEZE_SELF_UPGRADE_CHECK=1
\\
+# '--locked' already guarantees no rewrite; an inherited UV_FROZEN conflicts
with it on older uv.
+exec env -u UV_FROZEN AIRFLOW_ROOT_PATH="\${breeze_root}"
SKIP_BREEZE_SELF_UPGRADE_CHECK=1 \\
uv run --project "\${breeze_root}/dev/breeze" --locked --quiet breeze "\$@"
BREEZE_SHIM