You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ep...@apache.org on 2025/12/09 17:19:39 UTC

(airflow) branch v3-1-test updated (1718b9ec07d -> bf9a304bf98)

This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a change to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


    omit 1718b9ec07d [v3-1-test] Fix links for DurationChart (#59095) (#59237)
    omit 4e14fe272e1 [v3 branch] Fix misleading error message when GitHook creation fails (#59236)
    omit d260134dcf2 [v3-1-test] Create additional users in breeze for testing (#58126) (#59233)
    omit c308a5ba168 [v3-1-test] Fix side-effect of running version suffix replacements (#58937) (#59223)
    omit 6acd64fcb12 [v3-1-test] Fix outdated dependency documentation (#58970) (#59219)
    omit 3c4be95a155 missing ca translations in v3-1-test (#59216)
    omit 04e60fa30db Convert the exclusion on urllib3 to != for 2.6.0 (#59203) (#59212)
    omit f5ce4601cf3 [v3-1-test] Show asset extra in asset list (#59195) (#59201)
    omit 62e55e3374a [v3-1-test] Prevent dag processor crash on encountering excel files in the DAG directory (#59069) (#59170)
    omit 7135fb278bb Translation gaps in v3-1-test TR (#59169)
    omit fbec6fbf292 [v3-1-test] Fix DagRun.queued_at not updating when clearing (#59066) (#59177)
    omit dcf0f956c5d [v3-1-test] Drop Airflow 2 Support in Edge Provider (#59143) (#59179)
    omit 1e99c455e4a [v3-1-test] Align the term Dag in all translations (#59155)
    omit 28e838f03ed [v3-1-test] fix flaky TestEmrCreateJobFlowOperator (#59128) (#59137)
    omit 28bc92201e3 [v3-1-test] fix: Rendered Templates not showing dictionary items in AF3 (#58071) (#59176)
    omit 47d98167d45 [v3-1-test] Fix mypy error on version check in dev (#59171) (#59172)
    omit c3435fed2e7 [v3-1-test] Fix airflow/task-sdk relase PMC checks (#59164) (#59165)
    omit ec74f41848b [v3-1-test] Fix breeze check-release-files Command for Core+Task SDK checks (#59159) (#59163)
    omit fb313db2c0c [v3-1-test] Breeze exit on incompatible arguments (#59148) (#59157)
    omit 7b932f7f6c3 CI: Upgrade important CI environment (#59145)
    omit 76b1c7e3831 [v3-1-test] Bump ruff to 0.14.8, uv to 0.9.15 (#59058) (#59079)
    omit 482301979ad [v3-1-test] Uncomment Python version pin in `check-lazy-logging` (#59047) (#59067)
    omit 401b05ff937 Backport (#59052)
    omit 1e321c54cca [v3-1-test] Move HTTPAuthorizationCredentials import from TYPE_CHECKING block to (#59048) (#59056)
    omit a3245fcf7db [v3-1-test] Change task log source display to hidden by default (#58749) (#59045)
    omit d3eac781d35 [v3-1-test] Fix go back button from fab iframe (#58997) (#59007)
    omit 59d76a78fbf [v3-1-test] provide a clear naming and description for the attribute caching get_template_context (#59023) (#59036)
    omit 0731faaead1 [v3-1-test] Add prek check before compiling assets in start-airflow (#58979) (#58996)
    omit 2b1d6cdf509 [v3-1-test] Update the documentation for the LocalExecutor (#58990) (#59022)
    omit 099ae4eb715 [v3-1-test] Fix task instance and runs tooltips in Grid view (#58359) (#59013)
    omit b978f08adc7 [v3-1-test] Also limit urllib3 to < 2.6.0 in k8s tests - for use in v3-1-tests (#59152) (#59158)
    omit 7ed314e396a [v3-1-test] Limit urllib3 to <2.6.0 during latest boto tests (#59130) (#59132)
     add 60f6b2ca985 Update RELEASE_NOTES.rst for rc2
     new 6c3ecf83c85 [v3-1-test] Limit urllib3 to <2.6.0 during latest boto tests (#59130) (#59132)
     new 1fb72831977 [v3-1-test] Also limit urllib3 to < 2.6.0 in k8s tests - for use in v3-1-tests (#59152) (#59158)
     new 61f7f6818f2 [v3-1-test] Fix task instance and runs tooltips in Grid view (#58359) (#59013)
     new 833911fe19d [v3-1-test] Update the documentation for the LocalExecutor (#58990) (#59022)
     new 8a380071752 [v3-1-test] Add prek check before compiling assets in start-airflow (#58979) (#58996)
     new 8c2e29c07ef [v3-1-test] provide a clear naming and description for the attribute caching get_template_context (#59023) (#59036)
     new cdd824a4dbd [v3-1-test] Fix go back button from fab iframe (#58997) (#59007)
     new d138f75206c [v3-1-test] Change task log source display to hidden by default (#58749) (#59045)
     new 979a21184ea [v3-1-test] Move HTTPAuthorizationCredentials import from TYPE_CHECKING block to (#59048) (#59056)
     new d79f6b441c0 Backport (#59052)
     new db10eda9f93 [v3-1-test] Uncomment Python version pin in `check-lazy-logging` (#59047) (#59067)
     new 1977f09d201 [v3-1-test] Bump ruff to 0.14.8, uv to 0.9.15 (#59058) (#59079)
     new d8f3e42ff4e CI: Upgrade important CI environment (#59145)
     new 94cfab40ca6 [v3-1-test] Breeze exit on incompatible arguments (#59148) (#59157)
     new 68cca802a89 [v3-1-test] Fix breeze check-release-files Command for Core+Task SDK checks (#59159) (#59163)
     new 197c87b7f9c [v3-1-test] Fix airflow/task-sdk relase PMC checks (#59164) (#59165)
     new f770078e807 [v3-1-test] Fix mypy error on version check in dev (#59171) (#59172)
     new 46a223f32f1 [v3-1-test] fix: Rendered Templates not showing dictionary items in AF3 (#58071) (#59176)
     new 3f15542f036 [v3-1-test] fix flaky TestEmrCreateJobFlowOperator (#59128) (#59137)
     new 36851b7cb6f [v3-1-test] Align the term Dag in all translations (#59155)
     new 4b93cf1b592 [v3-1-test] Drop Airflow 2 Support in Edge Provider (#59143) (#59179)
     new 0466536f64a [v3-1-test] Fix DagRun.queued_at not updating when clearing (#59066) (#59177)
     new 8a34097b298 Translation gaps in v3-1-test TR (#59169)
     new 0068e0bfe14 [v3-1-test] Prevent dag processor crash on encountering excel files in the DAG directory (#59069) (#59170)
     new 5b13a2cbc6f [v3-1-test] Show asset extra in asset list (#59195) (#59201)
     new a5f0be48571 Convert the exclusion on urllib3 to != for 2.6.0 (#59203) (#59212)
     new d5818b9893b missing ca translations in v3-1-test (#59216)
     new c4b692880de [v3-1-test] Fix outdated dependency documentation (#58970) (#59219)
     new d9d4baa0dba [v3-1-test] Fix side-effect of running version suffix replacements (#58937) (#59223)
     new 5fe6e4e45b9 [v3-1-test] Create additional users in breeze for testing (#58126) (#59233)
     new ac53f64b5df [v3 branch] Fix misleading error message when GitHook creation fails (#59236)
     new bf9a304bf98 [v3-1-test] Fix links for DurationChart (#59095) (#59237)

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (1718b9ec07d)
            \
             N -- N -- N   refs/heads/v3-1-test (bf9a304bf98)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 32 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 RELEASE_NOTES.rst       | 5 +++--
 reproducible_build.yaml | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)


(airflow) 29/32: [v3-1-test] Fix side-effect of running version suffix replacements (#58937) (#59223)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit d9d4baa0dba8dd917c39762a232926194cc3852c
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Tue Dec 9 01:36:15 2025 +0100

    [v3-1-test] Fix side-effect of running version suffix replacements (#58937) (#59223)
    
    When Breeze tests are run with xdist, the in-place replacement
    of version suffix might lead to side effects if several tests are
    trying to read and write the files at the same time.
    
    This PR uses temporary per-test created versions of those files
    during tests.
    (cherry picked from commit 0bf6f82d3d615550397db0312ea859abf244268f)
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
---
 dev/breeze/tests/test_packages.py | 46 +++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/dev/breeze/tests/test_packages.py b/dev/breeze/tests/test_packages.py
index df35db28945..128cf5cfd0e 100644
--- a/dev/breeze/tests/test_packages.py
+++ b/dev/breeze/tests/test_packages.py
@@ -370,7 +370,9 @@ def _check_dependencies_modified_properly(
         ("standard", ".post1", ".post1"),
     ],
 )
-def test_apply_version_suffix_to_provider_pyproject_toml(provider_id, version_suffix, floored_version_suffix):
+def test_apply_version_suffix_to_provider_pyproject_toml(
+    provider_id, version_suffix, floored_version_suffix, tmp_path
+):
     """
     Test the apply_version_suffix function with different version suffixes for pyproject.toml of provider.
     """
@@ -378,10 +380,30 @@ def test_apply_version_suffix_to_provider_pyproject_toml(provider_id, version_su
         import tomllib
     except ImportError:
         import tomli as tomllib
-    provider_details = get_provider_details(provider_id)
-    original_content = (provider_details.root_provider_path / "pyproject.toml").read_text()
-    with apply_version_suffix_to_provider_pyproject_toml(provider_id, version_suffix) as pyproject_toml_path:
-        modified_content = pyproject_toml_path.read_text()
+    from unittest.mock import patch
+
+    # Get the original provider details
+    original_provider_details = get_provider_details(provider_id)
+    original_pyproject_path = original_provider_details.root_provider_path / "pyproject.toml"
+    original_content = original_pyproject_path.read_text()
+
+    # Create a temporary copy of the provider directory structure
+    temp_provider_path = tmp_path / "providers" / provider_id.replace(".", "/")
+    temp_provider_path.mkdir(parents=True, exist_ok=True)
+    temp_pyproject_path = temp_provider_path / "pyproject.toml"
+    temp_pyproject_path.write_text(original_content)
+
+    # Mock get_provider_details to return a modified version with temporary path
+    def mock_get_provider_details(provider_id: str):
+        # Use NamedTuple's _replace() method to create a copy with modified root_provider_path
+        return original_provider_details._replace(root_provider_path=temp_provider_path)
+
+    with patch("airflow_breeze.utils.packages.get_provider_details", side_effect=mock_get_provider_details):
+        with apply_version_suffix_to_provider_pyproject_toml(
+            provider_id, version_suffix
+        ) as pyproject_toml_path:
+            modified_content = pyproject_toml_path.read_text()
+
     original_toml = tomllib.loads(original_content)
     modified_toml = tomllib.loads(modified_content)
     assert original_toml["project"]["version"] != modified_toml["project"]["version"]
@@ -439,6 +461,7 @@ def test_apply_version_suffix_to_non_provider_pyproject_tomls(
     init_file_path: Path,
     version_suffix: str,
     floored_version_suffix: str,
+    tmp_path: Path,
 ):
     """
     Test the apply_version_suffix function with different version suffixes for pyproject.toml of non-provider.
@@ -450,15 +473,24 @@ def test_apply_version_suffix_to_non_provider_pyproject_tomls(
     distribution_paths = [AIRFLOW_ROOT_PATH / distribution for distribution in distributions]
     original_pyproject_toml_paths = [path / "pyproject.toml" for path in distribution_paths]
     original_contents = [path.read_text() for path in original_pyproject_toml_paths]
+    modified_pyproject_toml_paths = [
+        tmp_path / path.parent.name / path.name for path in original_pyproject_toml_paths
+    ]
+    for i, modified_pyproject_toml_path in enumerate(modified_pyproject_toml_paths):
+        modified_pyproject_toml_path.parent.mkdir(parents=True, exist_ok=True)
+        modified_pyproject_toml_path.write_text(original_pyproject_toml_paths[i].read_text())
     original_init_py = init_file_path.read_text()
+    modified_init_file_path = tmp_path / init_file_path.name
+    modified_init_file_path.write_text(original_init_py)
+
     with apply_version_suffix_to_non_provider_pyproject_tomls(
-        version_suffix, init_file_path, original_pyproject_toml_paths
+        version_suffix, modified_init_file_path, modified_pyproject_toml_paths
     ) as modified_pyproject_toml_paths:
         modified_contents = [path.read_text() for path in modified_pyproject_toml_paths]
 
         original_tomls = [tomllib.loads(content) for content in original_contents]
         modified_tomls = [tomllib.loads(content) for content in modified_contents]
-        modified_init_py = init_file_path.read_text()
+        modified_init_py = modified_init_file_path.read_text()
 
     assert original_init_py != modified_init_py
     assert version_suffix in modified_init_py


(airflow) 08/32: [v3-1-test] Change task log source display to hidden by default (#58749) (#59045)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit d138f75206ca2e33ad776dedd149bf52990d2435
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Thu Dec 4 16:18:38 2025 +0100

    [v3-1-test] Change task log source display to hidden by default (#58749) (#59045)
    
    * Change task log source display to hidden by default
    
      Update the default behavior for task log source display from shown
      to hidden, providing a cleaner initial view of logs. Users can still
      toggle source visibility using the settings menu
    
    * Fix tests
    (cherry picked from commit d024a46ce7d966f332e46b7f07208487b4cbdc3d)
    
    Co-authored-by: Dheeraj Turaga <dh...@gmail.com>
---
 .../ui/src/pages/TaskInstance/Logs/Logs.test.tsx   | 22 ++++++++++++----------
 .../ui/src/pages/TaskInstance/Logs/Logs.tsx        |  2 +-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx
index 54e82f8d604..6393bc94d71 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.test.tsx
@@ -57,24 +57,26 @@ describe("Task log source", () => {
     await waitForLogs();
 
     let logLine = screen.getByTestId("virtualized-item-2");
-    const source = logLine.querySelector('[data-key="logger"]');
-    const loc = logLine.querySelector('[data-key="loc"]');
-
-    expect(source).toBeVisible();
-    expect(source).toHaveProperty("innerText", "source=airflow.models.dagbag.DagBag");
 
-    expect(loc).toBeVisible();
-    expect(loc).toHaveProperty("innerText", "loc=dagbag.py:593");
+    // Source should be hidden by default
+    expect(logLine.querySelector('[data-key="logger"]')).toBeNull();
+    expect(logLine.querySelector('[data-key="loc"]')).toBeNull();
 
+    // Toggle source on
     fireEvent.keyDown(document.activeElement ?? document.body, { code: "KeyS", key: "S" });
     fireEvent.keyPress(document.activeElement ?? document.body, { code: "KeyS", key: "S" });
     fireEvent.keyUp(document.activeElement ?? document.body, { code: "KeyS", key: "S" });
 
     logLine = screen.getByTestId("virtualized-item-2");
+    const source = logLine.querySelector('[data-key="logger"]');
+    const loc = logLine.querySelector('[data-key="loc"]');
 
-    // These should now find nothing
-    expect(logLine.querySelector('[data-key="logger"]')).toBeNull();
-    expect(logLine.querySelector('[data-key="loc"]')).toBeNull();
+    // Source should now be visible
+    expect(source).toBeVisible();
+    expect(source).toHaveProperty("innerText", "source=airflow.models.dagbag.DagBag");
+
+    expect(loc).toBeVisible();
+    expect(loc).toHaveProperty("innerText", "loc=dagbag.py:593");
   });
 });
 describe("Task log grouping", () => {
diff --git a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
index 8344dbefb89..f9686f106b4 100644
--- a/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/TaskInstance/Logs/Logs.tsx
@@ -81,7 +81,7 @@ export const Logs = () => {
     "log_show_timestamp",
     defaultShowTimestamp,
   );
-  const [showSource, setShowSource] = useLocalStorage<boolean>("log_show_source", true);
+  const [showSource, setShowSource] = useLocalStorage<boolean>("log_show_source", false);
   const [fullscreen, setFullscreen] = useState(false);
   const [expanded, setExpanded] = useState(false);
 


(airflow) 22/32: [v3-1-test] Fix DagRun.queued_at not updating when clearing (#59066) (#59177)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 0466536f64aa615870eb1d848c4299f3cfa6739c
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Mon Dec 8 00:02:51 2025 +0100

    [v3-1-test] Fix DagRun.queued_at not updating when clearing (#59066) (#59177)
    
    Clearing a dag run sets the state to QUEUED so the scheduler will pick it up, but it did not reset the queued_at timestamp.
    (cherry picked from commit 2b38b194633e896dee8993a94c6dc7c4b11d3804)
    
    Co-authored-by: D. Ferruzzi <fe...@amazon.com>
---
 airflow-core/src/airflow/models/taskinstance.py   | 1 +
 airflow-core/tests/unit/models/test_cleartasks.py | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/airflow-core/src/airflow/models/taskinstance.py b/airflow-core/src/airflow/models/taskinstance.py
index 216bc9b1bca..29f2d98eefa 100644
--- a/airflow-core/src/airflow/models/taskinstance.py
+++ b/airflow-core/src/airflow/models/taskinstance.py
@@ -294,6 +294,7 @@ def clear_task_instances(
                     dr.last_scheduling_decision = None
                     dr.start_date = None
                     dr.clear_number += 1
+                    dr.queued_at = timezone.utcnow()
     session.flush()
 
 
diff --git a/airflow-core/tests/unit/models/test_cleartasks.py b/airflow-core/tests/unit/models/test_cleartasks.py
index 9a1f37c89ca..421e962515f 100644
--- a/airflow-core/tests/unit/models/test_cleartasks.py
+++ b/airflow-core/tests/unit/models/test_cleartasks.py
@@ -276,6 +276,7 @@ class TestClearTasks:
         ti1.state = TaskInstanceState.SUCCESS
         session = dag_maker.session
         session.flush()
+        original_queued_at = dr.queued_at
 
         # we use order_by(task_id) here because for the test DAG structure of ours
         # this is equivalent to topological sort. It would not work in general case
@@ -291,6 +292,10 @@ class TestClearTasks:
         assert dr.start_date is None
         assert dr.last_scheduling_decision is None
 
+        # The initial finished run has queued_at=None, clearing should populate it.
+        assert original_queued_at is None
+        assert dr.queued_at is not None
+
     @pytest.mark.parametrize("delete_tasks", [True, False])
     def test_clear_task_instances_maybe_task_removed(self, delete_tasks, dag_maker, session):
         """This verifies the behavior of clear_task_instances re task removal.


(airflow) 03/32: [v3-1-test] Fix task instance and runs tooltips in Grid view (#58359) (#59013)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 61f7f6818f269f71af719161364ceb41a3797cbd
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Wed Dec 3 13:58:07 2025 -0500

    [v3-1-test] Fix task instance and runs tooltips in Grid view (#58359) (#59013)
    
    * refactor: replace hovertooltip with basictooltip
    
    * feat: implement basic tooltip for grid TI
    
    * feat: implement basic tooltip for grid run
    
    * fix: use get duration util
    
    * refactor: simplify BasicTooltip and add auto-flip for viewport overflow
    
    * fix(i18n): add translation for tooltip states
    
    * refactor: improve BasicTooltip positioning and remove duration
    
    * fix: use Chakra semantic tokens
    
    * refactor: use dynamic height for BasicTooltip positioning
    (cherry picked from commit 4970ea2978ea675d5057475bc9200d0a5b598671)
    
    Co-authored-by: LI,JHE-CHEN <10...@users.noreply.github.com>
---
 .../src/airflow/ui/src/components/BasicTooltip.tsx | 127 +++++++++++++++++++++
 .../src/airflow/ui/src/components/DagRunInfo.tsx   |   2 +-
 .../src/airflow/ui/src/components/HoverTooltip.tsx |  63 ----------
 .../ui/src/components/TaskInstanceTooltip.tsx      |   5 +-
 .../ui/src/layouts/Details/Grid/GridButton.tsx     |  66 +++++++----
 .../airflow/ui/src/layouts/Details/Grid/GridTI.tsx |  65 ++++++-----
 .../ui/src/pages/Dag/Calendar/CalendarCell.tsx     |  15 +--
 .../ui/src/pages/Dag/Calendar/CalendarTooltip.tsx  | 104 +++++------------
 8 files changed, 241 insertions(+), 206 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/components/BasicTooltip.tsx b/airflow-core/src/airflow/ui/src/components/BasicTooltip.tsx
new file mode 100644
index 00000000000..96400e5d5f0
--- /dev/null
+++ b/airflow-core/src/airflow/ui/src/components/BasicTooltip.tsx
@@ -0,0 +1,127 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Box, Portal } from "@chakra-ui/react";
+import type { ReactElement, ReactNode } from "react";
+import { cloneElement, useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
+
+type Props = {
+  readonly children: ReactElement;
+  readonly content: ReactNode;
+};
+
+const offset = 8;
+
+export const BasicTooltip = ({ children, content }: Props): ReactElement => {
+  const triggerRef = useRef<HTMLElement>(null);
+  const tooltipRef = useRef<HTMLDivElement>(null);
+  const [isOpen, setIsOpen] = useState(false);
+  const [showOnTop, setShowOnTop] = useState(false);
+  const timeoutRef = useRef<NodeJS.Timeout>();
+
+  const handleMouseEnter = useCallback(() => {
+    if (timeoutRef.current) {
+      clearTimeout(timeoutRef.current);
+    }
+    timeoutRef.current = setTimeout(() => {
+      setIsOpen(true);
+    }, 500);
+  }, []);
+
+  const handleMouseLeave = useCallback(() => {
+    if (timeoutRef.current) {
+      clearTimeout(timeoutRef.current);
+      timeoutRef.current = undefined;
+    }
+    setIsOpen(false);
+  }, []);
+
+  // Calculate position based on actual tooltip height before paint
+  useLayoutEffect(() => {
+    if (isOpen && triggerRef.current && tooltipRef.current) {
+      const triggerRect = triggerRef.current.getBoundingClientRect();
+      const tooltipHeight = tooltipRef.current.clientHeight;
+      const wouldOverflow = triggerRect.bottom + offset + tooltipHeight > globalThis.innerHeight;
+
+      setShowOnTop(wouldOverflow);
+    }
+  }, [isOpen]);
+
+  // Cleanup on unmount
+  useEffect(
+    () => () => {
+      if (timeoutRef.current) {
+        clearTimeout(timeoutRef.current);
+      }
+    },
+    [],
+  );
+
+  // Clone children and attach event handlers + ref
+  const trigger = cloneElement(children, {
+    onMouseEnter: handleMouseEnter,
+    onMouseLeave: handleMouseLeave,
+    ref: triggerRef,
+  });
+
+  if (!isOpen || !triggerRef.current) {
+    return trigger;
+  }
+
+  const rect = triggerRef.current.getBoundingClientRect();
+  const { scrollX, scrollY } = globalThis;
+
+  return (
+    <>
+      {trigger}
+      <Portal>
+        <Box
+          bg="bg.inverted"
+          borderRadius="md"
+          boxShadow="md"
+          color="fg.inverted"
+          fontSize="sm"
+          left={`${rect.left + scrollX + rect.width / 2}px`}
+          paddingX="3"
+          paddingY="2"
+          pointerEvents="none"
+          position="absolute"
+          ref={tooltipRef}
+          top={showOnTop ? `${rect.top + scrollY - offset}px` : `${rect.bottom + scrollY + offset}px`}
+          transform={showOnTop ? "translate(-50%, -100%)" : "translateX(-50%)"}
+          whiteSpace="nowrap"
+          zIndex="popover"
+        >
+          <Box
+            borderLeft="4px solid transparent"
+            borderRight="4px solid transparent"
+            height={0}
+            left="50%"
+            position="absolute"
+            transform="translateX(-50%)"
+            width={0}
+            {...(showOnTop
+              ? { borderTop: "4px solid var(--chakra-colors-bg-inverted)", bottom: "-4px" }
+              : { borderBottom: "4px solid var(--chakra-colors-bg-inverted)", top: "-4px" })}
+          />
+          {content}
+        </Box>
+      </Portal>
+    </>
+  );
+};
diff --git a/airflow-core/src/airflow/ui/src/components/DagRunInfo.tsx b/airflow-core/src/airflow/ui/src/components/DagRunInfo.tsx
index 0fa1cab7658..fe6370fb8dd 100644
--- a/airflow-core/src/airflow/ui/src/components/DagRunInfo.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DagRunInfo.tsx
@@ -42,7 +42,7 @@ const DagRunInfo = ({ endDate, logicalDate, runAfter, startDate, state }: Props)
         <VStack align="left" gap={0}>
           {state === undefined ? undefined : (
             <Text>
-              {translate("state")}: {state}
+              {translate("state")}: {translate(`common:states.${state}`)}
             </Text>
           )}
           {Boolean(logicalDate) ? (
diff --git a/airflow-core/src/airflow/ui/src/components/HoverTooltip.tsx b/airflow-core/src/airflow/ui/src/components/HoverTooltip.tsx
deleted file mode 100644
index 46466858cae..00000000000
--- a/airflow-core/src/airflow/ui/src/components/HoverTooltip.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-/*!
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { Portal } from "@chakra-ui/react";
-import { useState, useRef, useCallback, cloneElement } from "react";
-import type { ReactElement, ReactNode, RefObject } from "react";
-
-type Props = {
-  readonly children: ReactElement;
-  readonly delayMs?: number;
-  readonly tooltip: (triggerRef: RefObject<HTMLElement>) => ReactNode;
-};
-
-export const HoverTooltip = ({ children, delayMs = 200, tooltip }: Props) => {
-  const triggerRef = useRef<HTMLElement>(null);
-  const [isOpen, setIsOpen] = useState(false);
-  const timeoutRef = useRef<NodeJS.Timeout>();
-
-  const handleMouseEnter = useCallback(() => {
-    if (timeoutRef.current) {
-      clearTimeout(timeoutRef.current);
-    }
-    timeoutRef.current = setTimeout(() => {
-      setIsOpen(true);
-    }, delayMs);
-  }, [delayMs]);
-
-  const handleMouseLeave = useCallback(() => {
-    if (timeoutRef.current) {
-      clearTimeout(timeoutRef.current);
-      timeoutRef.current = undefined;
-    }
-    setIsOpen(false);
-  }, []);
-
-  const trigger = cloneElement(children, {
-    onMouseEnter: handleMouseEnter,
-    onMouseLeave: handleMouseLeave,
-    ref: triggerRef,
-  });
-
-  return (
-    <>
-      {trigger}
-      {Boolean(isOpen) && <Portal>{tooltip(triggerRef)}</Portal>}
-    </>
-  );
-};
diff --git a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
index 025463dc955..a3494ee4a0b 100644
--- a/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
+++ b/airflow-core/src/airflow/ui/src/components/TaskInstanceTooltip.tsx
@@ -43,7 +43,10 @@ const TaskInstanceTooltip = ({ children, positioning, taskInstance, ...rest }: P
       content={
         <Box>
           <Text>
-            {translate("state")}: {taskInstance.state}
+            {translate("state")}:{" "}
+            {taskInstance.state
+              ? translate(`common:states.${taskInstance.state}`)
+              : translate("common:states.no_status")}
           </Text>
           {"dag_run_id" in taskInstance ? (
             <Text>
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx
index f3dd0b3dc07..c452cf43a79 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridButton.tsx
@@ -17,9 +17,11 @@
  * under the License.
  */
 import { Flex, type FlexProps } from "@chakra-ui/react";
+import { useTranslation } from "react-i18next";
 import { Link } from "react-router-dom";
 
 import type { DagRunState, TaskInstanceState } from "openapi/requests/types.gen";
+import { BasicTooltip } from "src/components/BasicTooltip";
 
 type Props = {
   readonly dagId: string;
@@ -41,39 +43,53 @@ export const GridButton = ({
   state,
   taskId,
   ...rest
-}: Props) =>
-  isGroup ? (
-    <Flex
-      background={`${state}.solid`}
-      borderRadius={2}
-      height="10px"
-      minW="14px"
-      pb="2px"
-      px="2px"
-      title={`${label}\n${state}`}
-      {...rest}
-    >
-      {children}
-    </Flex>
-  ) : (
-    <Link
-      replace
-      to={{
-        pathname: `/dags/${dagId}/runs/${runId}/${taskId === undefined ? "" : `tasks/${taskId}`}`,
-        search: searchParams.toString(),
-      }}
-    >
+}: Props) => {
+  const { t: translate } = useTranslation();
+
+  const tooltipContent = (
+    <>
+      {label}
+      <br />
+      {translate("state")}:{" "}
+      {state ? translate(`common:states.${state}`) : translate("common:states.no_status")}
+    </>
+  );
+
+  return isGroup ? (
+    <BasicTooltip content={tooltipContent}>
       <Flex
         background={`${state}.solid`}
         borderRadius={2}
         height="10px"
+        minW="14px"
         pb="2px"
         px="2px"
-        title={`${label}\n${state}`}
-        width="14px"
         {...rest}
       >
         {children}
       </Flex>
-    </Link>
+    </BasicTooltip>
+  ) : (
+    <BasicTooltip content={tooltipContent}>
+      <Link
+        replace
+        to={{
+          pathname: `/dags/${dagId}/runs/${runId}/${taskId === undefined ? "" : `tasks/${taskId}`}`,
+          search: searchParams.toString(),
+        }}
+      >
+        <Flex
+          background={`${state}.solid`}
+          borderRadius={2}
+          height="10px"
+          pb="2px"
+          px="2px"
+          width="14px"
+          {...rest}
+        >
+          {children}
+        </Flex>
+      </Link>
+    </BasicTooltip>
   );
+};
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
index ddf294353cb..d4d775da977 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
@@ -23,9 +23,9 @@ import { useTranslation } from "react-i18next";
 import { Link, useLocation, useParams, useSearchParams } from "react-router-dom";
 
 import type { LightGridTaskInstanceSummary } from "openapi/requests/types.gen";
+import { BasicTooltip } from "src/components/BasicTooltip";
 import { StateIcon } from "src/components/StateIcon";
 import Time from "src/components/Time";
-import { Tooltip } from "src/components/ui";
 import { type HoverContextType, useHover } from "src/context/hover";
 import { buildTaskInstanceUrl } from "src/utils/links";
 
@@ -106,35 +106,38 @@ const Instance = ({ dagId, instance, isGroup, isMapped, onClick, runId, taskId }
       py={0}
       transition="background-color 0.2s"
     >
-      <Link
-        id={`grid-${runId}-${taskId}`}
-        onClick={onClick}
-        replace
-        to={{
-          pathname: getTaskUrl(),
-          search: redirectionSearch,
-        }}
+      <BasicTooltip
+        content={
+          <>
+            {translate("taskId")}: {taskId}
+            <br />
+            {translate("state")}:{" "}
+            {instance.state
+              ? translate(`common:states.${instance.state}`)
+              : translate("common:states.no_status")}
+            {instance.min_start_date !== null && (
+              <>
+                <br />
+                {translate("startDate")}: <Time datetime={instance.min_start_date} />
+              </>
+            )}
+            {instance.max_end_date !== null && (
+              <>
+                <br />
+                {translate("endDate")}: <Time datetime={instance.max_end_date} />
+              </>
+            )}
+          </>
+        }
       >
-        <Tooltip
-          content={
-            <>
-              {translate("taskId")}: {taskId}
-              <br />
-              {translate("state")}: {instance.state}
-              {instance.min_start_date !== null && (
-                <>
-                  <br />
-                  {translate("startDate")}: <Time datetime={instance.min_start_date} />
-                </>
-              )}
-              {instance.max_end_date !== null && (
-                <>
-                  <br />
-                  {translate("endDate")}: <Time datetime={instance.max_end_date} />
-                </>
-              )}
-            </>
-          }
+        <Link
+          id={`grid-${runId}-${taskId}`}
+          onClick={onClick}
+          replace
+          to={{
+            pathname: getTaskUrl(),
+            search: redirectionSearch,
+          }}
         >
           <Badge
             alignItems="center"
@@ -150,8 +153,8 @@ const Instance = ({ dagId, instance, isGroup, isMapped, onClick, runId, taskId }
           >
             <StateIcon size={10} state={instance.state} />
           </Badge>
-        </Tooltip>
-      </Link>
+        </Link>
+      </BasicTooltip>
     </Flex>
   );
 };
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
index 4428a2b4e42..1a3c0fe30f1 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarCell.tsx
@@ -17,9 +17,8 @@
  * under the License.
  */
 import { Box } from "@chakra-ui/react";
-import type React from "react";
 
-import { HoverTooltip } from "src/components/HoverTooltip";
+import { BasicTooltip } from "src/components/BasicTooltip";
 
 import { CalendarTooltip } from "./CalendarTooltip";
 import type { CalendarCellData, CalendarColorMode } from "./types";
@@ -38,12 +37,6 @@ type Props = {
   readonly viewMode?: CalendarColorMode;
 };
 
-const renderTooltip =
-  (cellData: CalendarCellData | undefined, viewMode: CalendarColorMode) =>
-  (triggerRef: React.RefObject<HTMLElement>) => (
-    <CalendarTooltip cellData={cellData} triggerRef={triggerRef} viewMode={viewMode} />
-  );
-
 export const CalendarCell = ({
   backgroundColor,
   cellData,
@@ -103,5 +96,9 @@ export const CalendarCell = ({
     return cellBox;
   }
 
-  return <HoverTooltip tooltip={renderTooltip(cellData, viewMode)}>{cellBox}</HoverTooltip>;
+  return (
+    <BasicTooltip content={<CalendarTooltip cellData={cellData} viewMode={viewMode} />}>
+      {cellBox}
+    </BasicTooltip>
+  );
 };
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx
index 61f65e9b876..2edad9f62c2 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Calendar/CalendarTooltip.tsx
@@ -17,8 +17,6 @@
  * under the License.
  */
 import { Box, HStack, Text, VStack } from "@chakra-ui/react";
-import { useMemo } from "react";
-import type { RefObject } from "react";
 import { useTranslation } from "react-i18next";
 
 import type { CalendarCellData, CalendarColorMode } from "./types";
@@ -28,7 +26,6 @@ const SQUARE_BORDER_RADIUS = "2px";
 
 type Props = {
   readonly cellData: CalendarCellData | undefined;
-  readonly triggerRef: RefObject<HTMLElement>;
   readonly viewMode?: CalendarColorMode;
 };
 
@@ -39,48 +36,9 @@ const stateColorMap = {
   success: "success.solid",
 };
 
-export const CalendarTooltip = ({ cellData, triggerRef, viewMode = "total" }: Props) => {
+export const CalendarTooltip = ({ cellData, viewMode = "total" }: Props) => {
   const { t: translate } = useTranslation(["dag", "common"]);
 
-  const tooltipStyle = useMemo(() => {
-    if (!triggerRef.current) {
-      return { display: "none" };
-    }
-
-    const rect = triggerRef.current.getBoundingClientRect();
-
-    return {
-      backgroundColor: "var(--chakra-colors-bg-inverted)",
-      borderRadius: "4px",
-      color: "var(--chakra-colors-fg-inverted)",
-      fontSize: "14px",
-      left: `${rect.left + globalThis.scrollX + rect.width / 2}px`,
-      minWidth: "200px",
-      padding: "8px",
-      position: "absolute" as const,
-      top: `${rect.bottom + globalThis.scrollY + 8}px`,
-      transform: "translateX(-50%)",
-      whiteSpace: "nowrap" as const,
-      zIndex: 1000,
-    };
-  }, [triggerRef]);
-
-  const arrowStyle = useMemo(
-    () => ({
-      borderBottom: "4px solid var(--chakra-colors-bg-inverted)",
-      borderLeft: "4px solid transparent",
-      borderRight: "4px solid transparent",
-      content: '""',
-      height: 0,
-      left: "50%",
-      position: "absolute" as const,
-      top: "-4px",
-      transform: "translateX(-50%)",
-      width: 0,
-    }),
-    [],
-  );
-
   if (!cellData) {
     return undefined;
   }
@@ -111,38 +69,32 @@ export const CalendarTooltip = ({ cellData, triggerRef, viewMode = "total" }: Pr
       state: translate(`common:states.${state}`),
     }));
 
-  return (
-    <div style={tooltipStyle}>
-      <div style={arrowStyle} />
-      {hasRuns ? (
-        <VStack align="start" gap={2}>
-          <Text fontSize="sm" fontWeight="medium">
-            {date}
-          </Text>
-          <VStack align="start" gap={1.5}>
-            {states.map(({ color, count, state }) => (
-              <HStack gap={3} key={state}>
-                <Box
-                  bg={color}
-                  border="1px solid"
-                  borderColor="border.emphasized"
-                  borderRadius={SQUARE_BORDER_RADIUS}
-                  height={SQUARE_SIZE}
-                  width={SQUARE_SIZE}
-                />
-                <Text fontSize="xs">
-                  {count} {state}
-                </Text>
-              </HStack>
-            ))}
-          </VStack>
-        </VStack>
-      ) : (
-        <Text fontSize="sm">
-          {/* To do: remove fallback translations */}
-          {date}: {viewMode === "failed" ? translate("calendar.noFailedRuns") : translate("calendar.noRuns")}
-        </Text>
-      )}
-    </div>
+  return hasRuns ? (
+    <VStack align="start" gap={2}>
+      <Text fontSize="sm" fontWeight="medium">
+        {date}
+      </Text>
+      <VStack align="start" gap={1.5}>
+        {states.map(({ color, count, state }) => (
+          <HStack gap={3} key={state}>
+            <Box
+              bg={color}
+              border="1px solid"
+              borderColor="border.emphasized"
+              borderRadius={SQUARE_BORDER_RADIUS}
+              height={SQUARE_SIZE}
+              width={SQUARE_SIZE}
+            />
+            <Text fontSize="xs">
+              {count} {state}
+            </Text>
+          </HStack>
+        ))}
+      </VStack>
+    </VStack>
+  ) : (
+    <Text fontSize="sm">
+      {date}: {viewMode === "failed" ? translate("calendar.noFailedRuns") : translate("calendar.noRuns")}
+    </Text>
   );
 };


(airflow) 07/32: [v3-1-test] Fix go back button from fab iframe (#58997) (#59007)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit cdd824a4dbdf2a5e8a3aad1ce238f1ac8098e941
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Thu Dec 4 15:25:49 2025 +0100

    [v3-1-test] Fix go back button from fab iframe (#58997) (#59007)
    
    (cherry picked from commit ab8820e2d71e11ef870dc6729d49ab5f9345a506)
    
    Co-authored-by: Pierre Jeambrun <pi...@gmail.com>
---
 airflow-core/src/airflow/ui/src/pages/Security.tsx | 23 +++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/airflow-core/src/airflow/ui/src/pages/Security.tsx b/airflow-core/src/airflow/ui/src/pages/Security.tsx
index ab9941fc02a..67aefc1dd7a 100644
--- a/airflow-core/src/airflow/ui/src/pages/Security.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Security.tsx
@@ -18,6 +18,7 @@
  */
 import { Box } from "@chakra-ui/react";
 import { useParams } from "react-router-dom";
+import { useNavigate } from "react-router-dom";
 
 import { useAuthLinksServiceGetAuthMenus } from "openapi/queries";
 import { ProgressBar } from "src/components/ui";
@@ -37,6 +38,16 @@ export const Security = () => {
 
   const link = authLinks?.extra_menu_items.find((mi) => mi.text.toLowerCase().replace(" ", "-") === page);
 
+  const navigate = useNavigate();
+
+  const onLoad = () => {
+    const iframe: HTMLIFrameElement | null = document.querySelector("#security-iframe");
+
+    if (iframe?.contentWindow && !iframe.contentWindow.location.pathname.startsWith("/auth/")) {
+      navigate("/");
+    }
+  };
+
   if (!link) {
     if (isLoading) {
       return (
@@ -51,7 +62,17 @@ export const Security = () => {
 
   return (
     <Box flexGrow={1} m={-3}>
-      <iframe sandbox={SANDBOX} src={link.href} style={{ height: "100%", width: "100%" }} title={link.text} />
+      {
+        // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
+        <iframe
+          id="security-iframe"
+          onLoad={onLoad}
+          sandbox={SANDBOX}
+          src={link.href}
+          style={{ height: "100%", width: "100%" }}
+          title={link.text}
+        />
+      }
     </Box>
   );
 };


(airflow) 30/32: [v3-1-test] Create additional users in breeze for testing (#58126) (#59233)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 5fe6e4e45b9fb25e7e8143182c73b16a0ba50e54
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Tue Dec 9 11:46:37 2025 +0100

    [v3-1-test] Create additional users in breeze for testing (#58126) (#59233)
    
    * feat: added --create-all-roles flag to breeze. creates test users with each role by default for SimpleAuthManager
    
    * update command config
    
    * ci: ran prek --all-files
    
    * remove dev modecreate roles error
    
    * remove --dev-mode requirement for breeze start-airflow --create-all-roles
    
    * docs: remove documentation
    (cherry picked from commit e615354e34fff66cdd64e8aa7ab63f3258f4a248)
    
    Co-authored-by: Aaron Wolmutt <16...@users.noreply.github.com>
---
 dev/breeze/doc/03_developer_tasks.rst              | 38 +++++++++++++++++++++-
 .../files/simple_auth_manager_passwords.json       |  2 +-
 .../src/airflow_breeze/params/shell_params.py      |  6 +++-
 scripts/in_container/check_environment.sh          | 12 ++++++-
 4 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/dev/breeze/doc/03_developer_tasks.rst b/dev/breeze/doc/03_developer_tasks.rst
index f4968602889..1578d6dea2b 100644
--- a/dev/breeze/doc/03_developer_tasks.rst
+++ b/dev/breeze/doc/03_developer_tasks.rst
@@ -132,12 +132,48 @@ You can connect to these ports/databases using:
 
 If you do not use ``start-airflow`` command. You can use ``tmux`` to multiply terminals.
 You may need to create a user prior to running the API server in order to log in.
-This can be done with the following command:
+
+**Authentication and User Management**
+
+The authentication method depends on which auth manager is configured:
+
+**SimpleAuthManager (Default in Airflow 3.x)**
+
+SimpleAuthManager is the default authentication manager and comes pre-configured with test username and passwords for development:
+
+.. code-block::
+
+    * admin:admin     (Admin role)
+    * viewer:viewer   (Viewer role)
+    * user:user       (User role)
+    * op:op           (Operator role)
+
+These users are automatically available when using SimpleAuthManager and require no additional setup.
+
+**FabAuthManager**
+
+When using FabAuthManager, you can create users manually:
 
 .. code-block:: bash
 
     airflow users create --role Admin --username admin --password admin --email admin@example.com --firstname foo --lastname bar
 
+Or use the ``--create-all-roles`` flag with ``start-airflow`` in dev mode to automatically create test users:
+
+.. code-block:: bash
+
+    breeze start-airflow --dev-mode --create-all-roles --auth-manager FabAuthManager
+
+This will create the following test users:
+
+.. code-block::
+
+    * admin:admin         (Admin role)
+    * viewer:viewer       (Viewer role)
+    * user:user           (User role)
+    * op:op               (Op role)
+    * testadmin:testadmin (Admin role)
+
 .. note::
     ``airflow users`` command is only available when `FAB auth manager <https://airflow.apache.org/docs/apache-airflow-providers-fab/stable/auth-manager/index.html>`_ is enabled.
 
diff --git a/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json b/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json
index 8f297bdae3d..1f74a7b6616 100644
--- a/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json
+++ b/dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json
@@ -1 +1 @@
-{"admin": "admin", "viewer":  "viewer"}
+{"admin": "admin", "viewer": "viewer", "user": "user", "op": "op"}
diff --git a/dev/breeze/src/airflow_breeze/params/shell_params.py b/dev/breeze/src/airflow_breeze/params/shell_params.py
index 393f5ef9918..3f60a5cd6f1 100644
--- a/dev/breeze/src/airflow_breeze/params/shell_params.py
+++ b/dev/breeze/src/airflow_breeze/params/shell_params.py
@@ -171,6 +171,7 @@ class ShellParams:
     celery_flower: bool = False
     clean_airflow_installation: bool = False
     collect_only: bool = False
+    create_all_roles: bool = False
     debug_components: tuple[str, ...] = ()
     debugger: str = "debugpy"
     db_reset: bool = False
@@ -561,7 +562,9 @@ class ShellParams:
         _set_var(_env, "AIRFLOW__CORE__AUTH_MANAGER", self.auth_manager_path)
         _set_var(_env, "AIRFLOW__CORE__EXECUTOR", self.executor)
         if self.auth_manager == SIMPLE_AUTH_MANAGER:
-            _set_var(_env, "AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_USERS", "admin:admin,viewer:viewer")
+            _set_var(
+                _env, "AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_USERS", "admin:admin,viewer:viewer,user:user,op:op"
+            )
         _set_var(
             _env,
             "AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_PASSWORDS_FILE",
@@ -607,6 +610,7 @@ class ShellParams:
         _set_var(_env, "CI_TARGET_BRANCH", self.airflow_branch)
         _set_var(_env, "CI_TARGET_REPO", self.github_repository)
         _set_var(_env, "COLLECT_ONLY", self.collect_only)
+        _set_var(_env, "CREATE_ALL_ROLES", self.create_all_roles)
         _set_var(_env, "COMMIT_SHA", None, commit_sha())
         _set_var(_env, "COMPOSE_FILE", self.compose_file)
         _set_var(_env, "DB_RESET", self.db_reset)
diff --git a/scripts/in_container/check_environment.sh b/scripts/in_container/check_environment.sh
index 6c385f98173..77dcb636283 100755
--- a/scripts/in_container/check_environment.sh
+++ b/scripts/in_container/check_environment.sh
@@ -114,8 +114,18 @@ function startairflow_if_requested() {
 
         if airflow config get-value core auth_manager | grep -q "FabAuthManager"; then
             airflow users create -u admin -p admin -f Thor -l Adminstra -r Admin -e admin@email.domain || true
+
+            # Create all roles for testing if CREATE_ALL_ROLES is set
+            if [[ "${CREATE_ALL_ROLES}" == "true" ]]; then
+                echo "Creating all test roles for FabAuthManager..."
+                airflow users create -u viewer -p viewer -f Test -l Viewer -r Viewer -e viewer@email.domain || true
+                airflow users create -u user -p user -f Test -l User -r User -e user@email.domain || true
+                airflow users create -u op -p op -f Test -l Op -r Op -e op@email.domain || true
+                airflow users create -u testadmin -p testadmin -f Test -l TestAdmin -r Admin -e testadmin@email.domain || true
+                echo "All test roles created successfully for FabAuthManager."
+            fi
         else
-            echo "Skipping user creation as auth manager different from Fab is used"
+            echo "SimpleAuthManager detected. All roles (admin, viewer, user, op) are always available via configuration in .dev/breeze/src/airflow_breeze/files/simple_auth_manager_passwords.json"
         fi
     fi
     return $?


(airflow) 17/32: [v3-1-test] Fix mypy error on version check in dev (#59171) (#59172)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit f770078e8075501532a460f324729e3a51853678
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Sun Dec 7 21:39:34 2025 +0100

    [v3-1-test] Fix mypy error on version check in dev (#59171) (#59172)
    
    (cherry picked from commit 8879eb8cf23cea724d0d0cc251b27b235fc979e3)
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
---
 dev/breeze/src/airflow_breeze/commands/release_management_commands.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index 1347125d13a..a319438b5cb 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -4415,6 +4415,9 @@ def check_release_files(
         create_docker(AIRFLOW_DOCKER.format(version, version), dockerfile_path)
     elif release_type == "task-sdk":
         missing_files = check_task_sdk_release(files, version)
+        if not version:
+            get_console().print("[error]--version is required for task-sdk[/]")
+            sys.exit(1)
         airflow_version = version.replace("1", "3", 1)
         create_docker(
             TASK_SDK_DOCKER.format(version, airflow_version, airflow_version, airflow_version),


(airflow) 23/32: Translation gaps in v3-1-test TR (#59169)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 8a34097b2980de63c04aed68b88121ccbc44a92b
Author: Bugra Ozturk <bu...@users.noreply.github.com>
AuthorDate: Mon Dec 8 00:02:59 2025 +0100

    Translation gaps in v3-1-test TR (#59169)
---
 airflow-core/src/airflow/ui/public/i18n/locales/tr/assets.json | 1 +
 airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json | 1 +
 2 files changed, 2 insertions(+)

diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/assets.json
index 3999d970008..0cb5c8b276a 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/assets.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/assets.json
@@ -1,5 +1,6 @@
 {
   "consumingDags": "Tüketen Dag'ler",
+  "consumingTasks": "Tüketen Görevler",
   "createEvent": {
     "button": "Olay oluştur",
     "manual": {
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json
index 04be0181046..673d0f00db6 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/common.json
@@ -89,6 +89,7 @@
     "back": "Geri",
     "defaultMessage": "Beklenmeyen bir hata oluştu",
     "home": "Ana Sayfa",
+    "invalidUrl": "Sayfa Bulunamadı. Lütfen URL'yi kontrol edin ve tekrar deneyin.",
     "notFound": "Sayfa Bulunamadı",
     "title": "Hata"
   },


(airflow) 24/32: [v3-1-test] Prevent dag processor crash on encountering excel files in the DAG directory (#59069) (#59170)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 0068e0bfe1474d306bf0aba918a217d2388a70b5
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Mon Dec 8 00:04:25 2025 +0100

    [v3-1-test] Prevent dag processor crash on encountering excel files in the DAG directory (#59069) (#59170)
    
    (cherry picked from commit 5c41f2ee2937c6992781970f92a7570190ec1653)
    
    Co-authored-by: Jeff Stafford <je...@protonmail.com>
---
 airflow-core/src/airflow/dag_processing/manager.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/airflow-core/src/airflow/dag_processing/manager.py b/airflow-core/src/airflow/dag_processing/manager.py
index c774aa29fc6..2a37a1bbf6f 100644
--- a/airflow-core/src/airflow/dag_processing/manager.py
+++ b/airflow-core/src/airflow/dag_processing/manager.py
@@ -624,7 +624,7 @@ class DagFileProcessorManager(LoggingMixin):
                         if might_contain_dag(info.filename, True, z):
                             yield os.path.join(abs_path, info.filename)
             except zipfile.BadZipFile:
-                self.log.exception("There was an error accessing ZIP file %s %s", abs_path)
+                self.log.exception("There was an error accessing ZIP file %s", abs_path)
 
         rel_filelocs: list[str] = []
         for info in present:


(airflow) 27/32: missing ca translations in v3-1-test (#59216)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit d5818b9893bb5211509f2de26f5c83713994ef3e
Author: ecodina <41...@users.noreply.github.com>
AuthorDate: Mon Dec 8 21:53:04 2025 +0100

    missing ca translations in v3-1-test (#59216)
---
 airflow-core/src/airflow/ui/public/i18n/locales/ca/assets.json | 2 ++
 airflow-core/src/airflow/ui/public/i18n/locales/ca/browse.json | 4 ----
 airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json | 3 +++
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/ca/assets.json
index 0538c04501d..399abaee907 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/assets.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/assets.json
@@ -1,5 +1,6 @@
 {
   "consumingDags": "Dags consumidors",
+  "consumingTasks": "Tasques consumidores",
   "createEvent": {
     "button": "Crear esdeveniment",
     "manual": {
@@ -21,6 +22,7 @@
     },
     "title": "Crear esdeveniment d'Asset per {{name}}"
   },
+  "extra": "Extra",
   "group": "Grup",
   "lastAssetEvent": "Darrer esdeveniment d'Asset",
   "name": "Nom",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/ca/browse.json
index 217f330c565..5bee6083c0d 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/browse.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/browse.json
@@ -1,9 +1,5 @@
 {
   "auditLog": {
-    "actions": {
-      "collapseAllExtra": "Col·lapsar tots els camps extra json",
-      "expandAllExtra": "Expandir tots els camps extra json"
-    },
     "columns": {
       "event": "Esdeveniment",
       "extra": "Extra",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json
index d5dc92982c9..14b256967cb 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/ca/common.json
@@ -25,6 +25,7 @@
     "requiredActions": "Accions requerides",
     "xcoms": "XComs"
   },
+  "collapseAllExtra": "Col·lapsar tots els camps extra json",
   "collapseDetailsPanel": "Col·lapsar el panell de detalls",
   "createdAssetEvent_one": "Esdeveniment d'Asset creat",
   "createdAssetEvent_other": "Esdeveniments d'Asset creats",
@@ -89,6 +90,7 @@
     "back": "Tornar",
     "defaultMessage": "S'ha produït un error inesperat",
     "home": "Inici",
+    "invalidUrl": "Pàgina no trobada. Si us plau, comprova la URL i torna-ho a provar.",
     "notFound": "Pàgina no trobada",
     "title": "Error"
   },
@@ -98,6 +100,7 @@
     "hotkey": "e",
     "tooltip": "Prem {{hotkey}} per alternar l'expansió"
   },
+  "expandAllExtra": "Expandir tots els camps extra json",
   "expression": {
     "all": "Tots",
     "and": "I",


(airflow) 28/32: [v3-1-test] Fix outdated dependency documentation (#58970) (#59219)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit c4b692880de8fe32cf7814b7c475e1ddfc7229ba
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Tue Dec 9 01:28:10 2025 +0100

    [v3-1-test] Fix outdated dependency documentation (#58970) (#59219)
    
    (cherry picked from commit 442979423f7dd59945d440b2ca03c47578be53a5)
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
---
 airflow-core/docs/installation/dependencies.rst | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/airflow-core/docs/installation/dependencies.rst b/airflow-core/docs/installation/dependencies.rst
index e41e03ab46a..8e209869abb 100644
--- a/airflow-core/docs/installation/dependencies.rst
+++ b/airflow-core/docs/installation/dependencies.rst
@@ -38,9 +38,11 @@ For the list of the extras and what they enable, see: :doc:`/extra-packages-ref`
 Provider distributions
 ''''''''''''''''''''''
 
-Unlike Apache Airflow 1.10, the Airflow 2.0 is delivered in multiple, separate, but connected packages.
-The core of Airflow scheduling system is delivered as ``apache-airflow`` package and there are around
-60 providers which can be installed separately as so called ``Airflow providers``.
+Airflow is delivered in multiple, separate, but connected packages. There is the main ``apache-airflow``
+package, ``airflow-core`` package (which is a dependency of ``apache-airflow``) which implements
+main airflow functionality, ``airflow-task-sdk`` package that is used by Dag authors to implement Dags,
+and multiple so called ``Airflow providers`` packages.
+
 The default Airflow installation doesn't have many integrations and you have to install them yourself.
 
 You can even develop and install your own providers for Airflow. For more information,
@@ -59,13 +61,13 @@ optional features to "core" Apache Airflow. One type of such optional features i
 packages, but not all optional features of Apache Airflow have corresponding providers.
 
 We are using the ``extras`` setuptools features to also install providers.
-Most of the extras are also linked (same name) with providers - for example adding ``[google]``
-extra also adds ``apache-airflow-providers-google`` as dependency. However, there are some extras that do
-not install providers (examples ``github_enterprise``, ``kerberos``, ``async`` - they add some extra
-dependencies which are needed for those ``extra`` features of Airflow mentioned. The three examples
-above add respectively GitHub Enterprise OAuth authentication, Kerberos integration or
-asynchronous workers for Gunicorn. None of those have providers, they are just extending Apache Airflow
-"core" package with new functionalities.
+Most of the extras are also linked (same name) with providers - for example using ``apache-airflow[google]``
+extra installs ``airflow-core`` and adds ``apache-airflow-providers-google`` as dependency.
+However, there are some extras that do not install providers (examples ``github_enterprise``, ``kerberos`` -
+they add some extra dependencies which are needed for those ``extra`` features of
+Airflow mentioned. The three examples above add respectively GitHub Enterprise OAuth authentication,
+Kerberos integration . None of those have providers, they are just extending Apache Airflow
+``airflow-core`` package with new functionalities.
 
 System dependencies
 '''''''''''''''''''


(airflow) 32/32: [v3-1-test] Fix links for DurationChart (#59095) (#59237)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit bf9a304bf9814602486f06cc7b9843330f94d2cb
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Tue Dec 9 15:30:29 2025 +0100

    [v3-1-test] Fix links for DurationChart (#59095) (#59237)
    
    * Fix links for DurationChart
    
    * Address PR comments
    (cherry picked from commit 7218cf045812a5a7135d7f119cdde0aed817b132)
    
    Co-authored-by: Pierre Jeambrun <pi...@gmail.com>
---
 .../src/airflow/ui/src/components/DurationChart.tsx     | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
index c1dad57abc9..4c440288eef 100644
--- a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
@@ -37,6 +37,7 @@ import { useNavigate } from "react-router-dom";
 import type { TaskInstanceResponse, GridRunsResponse } from "openapi/requests/types.gen";
 import { getComputedCSSVariableValue } from "src/theme";
 import { DEFAULT_DATETIME_FORMAT, renderDuration } from "src/utils/datetimeUtils";
+import { buildTaskInstanceUrl } from "src/utils/links";
 
 ChartJS.register(
   CategoryScale,
@@ -191,9 +192,21 @@ export const DurationChart = ({
               }
               case "Task Instance": {
                 const entry = entries[element.index] as TaskInstanceResponse | undefined;
-                const baseUrl = `/dags/${entry?.dag_id}/runs/${entry?.dag_run_id}`;
 
-                navigate(`${baseUrl}/tasks/${entry?.task_id}`);
+                if (entry === undefined) {
+                  break;
+                }
+
+                const baseUrl = buildTaskInstanceUrl({
+                  currentPathname: location.pathname,
+                  dagId: entry.dag_id,
+                  isMapped: entry.map_index >= 0,
+                  mapIndex: entry.map_index.toString(),
+                  runId: entry.dag_run_id,
+                  taskId: entry.task_id,
+                });
+
+                navigate(baseUrl);
                 break;
               }
               default:


(airflow) 31/32: [v3 branch] Fix misleading error message when GitHook creation fails (#59236)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit ac53f64b5df46cd7ef36484bb41e5e398c47ade8
Author: Amogh Desai <am...@gmail.com>
AuthorDate: Tue Dec 9 17:35:11 2025 +0530

    [v3 branch] Fix misleading error message when GitHook creation fails (#59236)
---
 .../src/airflow/dag_processing/bundles/manager.py  | 19 +++++++--
 .../bundles/test_dag_bundle_manager.py             | 47 ++++++++++++++++++++++
 .../git/src/airflow/providers/git/bundles/git.py   |  5 ++-
 providers/git/tests/unit/git/bundles/test_git.py   | 35 +++++++++-------
 4 files changed, 87 insertions(+), 19 deletions(-)

diff --git a/airflow-core/src/airflow/dag_processing/bundles/manager.py b/airflow-core/src/airflow/dag_processing/bundles/manager.py
index cf3b7c51048..9b3cf4189c5 100644
--- a/airflow-core/src/airflow/dag_processing/bundles/manager.py
+++ b/airflow-core/src/airflow/dag_processing/bundles/manager.py
@@ -205,7 +205,11 @@ class DagBundlesManager(LoggingMixin):
         for name in self._bundle_config.keys():
             if bundle := stored.pop(name, None):
                 bundle.active = True
-                new_template, new_params = _extract_and_sign_template(name)
+                try:
+                    new_template, new_params = _extract_and_sign_template(name)
+                except Exception as e:
+                    self.log.exception("Error creating bundle '%s': %s", name, e)
+                    continue
                 if new_template != bundle.signed_url_template:
                     bundle.signed_url_template = new_template
                     self.log.debug("Updated URL template for bundle %s", name)
@@ -213,7 +217,11 @@ class DagBundlesManager(LoggingMixin):
                     bundle.template_params = new_params
                     self.log.debug("Updated template parameters for bundle %s", name)
             else:
-                new_template, new_params = _extract_and_sign_template(name)
+                try:
+                    new_template, new_params = _extract_and_sign_template(name)
+                except Exception as e:
+                    self.log.exception("Error creating bundle '%s': %s", name, e)
+                    continue
                 new_bundle = DagBundleModel(name=name)
                 new_bundle.signed_url_template = new_template
                 new_bundle.template_params = new_params
@@ -280,7 +288,12 @@ class DagBundlesManager(LoggingMixin):
         :return: list of DAG bundles.
         """
         for name, (class_, kwargs) in self._bundle_config.items():
-            yield class_(name=name, version=None, **kwargs)
+            try:
+                yield class_(name=name, version=None, **kwargs)
+            except Exception as e:
+                self.log.exception("Error creating bundle '%s': %s", name, e)
+                # Skip this bundle and continue with others
+                continue
 
     def view_url(self, name: str, version: str | None = None) -> str | None:
         warnings.warn(
diff --git a/airflow-core/tests/unit/dag_processing/bundles/test_dag_bundle_manager.py b/airflow-core/tests/unit/dag_processing/bundles/test_dag_bundle_manager.py
index b1e8b4f8b65..e532b53d969 100644
--- a/airflow-core/tests/unit/dag_processing/bundles/test_dag_bundle_manager.py
+++ b/airflow-core/tests/unit/dag_processing/bundles/test_dag_bundle_manager.py
@@ -379,3 +379,50 @@ def test_example_dags_name_is_reserved():
     with conf_vars({("dag_processor", "dag_bundle_config_list"): json.dumps(reserved_name_config)}):
         with pytest.raises(AirflowConfigException, match="Bundle name 'example_dags' is a reserved name."):
             DagBundlesManager().parse_config()
+
+
+class FailingBundle(BaseDagBundle):
+    """Test bundle that raises an exception during initialization."""
+
+    def __init__(self, *, should_fail: bool = True, **kwargs):
+        super().__init__(**kwargs)
+        if should_fail:
+            raise ValueError("Bundle creation failed for testing")
+
+    def refresh(self):
+        pass
+
+    def get_current_version(self):
+        return None
+
+    @property
+    def path(self):
+        return "/tmp/failing"
+
+
+FAILING_BUNDLE_CONFIG = [
+    {
+        "name": "failing-bundle",
+        "classpath": "unit.dag_processing.bundles.test_dag_bundle_manager.FailingBundle",
+        "kwargs": {"should_fail": True, "refresh_interval": 1},
+    }
+]
+
+
+@conf_vars({("core", "LOAD_EXAMPLES"): "False"})
+@pytest.mark.db_test
+def test_multiple_bundles_one_fails(clear_db, session):
+    """Test that when one bundle fails to create, other bundles still load successfully."""
+    mix_config = BASIC_BUNDLE_CONFIG + FAILING_BUNDLE_CONFIG
+
+    with patch.dict(os.environ, {"AIRFLOW__DAG_PROCESSOR__DAG_BUNDLE_CONFIG_LIST": json.dumps(mix_config)}):
+        manager = DagBundlesManager()
+
+        bundles = list(manager.get_all_dag_bundles())
+        assert len(bundles) == 1
+        assert bundles[0].name == "my-test-bundle"
+        assert isinstance(bundles[0], BasicBundle)
+
+        manager.sync_bundles_to_db()
+        bundle_names = {b.name for b in session.query(DagBundleModel).all()}
+        assert bundle_names == {"my-test-bundle"}
diff --git a/providers/git/src/airflow/providers/git/bundles/git.py b/providers/git/src/airflow/providers/git/bundles/git.py
index bd8dba47310..3ef88b82dd7 100644
--- a/providers/git/src/airflow/providers/git/bundles/git.py
+++ b/providers/git/src/airflow/providers/git/bundles/git.py
@@ -80,8 +80,9 @@ class GitDagBundle(BaseDagBundle):
         self.hook: GitHook | None = None
         try:
             self.hook = GitHook(git_conn_id=git_conn_id or "git_default", repo_url=self.repo_url)
-        except Exception as e:
-            self._log.warning("Could not create GitHook", conn_id=git_conn_id, exc=e)
+        except Exception:
+            # re raise so exception propagates immediately with clear error message
+            raise
 
         if self.hook and self.hook.repo_url:
             self.repo_url = self.hook.repo_url
diff --git a/providers/git/tests/unit/git/bundles/test_git.py b/providers/git/tests/unit/git/bundles/test_git.py
index 950388f6d6c..b59bd8605c5 100644
--- a/providers/git/tests/unit/git/bundles/test_git.py
+++ b/providers/git/tests/unit/git/bundles/test_git.py
@@ -33,8 +33,6 @@ from airflow.exceptions import AirflowException
 from airflow.models import Connection
 from airflow.providers.git.bundles.git import GitDagBundle
 from airflow.providers.git.hooks.git import GitHook
-from airflow.sdk.exceptions import ErrorType
-from airflow.sdk.execution_time.comms import ErrorResponse
 
 from tests_common.test_utils.config import conf_vars
 from tests_common.test_utils.version_compat import AIRFLOW_V_3_1_PLUS
@@ -673,20 +671,29 @@ class TestGitDagBundle:
 
     @patch.dict(os.environ, {"AIRFLOW_CONN_MY_TEST_GIT": '{"host": "something", "conn_type": "git"}'})
     @pytest.mark.parametrize(
-        "conn_id, expected_hook_type",
-        [("my_test_git", GitHook), ("something-else", type(None))],
+        ("conn_id", "expected_hook_type", "exception_expected"),
+        [
+            ("my_test_git", GitHook, False),
+            ("something-else", None, True),
+        ],
     )
-    def test_repo_url_access_missing_connection_doesnt_error(
-        self, conn_id, expected_hook_type, mock_supervisor_comms
+    def test_repo_url_access_missing_connection_raises_exception(
+        self, conn_id, expected_hook_type, exception_expected
     ):
-        if expected_hook_type is type(None):
-            mock_supervisor_comms.send.return_value = ErrorResponse(error=ErrorType.CONNECTION_NOT_FOUND)
-        bundle = GitDagBundle(
-            name="testa",
-            tracking_ref="main",
-            git_conn_id=conn_id,
-        )
-        assert isinstance(bundle.hook, expected_hook_type)
+        if exception_expected:
+            with pytest.raises(Exception, match="The conn_id `something-else` isn't defined"):
+                GitDagBundle(
+                    name="testa",
+                    tracking_ref="main",
+                    git_conn_id=conn_id,
+                )
+        else:
+            bundle = GitDagBundle(
+                name="testa",
+                tracking_ref="main",
+                git_conn_id=conn_id,
+            )
+            assert isinstance(bundle.hook, expected_hook_type)
 
     @mock.patch("airflow.providers.git.bundles.git.GitHook")
     def test_lock_used(self, mock_githook, git_repo):


(airflow) 26/32: Convert the exclusion on urllib3 to != for 2.6.0 (#59203) (#59212)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit a5f0be48571fb23d1d84df7882fac23924348d4e
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Mon Dec 8 17:47:15 2025 +0100

    Convert the exclusion on urllib3 to != for 2.6.0 (#59203) (#59212)
    
    After discussion in https://github.com/urllib3/urllib3/issues/3731
    maintainers of urllib3 decided to restore the removed getheaders()
    method for now. We should change < to !=.
    
    (cherry picked from commit dd31202e8c4930689a61394ecced3af710494790)
---
 clients/python/pyproject.toml            | 2 +-
 kubernetes-tests/pyproject.toml          | 2 +-
 providers/cncf/kubernetes/pyproject.toml | 4 ++++
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml
index 59593b1d8dd..2cef853a066 100644
--- a/clients/python/pyproject.toml
+++ b/clients/python/pyproject.toml
@@ -51,7 +51,7 @@ classifiers = [
 dependencies = [
     "pydantic >= 2.11.0",
     "python-dateutil",
-    "urllib3 >= 2.1.0",
+    "urllib3>=2.1.0,!=2.6.0",
 ]
 
 [project.urls]
diff --git a/kubernetes-tests/pyproject.toml b/kubernetes-tests/pyproject.toml
index 90ddc85ea62..d7f71b9af3d 100644
--- a/kubernetes-tests/pyproject.toml
+++ b/kubernetes-tests/pyproject.toml
@@ -44,7 +44,7 @@ dependencies = [
     # Urllib 2.6.0 breaks kubernetes client because kubernetes client uses deprecated in 2.0.0 and
     # removed in 2.6.0 `getheaders()` call (instead of `headers` property.
     # Tracked in https://github.com/kubernetes-client/python/issues/2477
-    "urllib3>=2.1.0,<2.6.0",
+    "urllib3>=2.1.0,!=2.6.0",
 ]
 
 [tool.pytest]
diff --git a/providers/cncf/kubernetes/pyproject.toml b/providers/cncf/kubernetes/pyproject.toml
index 5b937c8e2ad..b586d75772e 100644
--- a/providers/cncf/kubernetes/pyproject.toml
+++ b/providers/cncf/kubernetes/pyproject.toml
@@ -71,6 +71,10 @@ dependencies = [
     # potential breaking changes in Airflow Core as well (kubernetes is added as extra, so Airflow
     # core is not hard-limited via install-requirements, only by extra).
     "kubernetes>=32.0.0,<33.0.0",
+    # Urllib 2.6.0 breaks kubernetes client because kubernetes client uses deprecated in 2.0.0 and
+    # removed in 2.6.0 `getheaders()` call (instead of `headers` property.
+    # Tracked in https://github.com/kubernetes-client/python/issues/2477
+    "urllib3>=2.1.0,!=2.6.0",
     # the version is limited to the next MAJOR version and should by synced with the kubernetes version
     "kubernetes_asyncio>=32.0.0,<33.0.0",
 ]


(airflow) 11/32: [v3-1-test] Uncomment Python version pin in `check-lazy-logging` (#59047) (#59067)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit db10eda9f938c193f4dcd1390046ce13c3a7ebcc
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Thu Dec 4 20:49:02 2025 +0100

    [v3-1-test] Uncomment Python version pin in `check-lazy-logging` (#59047) (#59067)
    
    Breaks for 3.14
    (cherry picked from commit fe26bfe057542b955eb45538ceac875fa51a3a14)
    
    Co-authored-by: Bartosz Sławecki <ba...@ilikepython.com>
---
 scripts/ci/prek/check_lazy_logging.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/ci/prek/check_lazy_logging.py b/scripts/ci/prek/check_lazy_logging.py
index c827b3310a2..28357224699 100755
--- a/scripts/ci/prek/check_lazy_logging.py
+++ b/scripts/ci/prek/check_lazy_logging.py
@@ -17,7 +17,7 @@
 # specific language governing permissions and limitations
 # under the License.
 # /// script
-# # requires-python = ">=3.10,<3.11"
+# requires-python = ">=3.10,<3.11"
 # dependencies = [
 #   "astor>=0.8.1",
 #   "rich>=13.6.0",


(airflow) 18/32: [v3-1-test] fix: Rendered Templates not showing dictionary items in AF3 (#58071) (#59176)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 46a223f32f1b54ca009f47a5d9092e08261e043f
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Sun Dec 7 23:18:26 2025 +0100

    [v3-1-test] fix: Rendered Templates not showing dictionary items in AF3 (#58071) (#59176)
    
    * Rendered Templates not showing dictionary items in AF3
    
    * add a unit test
    
    * fix test error
    (cherry picked from commit 4408d68a93be5cd9785f65c3be6ee77647150879)
    
    Co-authored-by: GUAN-HAO HUANG <10...@users.noreply.github.com>
---
 .../src/airflow/models/renderedtifields.py         | 43 ++++++++++++-
 .../tests/unit/models/test_renderedtifields.py     | 70 ++++++++++++++++++++++
 2 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/airflow-core/src/airflow/models/renderedtifields.py b/airflow-core/src/airflow/models/renderedtifields.py
index b19b7f1f6ed..100da273154 100644
--- a/airflow-core/src/airflow/models/renderedtifields.py
+++ b/airflow-core/src/airflow/models/renderedtifields.py
@@ -20,7 +20,7 @@
 from __future__ import annotations
 
 import os
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Any
 
 import sqlalchemy_jsonfield
 from sqlalchemy import (
@@ -51,6 +51,28 @@ if TYPE_CHECKING:
     from airflow.serialization.serialized_objects import SerializedBaseOperator
 
 
+def _get_nested_value(obj: Any, path: str) -> Any:
+    """
+    Get a nested value from an object using a dot-separated path.
+
+    :param obj: The object to extract the value from
+    :param path: A dot-separated path (e.g., "configuration.query.sql")
+    :return: The value at the nested path, or None if the path doesn't exist
+    """
+    keys = path.split(".")
+    current = obj
+    for key in keys:
+        if isinstance(current, dict):
+            current = current.get(key)
+        elif hasattr(current, key):
+            current = getattr(current, key)
+        else:
+            return None
+        if current is None:
+            return None
+    return current
+
+
 def get_serialized_template_fields(task: SerializedBaseOperator):
     """
     Get and serialize the template fields for a task.
@@ -61,7 +83,24 @@ def get_serialized_template_fields(task: SerializedBaseOperator):
 
     :meta private:
     """
-    return {field: serialize_template_field(getattr(task, field), field) for field in task.template_fields}
+    rendered_fields = {}
+
+    for field in task.template_fields:
+        rendered_fields[field] = serialize_template_field(getattr(task, field), field)
+
+    renderers = getattr(task, "template_fields_renderers", {})
+    for renderer_path in renderers:
+        if "." in renderer_path:
+            base_field = renderer_path.split(".", 1)[0]
+
+            if base_field in task.template_fields:
+                base_value = getattr(task, base_field)
+                nested_value = _get_nested_value(base_value, renderer_path[len(base_field) + 1 :])
+
+                if nested_value is not None:
+                    rendered_fields[renderer_path] = serialize_template_field(nested_value, renderer_path)
+
+    return rendered_fields
 
 
 class RenderedTaskInstanceFields(TaskInstanceDependencies):
diff --git a/airflow-core/tests/unit/models/test_renderedtifields.py b/airflow-core/tests/unit/models/test_renderedtifields.py
index 47aa8829aa8..ee9cc3b9b12 100644
--- a/airflow-core/tests/unit/models/test_renderedtifields.py
+++ b/airflow-core/tests/unit/models/test_renderedtifields.py
@@ -21,6 +21,7 @@ from __future__ import annotations
 
 import os
 from collections import Counter
+from collections.abc import Sequence
 from datetime import date, timedelta
 from typing import TYPE_CHECKING
 from unittest import mock
@@ -33,6 +34,7 @@ from airflow import settings
 from airflow._shared.timezones.timezone import datetime
 from airflow.configuration import conf
 from airflow.models import DagRun, Variable
+from airflow.models.baseoperator import BaseOperator
 from airflow.models.renderedtifields import RenderedTaskInstanceFields as RTIF
 from airflow.models.taskmap import TaskMap
 from airflow.providers.standard.operators.bash import BashOperator
@@ -448,3 +450,71 @@ class TestRenderedTaskInstanceFields:
         # rerun the old run. this will shouldn't fail
         ti.task = task
         ti.run()
+
+    def test_nested_dictionary_template_field_rendering(self, dag_maker):
+        """
+        Test that nested dictionary items in template fields are properly rendered
+        when using template_fields_renderers with dot-separated paths.
+
+        This test verifies the fix for rendering dictionary items in templates.
+        Before the fix, nested dictionary items specified in template_fields_renderers
+        (e.g., "configuration.query.sql") would not be rendered. After the fix,
+        these nested items are properly extracted and rendered.
+        """
+
+        # Create a custom operator with a dictionary template field
+        class MyConfigOperator(BaseOperator):
+            template_fields: Sequence[str] = ("configuration",)
+            template_fields_renderers = {
+                "configuration": "json",
+                "configuration.query.sql": "sql",
+            }
+
+            def __init__(self, configuration: dict, **kwargs):
+                super().__init__(**kwargs)
+                self.configuration = configuration
+
+        # Create a configuration dictionary with nested structure
+        configuration = {
+            "query": {
+                "job_id": "123",
+                "sql": "select * from my_table where date = '{{ ds }}'",
+            }
+        }
+
+        with dag_maker("test_nested_dict_rendering"):
+            task = MyConfigOperator(task_id="test_config", configuration=configuration)
+        dr = dag_maker.create_dagrun()
+
+        session = dag_maker.session
+        ti = dr.task_instances[0]
+        ti.task = task
+        rtif = RTIF(ti=ti)
+
+        # Verify that the base configuration field is rendered
+        assert "configuration" in rtif.rendered_fields
+        rendered_config = rtif.rendered_fields["configuration"]
+        assert isinstance(rendered_config, dict)
+        assert rendered_config["query"]["job_id"] == "123"
+        # The SQL should be templated (ds should be replaced with actual date)
+        assert "select * from my_table where date = '" in rendered_config["query"]["sql"]
+        assert rendered_config["query"]["sql"] != configuration["query"]["sql"]
+
+        # Verify that the nested dictionary item is also rendered
+        # This is the key test - before the fix, this would not exist
+        assert "configuration.query.sql" in rtif.rendered_fields
+        rendered_sql = rtif.rendered_fields["configuration.query.sql"]
+        assert isinstance(rendered_sql, str)
+        assert "select * from my_table where date = '" in rendered_sql
+        # The template should be rendered (ds should be replaced)
+        assert "{{ ds }}" not in rendered_sql
+
+        # Store in database and verify retrieval
+        session.add(rtif)
+        session.flush()
+
+        retrieved_fields = RTIF.get_templated_fields(ti=ti, session=session)
+        assert retrieved_fields is not None
+        assert "configuration" in retrieved_fields
+        assert "configuration.query.sql" in retrieved_fields
+        assert retrieved_fields["configuration.query.sql"] == rendered_sql


(airflow) 01/32: [v3-1-test] Limit urllib3 to <2.6.0 during latest boto tests (#59130) (#59132)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 6c3ecf83c858886e363d0d0fe8c36a5ea382fe47
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Sat Dec 6 15:29:25 2025 +0100

    [v3-1-test] Limit urllib3 to <2.6.0 during latest boto tests (#59130) (#59132)
    
    This is follow up after #59108 as latest boto tests might upgrade
    urllib3.
    (cherry picked from commit 40ee29ce3cd00ddd30ed9a2a9bd743b5f51fbd3b)
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
---
 Dockerfile.ci                   | 6 +++++-
 scripts/docker/entrypoint_ci.sh | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/Dockerfile.ci b/Dockerfile.ci
index c4921b7df90..e82f35e7da5 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -1324,8 +1324,12 @@ function check_boto_upgrade() {
     echo
     # shellcheck disable=SC2086
     ${PACKAGING_TOOL_CMD} uninstall ${EXTRA_UNINSTALL_FLAGS} aiobotocore s3fs || true
+
+    # Urllib 2.6.0 breaks kubernetes client because kubernetes client uses deprecated in 2.0.0 and
+    # removed in 2.6.0 `getheaders()` call (instead of `headers` property.
+    # Tracked in https://github.com/kubernetes-client/python/issues/2477
     # shellcheck disable=SC2086
-    ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} --upgrade "boto3<1.38.3" "botocore<1.38.3"
+    ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} --upgrade "boto3<1.38.3" "botocore<1.38.3" "urllib3<2.6.0"
 }
 
 function check_upgrade_sqlalchemy() {
diff --git a/scripts/docker/entrypoint_ci.sh b/scripts/docker/entrypoint_ci.sh
index 28fd6300966..dabb4a59eff 100755
--- a/scripts/docker/entrypoint_ci.sh
+++ b/scripts/docker/entrypoint_ci.sh
@@ -303,8 +303,12 @@ function check_boto_upgrade() {
     echo
     # shellcheck disable=SC2086
     ${PACKAGING_TOOL_CMD} uninstall ${EXTRA_UNINSTALL_FLAGS} aiobotocore s3fs || true
+
+    # Urllib 2.6.0 breaks kubernetes client because kubernetes client uses deprecated in 2.0.0 and
+    # removed in 2.6.0 `getheaders()` call (instead of `headers` property.
+    # Tracked in https://github.com/kubernetes-client/python/issues/2477
     # shellcheck disable=SC2086
-    ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} --upgrade "boto3<1.38.3" "botocore<1.38.3"
+    ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} --upgrade "boto3<1.38.3" "botocore<1.38.3" "urllib3<2.6.0"
 }
 
 # Upgrade sqlalchemy to the latest version to run tests with it


(airflow) 05/32: [v3-1-test] Add prek check before compiling assets in start-airflow (#58979) (#58996)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 8a380071752a42c03418854d3c0021a0b0090a22
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Thu Dec 4 02:50:33 2025 +0100

    [v3-1-test] Add prek check before compiling assets in start-airflow (#58979) (#58996)
    
    (cherry picked from commit 08813da0d696c0f663c0f5b312ac6dfb3d2a72e1)
    
    Co-authored-by: Jarek Potiuk <ja...@potiuk.com>
---
 dev/breeze/src/airflow_breeze/commands/developer_commands.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
index ceb6b701da2..71ab14516b6 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
@@ -635,7 +635,9 @@ def start_airflow(
             "[info]Detected WSL environment. Automatically enabled CHOKIDAR_USEPOLLING for hot reloading."
         )
 
+    perform_environment_checks(quiet=False)
     if use_airflow_version is None and not skip_assets_compilation:
+        assert_prek_installed()
         # Now with the /ui project, lets only do a static build of /www and focus on the /ui
         run_compile_ui_assets(dev=dev_mode, run_in_background=True, force_clean=False)
     airflow_constraints_reference = _determine_constraint_branch_used(
@@ -701,7 +703,6 @@ def start_airflow(
         use_uv=use_uv,
         uv_http_timeout=uv_http_timeout,
     )
-    perform_environment_checks(quiet=shell_params.quiet)
     rebuild_or_pull_ci_image_if_needed(command_params=shell_params)
     result = enter_shell(shell_params=shell_params)
     fix_ownership_using_docker()


(airflow) 09/32: [v3-1-test] Move HTTPAuthorizationCredentials import from TYPE_CHECKING block to (#59048) (#59056)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 979a21184eaed762b37d6f2c239b75d1607984a9
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Thu Dec 4 18:05:30 2025 +0100

    [v3-1-test] Move HTTPAuthorizationCredentials import from TYPE_CHECKING block to (#59048) (#59056)
    
    Runtime imports to fix NameError when FastAPI evaluates type annotations
    at runtime.
    (cherry picked from commit d3bc5b96e8f7ae4082d3cf78e859e200233b0276)
    
    Co-authored-by: Ankit Chaurasia <86...@users.noreply.github.com>
---
 airflow-core/src/airflow/api_fastapi/core_api/security.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/airflow-core/src/airflow/api_fastapi/core_api/security.py b/airflow-core/src/airflow/api_fastapi/core_api/security.py
index 7bc7b155b68..e17f92776da 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/security.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/security.py
@@ -22,7 +22,7 @@ from typing import TYPE_CHECKING, Annotated, cast
 from urllib.parse import ParseResult, unquote, urljoin, urlparse
 
 from fastapi import Depends, HTTPException, Request, status
-from fastapi.security import HTTPBearer, OAuth2PasswordBearer
+from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer, OAuth2PasswordBearer
 from jwt import ExpiredSignatureError, InvalidTokenError
 from pydantic import NonNegativeInt
 
@@ -66,7 +66,6 @@ from airflow.models.taskinstance import TaskInstance as TI
 from airflow.models.xcom import XComModel
 
 if TYPE_CHECKING:
-    from fastapi.security import HTTPAuthorizationCredentials
     from sqlalchemy.sql import Select
 
     from airflow.api_fastapi.auth.managers.base_auth_manager import BaseAuthManager, ResourceMethod


(airflow) 13/32: CI: Upgrade important CI environment (#59145)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit d8f3e42ff4e5bff4f5c2e155809a8f9063da1a32
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Sun Dec 7 00:18:52 2025 +0100

    CI: Upgrade important CI environment (#59145)
---
 .github/actions/breeze/action.yml                  |   2 +-
 .github/actions/install-prek/action.yml            |   2 +-
 .github/workflows/airflow-distributions-tests.yml  |   2 +-
 .github/workflows/basic-tests.yml                  |   2 +-
 .github/workflows/release_dockerhub_image.yml      |   2 +-
 .pre-commit-config.yaml                            |   2 +-
 Dockerfile                                         |   2 +-
 Dockerfile.ci                                      |   2 +-
 chart/.pre-commit-config.yaml                      |   2 +-
 dev/breeze/doc/ci/02_images.md                     |   2 +-
 dev/breeze/pyproject.toml                          |   2 +-
 .../commands/release_management_commands.py        |   4 +-
 dev/breeze/src/airflow_breeze/global_constants.py  |   4 +-
 dev/breeze/uv.lock                                 | 290 +++++++++++----------
 go-sdk/.pre-commit-config.yaml                     |   2 +-
 pyproject.toml                                     |   2 +-
 scripts/tools/setup_breeze                         |   2 +-
 17 files changed, 168 insertions(+), 158 deletions(-)

diff --git a/.github/actions/breeze/action.yml b/.github/actions/breeze/action.yml
index 2eac64d3832..1465d45077e 100644
--- a/.github/actions/breeze/action.yml
+++ b/.github/actions/breeze/action.yml
@@ -24,7 +24,7 @@ inputs:
     default: "3.10"
   uv-version:
     description: 'uv version to use'
-    default: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
+    default: "0.9.16"  # Keep this comment to allow automatic replacement of uv version
 outputs:
   host-python-version:
     description: Python version used in host
diff --git a/.github/actions/install-prek/action.yml b/.github/actions/install-prek/action.yml
index e8160240b87..e72cf95adcf 100644
--- a/.github/actions/install-prek/action.yml
+++ b/.github/actions/install-prek/action.yml
@@ -24,7 +24,7 @@ inputs:
     default: "3.10"
   uv-version:
     description: 'uv version to use'
-    default: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
+    default: "0.9.16"  # Keep this comment to allow automatic replacement of uv version
   prek-version:
     description: 'prek version to use'
     default: "0.2.19"  # Keep this comment to allow automatic replacement of prek version
diff --git a/.github/workflows/airflow-distributions-tests.yml b/.github/workflows/airflow-distributions-tests.yml
index 69d31d60dfc..03236b9d40d 100644
--- a/.github/workflows/airflow-distributions-tests.yml
+++ b/.github/workflows/airflow-distributions-tests.yml
@@ -113,7 +113,7 @@ jobs:
           USE_LOCAL_HATCH: "${{ inputs.use-local-venv }}"
         run: |
           uv tool uninstall hatch || true
-          uv tool install hatch==1.16.1
+          uv tool install hatch==1.16.2
           breeze release-management "${DISTRIBUTION_TYPE}" --distribution-format wheel
         if: ${{ matrix.python-version == inputs.default-python-version }}
       - name: "Verify wheel packages with twine"
diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml
index d940097c24e..664945af7b0 100644
--- a/.github/workflows/basic-tests.yml
+++ b/.github/workflows/basic-tests.yml
@@ -66,7 +66,7 @@ on:  # yamllint disable-line rule:truthy
         type: string
       uv-version:
         description: 'uv version to use'
-        default: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
+        default: "0.9.16"  # Keep this comment to allow automatic replacement of uv version
         type: string
       platform:
         description: 'Platform for the build - linux/amd64 or linux/arm64'
diff --git a/.github/workflows/release_dockerhub_image.yml b/.github/workflows/release_dockerhub_image.yml
index f8dda5e53b5..6118057a214 100644
--- a/.github/workflows/release_dockerhub_image.yml
+++ b/.github/workflows/release_dockerhub_image.yml
@@ -58,7 +58,7 @@ jobs:
       AIRFLOW_VERSION: ${{ github.event.inputs.airflowVersion }}
       AMD_ONLY: ${{ github.event.inputs.amdOnly }}
       LIMIT_PYTHON_VERSIONS: ${{ github.event.inputs.limitPythonVersions }}
-      UV_VERSION: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
+      UV_VERSION: "0.9.16"  # Keep this comment to allow automatic replacement of uv version
     if: contains(fromJSON('[
       "ashb",
       "bugraoz93",
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index b1073d99a64..9c9d80d45e9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -59,7 +59,7 @@ repos:
           - "2"
   - repo: https://github.com/Lucas-C/pre-commit-hooks
     # replace hash with version once PR #103 merged comes in a release
-    rev: abdd8b62891099da34162217ecb3872d22184a51
+    rev: f5cfd5fdaf0211dfd1027d9d8442b764a232c7ad
     hooks:
       - id: insert-license
         name: Add license for all SQL files
diff --git a/Dockerfile b/Dockerfile
index 15b94ede71a..2ad4757c6d8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -56,7 +56,7 @@ ARG AIRFLOW_PYTHON_VERSION="3.12.12"
 # Also use `force pip` label on your PR to swap all places we use `uv` to `pip`
 ARG AIRFLOW_PIP_VERSION=25.3
 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main"
-ARG AIRFLOW_UV_VERSION=0.9.15
+ARG AIRFLOW_UV_VERSION=0.9.16
 ARG AIRFLOW_USE_UV="false"
 ARG UV_HTTP_TIMEOUT="300"
 ARG AIRFLOW_IMAGE_REPOSITORY="https://github.com/apache/airflow"
diff --git a/Dockerfile.ci b/Dockerfile.ci
index ff7b2524fc7..9364093c53c 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -1699,7 +1699,7 @@ COPY --from=scripts common.sh install_packaging_tools.sh install_additional_depe
 # Also use `force pip` label on your PR to swap all places we use `uv` to `pip`
 ARG AIRFLOW_PIP_VERSION=25.3
 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main"
-ARG AIRFLOW_UV_VERSION=0.9.15
+ARG AIRFLOW_UV_VERSION=0.9.16
 ARG AIRFLOW_PREK_VERSION="0.2.19"
 
 # UV_LINK_MODE=copy is needed since we are using cache mounted from the host
diff --git a/chart/.pre-commit-config.yaml b/chart/.pre-commit-config.yaml
index f5a31a9fdbe..94d138388bb 100644
--- a/chart/.pre-commit-config.yaml
+++ b/chart/.pre-commit-config.yaml
@@ -24,7 +24,7 @@ default_language_version:
 repos:
   - repo: https://github.com/Lucas-C/pre-commit-hooks
     # replace hash with version once PR #103 merged comes in a release
-    rev: abdd8b62891099da34162217ecb3872d22184a51
+    rev: f5cfd5fdaf0211dfd1027d9d8442b764a232c7ad
     hooks:
       - id: insert-license
         name: Add license for all Helm template files
diff --git a/dev/breeze/doc/ci/02_images.md b/dev/breeze/doc/ci/02_images.md
index 134bb92db76..fa874a7dcae 100644
--- a/dev/breeze/doc/ci/02_images.md
+++ b/dev/breeze/doc/ci/02_images.md
@@ -443,7 +443,7 @@ can be used for CI images:
 | `ADDITIONAL_DEV_APT_DEPS`         |                             | Additional apt dev dependencies installed in the first part of the image                                          |
 | `ADDITIONAL_DEV_APT_ENV`          |                             | Additional env variables defined when installing dev deps                                                         |
 | `AIRFLOW_PIP_VERSION`             | `25.3`                      | `pip` version used.                                                                                               |
-| `AIRFLOW_UV_VERSION`              | `0.9.15`                    | `uv` version used.                                                                                                |
+| `AIRFLOW_UV_VERSION`              | `0.9.16`                    | `uv` version used.                                                                                                |
 | `AIRFLOW_PREK_VERSION`            | `0.2.19`                    | `prek` version used.                                                                                              |
 | `AIRFLOW_USE_UV`                  | `true`                      | Whether to use UV for installation.                                                                               |
 | `PIP_PROGRESS_BAR`                | `on`                        | Progress bar for PIP installation                                                                                 |
diff --git a/dev/breeze/pyproject.toml b/dev/breeze/pyproject.toml
index 30397d00d04..5bb71ceebcd 100644
--- a/dev/breeze/pyproject.toml
+++ b/dev/breeze/pyproject.toml
@@ -54,7 +54,7 @@ dependencies = [
     "google-auth-httplib2>=0.2.0",
     "google-auth-oauthlib>=1.2.0",
     "gitpython>=3.1.40",
-    "hatch>=1.16.1",
+    "hatch>=1.16.2",
     "inputimeout>=1.0.4",
     "jinja2>=3.1.5",
     "jsonschema>=4.19.1",
diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index bd6df2494b4..3f78a043bdc 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -246,12 +246,12 @@ class VersionedFile(NamedTuple):
 
 
 AIRFLOW_PIP_VERSION = "25.3"
-AIRFLOW_UV_VERSION = "0.9.15"
+AIRFLOW_UV_VERSION = "0.9.16"
 AIRFLOW_USE_UV = False
 GITPYTHON_VERSION = "3.1.45"
 RICH_VERSION = "14.2.0"
 PREK_VERSION = "0.2.19"
-HATCH_VERSION = "1.16.1"
+HATCH_VERSION = "1.16.2"
 PYYAML_VERSION = "6.0.3"
 
 # prek environment and this is done with node, no python installation is needed.
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py
index d411fb6c48f..cd9e6f495a0 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -213,7 +213,7 @@ if MYSQL_INNOVATION_RELEASE:
 ALLOWED_INSTALL_MYSQL_CLIENT_TYPES = ["mariadb", "mysql"]
 
 PIP_VERSION = "25.3"
-UV_VERSION = "0.9.15"
+UV_VERSION = "0.9.16"
 
 DEFAULT_UV_HTTP_TIMEOUT = 300
 DEFAULT_WSL2_HTTP_TIMEOUT = 900
@@ -757,7 +757,7 @@ ALL_PYTHON_VERSION_TO_PATCHLEVEL_VERSION: dict[str, str] = {
     "3.10": "3.10.19",
     "3.11": "3.11.14",
     "3.12": "3.12.12",
-    "3.13": "3.13.10",
+    "3.13": "3.13.11",
 }
 
 # Number of slices for low dep tests
diff --git a/dev/breeze/uv.lock b/dev/breeze/uv.lock
index 48dc421af86..226420f24ba 100644
--- a/dev/breeze/uv.lock
+++ b/dev/breeze/uv.lock
@@ -69,7 +69,7 @@ requires-dist = [
     { name = "google-api-python-client", specifier = ">=2.142.0" },
     { name = "google-auth-httplib2", specifier = ">=0.2.0" },
     { name = "google-auth-oauthlib", specifier = ">=1.2.0" },
-    { name = "hatch", specifier = ">=1.16.1" },
+    { name = "hatch", specifier = ">=1.16.2" },
     { name = "inputimeout", specifier = ">=1.0.4" },
     { name = "jinja2", specifier = ">=3.1.5" },
     { name = "jsonschema", specifier = ">=4.19.1" },
@@ -111,97 +111,107 @@ wheels = [
 
 [[package]]
 name = "backports-zstd"
-version = "1.1.0"
+version = "1.2.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ee/76/403d81c1b9264f6ee1c25b2f2ce892ed9930d1a0a1939ef26a01a95e644d/backports_zstd-1.1.0.tar.gz", hash = "sha256:8ce84125e3094ddefbaa25306e8949965ce092b400a1fd63b5e6a5e932d2994f", size = 996020, upload-time = "2025-11-23T12:51:19.478Z" }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/2f/bb/9f71f34b1c7ad957f36ca320bcdfef1836816af9a8f5d256debe5f12bad6/backports_zstd-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f02ab91901b637fae5d27cc26f02874db3e5f98af481afafb86d6487a4287897", size = 435750, upload-time = "2025-11-23T12:49:03.092Z" },
-    { url = "https://files.pythonhosted.org/packages/ae/9a/f064362e44419625b79e049dc532c7b7606bd072f230d2729460cf4f5da8/backports_zstd-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5805a215a3b048a10ca18dd5c525c737e004e59c92c21c44baa0c13083579dc1", size = 362145, upload-time = "2025-11-23T12:49:04.823Z" },
-    { url = "https://files.pythonhosted.org/packages/69/c7/e163febeb3504a00f3a7625d40a2d1a120298762393caebe618e96c48594/backports_zstd-1.1.0-cp310-cp310-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:777ff9a60664abfa7e5cbcb676ecbedf49bd567d6184e538b9dee09d4bbee292", size = 506045, upload-time = "2025-11-23T12:49:05.951Z" },
-    { url = "https://files.pythonhosted.org/packages/aa/a9/d28aa8f16a9fafd8e15220f3ac32fcd000589088f45c80df7f45839503cc/backports_zstd-1.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27a40d9518019a6b6ad2df5f6c2dd6ce627af9396c929556188a67607ce12d57", size = 475659, upload-time = "2025-11-23T12:49:07.463Z" },
-    { url = "https://files.pythonhosted.org/packages/a3/94/9c9b2aa30d34e83f244057c6bf7b2a493c7d60df1caa999160bf83b5a525/backports_zstd-1.1.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a24e73d5d4b3c1b9c693f07081703db9e9398ce95576f1ed74892d6bd01adcb4", size = 581286, upload-time = "2025-11-23T12:49:09.095Z" },
-    { url = "https://files.pythonhosted.org/packages/78/6e/09f21da99977d3b220c8a4642fa1218b2b5d854fb2f00eb22dc38b02be3e/backports_zstd-1.1.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:097ea6090dfb60f4af3c09d816c6d64175bd94ead930e5089acd00ea2e5b8de8", size = 640931, upload-time = "2025-11-23T12:49:10.341Z" },
-    { url = "https://files.pythonhosted.org/packages/42/cb/d765b8f70e86e368d05632572e7eec3dd27d6bfb61c9c7867b3375b3f19e/backports_zstd-1.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0495547f5b727d798ff317b6cc6158655926b7149739ab9a193e184d65e4bc8f", size = 491149, upload-time = "2025-11-23T12:49:11.524Z" },
-    { url = "https://files.pythonhosted.org/packages/f2/1f/6ad1c8af282dc6ad464ff58ecfb29abaeeae6f745c45e5500723f8a0c1e2/backports_zstd-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:544494f7f1ba88f6500a5e14219b19718cc2aa4bcc563ce78d67aef3b8e54ed5", size = 481607, upload-time = "2025-11-23T12:49:12.659Z" },
-    { url = "https://files.pythonhosted.org/packages/d8/0a/6f82529599e92af47bd483bf3c318bd14c01e5a00b9a736d9bc7ab1db3b0/backports_zstd-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:559fe9384dbd43cdacc2b4aa7e19199f064da7aec947c6461d4a7aadfb614568", size = 509552, upload-time = "2025-11-23T12:49:14.166Z" },
-    { url = "https://files.pythonhosted.org/packages/39/5a/87e4be4c18c920122949d45a9de7e253084af22ae50b3c0773e4d58aa30a/backports_zstd-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6e7ffa9747051fd994f8070aefc8317af3ce485d9dbd175593c6df9d795d24ff", size = 585650, upload-time = "2025-11-23T12:49:15.379Z" },
-    { url = "https://files.pythonhosted.org/packages/a4/4c/4afff28eb575631882d564b6c8b93f4d43e53f99c62ceb03f51b15400f9a/backports_zstd-1.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:27858ea429914fc67446112fd7797e821d18e7ce3d6cfa7b2e124547c6a4ca83", size = 631508, upload-time = "2025-11-23T12:49:16.89Z" },
-    { url = "https://files.pythonhosted.org/packages/d0/8d/f2564d8fe96398bc15ccd4db605d448a8dc4d6dc4e1e3bc613c6f2306b87/backports_zstd-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:233f35525940b5153223909a4c9f554e27ae7f5bff5c946b9fe28b633cdd463a", size = 495209, upload-time = "2025-11-23T12:49:18.083Z" },
-    { url = "https://files.pythonhosted.org/packages/36/47/9eb4a27599af4501a79d9d80d6616a18b8cdf52683b1c711d403d247f6a2/backports_zstd-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be5723019ba1500cf727a6ba37a15e697a63f66314e3e7def52fd86c65249236", size = 288660, upload-time = "2025-11-23T12:49:19.553Z" },
-    { url = "https://files.pythonhosted.org/packages/f1/e8/e3f70c4835338167d7039152b8cb1c4adae8c14fed7a184f2d860b0bb952/backports_zstd-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:c28905252c4273e7097baad10ca786ff8e5ab67807f428504c4fe3cbdecb135e", size = 313570, upload-time = "2025-11-23T12:49:20.706Z" },
-    { url = "https://files.pythonhosted.org/packages/bc/bf/12f84454d23cd32a649adbc49983fed13ae2f60a75a6461e9db6e435d856/backports_zstd-1.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:bd2e69a69524161e20cad8245dcbacd9b825f83221c55b05bca0e506b7abddfd", size = 288773, upload-time = "2025-11-23T12:49:22.226Z" },
-    { url = "https://files.pythonhosted.org/packages/73/81/47935ce4c225681a2a962c69cdc061f721bc02c6b2d9806d0ba4d29a1454/backports_zstd-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8b1f9ea3d2d3638af80fcd896dceba7ad5d902ce3e5b411a9b16e4cddd79c4ac", size = 435751, upload-time = "2025-11-23T12:49:23.738Z" },
-    { url = "https://files.pythonhosted.org/packages/c1/36/85f89ea19338e7babfb91147ad3f4022c736c0bcbc1ebf83c90550f2722c/backports_zstd-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bfa36e208619fd152c20bd6c9d0febcb18ac90bdd811421c6a01e450f4b1dd6d", size = 362143, upload-time = "2025-11-23T12:49:25.245Z" },
-    { url = "https://files.pythonhosted.org/packages/6c/4f/f722122cbd44331245c674c9d3dac91df135d491348de7da5010980d346d/backports_zstd-1.1.0-cp311-cp311-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:9f43275263cfbd2e9096a8b333d15c2e96deb0a2df3751b15408155a03c57fab", size = 506044, upload-time = "2025-11-23T12:49:26.423Z" },
-    { url = "https://files.pythonhosted.org/packages/e6/10/41d5088c35bbbd03a07e0f315566e06f915b0371700f568e8c3b26c68b40/backports_zstd-1.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b1c6ae75c09f211b4f5439b0984bfb8b8d15975585e50b1dc658e9f9b94bd305", size = 475657, upload-time = "2025-11-23T12:49:28.056Z" },
-    { url = "https://files.pythonhosted.org/packages/d1/14/324476e8eef484779c390d0b9c83b7906c883ae82b7de4651a86463fbb71/backports_zstd-1.1.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2d38c6df19d5b828cb3d1c1ab62a2c61dd433ad00523d577e303f4552fa002b0", size = 581283, upload-time = "2025-11-23T12:49:29.536Z" },
-    { url = "https://files.pythonhosted.org/packages/bd/01/4f61e96f52dd391834dd457ee970b57d2818609677a786f94840da359f02/backports_zstd-1.1.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:64d5c359a04c26a36eaad82386a873ff1af9e12f896af4748cff1f35e2550af3", size = 640975, upload-time = "2025-11-23T12:49:30.916Z" },
-    { url = "https://files.pythonhosted.org/packages/57/79/69b97eea66a26f52975ae78d7413ca79efee51d2349a33ddfef9b196302c/backports_zstd-1.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:773cec5a3ff8c81e03f3db0c7df1d2f7c3cf820262138ec752c46fd25b532e85", size = 491188, upload-time = "2025-11-23T12:49:32.134Z" },
-    { url = "https://files.pythonhosted.org/packages/9d/4d/5d402a41c29121f387be38e3a507ba6c3d9c5304356f659beba8bcdadf80/backports_zstd-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:be97026835fb5cf0cb96e8c1c6ee72e53816f0ff34c368546ea6e53962476216", size = 481610, upload-time = "2025-11-23T12:49:33.331Z" },
-    { url = "https://files.pythonhosted.org/packages/85/9d/25dceef8e97fb815259b3c946236ff6e696bb5f461faa8303dca5d98e4e8/backports_zstd-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6fb2b381a404040c9dbfd258f3bcd740595e2aca088d822fb241942440fce509", size = 509555, upload-time = "2025-11-23T12:49:34.675Z" },
-    { url = "https://files.pythonhosted.org/packages/bd/74/fb0883e9dcc6333f33f3f90e1101498800b82b6437cfa110244c59d6a03e/backports_zstd-1.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:adac539e6fbcf72d70cd9f354ab5689e080b8621b4d268f2ba0f486c25dfd3f3", size = 585639, upload-time = "2025-11-23T12:49:36.033Z" },
-    { url = "https://files.pythonhosted.org/packages/88/ad/6db9224a34d0ef6ce553c9605649a522b485efc0aa098b1c78b4bcdaad5a/backports_zstd-1.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4298631dc91b4dafc20b6a7eb7edb028c341bc2e3b77a128c7ced5148aaa215c", size = 631550, upload-time = "2025-11-23T12:49:37.543Z" },
-    { url = "https://files.pythonhosted.org/packages/87/a5/383d1d9b2281854b2809b83ec6dfe9092f3a8b9700055340176b29230b1c/backports_zstd-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62451464559525ff093f7d684bf88381722d7b3759693ea842e94b41c01f306b", size = 495212, upload-time = "2025-11-23T12:49:38.814Z" },
-    { url = "https://files.pythonhosted.org/packages/cd/75/305ac0bf93de4a771d33926e27da401a807294c3858b133d3611d0b6be49/backports_zstd-1.1.0-cp311-cp311-win32.whl", hash = "sha256:b20309c15d4afa2919517669366da60dd30955dbc0784924ae79acb49f158ef6", size = 288753, upload-time = "2025-11-23T12:49:39.972Z" },
-    { url = "https://files.pythonhosted.org/packages/50/f3/8887a706bef88307a55719b4d0cf73600c6703e3cfb5926f97441c8ffc3b/backports_zstd-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:9e3df9c43e9f4ed970cd8f48df41736c5697fed06523e463661788762c95d454", size = 313698, upload-time = "2025-11-23T12:49:41.202Z" },
-    { url = "https://files.pythonhosted.org/packages/3c/ea/78f627df9b3765ac7036da11951db7c91eb77e6014f8819dbf575dc57f8e/backports_zstd-1.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:b5c43022248bd8711f606a481547dbcf4541b617446a07a359aad28ebf77973b", size = 288897, upload-time = "2025-11-23T12:49:42.306Z" },
-    { url = "https://files.pythonhosted.org/packages/48/98/1426b121772c4f05735ad7c9542dd333c18720179a549dd2e22e6be386df/backports_zstd-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:63e1ba127129c7c4786147f873eef63f90694a13c5459ca0e970cad1bd52cf6c", size = 436062, upload-time = "2025-11-23T12:49:43.409Z" },
-    { url = "https://files.pythonhosted.org/packages/4b/01/c851ce0cbe2611ce33232ecaa21f237b9b3c52964f01c9e96cabc7f60b0f/backports_zstd-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37b30c0fb5d118344706ed9e26cb2f43584c0012565254a819485bab180f1652", size = 362213, upload-time = "2025-11-23T12:49:44.886Z" },
-    { url = "https://files.pythonhosted.org/packages/af/c0/99596faafe038ba03695569adf0ec1f4e3f955c3156618b0f11deb3b9905/backports_zstd-1.1.0-cp312-cp312-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:b8b77fae55a245e5b61fc599b641343da2580ebc9fcb20a77822dcca9126bddc", size = 506466, upload-time = "2025-11-23T12:49:46.085Z" },
-    { url = "https://files.pythonhosted.org/packages/eb/84/b6410324c8f495bd6fd1c8ab8b3fbb70120ea2b06ee004db4549e0eb58b0/backports_zstd-1.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34c9c425d113071c90a241f04fb12be46c83e7028a090aca4e72fe9f5fe11fb6", size = 476287, upload-time = "2025-11-23T12:49:47.327Z" },
-    { url = "https://files.pythonhosted.org/packages/c1/7a/280f37869fb37dc16d2ca093734a6cac564a551d7fad8b55d0807d19f74c/backports_zstd-1.1.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33a7c9c2bd44b5bbfba2c78411feb2e0074406654f33e6b0317e307710c7fe57", size = 581744, upload-time = "2025-11-23T12:49:48.907Z" },
-    { url = "https://files.pythonhosted.org/packages/72/32/828ce97c1c18d3735ca42b65819241702df101cfd13a4b88bd77ca1f03bd/backports_zstd-1.1.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3baf8b13aa90ed5a03503063be670d8cca22d5d81aab4cc499741f013dba4351", size = 640474, upload-time = "2025-11-23T12:49:50.184Z" },
-    { url = "https://files.pythonhosted.org/packages/06/ad/5ba858ffc307ed2b51693d87642f9e9dd6013579840981ac364c6e24c38c/backports_zstd-1.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fe522558c4d56d9eb2294592fec5ac94b95c82ff22cf1f91d1bf589fe567f391", size = 494260, upload-time = "2025-11-23T12:49:51.765Z" },
-    { url = "https://files.pythonhosted.org/packages/fc/4c/3b2f67ae51d19716af5d9bd2c074b9a5ba03a7f6ef4c509adaee3e1f6958/backports_zstd-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4f459c3b43d382aa2ab44199b84ec86a33f79094701bd3bbf536d4b6e687e744", size = 482320, upload-time = "2025-11-23T12:49:52.943Z" },
-    { url = "https://files.pythonhosted.org/packages/c9/e0/05f1d8a8552254ab4ed447ad2950c079f15bd2c74125a8a15fa9f0eb28ef/backports_zstd-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b53841a136c326686d49f1b2b96dc5acdffb2e8e422a5298f36b95a7d927b69a", size = 509894, upload-time = "2025-11-23T12:49:54.149Z" },
-    { url = "https://files.pythonhosted.org/packages/62/0d/15dc13edf653ba14f61f9ce0a4119f79647750a9525659b410be124b5d71/backports_zstd-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d64a172db16fa5e3aed875776537103cae0f2dd0e614c9658fce62ebd5211847", size = 586126, upload-time = "2025-11-23T12:49:55.363Z" },
-    { url = "https://files.pythonhosted.org/packages/e8/c9/9ece6a0c684223e466188d7e8db74462075391f43be244f46ef46ce1f07a/backports_zstd-1.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:de5d7cdea31085b3d21c7f670f385ec666b8595c72c107efa50e29f3cc4e72a1", size = 630934, upload-time = "2025-11-23T12:49:57.115Z" },
-    { url = "https://files.pythonhosted.org/packages/d9/da/9c704e8f11cc4cb17adae9693d97903fe9dc5ea7e8182d044c00cf70fb1d/backports_zstd-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8dc11ddef5529aff9fa18565a0f2a98f9f5cff83751e4357c219ae20c160bc1f", size = 498755, upload-time = "2025-11-23T12:49:58.313Z" },
-    { url = "https://files.pythonhosted.org/packages/45/ac/843bc205463fce6aff56d2d6f8733635b0c8786c22d148978ecfed97645f/backports_zstd-1.1.0-cp312-cp312-win32.whl", hash = "sha256:8e0376da95159b39f538b6d7edafc211f4b9e7f5581ad4b2476b0f3c890bb25f", size = 288892, upload-time = "2025-11-23T12:49:59.569Z" },
-    { url = "https://files.pythonhosted.org/packages/43/aa/dbee1f51bf3af6017e1b48b93edf9c60f74a57c7d34940a728789365355e/backports_zstd-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:8067a95f560c503d683b9e18de44749eefe0a4ad6da318ff9eabb4afe47e79c5", size = 313910, upload-time = "2025-11-23T12:50:00.678Z" },
-    { url = "https://files.pythonhosted.org/packages/66/8f/cc99ca99a2e37a9a9f3c6053cd0a7bd255c465be24d1d931fe062dca55bd/backports_zstd-1.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:f8f2a975dd25b4b3ac901ce47d04881d43dcde18037d2d1513b8a5f4fededdd8", size = 289014, upload-time = "2025-11-23T12:50:02.226Z" },
-    { url = "https://files.pythonhosted.org/packages/bb/35/2a50f48bd16a4677b1f17f0ab0d173f9225114100326e67fdd65b74f9586/backports_zstd-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a18668f1373fe9e5e0349e3fe5cc8148cbef29eccbb9998993eeb0e90d35638", size = 435551, upload-time = "2025-11-23T12:50:03.881Z" },
-    { url = "https://files.pythonhosted.org/packages/0e/ee/10ddf48f87fe8aeedd4dca1a18061159eab006ede693ede00ba80946ba3a/backports_zstd-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3adf32f6e58323505c581a4d1e5b6404e98806c4cf01c54049c372642cf7ec6d", size = 361827, upload-time = "2025-11-23T12:50:04.999Z" },
-    { url = "https://files.pythonhosted.org/packages/4c/56/5d98bd5a7b0a5d203f705f3200b467af6a6d34fa6d9aa2b9c9538369dae8/backports_zstd-1.1.0-cp313-cp313-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:b71f45d12274021e1d7b689ac98faff94874cf6c7bac2f0ab14a3714d4047a6c", size = 505739, upload-time = "2025-11-23T12:50:06.496Z" },
-    { url = "https://files.pythonhosted.org/packages/22/16/5a3967e957fc5662eaaeca4ace5eb0646d1e174e70d149fe023092165047/backports_zstd-1.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd98ea2600335bd941bba347e168462c37a5ed1bdc21cbee2dce82871c3719b3", size = 475946, upload-time = "2025-11-23T12:50:07.737Z" },
-    { url = "https://files.pythonhosted.org/packages/7d/f6/71c99d08987df24e09b93fde4a2d3aeee8075563374be88572a1f265f9a5/backports_zstd-1.1.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83143a2a381d95276a8df5f0b6231f936595d3aeb15a55f91831a111d78297f4", size = 581425, upload-time = "2025-11-23T12:50:09.091Z" },
-    { url = "https://files.pythonhosted.org/packages/79/a8/8788b74b53961b3d3dfb08eb4632d07c846afbc2f677752d9f2ae0d6b843/backports_zstd-1.1.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7caf0d5c2954eea1c160922207afd87cd83cef7f5081b5a7b12d4a646a78c1a2", size = 642271, upload-time = "2025-11-23T12:50:10.329Z" },
-    { url = "https://files.pythonhosted.org/packages/f1/08/211d882fb5fcee5014bac84c64acf4c6f5c6df3a10e3bb5ed20409b5e54c/backports_zstd-1.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:222fb59203bb7c8104d049c587cd60bee6e8c1cd6d34c4a87158b8393dc8113a", size = 490893, upload-time = "2025-11-23T12:50:11.623Z" },
-    { url = "https://files.pythonhosted.org/packages/7c/8b/8a2625657cc9965c62a56fb2d97ad4cdd31e8cbdb6aad493375c337ac3fe/backports_zstd-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d74065d6b151443b25f3005ae96dac1d896ce616c56595c18c7dfbea77b73a5a", size = 481704, upload-time = "2025-11-23T12:50:12.896Z" },
-    { url = "https://files.pythonhosted.org/packages/56/ba/f3b225722e3f1544a1c8cdedc92a35650f6b4ce0ee1444db949240c40efa/backports_zstd-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bf5aa4431001eca56bac39e22e9c814075008d9be7317271e5f8bff21533086d", size = 509295, upload-time = "2025-11-23T12:50:14.409Z" },
-    { url = "https://files.pythonhosted.org/packages/93/0e/2f1335f7cf06de3140612ac72bb0735c4d8e973f15678f5e62ba752a16b0/backports_zstd-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c21cbeeba96d4b15e42ace21fd71f0bf2c431247ce66e82409c0f45dc7d7b4b", size = 585856, upload-time = "2025-11-23T12:50:15.595Z" },
-    { url = "https://files.pythonhosted.org/packages/ac/6d/0001f8c654672d5ac309f315919b4d0be26c1687b46b2c9438bff4d16895/backports_zstd-1.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:79ab438599cedf19cce056147a26c64167bf83d05609b4481ffadf9330a322cf", size = 632636, upload-time = "2025-11-23T12:50:16.855Z" },
-    { url = "https://files.pythonhosted.org/packages/6f/9a/5f1835d53ce4b66e445aeca019c516c3989d74269e96c58295b8cd629421/backports_zstd-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a8389d1edc351af4c5e6cef9fcd41f0795d7e639becfb0f331cec67aef3eefa3", size = 495191, upload-time = "2025-11-23T12:50:19.015Z" },
-    { url = "https://files.pythonhosted.org/packages/6b/f0/82b912cd9bec18cec86466300372ad2913febe4c7066eb6a6721eada9777/backports_zstd-1.1.0-cp313-cp313-win32.whl", hash = "sha256:f862567e43a989be9c0d1a04c9d3068a8544a1a48c908635ecaffcb896f2c1b1", size = 288529, upload-time = "2025-11-23T12:50:20.234Z" },
-    { url = "https://files.pythonhosted.org/packages/d7/07/182dc5e7c17206fc07f30c3786317fa82f18b124f037a5b8dbb73457a341/backports_zstd-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:2e93b0a04f624ebe5b4301ec4997b353db561b82e7e21b42c84c8b30c53218a8", size = 313745, upload-time = "2025-11-23T12:50:21.845Z" },
-    { url = "https://files.pythonhosted.org/packages/d3/f7/3418b0e3c15865c24fc390d57e33e141ea8f7347876e4a1feb2942e5abc7/backports_zstd-1.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:47ed787d85ea29776bc7a54825dd2bd6431a1497bb120d843f4dbacabb4f0d65", size = 288762, upload-time = "2025-11-23T12:50:23.114Z" },
-    { url = "https://files.pythonhosted.org/packages/c8/7c/7f62db771263bf5596489c2a5574278ebf4095980f6ee01305b7989ca78e/backports_zstd-1.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:01e488a5f1b008643a375936b655f383e92bd02b6b7830c4f4489eb9ede2661d", size = 436239, upload-time = "2025-11-23T12:50:24.651Z" },
-    { url = "https://files.pythonhosted.org/packages/bd/1b/b336683e6e470ddc4f3665588327cef4c96da876469ad3640e3af6d0c502/backports_zstd-1.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:feef6c896d58f93e8fb9c900eb5b0813580a3a689a7bab53a82d7980599952bb", size = 362524, upload-time = "2025-11-23T12:50:25.892Z" },
-    { url = "https://files.pythonhosted.org/packages/a0/23/e0497e863e37f7c659ee5037a743809d82270b84090fa4c7d3564312d4d4/backports_zstd-1.1.0-cp313-cp313t-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:91c741b17240469f414786051dadc24372a2270c7664908159d19075a6e58455", size = 507685, upload-time = "2025-11-23T12:50:27.497Z" },
-    { url = "https://files.pythonhosted.org/packages/be/cc/fa3d8656e0202030304c7d9de8da3e02157812ab04a5d726314073b04e61/backports_zstd-1.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef36d898fc5b592b9822a1b2c90d41c3fc4b684579ef558e6b08b53a747ee542", size = 475585, upload-time = "2025-11-23T12:50:28.834Z" },
-    { url = "https://files.pythonhosted.org/packages/6c/21/c6effc30caef1dd8db49a962e554601f1ea5782218f38e16013f719a5711/backports_zstd-1.1.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:37cc049f855654f76fd145c32f3818848848c0128940f2e0a2e0f5597e3658a9", size = 581008, upload-time = "2025-11-23T12:50:30.052Z" },
-    { url = "https://files.pythonhosted.org/packages/18/d2/bf2f74d68fde7884295138fe0ac8049031d8061346c395a61ebc256dd470/backports_zstd-1.1.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d30414d5d15ff358a1cbb88b293a108a2eebaed6ccf034176e2a4ffcc80672df", size = 639999, upload-time = "2025-11-23T12:50:31.29Z" },
-    { url = "https://files.pythonhosted.org/packages/e9/63/ea63603b691c54a6af0259b4c74c218cc9ba14985bd18ecd629d735c81ec/backports_zstd-1.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:747c341023725ea83e5ab874325e85dc89d9008626bbbc329c40426bedd03ecb", size = 494888, upload-time = "2025-11-23T12:50:32.627Z" },
-    { url = "https://files.pythonhosted.org/packages/55/c0/0a33c6036f8350954cb9f99363710c4e6589ba72e38dfe181a117c983fc2/backports_zstd-1.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:05b5d4f23b22f67b64825537e9c4d2e6a38914e924794803ee2c4f7a9715b46d", size = 482069, upload-time = "2025-11-23T12:50:33.862Z" },
-    { url = "https://files.pythonhosted.org/packages/dc/40/4a955634f174f569aa8a03433148818528736ec66d5baa4bce2f535899ad/backports_zstd-1.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:284d91e68e67ee7b8d2c58f26032bb15e4ed6ec9f2b95121af0b9c260741e497", size = 511445, upload-time = "2025-11-23T12:50:35.09Z" },
-    { url = "https://files.pythonhosted.org/packages/19/bf/8d99e2fb714e908b0282a432f9216968db46ed5b6ec42bdc9df5b0ffbea9/backports_zstd-1.1.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:9eb74ca6f9afa8d92eb268dff951d901ef3366a240ca358d1503da9a4355eab5", size = 585581, upload-time = "2025-11-23T12:50:36.745Z" },
-    { url = "https://files.pythonhosted.org/packages/14/9f/768d64b30e80b32e262393caf2784f5fd43b45e6ab8e2a44c146a550c607/backports_zstd-1.1.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:b3bef8f715a4f8135709846179fb748d4ec5619282a8858cdeaf90ab9a3c1cd9", size = 630606, upload-time = "2025-11-23T12:50:37.937Z" },
-    { url = "https://files.pythonhosted.org/packages/cd/69/41c3f1d2f97cb156e689e36f3ff8ddb9b1140f667394ce0b3d51f0a96012/backports_zstd-1.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:aba8cb745d48e66d5e9f007cbf6871e3a227b2812a81c99916de3f8edc2cfaa1", size = 499515, upload-time = "2025-11-23T12:50:39.16Z" },
-    { url = "https://files.pythonhosted.org/packages/68/92/bb10b678aa8038172047adfd748b73b410c34aa8fefac4768128d79dbc2d/backports_zstd-1.1.0-cp313-cp313t-win32.whl", hash = "sha256:d13e6406a50051f2bdd5047dc68e79e398c4d4bf65de910a1cd02e2d93f6d346", size = 289476, upload-time = "2025-11-23T12:50:40.365Z" },
-    { url = "https://files.pythonhosted.org/packages/b6/75/f1763f8f1cee20b2a836c1aa27a545cb1ae053bc1e282716f5062b9f6169/backports_zstd-1.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:029388257045a1bd091407ed4359899bb07ddac786ebd240ce6985b82da5729b", size = 314843, upload-time = "2025-11-23T12:50:41.519Z" },
-    { url = "https://files.pythonhosted.org/packages/44/18/43e36a5a0313a932827ef7b601e673cfec64838458cbb44c452604ac71cc/backports_zstd-1.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:e005d77a72ba6cd1ad85f46dbc0620922e7b46cb90235c4874d16ab1839b4994", size = 289399, upload-time = "2025-11-23T12:50:42.629Z" },
-    { url = "https://files.pythonhosted.org/packages/6a/80/c08720ce3d7c446b5f91c2c894e677b673d87c4e9c7dd6f5c36303baaee8/backports_zstd-1.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4d379e9c157e4b18df8852defe1d5da8888ba8ffb4d7d9410428b3245cf8216a", size = 409859, upload-time = "2025-11-23T12:51:04.504Z" },
-    { url = "https://files.pythonhosted.org/packages/8f/f1/6220850b09a52cb07854d098307d71d9b330f4d9b49c2fda86c960c7df00/backports_zstd-1.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:79b29d1c66f9bd2bedb87551b303e53f96364a641d30251e9f4e15bf5d84699e", size = 339376, upload-time = "2025-11-23T12:51:05.677Z" },
-    { url = "https://files.pythonhosted.org/packages/90/bf/0e6dfe1467dc228916a1715fc75421bafbb5dec4cf306c2395e45d8ef589/backports_zstd-1.1.0-pp310-pypy310_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:154870d0e0f817159671ffc8b0e39d70ca294542affe6df00d95ef135a2ceef5", size = 420422, upload-time = "2025-11-23T12:51:06.934Z" },
-    { url = "https://files.pythonhosted.org/packages/68/9b/85dc1f5dc66c22f691bb60ec739e4be17c53dc670dcfabdf16ff194aec44/backports_zstd-1.1.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f174d8c93bd2682932ecb736e8f03612c162ec6a182c4293a663165f8ffbf5a", size = 393966, upload-time = "2025-11-23T12:51:08.247Z" },
-    { url = "https://files.pythonhosted.org/packages/b6/23/1a375ea5e1e50741b80f9882c45a13c3b1b051985ae40eae44a34aa4e9e4/backports_zstd-1.1.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b1bf548087476e6ce997c2697072c67193b07e5a36d4eede2b582e7bc7324c2d", size = 413928, upload-time = "2025-11-23T12:51:09.353Z" },
-    { url = "https://files.pythonhosted.org/packages/3d/e0/687326aa8026b28251651add1e87931edbb0bc5bf563776cca6f81f35987/backports_zstd-1.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2a278c276e722399fbc769d1ae318a58578e20086bd09abcffe9af4b1daaf50c", size = 299788, upload-time = "2025-11-23T12:51:10.852Z" },
-    { url = "https://files.pythonhosted.org/packages/f7/16/ce8d770a7129540520261694b0e83ec61684ab734f671e4eff652c040a9f/backports_zstd-1.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:06cef3f3b690221fd55d95cfb0316b914ce72063b99578b309205c9f73ce0bab", size = 409754, upload-time = "2025-11-23T12:51:12.084Z" },
-    { url = "https://files.pythonhosted.org/packages/ef/c3/cbfdd61516d0a8448ad9194e34ffd434ac735ed1a89257f77407dbdbe0f1/backports_zstd-1.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:55446414f5deda38a4b8de22a0f3f93bacc1a8c4fe2205a0bace0dc55dbf9c90", size = 339289, upload-time = "2025-11-23T12:51:13.407Z" },
-    { url = "https://files.pythonhosted.org/packages/97/7f/5e65b583abf56f7e3c54835a707cdd159e47b73f4b8548082debc630baae/backports_zstd-1.1.0-pp311-pypy311_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f1524c54ec491d80068598ba4328b82c403b99a04c0db6326a5cc8f05565de87", size = 420422, upload-time = "2025-11-23T12:51:14.553Z" },
-    { url = "https://files.pythonhosted.org/packages/52/76/14349136c395f94fbd2af663301c2d661da9109fdf74692fe5095808cb9d/backports_zstd-1.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbcbb091fede530d096e32f3409056c59dc7b5e6cc9bf39131c7961eaaf8f475", size = 393965, upload-time = "2025-11-23T12:51:15.646Z" },
-    { url = "https://files.pythonhosted.org/packages/c1/5b/fa580166cdf945be0b3ca1dbf8b23bc1370087707fa825b764d7e98b9a3c/backports_zstd-1.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5ac888007be1724efaa565f69ba64ce0c0c0e135d7f22830565399ff76465f1", size = 413929, upload-time = "2025-11-23T12:51:16.75Z" },
-    { url = "https://files.pythonhosted.org/packages/aa/f3/650db1631d75c3f6ad46b09dfee2a761b2678b1e2e0004d90258020801c3/backports_zstd-1.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:08f66e228821a87ba7c74170b6b173cf249eeface98c0951c0da7db680b887d5", size = 299785, upload-time = "2025-11-23T12:51:17.969Z" },
+sdist = { url = "https://files.pythonhosted.org/packages/f4/d8/e8426a2abd7bfdafffcc1be07a23890314f199928515937c8ee7e3537157/backports_zstd-1.2.0.tar.gz", hash = "sha256:6c3fc19342db750b52fde793e4440a93575761b1493bb4a1d3b26033d2bd3452", size = 997263, upload-time = "2025-12-06T20:26:39.595Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/a0/97/01630376854dab8cc6e58819236c46ffc40bc2ad1c5a82b430e0c5b79009/backports_zstd-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:68d70396997cbaaf8e571dee93f05c4cec5053ef14a6e165c26ad4aadca6b7ee", size = 435932, upload-time = "2025-12-06T20:24:08.421Z" },
+    { url = "https://files.pythonhosted.org/packages/6c/62/a06ddca84e3c0ec45e667a02be5c4a157ab5e1e940d65096a80d409f0557/backports_zstd-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8dc2d15224ea683bbf7ad6aa8eacde40972c2c700e8ff72862cb0663e18ae953", size = 362327, upload-time = "2025-12-06T20:24:09.956Z" },
+    { url = "https://files.pythonhosted.org/packages/10/16/1045c674bb09fad1b838098c0b16a88bae9a7bab5e305aac11e55a8c813e/backports_zstd-1.2.0-cp310-cp310-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:7137114011f380f7e8bd97d92664b5bd71ab5f6e08144f22836263ad45273af2", size = 506230, upload-time = "2025-12-06T20:24:11.273Z" },
+    { url = "https://files.pythonhosted.org/packages/32/8d/ef8a8051374a1948d19c9888d2898d7091314448360a803bffc8474bbf58/backports_zstd-1.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb922d2f278ec2e62a29121f98e573f622cefa9408dc0462a0e51ac08bca30b8", size = 475845, upload-time = "2025-12-06T20:24:12.846Z" },
+    { url = "https://files.pythonhosted.org/packages/2c/b9/2c01e970e69f7ea2fa9710373fa4b48d31e677098d04d9b05d01e109feef/backports_zstd-1.2.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b72f4fe1764d53c6f8526d53ef566dcbe71daa81b3219fd802b51a153692159a", size = 581469, upload-time = "2025-12-06T20:24:14.343Z" },
+    { url = "https://files.pythonhosted.org/packages/84/a3/a2780c37d876badb483815239f2cc9bd863123248e20b2290e3f08355b7e/backports_zstd-1.2.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:743feb4e13e0f41a22d257bb5d2d4323f0308ecfedfd53db69172e2d9c3e4ba8", size = 641118, upload-time = "2025-12-06T20:24:16.024Z" },
+    { url = "https://files.pythonhosted.org/packages/92/88/5f40f9ead71dfb234fb7ab3c7949f2c0aa52eaed3f75115e4e7cfb5528f4/backports_zstd-1.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:199c41106c05bf12cb665a1d105ce2185da5e190e13b95933420d6fd9cd8bb10", size = 491335, upload-time = "2025-12-06T20:24:17.565Z" },
+    { url = "https://files.pythonhosted.org/packages/e9/e2/4fd0071eb6035d6a412f6c5c2802ebacdbb845569dbb7a1e723c13cc1742/backports_zstd-1.2.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:270f10d14852fd11f85e1199f59fcb9dbcb425d489c678e5b0ea669c091b1cf3", size = 565341, upload-time = "2025-12-06T20:24:18.705Z" },
+    { url = "https://files.pythonhosted.org/packages/fd/ef/b40a17346294c892d93fa738f48fc145432fa4ff265cf2d1ab3c177f10b1/backports_zstd-1.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c276433f6bbe67a8c71fa78bbfe1d7859ee17f799e6fcff9ac250840e38608d4", size = 481792, upload-time = "2025-12-06T20:24:19.948Z" },
+    { url = "https://files.pythonhosted.org/packages/ee/24/7e0d77b17a3ae899a0c3f5ed9be842a8e6134577ea3411d8ff0e3962764d/backports_zstd-1.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:772ad9b56a546fde9c1636dcf525d727330b11c6e34c9af8f879f23b41a8054e", size = 509736, upload-time = "2025-12-06T20:24:21.263Z" },
+    { url = "https://files.pythonhosted.org/packages/b3/2a/99f7d247b974de0e5238796e85ba29e49c285a2d8a51c3b6f5b8abd4cd93/backports_zstd-1.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f7fd5d7c8c1c7b26b52b49bf3e392c3c6295658a34a887c587044b37a0b68a3c", size = 585835, upload-time = "2025-12-06T20:24:22.835Z" },
+    { url = "https://files.pythonhosted.org/packages/47/d9/0eabba1630f4b0674ce6ae79793e8901b0cdb28c83a484b424df29ed66dc/backports_zstd-1.2.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:18b510dd03a2b7cdda62744802d8c43df7f027f578c4e67f6fa7208d8691db84", size = 563163, upload-time = "2025-12-06T20:24:24.35Z" },
+    { url = "https://files.pythonhosted.org/packages/5e/67/cc1cd5cbb8982ca156393b8b50698b86efdd0245ba56f3b3b539950061c6/backports_zstd-1.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:26301adc3008c2de40fedf780deb2bceb79471ea89efba37d30768871313f673", size = 631693, upload-time = "2025-12-06T20:24:26.166Z" },
+    { url = "https://files.pythonhosted.org/packages/fb/19/01d30f83e87ae4890297f0d2422eb2fad0679c48eb65de8f2c8e131a9345/backports_zstd-1.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9dc4c9cf3804e6b6cc5aa9aedc63cf81551cc4f6150ea4b248b95de84051317d", size = 495392, upload-time = "2025-12-06T20:24:27.424Z" },
+    { url = "https://files.pythonhosted.org/packages/06/5e/4fb7553901245637ae70d934f5ae719be7207aea3243b254a19f5947b554/backports_zstd-1.2.0-cp310-cp310-win32.whl", hash = "sha256:e456426bf45dd8d818df5ce6b81faaf3961ef8b16834e91cbe2b739346abe9fb", size = 288844, upload-time = "2025-12-06T20:24:28.563Z" },
+    { url = "https://files.pythonhosted.org/packages/dd/64/9f8a05ff703f5bdc2b2c9c8e5797299eb2cf4791226a46b2e14489784b4a/backports_zstd-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cf6e2cbe1e637a834e1920ded11e423897a9822d17a0be9486d3f63554f51618", size = 313759, upload-time = "2025-12-06T20:24:29.665Z" },
+    { url = "https://files.pythonhosted.org/packages/c4/e7/cc45af33a4e4aee365ab76c3f4fcadf984fea221563c2c29c5613cffeaa9/backports_zstd-1.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:4d50bd23c4520e1ccd60af59f8aadc43ce3a481f2793afe01c18a7aa6a518892", size = 288960, upload-time = "2025-12-06T20:24:30.819Z" },
+    { url = "https://files.pythonhosted.org/packages/b8/40/f914ee5a00c1f5df9a162efd7130db7ab339b838e6b1613eb2ed7f0594a2/backports_zstd-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b47ed63b1c04e06981ac552d107945752d1ffecae98a4bce9c8a627490ce460d", size = 435933, upload-time = "2025-12-06T20:24:31.903Z" },
+    { url = "https://files.pythonhosted.org/packages/36/5b/f03eeaee5b17cf88d9f252381f5b8573b1a1c958787af68e9d287c65086a/backports_zstd-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4e6433f889edb998abe33f3498c37ddd97b3ce3607eebbc0fed148f8c7c7f2ef", size = 362324, upload-time = "2025-12-06T20:24:33.186Z" },
+    { url = "https://files.pythonhosted.org/packages/f8/78/369773911bd9968ca5f4e10ee4232ab6b71cbe45d6e17c78d3399e4a3944/backports_zstd-1.2.0-cp311-cp311-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:4cd00e5bfd6d17233809f08d979742a5b9c322162d8daea16f7c3538387b9c64", size = 506229, upload-time = "2025-12-06T20:24:34.364Z" },
+    { url = "https://files.pythonhosted.org/packages/19/da/f23872cd114b5352c97bf83a2082427aa08bd22f42461309c23783e82da5/backports_zstd-1.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8c7239b457f4d51c03634edb0c9b2ebdffc6806f58c0396209f5eb7f8d7642e", size = 475842, upload-time = "2025-12-06T20:24:36.079Z" },
+    { url = "https://files.pythonhosted.org/packages/4d/ea/07b6ee0956b522e6a8e0aca97d7b28ed0dc72a7c35a5b77485d2b8d7c4dc/backports_zstd-1.2.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75c35e5292d5c5fa879ce3f40428fdb510b11a98801ccf1140690ed7a9c13b3d", size = 581467, upload-time = "2025-12-06T20:24:37.735Z" },
+    { url = "https://files.pythonhosted.org/packages/bc/ea/ce04fed217a484ad9f3e8e087dd29c198dbfcb2d4d2c216d044a2a18aea8/backports_zstd-1.2.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:153e1af06e348f5ed1b104c345880c001824a192536940a8d012d33014b27ecf", size = 641159, upload-time = "2025-12-06T20:24:38.967Z" },
+    { url = "https://files.pythonhosted.org/packages/96/8f/b28147869bb8aba7a0b30f05cfec567d90002c4161dabb8315f002709ee3/backports_zstd-1.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf700fd79758417b1c0b725a56fa485ba15b10ee07ada736ff7e669fddd28b38", size = 491371, upload-time = "2025-12-06T20:24:40.209Z" },
+    { url = "https://files.pythonhosted.org/packages/33/92/26c7f8bee4cb3e6aae08b04351aa5578d30bac2701197ca2e3cb2b785978/backports_zstd-1.2.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b04638b6adf68f730b04b21ac81fb58eef2ea10f6c221aa653f1009c0afcf67b", size = 565341, upload-time = "2025-12-06T20:24:41.551Z" },
+    { url = "https://files.pythonhosted.org/packages/d4/4b/d1595a7d877e67da6ec6d759d08f5dedaca59d4317c6116b19fd9e3c60bd/backports_zstd-1.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:35a445eb01e525ae8dec59fcbabcc373c9ace57f8c10455185038f54a930a039", size = 481793, upload-time = "2025-12-06T20:24:43.036Z" },
+    { url = "https://files.pythonhosted.org/packages/0a/0f/1e1c6a154026bcdd2daecb1abd1d924cb6d274b0f7bae4042f83fb0e97ab/backports_zstd-1.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1923ac203545a18a1b9726f6ae7bed1ab4f8825f0b8f4a32d2795932af3f5322", size = 509738, upload-time = "2025-12-06T20:24:44.427Z" },
+    { url = "https://files.pythonhosted.org/packages/40/7e/09a807f3920fa1fe4ae019275d5978168d94fe8615c5bde3f7969760edb7/backports_zstd-1.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:97d06ec9b5b21fb59cfa5e716ca1c91f3bac2cd2c3b14e21c3d29fa1b2b0baf9", size = 585823, upload-time = "2025-12-06T20:24:46.001Z" },
+    { url = "https://files.pythonhosted.org/packages/aa/14/ef90815a3ad6eabbca59b9cd62013c39acfd38c7cf1f5da31c733520a6d8/backports_zstd-1.2.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:57e773e295e7d56bd67a2f57071b1c978832566d0f908d7d7aabb16f35401810", size = 563165, upload-time = "2025-12-06T20:24:47.132Z" },
+    { url = "https://files.pythonhosted.org/packages/4a/98/8918bb085bb2f333d5785cc67918c65e497674de6d53834c1c42233ddde0/backports_zstd-1.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:157950cfd4ed85e03c2557067867e37090796b556c613badfaefcdf2750e95e1", size = 631734, upload-time = "2025-12-06T20:24:48.309Z" },
+    { url = "https://files.pythonhosted.org/packages/6b/c6/a2e494d412728fc04c7e1f40479bac80c505f9eaeafa8048f764104dbfc8/backports_zstd-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a3450d9cf69d76843ea195c1defeff087b68a8a4a3687f0927f870ab594e062", size = 495397, upload-time = "2025-12-06T20:24:49.516Z" },
+    { url = "https://files.pythonhosted.org/packages/fb/81/f9a762ad3e965324a19574c1aa7b39ac35196bc072534efd34b24bec9786/backports_zstd-1.2.0-cp311-cp311-win32.whl", hash = "sha256:77f0e7e71506e12f99927ddea7ab1de5933d47c9af048d05a229246977d89127", size = 288936, upload-time = "2025-12-06T20:24:50.68Z" },
+    { url = "https://files.pythonhosted.org/packages/21/95/1d699d9bc9a94ad5b8bc06d1a59246a5adce02668e3773a8c29b1f5a7554/backports_zstd-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:84a0b581408efce8624b887326e0b285fc2e5ba32348b9b6e6775f171fd4926b", size = 313884, upload-time = "2025-12-06T20:24:51.772Z" },
+    { url = "https://files.pythonhosted.org/packages/2a/56/74b78b9313af6e330b04ae010a98e1d8cc133254c3c53ae2b5e5f4d5ec83/backports_zstd-1.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:65e7591b20aa803c87a104c0dc9129a984f04adec9b042d88c7a14d1254c9524", size = 289080, upload-time = "2025-12-06T20:24:53.321Z" },
+    { url = "https://files.pythonhosted.org/packages/fb/53/235dcac25478d60c4e58b6f982b91550b60908dbc07ab42405f818f41794/backports_zstd-1.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff2348b69da19243b7148f69fc60753c27b3efe313dfb29dcb642b4b3a064261", size = 436243, upload-time = "2025-12-06T20:24:54.458Z" },
+    { url = "https://files.pythonhosted.org/packages/db/b2/549d1933995ccf4464b29f068f6fdd1e2d9f6abc8ecbcab99dd90d4d28fd/backports_zstd-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f194a3cb53173f8bf8160597d39be16731e576ccf0244e7694e3aeac47e6c85d", size = 362396, upload-time = "2025-12-06T20:24:55.712Z" },
+    { url = "https://files.pythonhosted.org/packages/f2/11/dc21a59734f2ce145a9a7f2d0016987cedf95598a850a3f4ab6ce73ddea0/backports_zstd-1.2.0-cp312-cp312-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:79a18d5d707cd92fc7ce28c4a1a63cfdaf8d19223b3167d2d879042bf1c018ac", size = 506651, upload-time = "2025-12-06T20:24:56.975Z" },
+    { url = "https://files.pythonhosted.org/packages/d5/16/12f84de430428f620a6ced01fd2768d2296951d7543b81d971455f39ef75/backports_zstd-1.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f04bcbb75de26d39de81e7c02a784cb55a706c6ce9665b8df218fa9275193a1a", size = 476474, upload-time = "2025-12-06T20:24:58.136Z" },
+    { url = "https://files.pythonhosted.org/packages/0f/8a/980e349fac1e1ba596f440b24901af498399c6e33b83032abbf22fed7d21/backports_zstd-1.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9c36bbd7cc85629d77f9537ad02bc438b3e3f9f1741a43f1cede1027fd9ebfb5", size = 581930, upload-time = "2025-12-06T20:24:59.605Z" },
+    { url = "https://files.pythonhosted.org/packages/36/f8/cba3372ca8d777cf5c3e312b35112ff608cf6b0b2f6a813b600b69763495/backports_zstd-1.2.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:28828f15a7429a7f7570a1465f9b71ccf7f99ea0a6bf786be7c276777f3cdc14", size = 640659, upload-time = "2025-12-06T20:25:01.164Z" },
+    { url = "https://files.pythonhosted.org/packages/61/59/c8bd0a5a39770cf7c0d864cbb65ac5df57405ee28a51fd5c11a5fbf1a169/backports_zstd-1.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d634cba354a3ca61837e5a8d9a6ee19d9d37927ec288f0828437b2620ae83fb", size = 494445, upload-time = "2025-12-06T20:25:02.867Z" },
+    { url = "https://files.pythonhosted.org/packages/d9/bf/52665f48d449fa1586fb775468e2fa83ebc8e222eb2d18332b3b5f12f933/backports_zstd-1.2.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3624a67d12695d5c32a332bd8cc4c1d45273eba1a4a451a0ecf70f4c3e67dd4f", size = 568897, upload-time = "2025-12-06T20:25:04.151Z" },
+    { url = "https://files.pythonhosted.org/packages/95/ca/e559551d4d206a71ae545fcb690e704dfee141d88984729b0100042e91d3/backports_zstd-1.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:93c9afeee3c60b203644e0a1cc54028283636b4e76ba670c84522584116c1b2e", size = 482506, upload-time = "2025-12-06T20:25:05.388Z" },
+    { url = "https://files.pythonhosted.org/packages/75/61/7440f4c72324c1c455498581faeadc1711cc6728f9d60aa781e6ef939446/backports_zstd-1.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4687dac0a3c5a4c30fbd871ee3be666822f1eb902a7a68ce0d1379f190917850", size = 510079, upload-time = "2025-12-06T20:25:06.703Z" },
+    { url = "https://files.pythonhosted.org/packages/3f/bf/248692d5e0960a50eebc982e4e2cbbb3ac0f6200ad81d222d4c01ddd500d/backports_zstd-1.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:dd63ed6c7139cef92b1073be892e92631aa468332570f7230089e93a9449f551", size = 586309, upload-time = "2025-12-06T20:25:08.351Z" },
+    { url = "https://files.pythonhosted.org/packages/f4/7c/ecfb1d8ba18e2c9090898f12b6ea83a9dd59e735021a2c564996c4599024/backports_zstd-1.2.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:464d5fea68f5b03feabea22a4db4f39622db4ff89dab2df259b3c8665f1f676b", size = 566493, upload-time = "2025-12-06T20:25:09.8Z" },
+    { url = "https://files.pythonhosted.org/packages/2d/8d/c81ed0da565f735e8a8f0c3b8c633f9e16bcfdb82ca5cb4d029dac0f1361/backports_zstd-1.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d5b3518f82c518a09067dab4ed1bd79ca542a2c248f7f9418262dc2c4a06ccdb", size = 631120, upload-time = "2025-12-06T20:25:10.974Z" },
+    { url = "https://files.pythonhosted.org/packages/d7/8e/9dec5a74249b3af4ea4fd4a5dfb5d70167ea82f96592b3b4e7d340ccfff0/backports_zstd-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d57ce6d62dfb28bd37ad5523678752a5516ec68595fd35559f6c2878edd4de0", size = 498938, upload-time = "2025-12-06T20:25:12.145Z" },
+    { url = "https://files.pythonhosted.org/packages/fd/99/ca71a403c79ec4bc419b71cee532de6545af1a0d8e61d0a2b8d70a034e0a/backports_zstd-1.2.0-cp312-cp312-win32.whl", hash = "sha256:e8bedc2372dae260397a99844420e16bb886912d685058d52e1f3533164f67a5", size = 289072, upload-time = "2025-12-06T20:25:13.48Z" },
+    { url = "https://files.pythonhosted.org/packages/e1/e4/77fc5813ea35906ac1b71cd284e20c5a6f808f138e2e6a13e9586cd61d1a/backports_zstd-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:4667b30ea5e9f8b505b2042a40c5115660151987ca748b4be07facc757212ff9", size = 314094, upload-time = "2025-12-06T20:25:14.966Z" },
+    { url = "https://files.pythonhosted.org/packages/44/e3/133652d59a6731f9180a107812c9d52a2c72be2d80c2fd4f874669592a0c/backports_zstd-1.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:cd6326f1562435677ab2bf607a44c96bb2a48beb0e14accff45e8c9f0931e9c1", size = 289197, upload-time = "2025-12-06T20:25:16.077Z" },
+    { url = "https://files.pythonhosted.org/packages/6e/6c/dd602f484f22d8df9ed71859735dc86e094e90b7d8f51e51d48808f3571e/backports_zstd-1.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1db671ac69df7cd88057c85a7bc614b94afd74a48faacd1576ad91dd18008f6a", size = 435731, upload-time = "2025-12-06T20:25:17.225Z" },
+    { url = "https://files.pythonhosted.org/packages/29/7d/b126e05650103f269282e5271a0960e30ac4ce9f192e3ae98e303325011b/backports_zstd-1.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f6520e555c2b597863b97ecb90ad21857bf044119f643130c29110b55f67c1a", size = 362007, upload-time = "2025-12-06T20:25:18.841Z" },
+    { url = "https://files.pythonhosted.org/packages/5c/e2/464e87930aa771da08634846300c13355f7ae07a476c8a30f75631fd1689/backports_zstd-1.2.0-cp313-cp313-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:9ef28be8bfebf5169cde28f36ebd146a0305569c91e836aed3a3aa79b7bbc58b", size = 505925, upload-time = "2025-12-06T20:25:20.319Z" },
+    { url = "https://files.pythonhosted.org/packages/44/08/bda420a2d13be0d6aa8323b735207de46bb01c08575e3a6810e01a20501f/backports_zstd-1.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9478c04e285da26ce1198d5ec1e43905531049c9e0f74169a39df5876f44643e", size = 476130, upload-time = "2025-12-06T20:25:21.839Z" },
+    { url = "https://files.pythonhosted.org/packages/17/d5/fca7eb6e5a12e390ea4437bc6705e18efd70c9966127c3c2fec8188654f1/backports_zstd-1.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f032452d783876c5f4d81907e42fc6fbe812a9a712c360b497968ea7109bb17", size = 581610, upload-time = "2025-12-06T20:25:23.077Z" },
+    { url = "https://files.pythonhosted.org/packages/81/e2/072fdf5bff7274788b49491a4d039bf0fe2f2f07a9975751d8b70fc14ac6/backports_zstd-1.2.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5642ae3832fb74817bdabc0d8b8877b109537c3f9ceeb54a6cd855aa0afc3bd9", size = 642454, upload-time = "2025-12-06T20:25:24.28Z" },
+    { url = "https://files.pythonhosted.org/packages/2c/74/a7ae8e421ccb779130d64745d3191daf6da02f37bf7cf099dc10d688d14e/backports_zstd-1.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4e7340a7fb7bac7607382554b138ae8dbffda0b8af72ce5c639fb86b49a3b2e4", size = 491079, upload-time = "2025-12-06T20:25:25.481Z" },
+    { url = "https://files.pythonhosted.org/packages/25/26/450b23bad6035f0f3dc8e1cf3729e31a10ce1821a7b6d3bf8555ba818a46/backports_zstd-1.2.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b72e343b1b2927fc047054450de8738bc64c268e93fabc8228d963690eaf348e", size = 566373, upload-time = "2025-12-06T20:25:27.034Z" },
+    { url = "https://files.pythonhosted.org/packages/c0/42/8161164fb26ac1a656f5fb5e3aa3aa9dcf4d06f6d9553fc596fa6f0ae3ad/backports_zstd-1.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3f2a3f898dd1eaba5c8f0ea0e1bd23d993ed86ea7d4c12bf7a0743158d123d6", size = 481888, upload-time = "2025-12-06T20:25:28.198Z" },
+    { url = "https://files.pythonhosted.org/packages/c0/2c/5c4f9a54c7c708f38cdb0670804d62237e9cacd1a6ff567f8c5fb8ef5d1a/backports_zstd-1.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:afb95bc88d7623eeda2c0c8fe0388ac8838fa5a09ddbd7dfa72b283de392024b", size = 509480, upload-time = "2025-12-06T20:25:29.438Z" },
+    { url = "https://files.pythonhosted.org/packages/13/fc/f7a86785fde290b3280adeb81c577a96323d4b661b9befa0d990aaa67a86/backports_zstd-1.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:59ddb84b8bd46a4a297cdf92601aaa9f59881c59f4a402a021173d6bb8bc367a", size = 586040, upload-time = "2025-12-06T20:25:30.598Z" },
+    { url = "https://files.pythonhosted.org/packages/40/7a/11c709c72abeef82c5ef752718c10a3fde0fba8258c069d717de33d366f7/backports_zstd-1.2.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:d3d0d54ef711ea5ffa4e2eebfb70784295eb517bd7ac64545a142ad35c5b02ba", size = 564125, upload-time = "2025-12-06T20:25:31.772Z" },
+    { url = "https://files.pythonhosted.org/packages/f5/ec/2ea033ceeca0808d830c3fb1d8ced1b6d2e5c4540ed8bdf66e0ec99180af/backports_zstd-1.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5c170f1329e90614f2d51f6f4622f6f775f51b92b7bc7801fa093b97db6cfc95", size = 632819, upload-time = "2025-12-06T20:25:33.027Z" },
+    { url = "https://files.pythonhosted.org/packages/cb/3a/1469312ce7b1c6d98c788b500df01d61468d17bfd58df21266a7160112fe/backports_zstd-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:49c675121210ee23ea9c9b28ad15822e1b0f9182df733f0e1a10a5385f628701", size = 495375, upload-time = "2025-12-06T20:25:34.362Z" },
+    { url = "https://files.pythonhosted.org/packages/c6/da/27ef9e6a169808fc6777fb58fb55991bdc9ec22eee1aaecaf076be91986b/backports_zstd-1.2.0-cp313-cp313-win32.whl", hash = "sha256:0724fb2958eb2ccc100c9f49315d856a88b5deb985c62953876a78ecb46027ba", size = 288717, upload-time = "2025-12-06T20:25:35.565Z" },
+    { url = "https://files.pythonhosted.org/packages/6e/f3/bfe0c470e2cfd0bbc274ca484e7a061f2d505c28df2479c52ed1dcce4fea/backports_zstd-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:b80b715170fc590d464d3342757978702ed4b6b41a3b3a0a5dbb46a89f4ccebe", size = 313927, upload-time = "2025-12-06T20:25:36.691Z" },
+    { url = "https://files.pythonhosted.org/packages/16/0d/cf6b22e4ca8cfa850061baa89664437b2da65698b2a8a02eb67de9d6b69e/backports_zstd-1.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:c09f5e985142fc04581c12e635dfd8cdc64b2d595479c1213f0b4db7ee37e3cb", size = 288947, upload-time = "2025-12-06T20:25:37.884Z" },
+    { url = "https://files.pythonhosted.org/packages/4f/65/285bccc9fddb1b1d7fa379b42407f3e88359db05a6955fbe02ef4d5ed6ce/backports_zstd-1.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:21c68b9d358f1062c5c8baad946e306b54380dcbe2b12d00fdebc42533b5a499", size = 436423, upload-time = "2025-12-06T20:25:39.048Z" },
+    { url = "https://files.pythonhosted.org/packages/9d/27/bba33f68cfc57a2885bbd1a1ffc9405cb461b12db5083ca63b15074bfa6d/backports_zstd-1.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4c3508074a30e3309bcc1bfdfe6cbd6bd3d64567788d3c6e15b1594e63bef276", size = 362704, upload-time = "2025-12-06T20:25:40.232Z" },
+    { url = "https://files.pythonhosted.org/packages/42/62/9233d99c1be673188afde322aecc467653023185077064dd3eac18678e22/backports_zstd-1.2.0-cp313-cp313t-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:9a0e5f6aebd1ff3c75b26d3e3ac3140996b9f0883b95847fad57992be06fe5d2", size = 507870, upload-time = "2025-12-06T20:25:41.364Z" },
+    { url = "https://files.pythonhosted.org/packages/0f/b0/089867ef455f6311caa9224e68020cabcbfc3f8759cfd19931b06ba7bb8d/backports_zstd-1.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b12f415fe62f1e9f7196ce9eaedc699547c38cc263e64b6939b610b2a29a200", size = 475770, upload-time = "2025-12-06T20:25:42.873Z" },
+    { url = "https://files.pythonhosted.org/packages/43/d5/8615151ea4bcf5d2dca0755bfa7cad97b7cb8dbd1c9c2e1da57081f1d8a6/backports_zstd-1.2.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00066e7c3df700fe0df66aa197dcbd3d691d55c16f6179c3acd87a6ca22e7993", size = 581191, upload-time = "2025-12-06T20:25:44.156Z" },
+    { url = "https://files.pythonhosted.org/packages/f5/71/eb6e7019db30622d2a31faa0e608fc3dc29e336b4a855bd5b0e78ac0943e/backports_zstd-1.2.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c56bdb8e57563d726ce46225011801ff748018cbeff5175576f8a46868e0f706", size = 640185, upload-time = "2025-12-06T20:25:45.348Z" },
+    { url = "https://files.pythonhosted.org/packages/d6/64/ebd64f84875f7feb83005bfc3e7352700d26f5396e7e5e494681af18fe18/backports_zstd-1.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f499ec4944c223814be97627d0f1b65c2474ba981e1f21ec8b541f2dff5f960", size = 495073, upload-time = "2025-12-06T20:25:46.546Z" },
+    { url = "https://files.pythonhosted.org/packages/45/a7/8f44bbd2a78855680c24e7f90cad69c0c70650f345c4cf13bc7a6dd56231/backports_zstd-1.2.0-cp313-cp313t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7a0957bc3eb84b4a537388c7a62ed055d61c2246c11babf4cbaafb3b5eda0a9c", size = 570664, upload-time = "2025-12-06T20:25:47.731Z" },
+    { url = "https://files.pythonhosted.org/packages/85/e3/476a8b3ac1d7d1b41442bf634603d0beb392d9df2a1439f9543312b67bc3/backports_zstd-1.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e38b22cb32bd9010ad65c0b75a2934448adfdd6bba4387b0f9bacce11e051716", size = 482252, upload-time = "2025-12-06T20:25:49.166Z" },
+    { url = "https://files.pythonhosted.org/packages/cc/2f/cebac7f4dc977da1dfbef4004dae6ae12e31f6978db34af530425568dea7/backports_zstd-1.2.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9af83bbd56f785dffc9a669918e7e7b7f96b0e32fd8877ff90e445ca531463ae", size = 511631, upload-time = "2025-12-06T20:25:50.4Z" },
+    { url = "https://files.pythonhosted.org/packages/22/29/1e9a135af0141d0e0eabb21491f0f058e73ddb4de356ca174406d60d1dd6/backports_zstd-1.2.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:e3ddf78b1b58291616df13844d5a0e6027b0ce299b15d7d3be2a93b974b7b5f6", size = 585764, upload-time = "2025-12-06T20:25:51.998Z" },
+    { url = "https://files.pythonhosted.org/packages/e1/17/e9b29c3d7c4d13e046876fb81b7564a85463d6ab65c10f7fc42a7c658042/backports_zstd-1.2.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:93332bf758954da70b1803ccc73697c7cdec475e4ec04286ff8c568f3786c398", size = 568581, upload-time = "2025-12-06T20:25:53.895Z" },
+    { url = "https://files.pythonhosted.org/packages/4a/b5/e2f2f68c204743a9060e50f6910fd7ae1b484250460fa85e843292e8e8d8/backports_zstd-1.2.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:8f5ba6a97712794ab9c284382a5faefd31ebcb84fa55cb4621e948264dbc6b97", size = 630790, upload-time = "2025-12-06T20:25:55.071Z" },
+    { url = "https://files.pythonhosted.org/packages/78/ff/87fc0e498e6c4ad475da178a4e4c81fbfaf19b043ca586a63068ad704f49/backports_zstd-1.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9d541c0c1992ac25bfd836a1e77cf0e70f18d5505aeeebc56c2cf06ffbc209f5", size = 499701, upload-time = "2025-12-06T20:25:56.265Z" },
+    { url = "https://files.pythonhosted.org/packages/b0/2e/e10d1b10f087094a108f542b91b44efe928800b6ecd8f1619c9967b6da5b/backports_zstd-1.2.0-cp313-cp313t-win32.whl", hash = "sha256:6c2bc4f7154d5c166912c5b7ee6cbb3a921726d1c2cee7c0f1bfaae736f7c250", size = 289660, upload-time = "2025-12-06T20:25:57.753Z" },
+    { url = "https://files.pythonhosted.org/packages/d6/ae/68e5bca7f9990c45c7b1940deccfa4a106c956c5ddd63393332372dad131/backports_zstd-1.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2b7b83331878041a259ec0b384bee7dbfd486b2a2579cd730aca718897d045d7", size = 315026, upload-time = "2025-12-06T20:25:58.952Z" },
+    { url = "https://files.pythonhosted.org/packages/e4/33/a519b4da2015069fb36cded5181ff078ecceb852861b675e2c79547ad10d/backports_zstd-1.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:a884be79cd0897436e1e06566d0b6bcad2360afca8e8e27fb19422ba0cca4d7a", size = 289583, upload-time = "2025-12-06T20:26:00.127Z" },
+    { url = "https://files.pythonhosted.org/packages/4a/03/0be0f44bfd5a77b6dc476eae791bb2847f786bef717aab510b0764aba2f9/backports_zstd-1.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f94f434e2265c067a7e6e2ea50f93e709421f2c9e4a2458a80284065a79caefd", size = 410041, upload-time = "2025-12-06T20:26:23.148Z" },
+    { url = "https://files.pythonhosted.org/packages/cb/7a/1d2390341fb97e9fa9c3242dce6825646bd6f47d96ca862bf070dce0c943/backports_zstd-1.2.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0d9e4d77f03524b59bc2d8d9636e5d808e50ef0d20c56f0ab2ab8ee00b6a367a", size = 339556, upload-time = "2025-12-06T20:26:24.718Z" },
+    { url = "https://files.pythonhosted.org/packages/5f/21/36a2a17f5cd360ddd89bc6d24d2cfb1f6b1e4051fe70da9e172697763d7d/backports_zstd-1.2.0-pp310-pypy310_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:5d8014aeaec1f47f3209bd5e9e29282fcafa7b9076f89cc342a5dab3f298fdec", size = 420605, upload-time = "2025-12-06T20:26:25.872Z" },
+    { url = "https://files.pythonhosted.org/packages/87/e3/ee54f99fda973cf18dcb5ef7fb481449b1e5770af4f449ac06af77c995d2/backports_zstd-1.2.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35b8390fde5644a067a66cbd6f1b1293f48264f7bd867f0148b09d4f206005bf", size = 394149, upload-time = "2025-12-06T20:26:27.57Z" },
+    { url = "https://files.pythonhosted.org/packages/36/d6/1e41a5469606fbe100b4841f03c42275a1b114fa02921cbdedb0aadeaa00/backports_zstd-1.2.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb3b0e175170422b1d095709356cb688b664d381f3dba424ae5107990ca913ee", size = 414113, upload-time = "2025-12-06T20:26:29.072Z" },
+    { url = "https://files.pythonhosted.org/packages/46/68/26c9802339a885f567f1c7bbfa5d5b786545e5bb754ba385f81dd6d2ccc1/backports_zstd-1.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5f7e28d44e322c16aaf8973ce3c062105b6d88fe2b4f4611b40e410176a4fd40", size = 299966, upload-time = "2025-12-06T20:26:30.333Z" },
+    { url = "https://files.pythonhosted.org/packages/e5/b1/2b7b0e1dcd165cf0e0fc792b74138489bfb90d66d7ded86f7f7e91f6764c/backports_zstd-1.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1c3a1748eaac8fd1c862d3e16c6beb023f118a82d7230a32d33f6ce65752a2d6", size = 409938, upload-time = "2025-12-06T20:26:31.55Z" },
+    { url = "https://files.pythonhosted.org/packages/b7/ce/c91b6a4681eb8f13c7919ce551d4b5364e9fd6f07e770e4e01ca2c0b1f92/backports_zstd-1.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9e126bd32c97b1f4717d30530a3762c1f9a85d5d629fdc2ad210e6427fd6849c", size = 339472, upload-time = "2025-12-06T20:26:32.765Z" },
+    { url = "https://files.pythonhosted.org/packages/2f/e6/abb1b8e6e5c9dfb8cbf05669745de81273b46fef5bafee00fb1698c75ce8/backports_zstd-1.2.0-pp311-pypy311_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:e4524beed644c4074ff017e96afc91c5e98064f40680fa859bddee5974641805", size = 420603, upload-time = "2025-12-06T20:26:34.374Z" },
+    { url = "https://files.pythonhosted.org/packages/50/2e/ca206b678cdbd2eca56aa2ce49996f6d6cd21db840efa6e2e6f73d4cb7db/backports_zstd-1.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72bc2b03590d66d8706e4717da25cc6c192f5a6bfc3f6148f671f79e73afd4e8", size = 394149, upload-time = "2025-12-06T20:26:35.563Z" },
+    { url = "https://files.pythonhosted.org/packages/50/c2/ba7bcfe28dc3f8e8848419757883c8a0c7a4263dcd5d3988dd7f49818ca8/backports_zstd-1.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89afe7d6e86bedbf2bac083beb096732a1e92025a5efa9c972941a6140994485", size = 414114, upload-time = "2025-12-06T20:26:36.808Z" },
+    { url = "https://files.pythonhosted.org/packages/71/ad/d5e8a3b28150e4f310999ef26db1e6b5f3bbb899c07d88ebd910954fcaf2/backports_zstd-1.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f00066de6ffd72c653b43afb9aaa36969fd0e2c91f66adb45a11f73e6423263a", size = 299968, upload-time = "2025-12-06T20:26:38.382Z" },
 ]
 
 [[package]]
@@ -245,30 +255,30 @@ wheels = [
 
 [[package]]
 name = "boto3"
-version = "1.42.2"
+version = "1.42.4"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "botocore" },
     { name = "jmespath" },
     { name = "s3transfer" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/e4/3b/be2c0175ff58d6abef88467d7e93225231059621181bc0cfd32fd8b05260/boto3-1.42.2.tar.gz", hash = "sha256:2b403f503bfe8486fd273e41f0b5a033d0e8dad5d94c5a5c0669e92272bd4f17", size = 112828, upload-time = "2025-12-03T17:50:22.599Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/f3/31/246916eec4fc5ff7bebf7e75caf47ee4d72b37d4120b6943e3460956e618/boto3-1.42.4.tar.gz", hash = "sha256:65f0d98a3786ec729ba9b5f70448895b2d1d1f27949aa7af5cb4f39da341bbc4", size = 112826, upload-time = "2025-12-05T20:27:14.931Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/54/3f/ba8d7e362ab595279663fdc77902ee46592252ea7210596bdcc3d2eee12b/boto3-1.42.2-py3-none-any.whl", hash = "sha256:e93c55fecfecc6f05de604288d216a49b06a3c2c53421848ca4afad55f0614b7", size = 140622, upload-time = "2025-12-03T17:50:20.106Z" },
+    { url = "https://files.pythonhosted.org/packages/00/25/9ae819385aad79f524859f7179cecf8ac019b63ac8f150c51b250967f6db/boto3-1.42.4-py3-none-any.whl", hash = "sha256:0f4089e230d55f981d67376e48cefd41c3d58c7f694480f13288e6ff7b1fefbc", size = 140621, upload-time = "2025-12-05T20:27:12.803Z" },
 ]
 
 [[package]]
 name = "botocore"
-version = "1.42.2"
+version = "1.42.4"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "jmespath" },
     { name = "python-dateutil" },
     { name = "urllib3" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/d7/29/1c9b4f73a738d1464c07ccd8b74ed7f21d7f00319bfd6e397a0e897fd61f/botocore-1.42.2.tar.gz", hash = "sha256:3dbeba76168764219cbe392aa67cbc9265cfa05b09970ed5f2e0c786b8ac5010", size = 14843197, upload-time = "2025-12-03T17:50:11.065Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/5c/b7/dec048c124619b2702b5236c5fc9d8e5b0a87013529e9245dc49aaaf31ff/botocore-1.42.4.tar.gz", hash = "sha256:d4816023492b987a804f693c2d76fb751fdc8755d49933106d69e2489c4c0f98", size = 14848605, upload-time = "2025-12-05T20:27:02.919Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/83/b3/4d413a69696a5d096af3f27c91e40f841886aecd849ee62dbb366c50d7ae/botocore-1.42.2-py3-none-any.whl", hash = "sha256:8bb3f0ce39c6a7f63b404a2632ab1a5189187b27317c7b97fe45494677633b5d", size = 14517436, upload-time = "2025-12-03T17:50:07.589Z" },
+    { url = "https://files.pythonhosted.org/packages/9b/a2/7b50f12a9c5a33cd85a5f23fdf78a0cbc445c0245c16051bb627f328be06/botocore-1.42.4-py3-none-any.whl", hash = "sha256:c3b091fd33809f187824b6434e518b889514ded5164cb379358367c18e8b0d7d", size = 14519938, upload-time = "2025-12-05T20:26:58.881Z" },
 ]
 
 [[package]]
@@ -738,7 +748,7 @@ wheels = [
 
 [[package]]
 name = "hatch"
-version = "1.16.1"
+version = "1.16.2"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "backports-zstd", marker = "python_full_version < '3.14'" },
@@ -759,9 +769,9 @@ dependencies = [
     { name = "uv" },
     { name = "virtualenv" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/4f/03/7fb64d1a85c84843890007b545dd64702ec3ace972df6fc3655badc1f152/hatch-1.16.1.tar.gz", hash = "sha256:87df6a17a0f8dc6f9a8ae459b742cb32ccc844a79634f9072797a2e38af1280f", size = 5215833, upload-time = "2025-11-27T20:06:41.204Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/b9/c1/8598996a6f264d430c530799dc65fb13942fb29092e35505039a5f2fb5dc/hatch-1.16.2.tar.gz", hash = "sha256:f288938da85b4b90e47d94788e19e9976dcd6fd53b48343ea251a2a37256a980", size = 5216569, upload-time = "2025-12-06T19:18:12.596Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/b6/39/42d25fed23c4fd4eb3c4ff3f0a7f547ed0d4ad6a1efb0105da0f43768141/hatch-1.16.1-py3-none-any.whl", hash = "sha256:c7c90d122f8fca602d10c9f2176027f935cc6071710d4aec2d94490f6c5ef697", size = 140600, upload-time = "2025-11-27T20:06:39.547Z" },
+    { url = "https://files.pythonhosted.org/packages/d4/7c/bbed5611b1cd7b0b42b2dadb0721d9ccfa4fa9d03abc05e0f57c85a319c6/hatch-1.16.2-py3-none-any.whl", hash = "sha256:827eaf9813c63119f172b85975c5c27110a2306b07e5304c9d38527b0239052a", size = 140658, upload-time = "2025-12-06T19:18:10.573Z" },
 ]
 
 [[package]]
@@ -1200,11 +1210,11 @@ wheels = [
 
 [[package]]
 name = "platformdirs"
-version = "4.5.0"
+version = "4.5.1"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", size = 21715, upload-time = "2025-12-05T13:52:58.638Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" },
+    { url = "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", size = 18731, upload-time = "2025-12-05T13:52:56.823Z" },
 ]
 
 [[package]]
@@ -1256,17 +1266,17 @@ wheels = [
 
 [[package]]
 name = "protobuf"
-version = "6.33.1"
+version = "6.33.2"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/0a/03/a1440979a3f74f16cab3b75b0da1a1a7f922d56a8ddea96092391998edc0/protobuf-6.33.1.tar.gz", hash = "sha256:97f65757e8d09870de6fd973aeddb92f85435607235d20b2dfed93405d00c85b", size = 443432, upload-time = "2025-11-13T16:44:18.895Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4", size = 444296, upload-time = "2025-12-06T00:17:53.311Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/06/f1/446a9bbd2c60772ca36556bac8bfde40eceb28d9cc7838755bc41e001d8f/protobuf-6.33.1-cp310-abi3-win32.whl", hash = "sha256:f8d3fdbc966aaab1d05046d0240dd94d40f2a8c62856d41eaa141ff64a79de6b", size = 425593, upload-time = "2025-11-13T16:44:06.275Z" },
-    { url = "https://files.pythonhosted.org/packages/a6/79/8780a378c650e3df849b73de8b13cf5412f521ca2ff9b78a45c247029440/protobuf-6.33.1-cp310-abi3-win_amd64.whl", hash = "sha256:923aa6d27a92bf44394f6abf7ea0500f38769d4b07f4be41cb52bd8b1123b9ed", size = 436883, upload-time = "2025-11-13T16:44:09.222Z" },
-    { url = "https://files.pythonhosted.org/packages/cd/93/26213ff72b103ae55bb0d73e7fb91ea570ef407c3ab4fd2f1f27cac16044/protobuf-6.33.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:fe34575f2bdde76ac429ec7b570235bf0c788883e70aee90068e9981806f2490", size = 427522, upload-time = "2025-11-13T16:44:10.475Z" },
-    { url = "https://files.pythonhosted.org/packages/c2/32/df4a35247923393aa6b887c3b3244a8c941c32a25681775f96e2b418f90e/protobuf-6.33.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:f8adba2e44cde2d7618996b3fc02341f03f5bc3f2748be72dc7b063319276178", size = 324445, upload-time = "2025-11-13T16:44:11.869Z" },
-    { url = "https://files.pythonhosted.org/packages/8e/d0/d796e419e2ec93d2f3fa44888861c3f88f722cde02b7c3488fcc6a166820/protobuf-6.33.1-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:0f4cf01222c0d959c2b399142deb526de420be8236f22c71356e2a544e153c53", size = 339161, upload-time = "2025-11-13T16:44:12.778Z" },
-    { url = "https://files.pythonhosted.org/packages/1d/2a/3c5f05a4af06649547027d288747f68525755de692a26a7720dced3652c0/protobuf-6.33.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:8fd7d5e0eb08cd5b87fd3df49bc193f5cfd778701f47e11d127d0afc6c39f1d1", size = 323171, upload-time = "2025-11-13T16:44:14.035Z" },
-    { url = "https://files.pythonhosted.org/packages/08/b4/46310463b4f6ceef310f8348786f3cff181cea671578e3d9743ba61a459e/protobuf-6.33.1-py3-none-any.whl", hash = "sha256:d595a9fd694fdeb061a62fbe10eb039cc1e444df81ec9bb70c7fc59ebcb1eafa", size = 170477, upload-time = "2025-11-13T16:44:17.633Z" },
+    { url = "https://files.pythonhosted.org/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d", size = 425603, upload-time = "2025-12-06T00:17:41.114Z" },
+    { url = "https://files.pythonhosted.org/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4", size = 436930, upload-time = "2025-12-06T00:17:43.278Z" },
+    { url = "https://files.pythonhosted.org/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43", size = 427621, upload-time = "2025-12-06T00:17:44.445Z" },
+    { url = "https://files.pythonhosted.org/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e", size = 324460, upload-time = "2025-12-06T00:17:45.678Z" },
+    { url = "https://files.pythonhosted.org/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872", size = 339168, upload-time = "2025-12-06T00:17:46.813Z" },
+    { url = "https://files.pythonhosted.org/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f", size = 323270, upload-time = "2025-12-06T00:17:48.253Z" },
+    { url = "https://files.pythonhosted.org/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c", size = 170501, upload-time = "2025-12-06T00:17:52.211Z" },
 ]
 
 [[package]]
@@ -1430,7 +1440,7 @@ wheels = [
 
 [[package]]
 name = "pytest"
-version = "9.0.1"
+version = "9.0.2"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "colorama", marker = "sys_platform == 'win32'" },
@@ -1441,9 +1451,9 @@ dependencies = [
     { name = "pygments" },
     { name = "tomli", marker = "python_full_version < '3.11'" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz", hash = "sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", size = 1564125, upload-time = "2025-11-12T13:05:09.333Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl", hash = "sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad", size = 373668, upload-time = "2025-11-12T13:05:07.379Z" },
+    { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" },
 ]
 
 [[package]]
@@ -2001,11 +2011,11 @@ wheels = [
 
 [[package]]
 name = "urllib3"
-version = "2.5.0"
+version = "2.6.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/1c/43/554c2569b62f49350597348fc3ac70f786e3c32e7f19d266e19817812dd3/urllib3-2.6.0.tar.gz", hash = "sha256:cb9bcef5a4b345d5da5d145dc3e30834f58e8018828cbc724d30b4cb7d4d49f1", size = 432585, upload-time = "2025-12-05T15:08:47.885Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" },
+    { url = "https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl", hash = "sha256:c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f", size = 131083, upload-time = "2025-12-05T15:08:45.983Z" },
 ]
 
 [[package]]
@@ -2022,28 +2032,28 @@ wheels = [
 
 [[package]]
 name = "uv"
-version = "0.9.15"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d0/b8/63e4ad24d7ef24ef1de10cb2db9ff0f74b2cceb4bd71c4b3909297d40967/uv-0.9.15.tar.gz", hash = "sha256:241a57d8ce90273d0ad8460897e1b2250bd4aa6bafe72fd8be07fbc3a7662f3d", size = 3788825, upload-time = "2025-12-03T01:33:06.404Z" }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/fd/e7/5c7fcf7a49884273c18a54b68ffd5f05775cb0e59aeeb2801f2b6d31787b/uv-0.9.15-py3-none-linux_armv6l.whl", hash = "sha256:4ccf2aa7f2e0fcb553dccc8badceb2fc533000e5baf144fd982bb9be88b304b8", size = 20936584, upload-time = "2025-12-03T01:32:58.983Z" },
-    { url = "https://files.pythonhosted.org/packages/30/a8/5c376318f57dd4fc58bb01db870f9e564a689d479ddc0440731933286740/uv-0.9.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:944cd6d500974f9693994ec990c5b263a185e66cbc1cbd230f319445f8330e4e", size = 20000398, upload-time = "2025-12-03T01:33:04.518Z" },
-    { url = "https://files.pythonhosted.org/packages/ca/c7/6af7e5dc21902eb936a54c037650f070cea015d742b3a49e82f53e6f32c4/uv-0.9.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ec4716fee5db65cfc78016d07f6fddb9b1fa29a0471fe67fe6676e2befee3215", size = 18440619, upload-time = "2025-12-03T01:32:56.388Z" },
-    { url = "https://files.pythonhosted.org/packages/88/73/8364801f678ba58d1a31ec9c8e0bfc407b48c0c57e0e3618e8fbf6b285f6/uv-0.9.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:2b9ad2581a90b7b2ed3f5a3b2657c3cf84119bdf101e1a1c49a2f38577eecb1b", size = 20326432, upload-time = "2025-12-03T01:32:53.805Z" },
-    { url = "https://files.pythonhosted.org/packages/89/ed/9c13d81005b00dcc759f7ea4b640b1efff8ecebbf852df90c2f237373ed5/uv-0.9.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d6a837537294e283ddbb18c494dbc085afca3e29d2176059140b7b4e94e485fd", size = 20531552, upload-time = "2025-12-03T01:33:18.894Z" },
-    { url = "https://files.pythonhosted.org/packages/b1/24/99c26056300c83f0d542272c02465937965191739d44bf8654d09d2d296f/uv-0.9.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:214013314564347ad629a5cfcd28b962038fc23c72155d7a798313f6b9f64f81", size = 21428020, upload-time = "2025-12-03T01:33:10.373Z" },
-    { url = "https://files.pythonhosted.org/packages/a2/4a/15dd32d695eae71cb4c09af6e9cbde703674824653c9f2963b068108b344/uv-0.9.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b32c1ac11ea80ab4cc6ea61029880e1319041d2b3783f2478c8eadfc9a9c9d5a", size = 23061719, upload-time = "2025-12-03T01:32:48.914Z" },
-    { url = "https://files.pythonhosted.org/packages/51/02/83c179d6a5cfee0c437dd1d73b515557c6b2b7ab19fb9421420c13b10bc8/uv-0.9.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64d99dfe8af75fed7fd6b7f6a8a81ba26ac88e046c5cb366184c2b53b023b070", size = 22609336, upload-time = "2025-12-03T01:32:41.645Z" },
-    { url = "https://files.pythonhosted.org/packages/a3/77/c620febe2662ab1897c2ef7c95a5424517efc456b77a1f75f6da81b4e542/uv-0.9.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5375c95a70fc76104fc178771cd4a8db1dab55345c7162c3d2d47ca2993c4bb", size = 21663700, upload-time = "2025-12-03T01:32:36.335Z" },
-    { url = "https://files.pythonhosted.org/packages/70/1b/4273d02565a4e86f238e9fee23e6c5c3bb7b5c237c63228e1b72451db224/uv-0.9.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9c1cefdd6e878baa32ff7a7d1ef463690750ff45d899fbb6bd6705e8329b00a", size = 21714799, upload-time = "2025-12-03T01:33:01.785Z" },
-    { url = "https://files.pythonhosted.org/packages/61/ae/29787af8124d821c1a88bb66612c24ff6180309d35348a4915214c5078d3/uv-0.9.15-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:b6d342a4610e7dbc3450c8000313ee7693905ddee12a65a34fdbcd8418a852a5", size = 20454218, upload-time = "2025-12-03T01:33:14.113Z" },
-    { url = "https://files.pythonhosted.org/packages/56/fe/ab906a1e530f0fbb7042e82057d7c08ef46131deb75d5fef2133de6725c5/uv-0.9.15-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:dea4fd678d48b9790234de43b2e5e4a445f9541fd361db7dc1a2cac861c9717a", size = 21549370, upload-time = "2025-12-03T01:32:46.766Z" },
-    { url = "https://files.pythonhosted.org/packages/19/11/20ea6dc5ca56f2ad9a8f1b5674f84c38a45a28ccf880aa7c1abb226355a6/uv-0.9.15-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:bae65f4748cacc20ea7f93b94a9ba82dd5505a98cf61e33d75e2669c6aefbfc5", size = 20502715, upload-time = "2025-12-03T01:32:51.454Z" },
-    { url = "https://files.pythonhosted.org/packages/37/38/ed98b5f48be2aeb63dc8853bc777b739c18277d0b950196b4d46f7b4d74a/uv-0.9.15-py3-none-musllinux_1_1_i686.whl", hash = "sha256:5473c1095a697b7c7996a312232f78e81cf71e5afc30c889e46a486fe298d853", size = 20890379, upload-time = "2025-12-03T01:32:28.035Z" },
-    { url = "https://files.pythonhosted.org/packages/dd/50/a97468ed93b80a50ea97a717662be4b841e7149bc68197ded087bcdd9e36/uv-0.9.15-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a0ef2e2bcf807aebd70e3a87bde618d0a01f07f627f5da0b0b457d7be2124843", size = 21921653, upload-time = "2025-12-03T01:32:31.016Z" },
-    { url = "https://files.pythonhosted.org/packages/94/e8/ad85878d4e789c40b75c9f670eba52c7e5e63393f31e1c1a7246849595a2/uv-0.9.15-py3-none-win32.whl", hash = "sha256:5efa39d9085f918d17869e43471ccd4526372e71d945b8d7cd3c8867ce6eab33", size = 19762699, upload-time = "2025-12-03T01:32:39.104Z" },
-    { url = "https://files.pythonhosted.org/packages/bc/37/e15a46f880b2c230f7d6934f046825ebe547f90008984c861e84e2ef34c4/uv-0.9.15-py3-none-win_amd64.whl", hash = "sha256:e46f36c80353fb406d4c0fb2cfe1953b4a01bfb3fc5b88dd4f763641b8899f1a", size = 21758441, upload-time = "2025-12-03T01:32:33.722Z" },
-    { url = "https://files.pythonhosted.org/packages/9a/fe/af3595c25dfaa85daff11ed0c8ca0fc1d088a426c65ef93d3751490673fd/uv-0.9.15-py3-none-win_arm64.whl", hash = "sha256:8f14456f357ebbf3f494ae5af41e9b306ba66ecc81cb2304095b38d99a1f7d28", size = 20203340, upload-time = "2025-12-03T01:32:44.184Z" },
+version = "0.9.16"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/bc/21/1a01209d34d49135151edd058bfefe395fd8c7f17233754d85c036311c4c/uv-0.9.16.tar.gz", hash = "sha256:b73269213e22e8638d14d0f8ae1bef34a0a3c20a3bd2010544456d36159e357d", size = 3806010, upload-time = "2025-12-06T14:19:17.889Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/1f/3c/dfea2ce3f863f5fe3762d6305ff54b05d49c36d531c452e0483b226899b4/uv-0.9.16-py3-none-linux_armv6l.whl", hash = "sha256:748b6d408429d9d9ee3e59a33e714bf41471b8534c8fc1526e0d8b695c7304e1", size = 21086205, upload-time = "2025-12-06T14:18:49.667Z" },
+    { url = "https://files.pythonhosted.org/packages/21/73/9b8059692dff670b10cc91aa7fb130397e35e22895f47a0d87b1fcd3c1b9/uv-0.9.16-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a4add59e5fb179ff01a8dc02cd24a9c7dcd8a60d3744c2dfacf2818eb709a1de", size = 20271218, upload-time = "2025-12-06T14:19:36.686Z" },
+    { url = "https://files.pythonhosted.org/packages/73/d3/2f81803f4fe818b8a1f0c256523a1fed17372d8b901798a92b6316c42757/uv-0.9.16-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ac60c04510e4710370762c8d7f9382f269b881efacc4262e2229ef27df39441c", size = 18831407, upload-time = "2025-12-06T14:19:03.524Z" },
+    { url = "https://files.pythonhosted.org/packages/16/42/13bd057513b7616ec0416d070186e410474f8f9c9fa48b965561a8d214af/uv-0.9.16-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:5cacb026d93e9be53f9c74ee4907d2df8c3d94c7b24b1c3130f0aee62b6a0b86", size = 20551474, upload-time = "2025-12-06T14:18:37.936Z" },
+    { url = "https://files.pythonhosted.org/packages/94/83/94c46b6f00fb9602cdb1c4f38f0226643f0151ba082544c516d866af84c8/uv-0.9.16-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cd1a625a4cd13a45a667297c30cceb1393167c413ee3fb7ed46606a857abb4fd", size = 20704842, upload-time = "2025-12-06T14:19:20.861Z" },
+    { url = "https://files.pythonhosted.org/packages/8e/0c/30fa6f16f31931d20db626f607783ada5e2f01d2307ee51fc477054b779b/uv-0.9.16-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69b405c7de06a8290eae6b246397ad2a3bda8b52e3b8f445a8417d9f62d938e8", size = 21681575, upload-time = "2025-12-06T14:18:54.972Z" },
+    { url = "https://files.pythonhosted.org/packages/3c/e6/6a6acdde5d7df54c65ea277fded6e480ff79ffc00d6c8c3404d0142ca5d5/uv-0.9.16-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7e2ea8e2c8e77c6d3406a66155b07b445107085d240fe52e33d7f5180f356028", size = 23322212, upload-time = "2025-12-06T14:19:11.298Z" },
+    { url = "https://files.pythonhosted.org/packages/1d/40/189099b44b9bd02d594dedafcd5da39f4d758e4690c504b624a61cb9eea8/uv-0.9.16-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f231876fa98247e8e009a91a5ea4c032e2f3315f141510259507f847f154254d", size = 22901411, upload-time = "2025-12-06T14:19:24.856Z" },
+    { url = "https://files.pythonhosted.org/packages/a7/76/f09c9967648dc22c01d6cf8ce9eeb8b83fdf19c6f0a4090607be608dbcf9/uv-0.9.16-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c43af679a125f41b2f0fe9801ec640e9971d6c24d9e3bea2eaea4d56f240d5ed", size = 21970469, upload-time = "2025-12-06T14:19:15.531Z" },
+    { url = "https://files.pythonhosted.org/packages/d1/24/3d737f69753143bba3808d18a1ec7e972cf5d337fbe1dbad6223a3d8d88f/uv-0.9.16-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13217422d30f5c70d37409dd5064d8dbc5a58c1cbaa29f081f43586195a50cc9", size = 22009128, upload-time = "2025-12-06T14:19:28.771Z" },
+    { url = "https://files.pythonhosted.org/packages/c6/1a/261d30ac548290bf13c743101c4a08bc3c37f001d3a45b8d0684fe2d151a/uv-0.9.16-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:f06a6e172f34c70865784ff9108a1eabc5a99c97363d9ee587884b111bb220d2", size = 20698915, upload-time = "2025-12-06T14:19:40.497Z" },
+    { url = "https://files.pythonhosted.org/packages/21/31/be1651da4398ee7d5064e712a80f0ad83dc47533531f78fb35ae237f1917/uv-0.9.16-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:307336087b53e0a1e6e1c7ec4633ca0bf11be786c692e23c3a343cac37b3e013", size = 21936423, upload-time = "2025-12-06T14:18:41.815Z" },
+    { url = "https://files.pythonhosted.org/packages/81/2d/953ddab1cbef688ceb365b571249ce333e7bc8a70af894d1f85e969dc427/uv-0.9.16-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:0b1e32a5c4024b8628b2799d407ffa7aa913ca1554258e963a516936119baba1", size = 20656496, upload-time = "2025-12-06T14:19:44.2Z" },
+    { url = "https://files.pythonhosted.org/packages/e8/9d/ef3ff37c6485a3d482c774da0cdb0cb7415a3e267af3b000978c10e0264b/uv-0.9.16-py3-none-musllinux_1_1_i686.whl", hash = "sha256:c21aa40106a902a531a3890d414dd3a418db4a17275f3a3829d08ddc1888bb2d", size = 21154195, upload-time = "2025-12-06T14:19:07.217Z" },
+    { url = "https://files.pythonhosted.org/packages/b5/8b/645a28fa9ff93dfe037385a04e27b45cd7335173c7c6239d157b6a09d623/uv-0.9.16-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0d012ef231699cad1eaf9ab1f5b076522970dcf87bfba3a684e66a02c6a1575d", size = 22207319, upload-time = "2025-12-06T14:18:59.521Z" },
+    { url = "https://files.pythonhosted.org/packages/a7/7a/c4e8bc5b759d5da4fcabe0b1fc876f67913da4880d0cec34e9e6418ff93c/uv-0.9.16-py3-none-win32.whl", hash = "sha256:0229a4dfd0ff7e257bcd791f2d78cf1d682b01856d52d95602c56bb5ed97cc72", size = 19908839, upload-time = "2025-12-06T14:18:46.032Z" },
+    { url = "https://files.pythonhosted.org/packages/3b/21/6ecf7db074235552d7b0be84c48d934e9916809d7dafb96d9a1019dd2ded/uv-0.9.16-py3-none-win_amd64.whl", hash = "sha256:e3e9a69a463607b9886afa34ce68dadf9a378eb6d191c878156fd8864e604c1e", size = 22033348, upload-time = "2025-12-06T14:19:48.091Z" },
+    { url = "https://files.pythonhosted.org/packages/db/a1/4c44988817b72b17f09010983fd40b05f76ce54988fbdd707a8a33cfd498/uv-0.9.16-py3-none-win_arm64.whl", hash = "sha256:18d430980e7f4915a42854bc98a76f87f30da8859469a864fcf33e0a31fafdd1", size = 20396419, upload-time = "2025-12-06T14:19:32.586Z" },
 ]
 
 [[package]]
diff --git a/go-sdk/.pre-commit-config.yaml b/go-sdk/.pre-commit-config.yaml
index 989478af031..70cfa0e2723 100644
--- a/go-sdk/.pre-commit-config.yaml
+++ b/go-sdk/.pre-commit-config.yaml
@@ -31,7 +31,7 @@ repos:
         name: Check if all hooks apply to the repository
   - repo: https://github.com/Lucas-C/pre-commit-hooks
     # replace hash with version once PR #103 merged comes in a release
-    rev: abdd8b62891099da34162217ecb3872d22184a51
+    rev: f5cfd5fdaf0211dfd1027d9d8442b764a232c7ad
     hooks:
       - id: insert-license
         name: Add license for all Go files
diff --git a/pyproject.toml b/pyproject.toml
index 7a57293a2d9..5a7427cb2b5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -533,7 +533,7 @@ packages = []
     "apache-airflow-providers-amazon[s3fs]",
 ]
 "uv" = [
-    "uv>=0.9.15",
+    "uv>=0.9.16",
 ]
 
 
diff --git a/scripts/tools/setup_breeze b/scripts/tools/setup_breeze
index 28780080114..34dfda80c2e 100755
--- a/scripts/tools/setup_breeze
+++ b/scripts/tools/setup_breeze
@@ -27,7 +27,7 @@ COLOR_YELLOW=$'\e[33m'
 COLOR_BLUE=$'\e[34m'
 COLOR_RESET=$'\e[0m'
 
-UV_VERSION="0.9.15"
+UV_VERSION="0.9.16"
 
 function manual_instructions() {
     echo


(airflow) 20/32: [v3-1-test] Align the term Dag in all translations (#59155)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 36851b7cb6f915c0456536a9cd7b2fc9c80afcb8
Author: Jens Scheffler <95...@users.noreply.github.com>
AuthorDate: Sun Dec 7 23:51:22 2025 +0100

    [v3-1-test] Align the term Dag in all translations (#59155)
---
 .../ui/public/i18n/locales/de/components.json      |  4 +--
 .../ui/public/i18n/locales/hu/components.json      |  4 +--
 .../src/airflow/ui/public/i18n/locales/hu/dag.json |  4 +--
 .../ui/public/i18n/locales/nl/components.json      |  4 +--
 .../airflow/ui/public/i18n/locales/pt/assets.json  | 10 +++---
 .../airflow/ui/public/i18n/locales/pt/browse.json  |  2 +-
 .../airflow/ui/public/i18n/locales/pt/common.json  | 38 +++++++++++-----------
 .../ui/public/i18n/locales/pt/components.json      | 28 ++++++++--------
 .../src/airflow/ui/public/i18n/locales/pt/dag.json | 12 +++----
 .../airflow/ui/public/i18n/locales/pt/dags.json    | 16 ++++-----
 .../ui/public/i18n/locales/pt/dashboard.json       | 28 ++++++++--------
 .../airflow/ui/public/i18n/locales/th/common.json  |  2 +-
 .../src/airflow/ui/public/i18n/locales/th/dag.json |  4 +--
 .../ui/public/i18n/locales/zh-CN/components.json   |  2 +-
 14 files changed, 79 insertions(+), 79 deletions(-)

diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json
index bad98315e82..85e7d17a1e0 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/de/components.json
@@ -109,8 +109,8 @@
   "toggleTableView": "Tabellenansicht anzeigen",
   "triggerDag": {
     "button": "Auslösen",
-    "loading": "Lade DAG Information...",
-    "loadingFailed": "Das Laden der DAG Information fehlgeschlagen. Bitt versuchen Sie es noch einmal.",
+    "loading": "Lade Dag Information...",
+    "loadingFailed": "Das Laden der Dag Information fehlgeschlagen. Bitt versuchen Sie es noch einmal.",
     "runIdHelp": "Optional - wird automatisch erzeugt wenn nicht angegeben",
     "selectDescription": "Einen einzelnen Lauf dieses Dag auslösen",
     "selectLabel": "Einzelner Lauf",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json
index 481812441f2..8d802e79a5e 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/hu/components.json
@@ -82,7 +82,7 @@
     "downloadImage": "Gráf kép letöltése",
     "downloadImageError": "A gráf letöltése sikertelen.",
     "downloadImageErrorTitle": "Sikertelen letöltés",
-    "otherDagRuns": "+További DAG futások",
+    "otherDagRuns": "+További Dag futások",
     "taskCount_one": "{{count}} feladat",
     "taskCount_other": "{{count}} feladat",
     "taskGroup": "Feladatcsoport"
@@ -110,7 +110,7 @@
   "triggerDag": {
     "button": "Indítás",
     "loading": "Dag információk betöltése...",
-    "loadingFailed": "A DAG információk betöltése sikertelen. Kérem, próbálja újra.",
+    "loadingFailed": "A Dag információk betöltése sikertelen. Kérem, próbálja újra.",
     "runIdHelp": "Opcionális – ha nincs megadva, automatikusan generálódik",
     "selectDescription": "Indítsd el ennek a Dag-nek egyetlen futását",
     "selectLabel": "Egyszeri futás",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json
index b06f88d0109..8f6955079c5 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/hu/dag.json
@@ -121,10 +121,10 @@
     "toaster": {
       "error": {
         "description": "A Dag feldolgozási kérelem meghiúsult. Lehetnek még feldolgozásra váró kérelmek.",
-        "title": "DAG újrafeldolgozása sikertelen"
+        "title": "Dag újrafeldolgozása sikertelen"
       },
       "success": {
-        "description": "A DAG újrafeldolgozása hamarosan.",
+        "description": "A Dag újrafeldolgozása hamarosan.",
         "title": "Újrafeldolgozási kérelem sikeresen elküldve"
       }
     }
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json
index 9997e067172..0349dc7d989 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/nl/components.json
@@ -105,8 +105,8 @@
   "toggleTableView": "Toon tabelweergave",
   "triggerDag": {
     "button": "Trigger",
-    "loading": "DAG informatie aan het laden...",
-    "loadingFailed": "Mislukt om DAG informatie te laden. Probeer het opnieuw.",
+    "loading": "Dag informatie aan het laden...",
+    "loadingFailed": "Mislukt om Dag informatie te laden. Probeer het opnieuw.",
     "runIdHelp": "Optioneel - wordt gegenereerd indien niet opgegeven",
     "selectDescription": "Trigger een enkele run van deze Dag",
     "selectLabel": "Enkele Run",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/assets.json
index f40bb8e70c9..ca1a65fc735 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pt/assets.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/assets.json
@@ -1,5 +1,5 @@
 {
-  "consumingDags": "Consumindo DAGs",
+  "consumingDags": "Consumindo Dags",
   "createEvent": {
     "button": "Criar Evento",
     "manual": {
@@ -8,15 +8,15 @@
       "label": "Manual"
     },
     "materialize": {
-      "description": "Ativar o DAG acima deste Asset",
-      "descriptionWithDag": "Ativar o DAG acima deste Asset: {{dagName}}",
+      "description": "Ativar o Dag acima deste Asset",
+      "descriptionWithDag": "Ativar o Dag acima deste Asset: {{dagName}}",
       "label": "Materializar",
       "unpauseDag": "Despausar {{dagName}} ao ativar"
     },
     "success": {
       "manualDescription": "Criação de evento de Asset manual foi bem-sucedida.",
       "manualTitle": "Evento de Asset Criado",
-      "materializeDescription": "DAG acima {{dagId}} foi ativado com sucesso.",
+      "materializeDescription": "Dag acima {{dagId}} foi ativado com sucesso.",
       "materializeTitle": "Materializando Asset"
     },
     "title": "Criar Evento de Asset para {{name}}"
@@ -25,6 +25,6 @@
   "lastAssetEvent": "Último Evento de Asset",
   "name": "Nome",
   "producingTasks": "Produzindo Tarefas",
-  "scheduledDags": "DAGs Programados",
+  "scheduledDags": "Dags Programados",
   "searchPlaceholder": "Pesquisar Assets"
 }
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/browse.json
index d22701bfabc..1ae262481be 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pt/browse.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/browse.json
@@ -17,7 +17,7 @@
   },
   "xcom": {
     "columns": {
-      "dag": "DAG",
+      "dag": "Dag",
       "key": "Chave",
       "value": "Valor"
     },
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/common.json
index 8ab097b993c..f47b8661239 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pt/common.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/common.json
@@ -36,22 +36,22 @@
   "createdAssetEvent_one": "Evento de Asset Criado",
   "createdAssetEvent_other": "Eventos de Asset Criados",
   "createdAssetEvent_zero": "Nenhum evento de asset criado",
-  "dag_many": "DAGs",
-  "dag_one": "DAG",
-  "dag_other": "DAGs",
-  "dag_zero": "Nenhum DAG",
+  "dag_many": "Dags",
+  "dag_one": "Dag",
+  "dag_other": "Dags",
+  "dag_zero": "Nenhum Dag",
   "dagDetails": {
     "catchup": "Catchup",
-    "dagRunTimeout": "Tempo Limite da Execução do DAG",
+    "dagRunTimeout": "Tempo Limite da Execução do Dag",
     "defaultArgs": "Argumentos Padrão",
     "description": "Descrição",
-    "documentation": "Documentação do DAG",
+    "documentation": "Documentação do Dag",
     "fileLocation": "Local do Arquivo",
     "hasTaskConcurrencyLimits": "Tem Limite de Concorrência de Tarefas",
     "lastExpired": "Último Expirado",
     "lastParseDuration": "Duração do Último Parse",
     "lastParsed": "Último Parseado",
-    "latestDagVersion": "Última Versão do DAG",
+    "latestDagVersion": "Última Versão do Dag",
     "latestRun": "Última Execução",
     "maxActiveRuns": "Máximo de Execuções Ativas",
     "maxActiveTasks": "Máximo de Tarefas Ativas",
@@ -62,10 +62,10 @@
     "schedule": "Agendamento",
     "tags": "Etiquetas"
   },
-  "dagId": "ID do DAG",
+  "dagId": "ID do Dag",
   "dagRun": {
     "conf": "Conf",
-    "dagVersions": "Versão(s) do DAG",
+    "dagVersions": "Versão(s) do Dag",
     "dataIntervalEnd": "Fim do Intervalo de Dados",
     "dataIntervalStart": "Início do Intervalo de Dados",
     "lastSchedulingDecision": "Última Decisão de Agendamento",
@@ -76,12 +76,12 @@
     "triggeredBy": "Acionado por",
     "triggeringUser": "Nome do Usuário que Disparou"
   },
-  "dagRun_many": "Execuções do DAG",
-  "dagRun_one": "Execução do DAG",
-  "dagRun_other": "Execuções do DAG",
-  "dagRun_zero": "Nenhuma execução do DAG",
-  "dagRunId": "ID da Execução do DAG",
-  "dagWarnings": "Avisos/Erros do DAG",
+  "dagRun_many": "Execuções do Dag",
+  "dagRun_one": "Execução do Dag",
+  "dagRun_other": "Execuções do Dag",
+  "dagRun_zero": "Nenhuma execução do Dag",
+  "dagRunId": "ID da Execução do Dag",
+  "dagWarnings": "Avisos/Erros do Dag",
   "defaultToGraphView": "Padrão para visualização gráfica",
   "defaultToGridView": "Padrão para visualização em grade",
   "direction": "Direção",
@@ -134,7 +134,7 @@
     "admin": "Administração",
     "assets": "Assets",
     "browse": "Navegar",
-    "dags": "DAGs",
+    "dags": "Dags",
     "docs": "Documentação",
     "home": "Início",
     "legacyFabViews": "Visualizações Legacy FAB",
@@ -144,7 +144,7 @@
   "noItemsFound": "Nenhum {{modelName}} encontrado",
   "note": {
     "add": "Adicionar uma nota",
-    "dagRun": "Nota da Execução do DAG",
+    "dagRun": "Nota da Execução do Dag",
     "label": "Nota",
     "placeholder": "Adicionar uma nota...",
     "taskInstance": "Nota da Instância de Tarefa"
@@ -215,7 +215,7 @@
   "table": {
     "completedAt": "Concluído em",
     "createdAt": "Criado em",
-    "filterByTag": "Filtrar DAGs por tag",
+    "filterByTag": "Filtrar Dags por tag",
     "filterColumns": "Filtrar colunas da tabela",
     "filterReset_many": "Resetar filtros",
     "filterReset_one": "Resetar filtro",
@@ -244,7 +244,7 @@
   "taskGroup": "Grupo de Tarefas",
   "taskId": "ID da Tarefa",
   "taskInstance": {
-    "dagVersion": "Versão do DAG",
+    "dagVersion": "Versão do Dag",
     "executor": "Executor",
     "executorConfig": "Configuração do Executor",
     "hostname": "Hostname",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/components.json
index 5b30826d8b7..6649bee37eb 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pt/components.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/components.json
@@ -14,7 +14,7 @@
     "missingRuns": "Execuções Faltando",
     "reprocessBehavior": "Comportamento de Reprocessamento",
     "run": "Executar Backfill",
-    "selectDescription": "Executar este DAG para um intervalo de datas",
+    "selectDescription": "Executar este Dag para um intervalo de datas",
     "selectLabel": "Backfill",
     "title": "Executar Backfill",
     "toaster": {
@@ -58,10 +58,10 @@
   },
   "durationChart": {
     "duration": "Duração (segundos)",
-    "lastDagRun_many": "Últimas {{count}} Execuções do DAG",
-    "lastDagRun_one": "Última Execução do DAG",
-    "lastDagRun_other": "Últimas {{count}} Execuções do DAG",
-    "lastDagRun_zero": "Nenhuma execução do DAG",
+    "lastDagRun_many": "Últimas {{count}} Execuções do Dag",
+    "lastDagRun_one": "Última Execução do Dag",
+    "lastDagRun_other": "Últimas {{count}} Execuções do Dag",
+    "lastDagRun_zero": "Nenhuma execução do Dag",
     "lastTaskInstance_many": "Últimas {{count}} Instâncias de Tarefa",
     "lastTaskInstance_one": "Última Instância de Tarefa",
     "lastTaskInstance_other": "Últimas {{count}} Instâncias de Tarefa",
@@ -94,7 +94,7 @@
     "downloadImage": "Baixar imagem do gráfico",
     "downloadImageError": "Falha ao baixar a imagem do gráfico.",
     "downloadImageErrorTitle": "Download Falhou",
-    "otherDagRuns": "+Outras Execuções do DAG",
+    "otherDagRuns": "+Outras Execuções do Dag",
     "taskCount_many": "{{count}} Tarefas",
     "taskCount_one": "{{count}} Tarefa",
     "taskCount_other": "{{count}} Tarefas",
@@ -110,7 +110,7 @@
     "file": "Arquivo",
     "location": "linha {{line}} em {{name}}"
   },
-  "reparseDag": "Reparse DAG",
+  "reparseDag": "Reparse Dag",
   "sortedAscending": "Ordenado em ordem crescente",
   "sortedDescending": "Ordenado em ordem decrescente",
   "sortedUnsorted": "Não ordenado",
@@ -119,16 +119,16 @@
   "toggleTableView": "Mostrar visualização de tabela",
   "triggerDag": {
     "button": "Acionar",
-    "loading": "Carregando informações do DAG...",
-    "loadingFailed": "Falha ao carregar informações do DAG. Por favor, tente novamente.",
+    "loading": "Carregando informações do Dag...",
+    "loadingFailed": "Falha ao carregar informações do Dag. Por favor, tente novamente.",
     "runIdHelp": "Opcional - será gerado se não for fornecido",
-    "selectDescription": "Acionar uma única execução deste DAG",
+    "selectDescription": "Acionar uma única execução deste Dag",
     "selectLabel": "Execução Única",
-    "title": "Acionar DAG",
+    "title": "Acionar Dag",
     "toaster": {
       "success": {
-        "description": "A execução do DAG foi acionada com sucesso.",
-        "title": "Execução do DAG acionada"
+        "description": "A execução do Dag foi acionada com sucesso.",
+        "title": "Execução do Dag acionada"
       }
     },
     "unpause": "Despausar {{dagDisplayName}} ao acionar"
@@ -146,7 +146,7 @@
     "versionId": "ID da Versão"
   },
   "versionSelect": {
-    "dagVersion": "Versão do DAG",
+    "dagVersion": "Versão do Dag",
     "versionCode": "v{{versionCode}}"
   }
 }
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dag.json
index c4a4a58b92a..2c9cb5cdbb4 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dag.json
@@ -48,7 +48,7 @@
   "header": {
     "buttons": {
       "advanced": "Avançado",
-      "dagDocs": "Documentação do DAG"
+      "dagDocs": "Documentação do Dag"
     }
   },
   "logs": {
@@ -107,12 +107,12 @@
       "showGridShortcut": "Mostrar Grade (Pressione g)"
     },
     "dagRuns": {
-      "label": "Número de Execuções do DAG"
+      "label": "Número de Execuções do Dag"
     },
     "dependencies": {
       "label": "Dependências",
       "options": {
-        "allDagDependencies": "Todas as Dependências do DAG",
+        "allDagDependencies": "Todas as Dependências do Dag",
         "externalConditions": "Condições Externas",
         "onlyTasks": "Somente Tarefas"
       },
@@ -126,11 +126,11 @@
   "parse": {
     "toaster": {
       "error": {
-        "description": "Falha ao processar o DAG. Pode haver solicitações de processamento pendentes ainda não processadas.",
-        "title": "Falha ao Reprocessar o DAG"
+        "description": "Falha ao processar o Dag. Pode haver solicitações de processamento pendentes ainda não processadas.",
+        "title": "Falha ao Reprocessar o Dag"
       },
       "success": {
-        "description": "O DAG deve ser reprocessado em breve.",
+        "description": "O Dag deve ser reprocessado em breve.",
         "title": "Solicitação de Reprocessamento Enviada com Sucesso"
       }
     }
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dags.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dags.json
index 6ac6422c19e..138a7b92931 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dags.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dags.json
@@ -2,11 +2,11 @@
   "assetSchedule": "{{count}} de {{total}} ativos atualizados",
   "dagActions": {
     "delete": {
-      "button": "Excluir DAG",
-      "warning": "Isso removerá todas as metadados relacionados ao DAG, incluindo Execuções e Tarefas."
+      "button": "Excluir Dag",
+      "warning": "Isso removerá todas as metadados relacionados ao Dag, incluindo Execuções e Tarefas."
     }
   },
-  "favoriteDag": "DAG Favorito",
+  "favoriteDag": "Dag Favorito",
   "filters": {
     "allRunTypes": "Todos os Tipos de Execução",
     "allStates": "Todos os Estados",
@@ -20,7 +20,7 @@
       "all": "Todos",
       "paused": "Pausado"
     },
-    "runIdPatternFilter": "Pesquisar Execuções de DAG"
+    "runIdPatternFilter": "Pesquisar Execuções de Dag"
   },
   "ownerLink": "Link do Proprietário para {{owner}}",
   "runAndTaskActions": {
@@ -69,7 +69,7 @@
   "search": {
     "advanced": "Pesquisa Avançada",
     "clear": "Limpar pesquisa",
-    "dags": "Pesquisar DAGs",
+    "dags": "Pesquisar Dags",
     "hotkey": "+K",
     "tasks": "Pesquisar Tarefas"
   },
@@ -87,10 +87,10 @@
       "desc": "Ordenar por Estado da Última Execução (Z-A)"
     },
     "nextDagRun": {
-      "asc": "Ordenar por Próxima Execução do DAG (Mais Antiga-Mais Recente)",
-      "desc": "Ordenar por Próxima Execução do DAG (Mais Recente-Mais Antiga)"
+      "asc": "Ordenar por Próxima Execução do Dag (Mais Antiga-Mais Recente)",
+      "desc": "Ordenar por Próxima Execução do Dag (Mais Recente-Mais Antiga)"
     },
     "placeholder": "Ordenar por"
   },
-  "unfavoriteDag": "Remover DAG dos Favoritos"
+  "unfavoriteDag": "Remover Dag dos Favoritos"
 }
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dashboard.json b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dashboard.json
index 725875494a1..d5245e4b623 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/pt/dashboard.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/pt/dashboard.json
@@ -1,15 +1,15 @@
 {
   "favorite": {
-    "favoriteDags_many": "Primeiros {{count}} DAGs favoritos",
-    "favoriteDags_one": "Primeiro {{count}} DAG favorito",
-    "favoriteDags_other": "Primeiros {{count}} DAGs favoritos",
-    "favoriteDags_zero": "Nenhum DAG favorito",
+    "favoriteDags_many": "Primeiros {{count}} Dags favoritos",
+    "favoriteDags_one": "Primeiro {{count}} Dag favorito",
+    "favoriteDags_other": "Primeiros {{count}} Dags favoritos",
+    "favoriteDags_zero": "Nenhum Dag favorito",
     "noDagRuns": "Ainda não há DagRun para este dag.",
-    "noFavoriteDags": "Nenhum favorito ainda. Clique no ícone de estrela ao lado de um DAG na lista para adicioná-lo aos seus favoritos."
+    "noFavoriteDags": "Nenhum favorito ainda. Clique no ícone de estrela ao lado de um Dag na lista para adicioná-lo aos seus favoritos."
   },
   "group": "Grupo",
   "health": {
-    "dagProcessor": "Processador de DAG",
+    "dagProcessor": "Processador de Dag",
     "health": "Saúde",
     "healthy": "Saúde",
     "lastHeartbeat": "Último Heartbeat",
@@ -21,10 +21,10 @@
   },
   "history": "Histórico",
   "importErrors": {
-    "dagImportError_many": "Erros de Importação de DAG",
-    "dagImportError_one": "Erro de Importação de DAG",
-    "dagImportError_other": "Erros de Importação de DAG",
-    "dagImportError_zero": "Nenhum erro de importação de DAG",
+    "dagImportError_many": "Erros de Importação de Dag",
+    "dagImportError_one": "Erro de Importação de Dag",
+    "dagImportError_other": "Erros de Importação de Dag",
+    "dagImportError_zero": "Nenhum erro de importação de Dag",
     "searchByFile": "Pesquisar por arquivo",
     "timestamp": "Timestamp"
   },
@@ -37,11 +37,11 @@
   },
   "source": "Fonte",
   "stats": {
-    "activeDags": "DAGs Ativos",
-    "failedDags": "DAGs Falhados",
-    "queuedDags": "DAGs em Fila",
+    "activeDags": "Dags Ativos",
+    "failedDags": "Dags Falhados",
+    "queuedDags": "Dags em Fila",
     "requiredActions": "Ações Necessárias",
-    "runningDags": "DAGs em Execução",
+    "runningDags": "Dags em Execução",
     "stats": "Estatísticas"
   },
   "uri": "URI",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/common.json
index f55f6598827..c7a609906f7 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/th/common.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/common.json
@@ -32,7 +32,7 @@
   "dag_other": "Dags",
   "dagDetails": {
     "catchup": "Catchup",
-    "dagRunTimeout": "ระยะหมดเวลาของ DAG Run",
+    "dagRunTimeout": "ระยะหมดเวลาของ Dag Run",
     "defaultArgs": "ค่า Arguments เริ่มต้น",
     "description": "คำอธิบาย",
     "documentation": "เอกสารประกอบ Dag",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/th/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/th/dag.json
index 5c59ecd6908..d632937f24d 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/th/dag.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/th/dag.json
@@ -121,10 +121,10 @@
     "toaster": {
       "error": {
         "description": "การร้องขอประมวลผล Dag ล้มเหลว อาจมีคำขอการประมวลผลที่รอดำเนินการอยู่",
-        "title": "การประมวลผล DAG ล้มเหลว"
+        "title": "การประมวลผล Dag ล้มเหลว"
       },
       "success": {
-        "description": "DAG จะถูกประมวลผลใหม่ในเร็ว ๆ นี้",
+        "description": "Dag จะถูกประมวลผลใหม่ในเร็ว ๆ นี้",
         "title": "ส่งคำขอประมวลผลใหม่สำเร็จแล้ว"
       }
     }
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json
index 652011da2be..b52f071f607 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/zh-CN/components.json
@@ -87,7 +87,7 @@
   },
   "limitedList": "+ 其他 {{count}} 项",
   "limitedList.allItems": "所有 {{count}} 项:",
-  "limitedList.clickToInteract": "点击标签以筛选 DAGs",
+  "limitedList.clickToInteract": "点击标签以筛选 Dags",
   "limitedList.clickToOpenFull": "点击 \"+{{count}} 更多\" 打开完整视图",
   "limitedList.copyPasteText": "你可以复制并粘贴上方文本",
   "logs": {


(airflow) 10/32: Backport (#59052)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit d79f6b441c0bacfb51216aedf4bf708e1fb32c20
Author: Pierre Jeambrun <pi...@gmail.com>
AuthorDate: Thu Dec 4 18:18:17 2025 +0100

    Backport (#59052)
---
 airflow-core/docs/howto/index.rst                  |  1 +
 airflow-core/docs/howto/performance.rst            | 55 +++++++++++++++
 .../src/airflow/api_fastapi/common/parameters.py   |  7 +-
 .../core_api/routes/public/test_dags.py            | 80 ++++++++++++++--------
 .../core_api/routes/public/test_event_logs.py      | 53 ++++++++++----
 .../core_api/routes/public/test_hitl.py            |  4 ++
 .../core_api/routes/public/test_task_instances.py  |  4 +-
 7 files changed, 153 insertions(+), 51 deletions(-)

diff --git a/airflow-core/docs/howto/index.rst b/airflow-core/docs/howto/index.rst
index 9abc9caa76e..0d4f79e74e5 100644
--- a/airflow-core/docs/howto/index.rst
+++ b/airflow-core/docs/howto/index.rst
@@ -56,3 +56,4 @@ configuring an Airflow environment.
     dynamic-dag-generation
     docker-compose/index
     run-with-self-signed-certificate
+    performance
diff --git a/airflow-core/docs/howto/performance.rst b/airflow-core/docs/howto/performance.rst
new file mode 100644
index 00000000000..1f7d77d85dc
--- /dev/null
+++ b/airflow-core/docs/howto/performance.rst
@@ -0,0 +1,55 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+..   http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+Performance tuning (API and UI)
+===============================
+
+This guide collects pragmatic tips that improve Airflow performance for API and UI workloads.
+
+Custom metadata indexes
+-----------------------
+
+If you observe slowness in some API calls or specific UI views, you should inspect query plans and add indexes yourself
+that match your workload. Listing endpoints and UI table views with specific ordering criteria are likely
+to benefit from additional indexes if you have a large volume of metadata.
+
+When to use
+^^^^^^^^^^^
+
+- Slow API list/detail endpoints caused by frequent scans or lookups on columns like ``start_date``, timestamps (e.g. ``dttm``), or status fields.
+- UI pages that load large lists or perform heavy filtering on metadata tables.
+
+Guidance
+^^^^^^^^
+
+- Inspect the query planner (e.g., ``EXPLAIN``/``EXPLAIN ANALYZE``) for slow endpoints and identify missing indexes.
+- Prefer single or composite indexes that match your most common ordering logic, typically the ``order_by``
+  query parameter used in API calls. Composite indexes can cover multi criteria ordering.
+- Your optimal indexes depend on how you use the API and UI; there is no one-size-fits-all set we can ship by default.
+
+Upgrade considerations
+^^^^^^^^^^^^^^^^^^^^^^
+
+To avoid conflicts with Airflow database upgrades, delete your custom indexes before running an Airflow DB upgrade
+and re-apply them after the upgrade succeeds.
+
+Notes
+^^^^^
+
+- Review query plans (e.g. via ``EXPLAIN``) to choose effective column sets and ordering for your workload.
+- Composite indexes should list columns in selectivity order appropriate to your most common predicates.
+- Indexes incur write overhead; add only those that materially improve your read paths.
diff --git a/airflow-core/src/airflow/api_fastapi/common/parameters.py b/airflow-core/src/airflow/api_fastapi/common/parameters.py
index 668e6721f87..123b6d9841f 100644
--- a/airflow-core/src/airflow/api_fastapi/common/parameters.py
+++ b/airflow-core/src/airflow/api_fastapi/common/parameters.py
@@ -34,7 +34,7 @@ from typing import (
 from fastapi import Depends, HTTPException, Query, status
 from pendulum.parsing.exceptions import ParserError
 from pydantic import AfterValidator, BaseModel, NonNegativeInt
-from sqlalchemy import Column, and_, case, func, not_, or_, select as sql_select
+from sqlalchemy import Column, and_, func, not_, or_, select as sql_select
 from sqlalchemy.inspection import inspect
 
 from airflow._shared.timezones import timezone
@@ -248,11 +248,6 @@ class SortParam(BaseParam[list[str]]):
             if column is None:
                 column = getattr(self.model, lstriped_orderby)
 
-            # MySQL does not support `nullslast`, and True/False ordering depends on the
-            # database implementation.
-            nullscheck = case((column.isnot(None), 0), else_=1)
-
-            columns.append(nullscheck)
             if order_by_value.startswith("-"):
                 columns.append(column.desc())
             else:
diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
index 78293779a09..cd843b336b6 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_dags.py
@@ -383,36 +383,6 @@ class TestGetDags(TestDagEndpoint):
                 2,
                 [DAG1_ID, DAG2_ID],
             ),
-            (
-                {"order_by": "next_dagrun", "exclude_stale": False},
-                3,
-                [DAG3_ID, DAG1_ID, DAG2_ID],
-            ),
-            (
-                {"order_by": "last_run_state", "exclude_stale": False},
-                3,
-                [DAG1_ID, DAG3_ID, DAG2_ID],
-            ),
-            (
-                {"order_by": "-last_run_state", "exclude_stale": False},
-                3,
-                [DAG3_ID, DAG1_ID, DAG2_ID],
-            ),
-            (
-                {"order_by": "last_run_start_date", "exclude_stale": False},
-                3,
-                [DAG1_ID, DAG3_ID, DAG2_ID],
-            ),
-            (
-                {"order_by": "-last_run_start_date", "exclude_stale": False},
-                3,
-                [DAG3_ID, DAG1_ID, DAG2_ID],
-            ),
-            (
-                {"order_by": ["next_dagrun", "-dag_display_name"], "exclude_stale": False},
-                3,
-                [DAG3_ID, DAG2_ID, DAG1_ID],
-            ),
             # Search
             ({"dag_id_pattern": "1"}, 1, [DAG1_ID]),
             ({"dag_display_name_pattern": "test_dag2"}, 1, [DAG2_ID]),
@@ -451,6 +421,56 @@ class TestGetDags(TestDagEndpoint):
 
         assert actual_ids == expected_ids
 
+    # Ordering of nulls values is DB specific.
+    @pytest.mark.backend("sqlite")
+    @pytest.mark.parametrize(
+        ("query_params", "expected_total_entries", "expected_ids"),
+        [
+            (
+                {"order_by": "next_dagrun", "exclude_stale": False},
+                3,
+                [DAG1_ID, DAG2_ID, DAG3_ID],
+            ),
+            (
+                {"order_by": "last_run_state", "exclude_stale": False},
+                3,
+                [DAG2_ID, DAG1_ID, DAG3_ID],
+            ),
+            (
+                {"order_by": "-last_run_state", "exclude_stale": False},
+                3,
+                [DAG3_ID, DAG1_ID, DAG2_ID],
+            ),
+            (
+                {"order_by": "last_run_start_date", "exclude_stale": False},
+                3,
+                [DAG2_ID, DAG1_ID, DAG3_ID],
+            ),
+            (
+                {"order_by": "-last_run_start_date", "exclude_stale": False},
+                3,
+                [DAG3_ID, DAG1_ID, DAG2_ID],
+            ),
+            (
+                {"order_by": ["next_dagrun", "-dag_display_name"], "exclude_stale": False},
+                3,
+                [DAG2_ID, DAG1_ID, DAG3_ID],
+            ),
+        ],
+    )
+    def test_get_dags_with_nullable_fields(
+        self, test_client, query_params, expected_total_entries, expected_ids, session
+    ):
+        with assert_queries_count(4):
+            response = test_client.get("/dags", params=query_params)
+        assert response.status_code == 200
+        body = response.json()
+
+        assert body["total_entries"] == expected_total_entries
+        actual_ids = [dag["dag_id"] for dag in body["dags"]]
+
+        assert actual_ids == expected_ids
+
     @mock.patch("airflow.api_fastapi.auth.managers.base_auth_manager.BaseAuthManager.get_authorized_dag_ids")
     def test_get_dags_should_call_authorized_dag_ids(self, mock_get_authorized_dag_ids, test_client):
         mock_get_authorized_dag_ids.return_value = {DAG1_ID, DAG2_ID}
diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_event_logs.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_event_logs.py
index e46a355c0f7..dd87e8d7fac 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_event_logs.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_event_logs.py
@@ -279,20 +279,6 @@ class TestGetEventLogs(TestEventLogsEndpoint):
                 4,
                 [EVENT_NORMAL, EVENT_WITH_OWNER, TASK_INSTANCE_EVENT, EVENT_WITH_OWNER_AND_TASK_INSTANCE],
             ),
-            # order_by
-            (
-                {"order_by": "-id"},
-                200,
-                4,
-                [EVENT_WITH_OWNER_AND_TASK_INSTANCE, TASK_INSTANCE_EVENT, EVENT_WITH_OWNER, EVENT_NORMAL],
-            ),
-            (
-                {"order_by": "logical_date"},
-                200,
-                4,
-                [TASK_INSTANCE_EVENT, EVENT_WITH_OWNER_AND_TASK_INSTANCE, EVENT_NORMAL, EVENT_WITH_OWNER],
-            ),
-            # combination of query parameters
             (
                 {"offset": 1, "excluded_events": ["non_existed_event"], "order_by": "event"},
                 200,
@@ -327,6 +313,45 @@ class TestGetEventLogs(TestEventLogsEndpoint):
         for event_log, expected_event in zip(resp_json["event_logs"], expected_events):
             assert event_log["event"] == expected_event
 
+    # Ordering of nulls values is DB specific.
+    @pytest.mark.backend("sqlite")
+    @pytest.mark.parametrize(
+        ("query_params", "expected_status_code", "expected_total_entries", "expected_events"),
+        [
+            (
+                {"order_by": "-id"},
+                200,
+                4,
+                [EVENT_WITH_OWNER_AND_TASK_INSTANCE, TASK_INSTANCE_EVENT, EVENT_WITH_OWNER, EVENT_NORMAL],
+            ),
+            (
+                {"order_by": "logical_date"},
+                200,
+                4,
+                [EVENT_NORMAL, EVENT_WITH_OWNER, TASK_INSTANCE_EVENT, EVENT_WITH_OWNER_AND_TASK_INSTANCE],
+            ),
+            (
+                {"order_by": "-logical_date"},
+                200,
+                4,
+                [EVENT_WITH_OWNER_AND_TASK_INSTANCE, TASK_INSTANCE_EVENT, EVENT_WITH_OWNER, EVENT_NORMAL],
+            ),
+        ],
+    )
+    def test_get_event_logs_order_by(
+        self, test_client, query_params, expected_status_code, expected_total_entries, expected_events
+    ):
+        with assert_queries_count(2):
+            response = test_client.get("/eventLogs", params=query_params)
+        assert response.status_code == expected_status_code
+        if expected_status_code != 200:
+            return
+
+        resp_json = response.json()
+        assert resp_json["total_entries"] == expected_total_entries
+        for event_log, expected_event in zip(resp_json["event_logs"], expected_events):
+            assert event_log["event"] == expected_event
+
     def test_should_raises_401_unauthenticated(self, unauthenticated_test_client):
         response = unauthenticated_test_client.get("/eventLogs")
         assert response.status_code == 401
diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py
index 4c10feee7d6..e025ea50969 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py
@@ -695,6 +695,10 @@ class TestGetHITLDetailsEndpoint:
             reverse=reverse,
         )
 
+        # Remove entries with None, because None orders depends on the DB implementation
+        hitl_details = [d for d in hitl_details if get_key_lambda(d) is not None]
+        sorted_hitl_details = [d for d in sorted_hitl_details if get_key_lambda(d) is not None]
+
         assert hitl_details == sorted_hitl_details
 
     def test_should_respond_200_without_response(self, test_client: TestClient) -> None:
diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
index 6f743cd7d4b..a353b110791 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_task_instances.py
@@ -813,10 +813,12 @@ class TestGetMappedTaskInstances:
         assert len(body["task_instances"]) == params["limit"]
         assert expected_map_indexes == [ti["map_index"] for ti in body["task_instances"]]
 
+    # Ordering of nulls values is DB specific.
+    @pytest.mark.backend("sqlite")
     @pytest.mark.parametrize(
         "params, expected_map_indexes",
         [
-            ({"order_by": "rendered_map_index", "limit": 108}, [0] + list(range(1, 108))),  # Asc
+            ({"order_by": "rendered_map_index", "limit": 108}, list(range(1, 109))),  # Asc
             ({"order_by": "-rendered_map_index", "limit": 100}, [0] + list(range(11, 110)[::-1])),  # Desc
         ],
     )


(airflow) 25/32: [v3-1-test] Show asset extra in asset list (#59195) (#59201)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 5b13a2cbc6fc406f3e2e4a5d4c9d0419874aaa4a
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Mon Dec 8 16:01:41 2025 +0100

    [v3-1-test] Show asset extra in asset list (#59195) (#59201)
    
    (cherry picked from commit 38db2defa230cdd9976fe12dc2fb0a9048ed01b2)
    
    Co-authored-by: Pierre Jeambrun <pi...@gmail.com>
---
 .../airflow/ui/public/i18n/locales/en/assets.json  |  1 +
 .../airflow/ui/public/i18n/locales/en/browse.json  |  4 --
 .../airflow/ui/public/i18n/locales/en/common.json  |  2 +
 .../airflow/ui/src/pages/AssetsList/AssetsList.tsx | 43 +++++++++++++++++++---
 .../src/airflow/ui/src/pages/Events/Events.tsx     |  6 +--
 .../src/airflow/ui/src/pages/XCom/XCom.tsx         |  4 +-
 6 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/assets.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/assets.json
index 527dfeb9e0b..1a0bc7bf86b 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/en/assets.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/assets.json
@@ -22,6 +22,7 @@
     },
     "title": "Create Asset Event for {{name}}"
   },
+  "extra": "Extra",
   "group": "Group",
   "lastAssetEvent": "Last Asset Event",
   "name": "Name",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/browse.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/browse.json
index 07259fd1e58..235c3ef4aa2 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/en/browse.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/browse.json
@@ -1,9 +1,5 @@
 {
   "auditLog": {
-    "actions": {
-      "collapseAllExtra": "Collapse all extra json",
-      "expandAllExtra": "Expand all extra json"
-    },
     "columns": {
       "event": "Event",
       "extra": "Extra",
diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json
index 8aee7cb16de..d7688753c36 100644
--- a/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json
+++ b/airflow-core/src/airflow/ui/public/i18n/locales/en/common.json
@@ -25,6 +25,7 @@
     "requiredActions": "Required Actions",
     "xcoms": "XComs"
   },
+  "collapseAllExtra": "Collapse all extra json",
   "collapseDetailsPanel": "Collapse Details Panel",
   "createdAssetEvent_one": "Created Asset Event",
   "createdAssetEvent_other": "Created Asset Events",
@@ -99,6 +100,7 @@
     "hotkey": "e",
     "tooltip": "Press {{hotkey}} to toggle expand"
   },
+  "expandAllExtra": "Expand all extra json",
   "expression": {
     "all": "All",
     "and": "AND",
diff --git a/airflow-core/src/airflow/ui/src/pages/AssetsList/AssetsList.tsx b/airflow-core/src/airflow/ui/src/pages/AssetsList/AssetsList.tsx
index 1a7c94d6427..ee0e8cc2a3a 100644
--- a/airflow-core/src/airflow/ui/src/pages/AssetsList/AssetsList.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/AssetsList/AssetsList.tsx
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { Box, Heading, Link, VStack } from "@chakra-ui/react";
+import { Box, Flex, Heading, Link, useDisclosure, VStack } from "@chakra-ui/react";
 import type { ColumnDef } from "@tanstack/react-table";
 import { useMemo } from "react";
 import { useTranslation } from "react-i18next";
@@ -27,6 +27,8 @@ import type { AssetResponse } from "openapi/requests/types.gen";
 import { DataTable } from "src/components/DataTable";
 import { useTableURLState } from "src/components/DataTable/useTableUrlState";
 import { ErrorAlert } from "src/components/ErrorAlert";
+import { ExpandCollapseButtons } from "src/components/ExpandCollapseButtons";
+import RenderedJsonField from "src/components/RenderedJsonField";
 import { SearchBar } from "src/components/SearchBar";
 import Time from "src/components/Time";
 import { SearchParamsKeys } from "src/constants/searchParams";
@@ -36,7 +38,10 @@ import { DependencyPopover } from "./DependencyPopover";
 
 type AssetRow = { row: { original: AssetResponse } };
 
-const createColumns = (translate: (key: string) => string): Array<ColumnDef<AssetResponse>> => [
+const createColumns = (
+  translate: (key: string) => string,
+  open?: boolean,
+): Array<ColumnDef<AssetResponse>> => [
   {
     accessorKey: "name",
     cell: ({ row: { original } }: AssetRow) => (
@@ -90,6 +95,21 @@ const createColumns = (translate: (key: string) => string): Array<ColumnDef<Asse
     enableSorting: false,
     header: "",
   },
+  {
+    accessorKey: "extra",
+    cell: ({ row: { original } }) => {
+      if (original.extra !== null) {
+        return <RenderedJsonField content={original.extra ?? {}} jsonProps={{ collapsed: !open }} />;
+      }
+
+      return undefined;
+    },
+    enableSorting: false,
+    header: translate("extra"),
+    meta: {
+      skeletonWidth: 200,
+    },
+  },
 ];
 
 const NAME_PATTERN_PARAM = SearchParamsKeys.NAME_PATTERN;
@@ -105,6 +125,8 @@ export const AssetsList = () => {
   const [sort] = sorting;
   const orderBy = sort ? [`${sort.desc ? "-" : ""}${sort.id}`] : undefined;
 
+  const { onClose, onOpen, open } = useDisclosure();
+
   const { data, error, isLoading } = useAssetServiceGetAssets({
     limit: pagination.pageSize,
     namePattern,
@@ -112,7 +134,7 @@ export const AssetsList = () => {
     orderBy,
   });
 
-  const columns = useMemo(() => createColumns(translate), [translate]);
+  const columns = useMemo(() => createColumns(translate, open), [translate, open]);
 
   const handleSearchChange = (value: string) => {
     setTableURLState({
@@ -137,9 +159,18 @@ export const AssetsList = () => {
           placeHolder={translate("searchPlaceholder")}
         />
 
-        <Heading py={3} size="md">
-          {data?.total_entries} {translate("common:asset", { count: data?.total_entries })}
-        </Heading>
+        <Flex alignItems="center" justifyContent="space-between">
+          <Heading py={3} size="md">
+            {data?.total_entries} {translate("common:asset", { count: data?.total_entries })}
+          </Heading>
+
+          <ExpandCollapseButtons
+            collapseLabel={translate("collapseAllExtra")}
+            expandLabel={translate("expandAllExtra")}
+            onCollapse={onClose}
+            onExpand={onOpen}
+          />
+        </Flex>
       </VStack>
       <Box overflow="auto">
         <DataTable
diff --git a/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx b/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx
index e94bf74bdb2..6365ab24f10 100644
--- a/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Events/Events.tsx
@@ -159,7 +159,7 @@ const {
 }: SearchParamsKeysType = SearchParamsKeys;
 
 export const Events = () => {
-  const { t: translate } = useTranslation("browse");
+  const { t: translate } = useTranslation(["browse", "common"]);
   const { dagId, runId, taskId } = useParams();
   const [searchParams] = useSearchParams();
   const { setTableURLState, tableURLState } = useTableURLState();
@@ -221,8 +221,8 @@ export const Events = () => {
       <Flex alignItems="center" justifyContent="space-between">
         <EventsFilters urlDagId={dagId} urlRunId={runId} urlTaskId={taskId} />
         <ExpandCollapseButtons
-          collapseLabel={translate("auditLog.actions.collapseAllExtra")}
-          expandLabel={translate("auditLog.actions.expandAllExtra")}
+          collapseLabel={translate("collapseAllExtra")}
+          expandLabel={translate("expandAllExtra")}
           onCollapse={onClose}
           onExpand={onOpen}
         />
diff --git a/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx b/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
index fc0e8045b3f..6a7c0c80a20 100644
--- a/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
@@ -173,8 +173,8 @@ export const XCom = () => {
       <Flex alignItems="center" justifyContent="space-between">
         <XComFilters />
         <ExpandCollapseButtons
-          collapseLabel={translate("auditLog.actions.collapseAllExtra")}
-          expandLabel={translate("auditLog.actions.expandAllExtra")}
+          collapseLabel={translate("collapseAllExtra")}
+          expandLabel={translate("expandAllExtra")}
           onCollapse={onClose}
           onExpand={onOpen}
         />


(airflow) 06/32: [v3-1-test] provide a clear naming and description for the attribute caching get_template_context (#59023) (#59036)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 8c2e29c07ef33f673bdf8b28aa9d7df6a9e8ae48
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Thu Dec 4 21:10:25 2025 +0800

    [v3-1-test] provide a clear naming and description for the attribute caching get_template_context (#59023) (#59036)
    
    Co-authored-by: Kevin Yang <85...@users.noreply.github.com>
---
 scripts/ci/prek/check_template_context_variable_in_sync.py |  4 ++--
 task-sdk/src/airflow/sdk/execution_time/task_runner.py     | 12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/scripts/ci/prek/check_template_context_variable_in_sync.py b/scripts/ci/prek/check_template_context_variable_in_sync.py
index dec8708e282..01f4c461c68 100755
--- a/scripts/ci/prek/check_template_context_variable_in_sync.py
+++ b/scripts/ci/prek/check_template_context_variable_in_sync.py
@@ -90,11 +90,11 @@ def _iter_template_context_keys_from_original_return() -> typing.Iterator[str]:
         and isinstance(stmt.target, ast.Attribute)
         and isinstance(stmt.target.value, ast.Name)
         and stmt.target.value.id == "self"
-        and stmt.target.attr == "_context"
+        and stmt.target.attr == "_cached_template_context"
     )
 
     if not isinstance(context_assignment.value, ast.BoolOp):
-        raise TypeError("Expected a BoolOp like 'self._context or {...}'.")
+        raise TypeError("Expected a BoolOp like 'self._cached_template_context or {...}'.")
 
     context_assignment_op = context_assignment.value
     _, context_assignment_value = context_assignment_op.values
diff --git a/task-sdk/src/airflow/sdk/execution_time/task_runner.py b/task-sdk/src/airflow/sdk/execution_time/task_runner.py
index e4fd3ace38c..dbcd6329bce 100644
--- a/task-sdk/src/airflow/sdk/execution_time/task_runner.py
+++ b/task-sdk/src/airflow/sdk/execution_time/task_runner.py
@@ -131,8 +131,8 @@ class RuntimeTaskInstance(TaskInstance):
 
     task: BaseOperator
     bundle_instance: BaseDagBundle
-    _context: Context | None = None
-    """The Task Instance context."""
+    _cached_template_context: Context | None = None
+    """The Task Instance context. This is used to cache get_template_context."""
 
     _ti_context_from_server: Annotated[TIRunContext | None, Field(repr=False)] = None
     """The Task Instance context from the API server, if any."""
@@ -178,7 +178,7 @@ class RuntimeTaskInstance(TaskInstance):
 
         # Cache the context object, which ensures that all calls to get_template_context
         # are operating on the same context object.
-        self._context: Context = self._context or {
+        self._cached_template_context: Context = self._cached_template_context or {
             # From the Task Execution interface
             "dag": self.task.dag,
             "inlets": self.task.inlets,
@@ -218,7 +218,7 @@ class RuntimeTaskInstance(TaskInstance):
                     lambda: coerce_datetime(get_previous_dagrun_success(self.id).end_date)
                 ),
             }
-            self._context.update(context_from_server)
+            self._cached_template_context.update(context_from_server)
 
             if logical_date := coerce_datetime(dag_run.logical_date):
                 if TYPE_CHECKING:
@@ -229,7 +229,7 @@ class RuntimeTaskInstance(TaskInstance):
                 ts_nodash = logical_date.strftime("%Y%m%dT%H%M%S")
                 ts_nodash_with_tz = ts.replace("-", "").replace(":", "")
                 # logical_date and data_interval either coexist or be None together
-                self._context.update(
+                self._cached_template_context.update(
                     {
                         # keys that depend on logical_date
                         "logical_date": logical_date,
@@ -256,7 +256,7 @@ class RuntimeTaskInstance(TaskInstance):
                 # existence. Should this be a private attribute on RuntimeTI instead perhaps?
                 setattr(self, "_upstream_map_indexes", from_server.upstream_map_indexes)
 
-        return self._context
+        return self._cached_template_context
 
     def render_templates(
         self, context: Context | None = None, jinja_env: jinja2.Environment | None = None


(airflow) 14/32: [v3-1-test] Breeze exit on incompatible arguments (#59148) (#59157)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 94cfab40ca673594e8389e4a589506fc3681266e
Author: Jens Scheffler <95...@users.noreply.github.com>
AuthorDate: Sun Dec 7 17:34:18 2025 +0100

    [v3-1-test] Breeze exit on incompatible arguments (#59148) (#59157)
    
    * Breeze exit on incompatible arguments
    
    * Apply suggestion from @choo121600
    
    
    
    * Nit fix
    
    ---------
    (cherry picked from commit 236dab6406e55f88b879f69154e54f2763ce5d3b)
    
    Co-authored-by: Kunal Bhattacharya <ku...@pepsico.com>
    Co-authored-by: Yeonguk Choo <ch...@gmail.com>
---
 dev/breeze/doc/images/output_start-airflow.svg               |  2 +-
 dev/breeze/doc/images/output_start-airflow.txt               |  2 +-
 dev/breeze/src/airflow_breeze/commands/developer_commands.py | 10 +++++++++-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/dev/breeze/doc/images/output_start-airflow.svg b/dev/breeze/doc/images/output_start-airflow.svg
index 286eefb8fe5..66757b5b0ca 100644
--- a/dev/breeze/doc/images/output_start-airflow.svg
+++ b/dev/breeze/doc/images/output_start-airflow.svg
@@ -582,7 +582,7 @@
 </text><text class="breeze-start-airflow-r5" x="0" y="1557.2" textLength="12.2" clip-path="url(#breeze-start-airflow-line-63)">│</text><text class="breeze-start-airflow-r4" x="24.4" y="1557.2" textLength="305" clip-path="url(#breeze-start-airflow-line-63)">--skip-assets-compilation</text><text class="breeze-start-airflow-r1" x="378.2" y="1557.2" textLength="1061.4" clip-path="url(#breeze-start-airflow-line-63)">Skips&#160;compilation&#160;of&#160;assets&#160;when&#160;starting&#160;airfl [...]
 </text><text class="breeze-start-airflow-r5" x="0" y="1581.6" textLength="12.2" clip-path="url(#breeze-start-airflow-line-64)">│</text><text class="breeze-start-airflow-r1" x="378.2" y="1581.6" textLength="305" clip-path="url(#breeze-start-airflow-line-64)">(mutually&#160;exclusive&#160;with&#160;</text><text class="breeze-start-airflow-r4" x="683.2" y="1581.6" textLength="122" clip-path="url(#breeze-start-airflow-line-64)">--dev-mode</text><text class="breeze-start-airflow-r1" x="805.2" [...]
 </text><text class="breeze-start-airflow-r5" x="0" y="1606" textLength="12.2" clip-path="url(#breeze-start-airflow-line-65)">│</text><text class="breeze-start-airflow-r4" x="24.4" y="1606" textLength="122" clip-path="url(#breeze-start-airflow-line-65)">--dev-mode</text><text class="breeze-start-airflow-r1" x="378.2" y="1606" textLength="1061.4" clip-path="url(#breeze-start-airflow-line-65)">Starts&#160;api-server&#160;in&#160;dev&#160;mode&#160;(assets&#160;are&#160;always&#160;recompile [...]
-</text><text class="breeze-start-airflow-r5" x="0" y="1630.4" textLength="12.2" clip-path="url(#breeze-start-airflow-line-66)">│</text><text class="breeze-start-airflow-r1" x="378.2" y="1630.4" textLength="305" clip-path="url(#breeze-start-airflow-line-66)">(mutually&#160;exclusive&#160;with&#160;</text><text class="breeze-start-airflow-r4" x="683.2" y="1630.4" textLength="305" clip-path="url(#breeze-start-airflow-line-66)">--skip-assets-compilation</text><text class="breeze-start-airflo [...]
+</text><text class="breeze-start-airflow-r5" x="0" y="1630.4" textLength="12.2" clip-path="url(#breeze-start-airflow-line-66)">│</text><text class="breeze-start-airflow-r1" x="378.2" y="1630.4" textLength="305" clip-path="url(#breeze-start-airflow-line-66)">(mutually&#160;exclusive&#160;with&#160;</text><text class="breeze-start-airflow-r4" x="683.2" y="1630.4" textLength="305" clip-path="url(#breeze-start-airflow-line-66)">--skip-assets-compilation</text><text class="breeze-start-airflo [...]
 </text><text class="breeze-start-airflow-r5" x="0" y="1654.8" textLength="1464" clip-path="url(#breeze-start-airflow-line-67)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-start-airflow-r1" x="1464" y="1654.8" textLength="12.2" clip-path="url(#breeze-start-airflow-line-67)">
 </text><text class="breeze-start-airflow-r5" x="0" y="1679.2" textLength="24.4" clip-path="url(#breeze-start-airflow-line-68)">╭─</text><text class="breeze-start-airflow-r5" x="24.4" y="1679.2" textLength="488" clip-path="url(#breeze-start-airflow-line-68)">&#160;Build&#160;CI&#160;image&#160;(before&#160;entering&#160;shell)&#160;</text><text class="breeze-start-airflow-r5" x="512.4" y="1679.2" textLength="927.2" clip-path="url(#breeze-start-airflow-line-68)">─────────────────────────── [...]
 </text><text class="breeze-start-airflow-r5" x="0" y="1703.6" textLength="12.2" clip-path="url(#breeze-start-airflow-line-69)">│</text><text class="breeze-start-airflow-r4" x="24.4" y="1703.6" textLength="158.6" clip-path="url(#breeze-start-airflow-line-69)">--force-build</text><text class="breeze-start-airflow-r1" x="341.6" y="1703.6" textLength="707.6" clip-path="url(#breeze-start-airflow-line-69)">Force&#160;image&#160;build&#160;no&#160;matter&#160;if&#160;it&#160;is&#160;determined& [...]
diff --git a/dev/breeze/doc/images/output_start-airflow.txt b/dev/breeze/doc/images/output_start-airflow.txt
index b20c774a1b1..2eabe2c3e6f 100644
--- a/dev/breeze/doc/images/output_start-airflow.txt
+++ b/dev/breeze/doc/images/output_start-airflow.txt
@@ -1 +1 @@
-0e0e91f58cc936fdc0c2f2621f23fb3e
+6de827b3ac600a7b488313a094d227a0
diff --git a/dev/breeze/src/airflow_breeze/commands/developer_commands.py b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
index 71ab14516b6..a32cf74ec2a 100644
--- a/dev/breeze/src/airflow_breeze/commands/developer_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/developer_commands.py
@@ -515,7 +515,7 @@ option_executor_start_airflow = click.option(
 @click.option(
     "--dev-mode",
     help="Starts api-server in dev mode (assets are always recompiled in this case when starting) "
-    "(mutually exclusive with --skip-assets-compilation).",
+    "(mutually exclusive with --skip-assets-compilation and --use-airflow-version).",
     is_flag=True,
 )
 @click.option(
@@ -628,6 +628,14 @@ def start_airflow(
         )
         skip_assets_compilation = True
 
+    if dev_mode and use_airflow_version:
+        get_console().print(
+            "[error]You cannot set Airflow version in dev mode! Consider switching to the respective "
+            "version branch if you need to use --dev-mode on a different Airflow version! \nExiting!!"
+        )
+
+        sys.exit(1)
+
     # Automatically enable file polling for hot reloading under WSL
     if dev_mode and is_wsl():
         os.environ["CHOKIDAR_USEPOLLING"] = "true"


(airflow) 21/32: [v3-1-test] Drop Airflow 2 Support in Edge Provider (#59143) (#59179)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 4b93cf1b592a326625d3335cf8e0e5a057b1c329
Author: Jens Scheffler <95...@users.noreply.github.com>
AuthorDate: Sun Dec 7 23:59:39 2025 +0100

    [v3-1-test] Drop Airflow 2 Support in Edge Provider (#59143) (#59179)
    
    * Drop Airflow 2 Support in Edge Provider
    
    * Fix pytests
    
    * Add note about support in changelog
    (cherry picked from commit fffab39f99607e3c54842342fdc982babd403707)
---
 dev/breeze/src/airflow_breeze/global_constants.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py
index cd9e6f495a0..d158b08d68f 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -736,7 +736,7 @@ PROVIDERS_COMPATIBILITY_TESTS_MATRIX: list[dict[str, str | list[str]]] = [
     {
         "python-version": "3.10",
         "airflow-version": "2.11.0",
-        "remove-providers": "common.messaging fab git keycloak",
+        "remove-providers": "common.messaging edge3 fab git keycloak",
         "run-unit-tests": "true",
     },
     {


(airflow) 04/32: [v3-1-test] Update the documentation for the LocalExecutor (#58990) (#59022)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 833911fe19dbbe1995a71995b12fb705c4a310dc
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Thu Dec 4 02:11:53 2025 +0100

    [v3-1-test] Update the documentation for the LocalExecutor (#58990) (#59022)
    
    (cherry picked from commit 729571b1a8d6009b86fd24d8482907894da8a4f1)
    
    Co-authored-by: Jeongwoo Do <48...@users.noreply.github.com>
---
 airflow-core/docs/core-concepts/executor/local.rst | 23 ++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/airflow-core/docs/core-concepts/executor/local.rst b/airflow-core/docs/core-concepts/executor/local.rst
index a533ae3a5b8..dc7a70fd873 100644
--- a/airflow-core/docs/core-concepts/executor/local.rst
+++ b/airflow-core/docs/core-concepts/executor/local.rst
@@ -29,8 +29,27 @@ This parameter must be greater than ``0``.
 The :class:`~airflow.executors.local_executor.LocalExecutor` spawns the number of processes equal to the value of ``self.parallelism`` at
 ``start`` time, using a ``task_queue`` to coordinate the ingestion of tasks and the work distribution among the workers, which will take
 a task as soon as they are ready. During the lifecycle of the LocalExecutor, the worker processes are running waiting for tasks, once the
-LocalExecutor receives the call to shutdown the executor a poison token is sent to the workers to terminate them. Processes used in this
-strategy are of class :class:`~airflow.executors.local_executor.QueuedLocalWorker`.
+LocalExecutor receives the call to shutdown the executor a poison token is sent to the workers to terminate them.
+
+The worker spawning behavior differs based on the multiprocessing start method:
+
+- **Fork mode** (default on Linux): Workers are spawned all at once up to ``parallelism`` to prevent memory spikes
+  caused by Copy-on-Write (COW). See `Discussion <https://github.com/apache/airflow/discussions/58143>`_
+  for details.
+- **Spawn mode** (default on macOS and Windows): Workers are spawned one at a time as needed to prevent
+  the overhead of spawning many processes simultaneously.
+
+.. note::
+
+   The ``parallelism`` parameter can be configured via the ``[core] parallelism`` option in ``airflow.cfg``.
+   The default value is ``32``.
+
+.. warning::
+
+   Since LocalExecutor workers are spawned as sub-processes of the scheduler, in containerized environments
+   this may appear as excessive memory consumption by the scheduler process. This can potentially trigger
+   container restarts due to OOM (Out of Memory). Consider adjusting the ``parallelism`` value based on
+   your container's resource limits.
 
 .. note::
 


(airflow) 16/32: [v3-1-test] Fix airflow/task-sdk relase PMC checks (#59164) (#59165)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 197c87b7f9c0c44fd54e07a9e5ada4b9759debf6
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Sun Dec 7 19:33:30 2025 +0100

    [v3-1-test] Fix airflow/task-sdk relase PMC checks (#59164) (#59165)
    
    There were few small issues with the airflow/task-sdk release-checks:
    
    * one cd was missing in the process
    * task-sdk folder was not pointing to the right sub-folder.
    * Dockerfile.pmc should use constraints and for task-sdk they
      should install also apache-airflow and apache-airflow-core
      as those are not dependencies of task-sdk and pip failed
      to find them without --pre flag.
    (cherry picked from commit ad6961dc447001e9aa1b6080dffb0f7d51eb060e)
---
 dev/README_RELEASE_AIRFLOW.md                      |   5 +-
 dev/breeze/doc/09_release_management_tasks.rst     |  49 +-
 .../doc/images/output_release-management.svg       |  64 +--
 .../doc/images/output_release-management.txt       |   2 +-
 ...management_generate-issue-content-providers.svg |  32 +-
 ...management_generate-issue-content-providers.txt |   2 +-
 ...lease-management_prepare-helm-chart-package.svg |  32 +-
 ...lease-management_prepare-helm-chart-package.txt |   2 +-
 ...e-management_prepare-provider-distributions.svg |   2 +-
 ...e-management_prepare-provider-distributions.txt |   2 +-
 ...e-management_prepare-provider-documentation.svg | 102 +++--
 ...e-management_prepare-provider-documentation.txt |   2 +-
 .../output_release-management_publish-docs.svg     |   2 +-
 .../output_release-management_publish-docs.txt     |   2 +-
 .../output_release-management_tag-providers.svg    |  37 +-
 .../output_release-management_tag-providers.txt    |   2 +-
 ...se-management_update-providers-next-version.svg |  95 ++++
 ...se-management_update-providers-next-version.txt |   1 +
 .../output_setup_check-all-params-in-groups.svg    |  20 +-
 .../output_setup_check-all-params-in-groups.txt    |   2 +-
 .../output_setup_regenerate-command-images.svg     |  22 +-
 .../output_setup_regenerate-command-images.txt     |   2 +-
 .../commands/release_management_commands.py        | 503 +++++++++++++++------
 .../commands/release_management_commands_config.py |  51 ++-
 .../airflow_breeze/utils/check_release_files.py    |   8 +-
 .../src/airflow_breeze/utils/click_validators.py   |  52 +++
 dev/breeze/src/airflow_breeze/utils/path_utils.py  |  11 +
 27 files changed, 808 insertions(+), 298 deletions(-)

diff --git a/dev/README_RELEASE_AIRFLOW.md b/dev/README_RELEASE_AIRFLOW.md
index 9bbfd99bca3..598cc4e9096 100644
--- a/dev/README_RELEASE_AIRFLOW.md
+++ b/dev/README_RELEASE_AIRFLOW.md
@@ -712,6 +712,7 @@ As a PMC member, you should be able to clone the SVN repository
 or update it if you already checked it out:
 
 ```shell script
+cd ${AIRFLOW_REPO_ROOT}
 cd ..
 [ -d asf-dist ] || svn checkout --depth=immediates https://dist.apache.org/repos/dist asf-dist
 svn update --set-depth=infinity asf-dist/dev/airflow
@@ -728,12 +729,12 @@ Optionally you can use the `breeze release-management check-release-files` comma
 present in SVN. This command may also help with verifying installation of the packages.
 
 ```shell script
-breeze release-management check-release-files airflow --version ${VERSION_RC} --path-to-airflow-svn "${PATH_TO_AIRFLOW_SVN}"
+breeze release-management check-release-files airflow --version ${VERSION_RC}
 ```
 
 
 ```shell script
-breeze release-management check-release-files task-sdk --version ${TASK_SDK_VERSION_RC} --path-to-airflow-svn "${PATH_TO_AIRFLOW_SVN}/task-sdk"
+breeze release-management check-release-files task-sdk --version ${TASK_SDK_VERSION_RC}
 ```
 
 ## Licence check
diff --git a/dev/breeze/doc/09_release_management_tasks.rst b/dev/breeze/doc/09_release_management_tasks.rst
index 731942706c7..3d3108c6df2 100644
--- a/dev/breeze/doc/09_release_management_tasks.rst
+++ b/dev/breeze/doc/09_release_management_tasks.rst
@@ -94,6 +94,32 @@ When testing from HEAD of the branch when the tag
   :width: 100%
   :alt: Breeze release-management prepare-tarball
 
+Validating Release Candidate for PMC
+"""""""""""""""""""""""""""""""""""""
+
+PMC members can use Breeze to automate verification of release candidates instead of manually
+running multiple verification steps. This command validates SVN files, GPG signatures, SHA512
+checksums, Apache RAT licenses, and reproducible builds.
+
+.. code-block:: bash
+
+    breeze release-management validate-rc-by-pmc --distribution airflow --version 3.1.3rc1 --task-sdk-version 1.1.3rc1 --svn-path ~/asf-dist/dev/airflow
+
+You can run individual checks by specifying the ``--checks`` flag:
+
+.. code-block:: bash
+
+    breeze release-management validate-rc-by-pmc \
+      --distribution airflow \
+      --version 3.1.3rc1 \
+      --svn-path ~/asf-dist/dev/airflow \
+      --checks svn,signatures,checksums,licenses
+
+.. image:: ./images/output_release-management_validate-rc-by-pmc.svg
+  :target: https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_release-management_validate-rc-by-pmc.svg
+  :width: 100%
+  :alt: Breeze release-management validate-rc-by-pmc
+
 Start minor branch of Airflow
 """""""""""""""""""""""""""""
 
@@ -281,10 +307,10 @@ This command can be utilized to manage git tags for providers within the Airflow
 Sometimes in cases when there is a connectivity issue to GitHub, it might be possible that local tags get created and lead to annoying errors.
 The default behaviour would be to clean such local tags up.
 
-The flag ``--clean-local-tags`` can be used to delete the local tags.
+The flag ``--clean-tags`` can be used to delete the local tags.
 
 However, If you want to disable this behaviour, set the envvar CLEAN_LOCAL_TAGS to false or use the
-``--no-clean-local-tags`` flag.
+``--no-clean-tags`` flag.
 
 .. code-block:: bash
 
@@ -381,6 +407,23 @@ You can also add ``--answer yes`` to perform non-interactive build.
   :width: 100%
   :alt: Breeze prepare-provider-documentation
 
+Updating provider next version
+""""""""""""""""""""""""""""""
+
+You can use Breeze to update references to other providers automatically to the
+next version of dependent providers, when they are commented with ``# use next version``.
+
+The below example perform the upgrade.
+
+.. code-block:: bash
+
+     breeze release-management update-providers-next-version
+
+
+.. image:: ./images/output_release-management_update-providers-next-version.svg
+  :target: https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_release-management_update-providers-next-version.svg
+  :alt: Breeze update-providers-next-version
+
 Preparing providers
 """""""""""""""""""
 
@@ -428,7 +471,7 @@ Installing providers
 """"""""""""""""""""
 
 In some cases we want to just see if the providers generated can be installed with Airflow without
-verifying them. This happens automatically on CI for sdist pcackages but you can also run it manually if you
+verifying them. This happens automatically on CI for ``sdist`` packages but you can also run it manually if you
 just prepared providers and they are present in ``dist`` folder.
 
 .. code-block:: bash
diff --git a/dev/breeze/doc/images/output_release-management.svg b/dev/breeze/doc/images/output_release-management.svg
index a58d6ee577c..4b0ea7d3f6f 100644
--- a/dev/breeze/doc/images/output_release-management.svg
+++ b/dev/breeze/doc/images/output_release-management.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 1294.3999999999999" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 1318.8" xmlns="http://www.w3.org/2000/svg">
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -42,7 +42,7 @@
 
     <defs>
     <clipPath id="breeze-release-management-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="1243.3999999999999" />
+      <rect x="0" y="0" width="1463.0" height="1267.8" />
     </clipPath>
     <clipPath id="breeze-release-management-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -194,9 +194,12 @@
 <clipPath id="breeze-release-management-line-49">
     <rect x="0" y="1197.1" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-release-management-line-50">
+    <rect x="0" y="1221.5" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="1292.4" rx="8"/><text class="breeze-release-management-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="1316.8" rx="8"/><text class="breeze-release-management-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -230,33 +233,34 @@
 </text><text class="breeze-release-management-r5" x="0" y="532.4" textLength="1464" clip-path="url(#breeze-release-management-line-21)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-line-21)">
 </text><text class="breeze-release-management-r5" x="0" y="556.8" textLength="24.4" clip-path="url(#breeze-release-management-line-22)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="556.8" textLength="341.6" clip-path="url(#breeze-release-management-line-22)">&#160;Providers&#160;release&#160;commands&#160;</text><text class="breeze-release-management-r5" x="366" y="556.8" textLength="1073.6" clip-path="url(#breeze-release-management-line-22)">────────────────────────── [...]
 </text><text class="breeze-release-management-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-line-23)">│</text><text class="breeze-release-management-r4" x="24.4" y="581.2" textLength="439.2" clip-path="url(#breeze-release-management-line-23)">prepare-provider-documentation&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="581.2" textLength="951.6" clip-path="url(#breeze-release-management-line-23)">Prepare&#1 [...]
-</text><text class="breeze-release-management-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-line-24)">│</text><text class="breeze-release-management-r4" x="24.4" y="605.6" textLength="439.2" clip-path="url(#breeze-release-management-line-24)">prepare-provider-distributions&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="605.6" textLength="951.6" clip-path="url(#breeze-release-management-line-24)">Prepare&#1 [...]
-</text><text class="breeze-release-management-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-release-management-line-25)">│</text><text class="breeze-release-management-r4" x="24.4" y="630" textLength="439.2" clip-path="url(#breeze-release-management-line-25)">install-provider-distributions&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="630" textLength="951.6" clip-path="url(#breeze-release-management-line-25)">Installs&#160;pr [...]
-</text><text class="breeze-release-management-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-line-26)">│</text><text class="breeze-release-management-r4" x="24.4" y="654.4" textLength="439.2" clip-path="url(#breeze-release-management-line-26)">verify-provider-distributions&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="654.4" textLength="951.6" clip-path="url(#breeze-release-management-line-26)">Verif [...]
-</text><text class="breeze-release-management-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-line-27)">│</text><text class="breeze-release-management-r4" x="24.4" y="678.8" textLength="439.2" clip-path="url(#breeze-release-management-line-27)">generate-providers-metadata&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="678.8" textLength="951.6" clip-path="url(#breeze-release-management-line- [...]
-</text><text class="breeze-release-management-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-line-28)">│</text><text class="breeze-release-management-r4" x="24.4" y="703.2" textLength="439.2" clip-path="url(#breeze-release-management-line-28)">generate-issue-content-providers&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="703.2" textLength="951.6" clip-path="url(#breeze-release-management-line-28)">Generates&#160;conte [...]
-</text><text class="breeze-release-management-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-line-29)">│</text><text class="breeze-release-management-r4" x="24.4" y="727.6" textLength="439.2" clip-path="url(#breeze-release-management-line-29)">clean-old-provider-artifacts&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="727.6" textLength="951.6" clip-path="url(#breeze-release-management-line-29)"> [...]
-</text><text class="breeze-release-management-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-release-management-line-30)">│</text><text class="breeze-release-management-r4" x="24.4" y="752" textLength="439.2" clip-path="url(#breeze-release-management-line-30)">tag-providers&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="752" te [...]
-</text><text class="breeze-release-management-r5" x="0" y="776.4" textLength="1464" clip-path="url(#breeze-release-management-line-31)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-line-31)">
-</text><text class="breeze-release-management-r5" x="0" y="800.8" textLength="24.4" clip-path="url(#breeze-release-management-line-32)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="800.8" textLength="427" clip-path="url(#breeze-release-management-line-32)">&#160;Airflow&#160;Task&#160;SDK&#160;release&#160;commands&#160;</text><text class="breeze-release-management-r5" x="451.4" y="800.8" textLength="988.2" clip-path="url(#breeze-release-management-line-32)">────────── [...]
-</text><text class="breeze-release-management-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-release-management-line-33)">│</text><text class="breeze-release-management-r4" x="24.4" y="825.2" textLength="512.4" clip-path="url(#breeze-release-management-line-33)">prepare-task-sdk-distributions&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="561.2" y="825.2" textLength="878.4" clip-path="url(#breeze-r [...]
-</text><text class="breeze-release-management-r5" x="0" y="849.6" textLength="1464" clip-path="url(#breeze-release-management-line-34)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#breeze-release-management-line-34)">
-</text><text class="breeze-release-management-r5" x="0" y="874" textLength="24.4" clip-path="url(#breeze-release-management-line-35)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="874" textLength="353.8" clip-path="url(#breeze-release-management-line-35)">&#160;airflowctl&#160;release&#160;commands&#160;</text><text class="breeze-release-management-r5" x="378.2" y="874" textLength="1061.4" clip-path="url(#breeze-release-management-line-35)">───────────────────────────── [...]
-</text><text class="breeze-release-management-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-release-management-line-36)">│</text><text class="breeze-release-management-r4" x="24.4" y="898.4" textLength="585.6" clip-path="url(#breeze-release-management-line-36)">prepare-airflow-ctl-distributions&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="634.4" y="898.4" textLength="805.2" cli [...]
-</text><text class="breeze-release-management-r5" x="0" y="922.8" textLength="1464" clip-path="url(#breeze-release-management-line-37)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="922.8" textLength="12.2" clip-path="url(#breeze-release-management-line-37)">
-</text><text class="breeze-release-management-r5" x="0" y="947.2" textLength="24.4" clip-path="url(#breeze-release-management-line-38)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="947.2" textLength="292.8" clip-path="url(#breeze-release-management-line-38)">&#160;Other&#160;release&#160;commands&#160;</text><text class="breeze-release-management-r5" x="317.2" y="947.2" textLength="1122.4" clip-path="url(#breeze-release-management-line-38)">──────────────────────────── [...]
-</text><text class="breeze-release-management-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-release-management-line-39)">│</text><text class="breeze-release-management-r4" x="24.4" y="971.6" textLength="292.8" clip-path="url(#breeze-release-management-line-39)">add-back-references&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="971.6" textLength="1098" clip-path="url(#breeze-release-management-line-39)">Command&#160;to&#160;add&# [...]
-</text><text class="breeze-release-management-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-release-management-line-40)">│</text><text class="breeze-release-management-r4" x="24.4" y="996" textLength="292.8" clip-path="url(#breeze-release-management-line-40)">prepare-python-client&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="996" textLength="1098" clip-path="url(#breeze-release-management-line-40)">Prepares&#160;python&#160;client&#160;pack [...]
-</text><text class="breeze-release-management-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-release-management-line-41)">│</text><text class="breeze-release-management-r4" x="24.4" y="1020.4" textLength="292.8" clip-path="url(#breeze-release-management-line-41)">publish-docs&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1020.4" textLength="1098" clip-path="url(#breeze-release-managemen [...]
-</text><text class="breeze-release-management-r5" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-release-management-line-42)">│</text><text class="breeze-release-management-r4" x="24.4" y="1044.8" textLength="292.8" clip-path="url(#breeze-release-management-line-42)">generate-constraints&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1044.8" textLength="1098" clip-path="url(#breeze-release-management-line-42)">Generates&#160;pinned&#160;c [...]
-</text><text class="breeze-release-management-r5" x="0" y="1069.2" textLength="12.2" clip-path="url(#breeze-release-management-line-43)">│</text><text class="breeze-release-management-r4" x="24.4" y="1069.2" textLength="292.8" clip-path="url(#breeze-release-management-line-43)">update-constraints&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1069.2" textLength="1098" clip-path="url(#breeze-release-management-line-43)">Update&#160;releas [...]
-</text><text class="breeze-release-management-r5" x="0" y="1093.6" textLength="12.2" clip-path="url(#breeze-release-management-line-44)">│</text><text class="breeze-release-management-r4" x="24.4" y="1093.6" textLength="292.8" clip-path="url(#breeze-release-management-line-44)">publish-docs-to-s3&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1093.6" textLength="1098" clip-path="url(#breeze-release-management-line-44)">Publishes&#160;doc [...]
-</text><text class="breeze-release-management-r5" x="0" y="1118" textLength="12.2" clip-path="url(#breeze-release-management-line-45)">│</text><text class="breeze-release-management-r4" x="24.4" y="1118" textLength="292.8" clip-path="url(#breeze-release-management-line-45)">check-release-files&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1118" textLength="1098" clip-path="url(#breeze-release-management-line-45)">Verify&#160;that&#160;all&#16 [...]
-</text><text class="breeze-release-management-r5" x="0" y="1142.4" textLength="1464" clip-path="url(#breeze-release-management-line-46)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="1142.4" textLength="12.2" clip-path="url(#breeze-release-management-line-46)">
-</text><text class="breeze-release-management-r5" x="0" y="1166.8" textLength="24.4" clip-path="url(#breeze-release-management-line-47)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="1166.8" textLength="122" clip-path="url(#breeze-release-management-line-47)">&#160;Commands&#160;</text><text class="breeze-release-management-r5" x="146.4" y="1166.8" textLength="1293.2" clip-path="url(#breeze-release-management-line-47)">─────────────────────────────────────────────────── [...]
-</text><text class="breeze-release-management-r5" x="0" y="1191.2" textLength="12.2" clip-path="url(#breeze-release-management-line-48)">│</text><text class="breeze-release-management-r4" x="24.4" y="1191.2" textLength="305" clip-path="url(#breeze-release-management-line-48)">constraints-version-check</text><text class="breeze-release-management-r1" x="353.8" y="1191.2" textLength="1085.8" clip-path="url(#breeze-release-management-line-48)">Check&#160;constraints&#160;against&#160;releas [...]
-</text><text class="breeze-release-management-r5" x="0" y="1215.6" textLength="12.2" clip-path="url(#breeze-release-management-line-49)">│</text><text class="breeze-release-management-r4" x="24.4" y="1215.6" textLength="305" clip-path="url(#breeze-release-management-line-49)">merge-prod-images&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="353.8" y="1215.6" textLength="1085.8" clip-path="url(#breeze-release-management-line-49)">Merge&# [...]
-</text><text class="breeze-release-management-r5" x="0" y="1240" textLength="1464" clip-path="url(#breeze-release-management-line-50)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="1240" textLength="12.2" clip-path="url(#breeze-release-management-line-50)">
+</text><text class="breeze-release-management-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-line-24)">│</text><text class="breeze-release-management-r4" x="24.4" y="605.6" textLength="439.2" clip-path="url(#breeze-release-management-line-24)">update-providers-next-version&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="605.6" textLength="951.6" clip-path="url(#breeze-release-management-line-24)">Updat [...]
+</text><text class="breeze-release-management-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-release-management-line-25)">│</text><text class="breeze-release-management-r4" x="24.4" y="630" textLength="439.2" clip-path="url(#breeze-release-management-line-25)">prepare-provider-distributions&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="630" textLength="951.6" clip-path="url(#breeze-release-management-line-25)">Prepare&#160;sdi [...]
+</text><text class="breeze-release-management-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-line-26)">│</text><text class="breeze-release-management-r4" x="24.4" y="654.4" textLength="439.2" clip-path="url(#breeze-release-management-line-26)">install-provider-distributions&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="654.4" textLength="951.6" clip-path="url(#breeze-release-management-line-26)">Installs&# [...]
+</text><text class="breeze-release-management-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-line-27)">│</text><text class="breeze-release-management-r4" x="24.4" y="678.8" textLength="439.2" clip-path="url(#breeze-release-management-line-27)">verify-provider-distributions&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="678.8" textLength="951.6" clip-path="url(#breeze-release-management-line-27)">Verif [...]
+</text><text class="breeze-release-management-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-line-28)">│</text><text class="breeze-release-management-r4" x="24.4" y="703.2" textLength="439.2" clip-path="url(#breeze-release-management-line-28)">generate-providers-metadata&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="703.2" textLength="951.6" clip-path="url(#breeze-release-management-line- [...]
+</text><text class="breeze-release-management-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-line-29)">│</text><text class="breeze-release-management-r4" x="24.4" y="727.6" textLength="439.2" clip-path="url(#breeze-release-management-line-29)">generate-issue-content-providers&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="727.6" textLength="951.6" clip-path="url(#breeze-release-management-line-29)">Generates&#160;conte [...]
+</text><text class="breeze-release-management-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-release-management-line-30)">│</text><text class="breeze-release-management-r4" x="24.4" y="752" textLength="439.2" clip-path="url(#breeze-release-management-line-30)">clean-old-provider-artifacts&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="752" textLength="951.6" clip-path="url(#breeze-release-management-line-30)">Cleans [...]
+</text><text class="breeze-release-management-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-line-31)">│</text><text class="breeze-release-management-r4" x="24.4" y="776.4" textLength="439.2" clip-path="url(#breeze-release-management-line-31)">tag-providers&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="488" y="776 [...]
+</text><text class="breeze-release-management-r5" x="0" y="800.8" textLength="1464" clip-path="url(#breeze-release-management-line-32)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#breeze-release-management-line-32)">
+</text><text class="breeze-release-management-r5" x="0" y="825.2" textLength="24.4" clip-path="url(#breeze-release-management-line-33)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="825.2" textLength="427" clip-path="url(#breeze-release-management-line-33)">&#160;Airflow&#160;Task&#160;SDK&#160;release&#160;commands&#160;</text><text class="breeze-release-management-r5" x="451.4" y="825.2" textLength="988.2" clip-path="url(#breeze-release-management-line-33)">────────── [...]
+</text><text class="breeze-release-management-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-release-management-line-34)">│</text><text class="breeze-release-management-r4" x="24.4" y="849.6" textLength="512.4" clip-path="url(#breeze-release-management-line-34)">prepare-task-sdk-distributions&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="561.2" y="849.6" textLength="878.4" clip-path="url(#breeze-r [...]
+</text><text class="breeze-release-management-r5" x="0" y="874" textLength="1464" clip-path="url(#breeze-release-management-line-35)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="874" textLength="12.2" clip-path="url(#breeze-release-management-line-35)">
+</text><text class="breeze-release-management-r5" x="0" y="898.4" textLength="24.4" clip-path="url(#breeze-release-management-line-36)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="898.4" textLength="353.8" clip-path="url(#breeze-release-management-line-36)">&#160;airflowctl&#160;release&#160;commands&#160;</text><text class="breeze-release-management-r5" x="378.2" y="898.4" textLength="1061.4" clip-path="url(#breeze-release-management-line-36)">─────────────────────── [...]
+</text><text class="breeze-release-management-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-release-management-line-37)">│</text><text class="breeze-release-management-r4" x="24.4" y="922.8" textLength="585.6" clip-path="url(#breeze-release-management-line-37)">prepare-airflow-ctl-distributions&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="634.4" y="922.8" textLength="805.2" cli [...]
+</text><text class="breeze-release-management-r5" x="0" y="947.2" textLength="1464" clip-path="url(#breeze-release-management-line-38)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="947.2" textLength="12.2" clip-path="url(#breeze-release-management-line-38)">
+</text><text class="breeze-release-management-r5" x="0" y="971.6" textLength="24.4" clip-path="url(#breeze-release-management-line-39)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="971.6" textLength="292.8" clip-path="url(#breeze-release-management-line-39)">&#160;Other&#160;release&#160;commands&#160;</text><text class="breeze-release-management-r5" x="317.2" y="971.6" textLength="1122.4" clip-path="url(#breeze-release-management-line-39)">──────────────────────────── [...]
+</text><text class="breeze-release-management-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-release-management-line-40)">│</text><text class="breeze-release-management-r4" x="24.4" y="996" textLength="292.8" clip-path="url(#breeze-release-management-line-40)">add-back-references&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="996" textLength="1098" clip-path="url(#breeze-release-management-line-40)">Command&#160;to&#160;add&#160;ba [...]
+</text><text class="breeze-release-management-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-release-management-line-41)">│</text><text class="breeze-release-management-r4" x="24.4" y="1020.4" textLength="292.8" clip-path="url(#breeze-release-management-line-41)">prepare-python-client&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1020.4" textLength="1098" clip-path="url(#breeze-release-management-line-41)">Prepares&#160;python&#160;client& [...]
+</text><text class="breeze-release-management-r5" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-release-management-line-42)">│</text><text class="breeze-release-management-r4" x="24.4" y="1044.8" textLength="292.8" clip-path="url(#breeze-release-management-line-42)">publish-docs&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1044.8" textLength="1098" clip-path="url(#breeze-release-managemen [...]
+</text><text class="breeze-release-management-r5" x="0" y="1069.2" textLength="12.2" clip-path="url(#breeze-release-management-line-43)">│</text><text class="breeze-release-management-r4" x="24.4" y="1069.2" textLength="292.8" clip-path="url(#breeze-release-management-line-43)">generate-constraints&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1069.2" textLength="1098" clip-path="url(#breeze-release-management-line-43)">Generates&#160;pinned&#160;c [...]
+</text><text class="breeze-release-management-r5" x="0" y="1093.6" textLength="12.2" clip-path="url(#breeze-release-management-line-44)">│</text><text class="breeze-release-management-r4" x="24.4" y="1093.6" textLength="292.8" clip-path="url(#breeze-release-management-line-44)">update-constraints&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1093.6" textLength="1098" clip-path="url(#breeze-release-management-line-44)">Update&#160;releas [...]
+</text><text class="breeze-release-management-r5" x="0" y="1118" textLength="12.2" clip-path="url(#breeze-release-management-line-45)">│</text><text class="breeze-release-management-r4" x="24.4" y="1118" textLength="292.8" clip-path="url(#breeze-release-management-line-45)">publish-docs-to-s3&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1118" textLength="1098" clip-path="url(#breeze-release-management-line-45)">Publishes&#160;docs&#160 [...]
+</text><text class="breeze-release-management-r5" x="0" y="1142.4" textLength="12.2" clip-path="url(#breeze-release-management-line-46)">│</text><text class="breeze-release-management-r4" x="24.4" y="1142.4" textLength="292.8" clip-path="url(#breeze-release-management-line-46)">check-release-files&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="341.6" y="1142.4" textLength="1098" clip-path="url(#breeze-release-management-line-46)">Verify&#160;that&#160;a [...]
+</text><text class="breeze-release-management-r5" x="0" y="1166.8" textLength="1464" clip-path="url(#breeze-release-management-line-47)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="1166.8" textLength="12.2" clip-path="url(#breeze-release-management-line-47)">
+</text><text class="breeze-release-management-r5" x="0" y="1191.2" textLength="24.4" clip-path="url(#breeze-release-management-line-48)">╭─</text><text class="breeze-release-management-r5" x="24.4" y="1191.2" textLength="122" clip-path="url(#breeze-release-management-line-48)">&#160;Commands&#160;</text><text class="breeze-release-management-r5" x="146.4" y="1191.2" textLength="1293.2" clip-path="url(#breeze-release-management-line-48)">─────────────────────────────────────────────────── [...]
+</text><text class="breeze-release-management-r5" x="0" y="1215.6" textLength="12.2" clip-path="url(#breeze-release-management-line-49)">│</text><text class="breeze-release-management-r4" x="24.4" y="1215.6" textLength="305" clip-path="url(#breeze-release-management-line-49)">constraints-version-check</text><text class="breeze-release-management-r1" x="353.8" y="1215.6" textLength="1085.8" clip-path="url(#breeze-release-management-line-49)">Check&#160;constraints&#160;against&#160;releas [...]
+</text><text class="breeze-release-management-r5" x="0" y="1240" textLength="12.2" clip-path="url(#breeze-release-management-line-50)">│</text><text class="breeze-release-management-r4" x="24.4" y="1240" textLength="305" clip-path="url(#breeze-release-management-line-50)">merge-prod-images&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="breeze-release-management-r1" x="353.8" y="1240" textLength="1085.8" clip-path="url(#breeze-release-management-line-50)">Merge&#160;pr [...]
+</text><text class="breeze-release-management-r5" x="0" y="1264.4" textLength="1464" clip-path="url(#breeze-release-management-line-51)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-r1" x="1464" y="1264.4" textLength="12.2" clip-path="url(#breeze-release-management-line-51)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_release-management.txt b/dev/breeze/doc/images/output_release-management.txt
index 04d1453a712..74e81545457 100644
--- a/dev/breeze/doc/images/output_release-management.txt
+++ b/dev/breeze/doc/images/output_release-management.txt
@@ -1 +1 @@
-eac5e457db3b3fa57c5180ad88ee7c05
+adf95164020fa37164c778e10dcdaa36
diff --git a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg
index 16a1bc10274..1036ffeb24e 100644
--- a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg
+++ b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 757.5999999999999" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 733.1999999999999" xmlns="http://www.w3.org/2000/svg">
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-release-management-generate-issue-content-providers-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="706.5999999999999" />
+      <rect x="0" y="0" width="1463.0" height="682.1999999999999" />
     </clipPath>
     <clipPath id="breeze-release-management-generate-issue-content-providers-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -126,12 +126,9 @@
 <clipPath id="breeze-release-management-generate-issue-content-providers-line-26">
     <rect x="0" y="635.9" width="1464" height="24.65"/>
             </clipPath>
-<clipPath id="breeze-release-management-generate-issue-content-providers-line-27">
-    <rect x="0" y="660.3" width="1464" height="24.65"/>
-            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="755.6" rx="8"/><text class="breeze-release-management-generate-issue-content-providers-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;generate-issue-content-providers</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="731.2" rx="8"/><text class="breeze-release-management-generate-issue-content-providers-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;generate-issue-content-providers</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -158,18 +155,17 @@
 </text><text class="breeze-release-management-generate-issue-content-providers-r1" x="12.2" y="361.6" textLength="585.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-14)">Generates&#160;content&#160;for&#160;issue&#160;to&#160;test&#160;the&#160;release.</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-14)">
 </text><text class="breeze-release-management-generate-issue-content-providers-r1" x="1464" y="386" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-15)">
 </text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="410.4" textLength="24.4" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-16)">╭─</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="24.4" y="410.4" textLength="366" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-16)">&#160;Generate&#160;issue&#160;content&#160;flags&#160;</text><text class="breeze-re [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="434.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-17)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="434.8" textLength="219.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-17)">--disable-progress</text><text class="breeze-release-management-generate-issue-cont [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="459.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-18)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="459.2" textLength="219.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-18)">--excluded-pr-list</text><text class="breeze-release-management-generate-issue-cont [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-19)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="483.6" textLength="170.8" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-19)">--github-token</text><text class="breeze-release-management-generate-issue-content- [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-20)">│</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="378.2" y="508" textLength="1061.4" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-20)">variable&#160;set.&#160;Can&#160;be&#160;generated&#160;with:&#160;&#160;&#160;&#160; [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-21)">│</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="378.2" y="532.4" textLength="1061.4" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-21)">https://github.com/settings/tokens/new?description=Read%20sssues&amp;scopes=repo: [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-22)">│</text><text class="breeze-release-management-generate-issue-content-providers-r6" x="378.2" y="556.8" textLength="1061.4" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-22)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-23)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="581.2" textLength="292.8" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-23)">--only-available-in-dist</text><text class="breeze-release-management-generate-issu [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-24)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="605.6" textLength="305" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-24)">--no-include-browser-link</text><text class="breeze-release-management-generate-issue [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="630" textLength="1464" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-25)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="1464" y="630" textLength="12.2" clip-path="url(#breeze-release-management-generate-iss [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="654.4" textLength="24.4" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-26)">╭─</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="24.4" y="654.4" textLength="195.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-26)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-gener [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-27)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="678.8" textLength="73.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-27)">--help</text><text class="breeze-release-management-generate-issue-content-providers [...]
-</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="703.2" textLength="1464" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-28)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-generate [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="434.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-17)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="434.8" textLength="219.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-17)">--disable-progress</text><text class="breeze-release-management-generate-issue-cont [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="459.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-18)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="459.2" textLength="219.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-18)">--excluded-pr-list</text><text class="breeze-release-management-generate-issue-cont [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-19)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="483.6" textLength="170.8" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-19)">--github-token</text><text class="breeze-release-management-generate-issue-content- [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-20)">│</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="366" y="508" textLength="1073.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-20)">variable&#160;set.&#160;Can&#160;be&#160;generated&#160;with:&#160;&#160;&#160;&#160;&# [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-21)">│</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="366" y="532.4" textLength="1073.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-21)">https://github.com/settings/tokens/new?description=Read%20sssues&amp;scopes=repo:st [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-22)">│</text><text class="breeze-release-management-generate-issue-content-providers-r6" x="366" y="556.8" textLength="1073.6" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-22)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-23)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="581.2" textLength="292.8" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-23)">--only-available-in-dist</text><text class="breeze-release-management-generate-issu [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="605.6" textLength="1464" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-24)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-generate [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="630" textLength="24.4" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-25)">╭─</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="24.4" y="630" textLength="195.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-25)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-generate- [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-26)">│</text><text class="breeze-release-management-generate-issue-content-providers-r4" x="24.4" y="654.4" textLength="73.2" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-26)">--help</text><text class="breeze-release-management-generate-issue-content-providers [...]
+</text><text class="breeze-release-management-generate-issue-content-providers-r5" x="0" y="678.8" textLength="1464" clip-path="url(#breeze-release-management-generate-issue-content-providers-line-27)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-generate-issue-content-providers-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-generate [...]
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt
index 9d4f5e8d26c..2e7720d4e17 100644
--- a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt
+++ b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt
@@ -1 +1 @@
-c025f2c9ea1fa5f8b3e3e5b8f01dcd6d
+4a8d979dd9f841744b5b400de502144b
diff --git a/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.svg b/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.svg
index 996c438385a..f07b12057bd 100644
--- a/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.svg
+++ b/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 367.2" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 440.4" xmlns="http://www.w3.org/2000/svg">
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-release-management-prepare-helm-chart-package-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="316.2" />
+      <rect x="0" y="0" width="1463.0" height="389.4" />
     </clipPath>
     <clipPath id="breeze-release-management-prepare-helm-chart-package-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -81,9 +81,18 @@
 <clipPath id="breeze-release-management-prepare-helm-chart-package-line-11">
     <rect x="0" y="269.9" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-release-management-prepare-helm-chart-package-line-12">
+    <rect x="0" y="294.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-helm-chart-package-line-13">
+    <rect x="0" y="318.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-helm-chart-package-line-14">
+    <rect x="0" y="343.1" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="365.2" rx="8"/><text class="breeze-release-management-prepare-helm-chart-package-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;prepare-helm-chart-package</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="438.4" rx="8"/><text class="breeze-release-management-prepare-helm-chart-package-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;prepare-helm-chart-package</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -99,13 +108,16 @@
 </text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="12.2" y="93.2" textLength="341.6" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-3)">Prepares&#160;helm&#160;chart&#160;package.</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-3)">
 </text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-4)">
 </text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="142" textLength="24.4" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-5)">╭─</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="24.4" y="142" textLength="183" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-5)">&#160;Package&#160;flags&#160;</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="207. [...]
-</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-6)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="166.4" textLength="146.4" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-6)">--sign-email</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="219.6" y="166.4"  [...]
-</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="190.8" textLength="1464" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-7)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package- [...]
-</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="215.2" textLength="24.4" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-8)">╭─</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="24.4" y="215.2" textLength="195.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-8)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-prepare-helm-chart-package-r5"  [...]
-</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="239.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-9)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="239.6" textLength="109.8" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-9)">--dry-run</text><text class="breeze-release-management-prepare-helm-chart-package-r7" x="158.6" y="239.6" tex [...]
-</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="264" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-10)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="264" textLength="109.8" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-10)">--verbose</text><text class="breeze-release-management-prepare-helm-chart-package-r7" x="158.6" y="264" textLen [...]
-</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="288.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-11)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="288.4" textLength="73.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-11)">--help</text><text class="breeze-release-management-prepare-helm-chart-package-r7" x="158.6" y="288.4" textL [...]
-</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="312.8" textLength="1464" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-12)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-6)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="166.4" textLength="146.4" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-6)">--sign-email</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="268.4" y="166.4"  [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-7)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="190.8" textLength="195.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-7)">--version-suffix</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="268.4" y="190 [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="215.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-8)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="268.4" y="215.2" textLength="1171.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-8)">replaced&#160;with&#160;staging&#160;URLs.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="239.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-9)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r6" x="268.4" y="239.6" textLength="1171.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-9)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="264" textLength="1464" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-10)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="1464" y="264" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-10)">
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="288.4" textLength="24.4" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-11)">╭─</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="24.4" y="288.4" textLength="195.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-11)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-prepare-helm-chart-package-r5 [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="312.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-12)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="312.8" textLength="109.8" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-12)">--dry-run</text><text class="breeze-release-management-prepare-helm-chart-package-r7" x="158.6" y="312.8" t [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-13)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="337.2" textLength="109.8" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-13)">--verbose</text><text class="breeze-release-management-prepare-helm-chart-package-r7" x="158.6" y="337.2" t [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-14)">│</text><text class="breeze-release-management-prepare-helm-chart-package-r4" x="24.4" y="361.6" textLength="73.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-14)">--help</text><text class="breeze-release-management-prepare-helm-chart-package-r7" x="158.6" y="361.6" textL [...]
+</text><text class="breeze-release-management-prepare-helm-chart-package-r5" x="0" y="386" textLength="1464" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-15)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-helm-chart-package-r1" x="1464" y="386" textLength="12.2" clip-path="url(#breeze-release-management-prepare-helm-chart-package-line-15)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.txt b/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.txt
index 6051dbc2d79..73731275785 100644
--- a/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.txt
+++ b/dev/breeze/doc/images/output_release-management_prepare-helm-chart-package.txt
@@ -1 +1 @@
-27169c83fcbcca907a0b32a5c4faeb48
+4d19d7c6652330646ee94bf409c14787
diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg
index 35e62f8a7e7..ff5a15defb9 100644
--- a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg
+++ b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg
@@ -215,7 +215,7 @@
 </text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-29)">│</text><text class="breeze-release-management-prepare-provider-distributions-r1" x="475.8" y="727.6" textLength="963.8" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-29)">.post1,&#160;.post2&#160;etc.).&#160;Note&#160;the&#160;`.`&#160;is&#160;need&#160;in&#160 [...]
 </text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-30)">│</text><text class="breeze-release-management-prepare-provider-distributions-r1" x="475.8" y="752" textLength="963.8" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-30)">followed&#160;with&#160;+local_version&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
 </text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-31)">│</text><text class="breeze-release-management-prepare-provider-distributions-r7" x="475.8" y="776.4" textLength="963.8" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-31)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
-</text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-32)">│</text><text class="breeze-release-management-prepare-provider-distributions-r4" x="24.4" y="800.8" textLength="244" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-32)">--distributions-list</text><text class="breeze-release-management-prepare-provider-distributi [...]
+</text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-32)">│</text><text class="breeze-release-management-prepare-provider-distributions-r4" x="24.4" y="800.8" textLength="244" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-32)">--distributions-list</text><text class="breeze-release-management-prepare-provider-distributi [...]
 </text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-33)">│</text><text class="breeze-release-management-prepare-provider-distributions-r1" x="475.8" y="825.2" textLength="963.8" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-33)">documentation&#160;building,&#160;and&#160;document&#160;publishing.&#160;It&#160;is&#160; [...]
 </text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-34)">│</text><text class="breeze-release-management-prepare-provider-distributions-r1" x="475.8" y="849.6" textLength="963.8" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-34)">adding&#160;individual&#160;packages&#160;as&#160;arguments&#160;to&#160;every&#160;comman [...]
 </text><text class="breeze-release-management-prepare-provider-distributions-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-35)">│</text><text class="breeze-release-management-prepare-provider-distributions-r1" x="475.8" y="874" textLength="963.8" clip-path="url(#breeze-release-management-prepare-provider-distributions-line-35)">packages&#160;passed&#160;as&#160;arguments.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt
index d9a7af41394..8d2300bf36f 100644
--- a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt
+++ b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt
@@ -1 +1 @@
-1d031671d50f0a45410fda366afe659f
+92b4cf987fa3fa7bf32c06a96408a1c6
diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg
index b615329317a..2b6b595341c 100644
--- a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg
+++ b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 1074.8" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 1343.1999999999998" xmlns="http://www.w3.org/2000/svg">
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -43,7 +43,7 @@
 
     <defs>
     <clipPath id="breeze-release-management-prepare-provider-documentation-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="1023.8" />
+      <rect x="0" y="0" width="1463.0" height="1292.1999999999998" />
     </clipPath>
     <clipPath id="breeze-release-management-prepare-provider-documentation-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -168,9 +168,42 @@
 <clipPath id="breeze-release-management-prepare-provider-documentation-line-40">
     <rect x="0" y="977.5" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-41">
+    <rect x="0" y="1001.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-42">
+    <rect x="0" y="1026.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-43">
+    <rect x="0" y="1050.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-44">
+    <rect x="0" y="1075.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-45">
+    <rect x="0" y="1099.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-46">
+    <rect x="0" y="1123.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-47">
+    <rect x="0" y="1148.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-48">
+    <rect x="0" y="1172.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-49">
+    <rect x="0" y="1197.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-50">
+    <rect x="0" y="1221.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-prepare-provider-documentation-line-51">
+    <rect x="0" y="1245.9" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="1072.8" rx="8"/><text class="breeze-release-management-prepare-provider-documentation-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;prepare-provider-documentation</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="1341.2" rx="8"/><text class="breeze-release-management-prepare-provider-documentation-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;prepare-provider-documentation</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -196,32 +229,43 @@
 </text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-13)">
 </text><text class="breeze-release-management-prepare-provider-documentation-r1" x="12.2" y="361.6" textLength="780.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-14)">Prepare&#160;CHANGELOG,&#160;README&#160;and&#160;COMMITS&#160;information&#160;for&#160;providers.</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation- [...]
 </text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="386" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-15)">
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="410.4" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-16)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="410.4" textLength="512.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-16)">&#160;Provider&#160;documentation&#160;preparation&#160;flags&#160;</text><text class="bre [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="434.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-17)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="434.8" textLength="158.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-17)">--base-branch</text><text class="breeze-release-management-prepare-provider-documentation-r [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="459.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-18)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="451.4" y="459.2" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-18)">old&#160;branch)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">│</text><text class="breeze-release-management-prepare-provider-documentation-r6" x="451.4" y="483.6" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="508" textLength="231.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">--github-repository</text><text class="breeze-release-management-prepare-provider-documentation [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="532.4" textLength="353.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">--include-not-ready-providers</text><text class="breeze-release-management-prepare-provider [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="556.8" textLength="329.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">--include-removed-providers</text><text class="breeze-release-management-prepare-provider-d [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="581.2" textLength="207.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">--non-interactive</text><text class="breeze-release-management-prepare-provider-documentati [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="451.4" y="605.6" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">confirms&#160;releasefor&#160;providers&#160;prepared&#160;for&#160;release&#160;-&#160;us [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="451.4" y="630" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">non-interactive&#160;mode&#160;in&#160;CI.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="654.4" textLength="305" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">--only-min-version-update</text><text class="breeze-release-management-prepare-provider-docum [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="451.4" y="678.8" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">documentation&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="703.2" textLength="292.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">--reapply-templates-only</text><text class="breeze-release-management-prepare-provider-docu [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="451.4" y="727.6" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">you&#160;need&#160;to&#160;regenerate&#160;documentation.&#160;&#160;&#160;&#160;&#160;&#1 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="752" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">--skip-git-fetch</text><text class="breeze-release-management-prepare-provider-documentation-r1 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="451.4" y="776.4" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">default,&#160;the&#160;remote&#160;is&#160;recreated&#160;and&#160;fetched&#160;to&#160;ma [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="451.4" y="800.8" textLength="988.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">and&#160;that&#160;recent&#160;commits&#160;are&#160;not&#160;missing&#160;&#160;&#160;&#1 [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-33)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="825.2" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-33)">--skip-changelog</text><text class="breeze-release-management-prepare-provider-documentatio [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="849.6" textLength="158.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)">--skip-readme</text><text class="breeze-release-management-prepare-provider-documentation-r [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="874" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-35)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="874" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-d [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="898.4" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="898.4" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-prepare-provi [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-37)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="922.8" textLength="109.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-37)">--verbose</text><text class="breeze-release-management-prepare-provider-documentation-r7" x [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="947.2" textLength="97.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)">--answer</text><text class="breeze-release-management-prepare-provider-documentation-r7" x=" [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-39)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="971.6" textLength="109.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-39)">--dry-run</text><text class="breeze-release-management-prepare-provider-documentation-r7" x [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-40)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="996" textLength="73.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-40)">--help</text><text class="breeze-release-management-prepare-provider-documentation-r7" x="158.6" [...]
-</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1020.4" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-41)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="1020.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-prov [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="410.4" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-16)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="410.4" textLength="378.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-16)">&#160;Documentation&#160;generation&#160;mode&#160;</text><text class="breeze-release-mana [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="434.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-17)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="434.8" textLength="170.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-17)">--release-date</text><text class="breeze-release-management-prepare-provider-documentation- [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="459.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-18)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="378.2" y="459.2" textLength="1061.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-18)">2025-11-16&#160;or&#160;2025-11-16_01).&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">│</text><text class="breeze-release-management-prepare-provider-documentation-r6" x="378.2" y="483.6" textLength="1061.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="508" textLength="244" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">--incremental-update</text><text class="breeze-release-management-prepare-provider-documentation- [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="378.2" y="532.4" textLength="1061.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">changes.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="556.8" textLength="305" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">--only-min-version-update</text><text class="breeze-release-management-prepare-provider-docum [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="378.2" y="581.2" textLength="1061.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">documentation&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="605.6" textLength="292.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">--reapply-templates-only</text><text class="breeze-release-management-prepare-provider-docu [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="378.2" y="630" textLength="1061.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">need&#160;to&#160;regenerate&#160;documentation.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="654.4" textLength="207.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">--non-interactive</text><text class="breeze-release-management-prepare-provider-documentati [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="378.2" y="678.8" textLength="1061.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">confirms&#160;releasefor&#160;providers&#160;prepared&#160;for&#160;release&#160;-&#160;u [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="378.2" y="703.2" textLength="1061.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">non-interactive&#160;mode&#160;in&#160;CI.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="727.6" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provid [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="752" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="752" textLength="366" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">&#160;Select&#160;non-regular&#160;providers&#160;</text><text class="breeze-release-management- [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="776.4" textLength="353.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">--include-not-ready-providers</text><text class="breeze-release-management-prepare-provider [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="800.8" textLength="329.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">--include-removed-providers</text><text class="breeze-release-management-prepare-provider-d [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="825.2" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-33)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provid [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="849.6" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="849.6" textLength="146.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)">&#160;Skip&#160;steps&#160;</text><text class="breeze-release-management-prepare-provider- [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-35)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="874" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-35)">--skip-git-fetch</text><text class="breeze-release-management-prepare-provider-documentation-r1 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="268.4" y="898.4" textLength="1171.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">remote&#160;is&#160;recreated&#160;and&#160;fetched&#160;to&#160;make&#160;sure&#160;that [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-37)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="268.4" y="922.8" textLength="1171.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-37)">not&#160;missing&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="947.2" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)">--skip-changelog</text><text class="breeze-release-management-prepare-provider-documentatio [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-39)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="971.6" textLength="158.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-39)">--skip-readme</text><text class="breeze-release-management-prepare-provider-documentation-r [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="996" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-40)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="996" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-d [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1020.4" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-41)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="1020.4" textLength="219.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-41)">&#160;Advanced&#160;options&#160;</text><text class="breeze-release-management-prepare-p [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-42)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="1044.8" textLength="158.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-42)">--base-branch</text><text class="breeze-release-management-prepare-provider-documentation [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1069.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-43)">│</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="329.4" y="1069.2" textLength="1110.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-43)">branch)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1093.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-44)">│</text><text class="breeze-release-management-prepare-provider-documentation-r6" x="329.4" y="1093.6" textLength="1110.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-44)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1118" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-45)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="1118" textLength="231.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-45)">--github-repository</text><text class="breeze-release-management-prepare-provider-documentati [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1142.4" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-46)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="1142.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-prov [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1166.8" textLength="24.4" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-47)">╭─</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="24.4" y="1166.8" textLength="195.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-47)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-prepare-pro [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1191.2" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-48)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="1191.2" textLength="109.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-48)">--verbose</text><text class="breeze-release-management-prepare-provider-documentation-r7" [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1215.6" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-49)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="1215.6" textLength="97.6" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-49)">--answer</text><text class="breeze-release-management-prepare-provider-documentation-r7" x [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1240" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-50)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="1240" textLength="109.8" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-50)">--dry-run</text><text class="breeze-release-management-prepare-provider-documentation-r7" x=" [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1264.4" textLength="12.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-51)">│</text><text class="breeze-release-management-prepare-provider-documentation-r4" x="24.4" y="1264.4" textLength="73.2" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-51)">--help</text><text class="breeze-release-management-prepare-provider-documentation-r7" x=" [...]
+</text><text class="breeze-release-management-prepare-provider-documentation-r5" x="0" y="1288.8" textLength="1464" clip-path="url(#breeze-release-management-prepare-provider-documentation-line-52)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-prepare-provider-documentation-r1" x="1464" y="1288.8" textLength="12.2" clip-path="url(#breeze-release-management-prepare-prov [...]
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt
index 638ef96ff40..4be325bf750 100644
--- a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt
+++ b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt
@@ -1 +1 @@
-b3476f20044a01072d03971ddea1b6c4
+df4caa6f639503f0f0da3fe91e7cf1b0
diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.svg b/dev/breeze/doc/images/output_release-management_publish-docs.svg
index 91f36f758b8..149b660fda1 100644
--- a/dev/breeze/doc/images/output_release-management_publish-docs.svg
+++ b/dev/breeze/doc/images/output_release-management_publish-docs.svg
@@ -211,7 +211,7 @@
 </text><text class="breeze-release-management-publish-docs-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-23)">│</text><text class="breeze-release-management-publish-docs-r1" x="488" y="581.2" textLength="951.6" clip-path="url(#breeze-release-management-publish-docs-line-23)">matching&#160;the&#160;full&#160;package&#160;name,&#160;for&#160;example&#160;`apache-airflow-providers-*`.&#160;&#160;&#160;&#160;&#160;</text><text class="breeze [...]
 </text><text class="breeze-release-management-publish-docs-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-24)">│</text><text class="breeze-release-management-publish-docs-r1" x="488" y="605.6" textLength="951.6" clip-path="url(#breeze-release-management-publish-docs-line-24)">Useful&#160;when&#160;you&#160;want&#160;to&#160;selectseveral&#160;similarly&#160;named&#160;packages&#160;together.&#160;&#160;&#160;&#160;&#160;&#160;</text><tex [...]
 </text><text class="breeze-release-management-publish-docs-r5" x="0" y="630" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-25)">│</text><text class="breeze-release-management-publish-docs-r8" x="488" y="630" textLength="951.6" clip-path="url(#breeze-release-management-publish-docs-line-25)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
-</text><text class="breeze-release-management-publish-docs-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-26)">│</text><text class="breeze-release-management-publish-docs-r4" x="61" y="654.4" textLength="244" clip-path="url(#breeze-release-management-publish-docs-line-26)">--distributions-list</text><text class="breeze-release-management-publish-docs-r1" x="488" y="654.4" textLength="951.6" clip-path="url(#breeze-release-management-publi [...]
+</text><text class="breeze-release-management-publish-docs-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-26)">│</text><text class="breeze-release-management-publish-docs-r4" x="61" y="654.4" textLength="244" clip-path="url(#breeze-release-management-publish-docs-line-26)">--distributions-list</text><text class="breeze-release-management-publish-docs-r1" x="488" y="654.4" textLength="951.6" clip-path="url(#breeze-release-management-publi [...]
 </text><text class="breeze-release-management-publish-docs-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-27)">│</text><text class="breeze-release-management-publish-docs-r1" x="488" y="678.8" textLength="951.6" clip-path="url(#breeze-release-management-publish-docs-line-27)">documentation&#160;building,&#160;and&#160;document&#160;publishing.&#160;It&#160;is&#160;an&#160;easier&#160;alternative&#160;&#160;</text><text class="breeze-rele [...]
 </text><text class="breeze-release-management-publish-docs-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-28)">│</text><text class="breeze-release-management-publish-docs-r1" x="488" y="703.2" textLength="951.6" clip-path="url(#breeze-release-management-publish-docs-line-28)">to&#160;adding&#160;individual&#160;packages&#160;as&#160;arguments&#160;to&#160;every&#160;command.&#160;This&#160;overrides&#160;&#160;&#160;</text><text class="b [...]
 </text><text class="breeze-release-management-publish-docs-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-release-management-publish-docs-line-29)">│</text><text class="breeze-release-management-publish-docs-r1" x="488" y="727.6" textLength="951.6" clip-path="url(#breeze-release-management-publish-docs-line-29)">the&#160;packages&#160;passed&#160;as&#160;arguments.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.txt b/dev/breeze/doc/images/output_release-management_publish-docs.txt
index 7b07e4d1e09..32edfe4bad9 100644
--- a/dev/breeze/doc/images/output_release-management_publish-docs.txt
+++ b/dev/breeze/doc/images/output_release-management_publish-docs.txt
@@ -1 +1 @@
-90b3e65f6dfe76c5580f0cb3880e688a
+a67dcc78f2f47fb5e9a3081485d38a77
diff --git a/dev/breeze/doc/images/output_release-management_tag-providers.svg b/dev/breeze/doc/images/output_release-management_tag-providers.svg
index 00ac6b5bee3..11d454ad8f8 100644
--- a/dev/breeze/doc/images/output_release-management_tag-providers.svg
+++ b/dev/breeze/doc/images/output_release-management_tag-providers.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 416.0" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 464.79999999999995" xmlns="http://www.w3.org/2000/svg">
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -37,12 +37,15 @@
 .breeze-release-management-tag-providers-r3 { fill: #c5c8c6;font-weight: bold }
 .breeze-release-management-tag-providers-r4 { fill: #68a0b3;font-weight: bold }
 .breeze-release-management-tag-providers-r5 { fill: #868887 }
-.breeze-release-management-tag-providers-r6 { fill: #98a84b;font-weight: bold }
+.breeze-release-management-tag-providers-r6 { fill: #cc555a }
+.breeze-release-management-tag-providers-r7 { fill: #8d7b39 }
+.breeze-release-management-tag-providers-r8 { fill: #8a4346 }
+.breeze-release-management-tag-providers-r9 { fill: #98a84b;font-weight: bold }
     </style>
 
     <defs>
     <clipPath id="breeze-release-management-tag-providers-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="365.0" />
+      <rect x="0" y="0" width="1463.0" height="413.79999999999995" />
     </clipPath>
     <clipPath id="breeze-release-management-tag-providers-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -86,9 +89,15 @@
 <clipPath id="breeze-release-management-tag-providers-line-13">
     <rect x="0" y="318.7" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-release-management-tag-providers-line-14">
+    <rect x="0" y="343.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-tag-providers-line-15">
+    <rect x="0" y="367.5" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="414" rx="8"/><text class="breeze-release-management-tag-providers-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;tag-providers</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="462.8" rx="8"/><text class="breeze-release-management-tag-providers-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;tag-providers</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -104,15 +113,17 @@
 </text><text class="breeze-release-management-tag-providers-r1" x="12.2" y="93.2" textLength="549" clip-path="url(#breeze-release-management-tag-providers-line-3)">Generates&#160;tags&#160;for&#160;airflow&#160;provider&#160;releases.</text><text class="breeze-release-management-tag-providers-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-3)">
 </text><text class="breeze-release-management-tag-providers-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-4)">
 </text><text class="breeze-release-management-tag-providers-r5" x="0" y="142" textLength="24.4" clip-path="url(#breeze-release-management-tag-providers-line-5)">╭─</text><text class="breeze-release-management-tag-providers-r5" x="24.4" y="142" textLength="280.6" clip-path="url(#breeze-release-management-tag-providers-line-5)">&#160;Add&#160;tags&#160;to&#160;providers&#160;</text><text class="breeze-release-management-tag-providers-r5" x="305" y="142" textLength="1134.6" clip-path="url(# [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-6)">│</text><text class="breeze-release-management-tag-providers-r4" x="24.4" y="166.4" textLength="219.6" clip-path="url(#breeze-release-management-tag-providers-line-6)">--clean-local-tags</text><text class="breeze-release-management-tag-providers-r1" x="244" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-t [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-7)">│</text><text class="breeze-release-management-tag-providers-r1" x="561.2" y="190.8" textLength="878.4" clip-path="url(#breeze-release-management-tag-providers-line-7)">avoid&#160;errors.&#160;The&#160;default&#160;behaviour&#160;would&#160;be&#160;to&#160;clean&#160;such&#160;local&#160;tags.&#160;&#160;</text><text class="bre [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="215.2" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-8)">│</text><text class="breeze-release-management-tag-providers-r5" x="561.2" y="215.2" textLength="878.4" clip-path="url(#breeze-release-management-tag-providers-line-8)">[default:&#160;clean-local-tags]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="239.6" textLength="1464" clip-path="url(#breeze-release-management-tag-providers-line-9)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-tag-providers-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-9)">
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="264" textLength="24.4" clip-path="url(#breeze-release-management-tag-providers-line-10)">╭─</text><text class="breeze-release-management-tag-providers-r5" x="24.4" y="264" textLength="195.2" clip-path="url(#breeze-release-management-tag-providers-line-10)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-tag-providers-r5" x="219.6" y="264" textLength="1220" clip-path="url(#breeze-release- [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="288.4" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-11)">│</text><text class="breeze-release-management-tag-providers-r4" x="24.4" y="288.4" textLength="109.8" clip-path="url(#breeze-release-management-tag-providers-line-11)">--dry-run</text><text class="breeze-release-management-tag-providers-r6" x="158.6" y="288.4" textLength="24.4" clip-path="url(#breeze-release-management-tag-pr [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="312.8" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-12)">│</text><text class="breeze-release-management-tag-providers-r4" x="24.4" y="312.8" textLength="109.8" clip-path="url(#breeze-release-management-tag-providers-line-12)">--verbose</text><text class="breeze-release-management-tag-providers-r6" x="158.6" y="312.8" textLength="24.4" clip-path="url(#breeze-release-management-tag-pr [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-13)">│</text><text class="breeze-release-management-tag-providers-r4" x="24.4" y="337.2" textLength="73.2" clip-path="url(#breeze-release-management-tag-providers-line-13)">--help</text><text class="breeze-release-management-tag-providers-r6" x="158.6" y="337.2" textLength="24.4" clip-path="url(#breeze-release-management-tag-provid [...]
-</text><text class="breeze-release-management-tag-providers-r5" x="0" y="361.6" textLength="1464" clip-path="url(#breeze-release-management-tag-providers-line-14)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-tag-providers-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-14)">
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-6)">│</text><text class="breeze-release-management-tag-providers-r4" x="61" y="166.4" textLength="146.4" clip-path="url(#breeze-release-management-tag-providers-line-6)">--clean-tags</text><text class="breeze-release-management-tag-providers-r1" x="207.4" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-tag-pro [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-7)">│</text><text class="breeze-release-management-tag-providers-r1" x="451.4" y="190.8" textLength="988.2" clip-path="url(#breeze-release-management-tag-providers-line-7)">issues&#160;to&#160;avoid&#160;errors.&#160;The&#160;default&#160;behaviour&#160;would&#160;be&#160;to&#160;clean&#160;both&#160;local&#160;and&#160;&#160;&#160 [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="215.2" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-8)">│</text><text class="breeze-release-management-tag-providers-r1" x="451.4" y="215.2" textLength="988.2" clip-path="url(#breeze-release-management-tag-providers-line-8)">remote&#160;tags.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="239.6" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-9)">│</text><text class="breeze-release-management-tag-providers-r5" x="451.4" y="239.6" textLength="988.2" clip-path="url(#breeze-release-management-tag-providers-line-9)">[default:&#160;clean-tags]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="264" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-10)">│</text><text class="breeze-release-management-tag-providers-r6" x="24.4" y="264" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-10)">*</text><text class="breeze-release-management-tag-providers-r4" x="61" y="264" textLength="170.8" clip-path="url(#breeze-release-management-tag-providers-line-10)" [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="288.4" textLength="1464" clip-path="url(#breeze-release-management-tag-providers-line-11)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-tag-providers-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-11)">
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="312.8" textLength="24.4" clip-path="url(#breeze-release-management-tag-providers-line-12)">╭─</text><text class="breeze-release-management-tag-providers-r5" x="24.4" y="312.8" textLength="195.2" clip-path="url(#breeze-release-management-tag-providers-line-12)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-tag-providers-r5" x="219.6" y="312.8" textLength="1220" clip-path="url(#breeze-re [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-13)">│</text><text class="breeze-release-management-tag-providers-r4" x="24.4" y="337.2" textLength="109.8" clip-path="url(#breeze-release-management-tag-providers-line-13)">--dry-run</text><text class="breeze-release-management-tag-providers-r9" x="158.6" y="337.2" textLength="24.4" clip-path="url(#breeze-release-management-tag-pr [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-14)">│</text><text class="breeze-release-management-tag-providers-r4" x="24.4" y="361.6" textLength="109.8" clip-path="url(#breeze-release-management-tag-providers-line-14)">--verbose</text><text class="breeze-release-management-tag-providers-r9" x="158.6" y="361.6" textLength="24.4" clip-path="url(#breeze-release-management-tag-pr [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="386" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-15)">│</text><text class="breeze-release-management-tag-providers-r4" x="24.4" y="386" textLength="73.2" clip-path="url(#breeze-release-management-tag-providers-line-15)">--help</text><text class="breeze-release-management-tag-providers-r9" x="158.6" y="386" textLength="24.4" clip-path="url(#breeze-release-management-tag-providers-li [...]
+</text><text class="breeze-release-management-tag-providers-r5" x="0" y="410.4" textLength="1464" clip-path="url(#breeze-release-management-tag-providers-line-16)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-tag-providers-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#breeze-release-management-tag-providers-line-16)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_release-management_tag-providers.txt b/dev/breeze/doc/images/output_release-management_tag-providers.txt
index eb987987e51..3b892e2f68d 100644
--- a/dev/breeze/doc/images/output_release-management_tag-providers.txt
+++ b/dev/breeze/doc/images/output_release-management_tag-providers.txt
@@ -1 +1 @@
-403dae670f839e37c83baa15ac65af9a
+c9affbadf2d92903409f2c73cba6bfd2
diff --git a/dev/breeze/doc/images/output_release-management_update-providers-next-version.svg b/dev/breeze/doc/images/output_release-management_update-providers-next-version.svg
new file mode 100644
index 00000000000..bd1a673193a
--- /dev/null
+++ b/dev/breeze/doc/images/output_release-management_update-providers-next-version.svg
@@ -0,0 +1,95 @@
+<svg class="rich-terminal" viewBox="0 0 1482 269.6" xmlns="http://www.w3.org/2000/svg">
+    <!-- Generated with Rich https://www.textualize.io -->
+    <style>
+
+    @font-face {
+        font-family: "Fira Code";
+        src: local("FiraCode-Regular"),
+                url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
+                url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
+        font-style: normal;
+        font-weight: 400;
+    }
+    @font-face {
+        font-family: "Fira Code";
+        src: local("FiraCode-Bold"),
+                url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
+                url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
+        font-style: bold;
+        font-weight: 700;
+    }
+
+    .breeze-release-management-update-providers-next-version-matrix {
+        font-family: Fira Code, monospace;
+        font-size: 20px;
+        line-height: 24.4px;
+        font-variant-east-asian: full-width;
+    }
+
+    .breeze-release-management-update-providers-next-version-title {
+        font-size: 18px;
+        font-weight: bold;
+        font-family: arial;
+    }
+
+    .breeze-release-management-update-providers-next-version-r1 { fill: #c5c8c6 }
+.breeze-release-management-update-providers-next-version-r2 { fill: #d0b344 }
+.breeze-release-management-update-providers-next-version-r3 { fill: #c5c8c6;font-weight: bold }
+.breeze-release-management-update-providers-next-version-r4 { fill: #68a0b3;font-weight: bold }
+.breeze-release-management-update-providers-next-version-r5 { fill: #868887 }
+.breeze-release-management-update-providers-next-version-r6 { fill: #98a84b;font-weight: bold }
+    </style>
+
+    <defs>
+    <clipPath id="breeze-release-management-update-providers-next-version-clip-terminal">
+      <rect x="0" y="0" width="1463.0" height="218.6" />
+    </clipPath>
+    <clipPath id="breeze-release-management-update-providers-next-version-line-0">
+    <rect x="0" y="1.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-providers-next-version-line-1">
+    <rect x="0" y="25.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-providers-next-version-line-2">
+    <rect x="0" y="50.3" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-providers-next-version-line-3">
+    <rect x="0" y="74.7" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-providers-next-version-line-4">
+    <rect x="0" y="99.1" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-providers-next-version-line-5">
+    <rect x="0" y="123.5" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-providers-next-version-line-6">
+    <rect x="0" y="147.9" width="1464" height="24.65"/>
+            </clipPath>
+<clipPath id="breeze-release-management-update-providers-next-version-line-7">
+    <rect x="0" y="172.3" width="1464" height="24.65"/>
+            </clipPath>
+    </defs>
+
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="267.6" rx="8"/><text class="breeze-release-management-update-providers-next-version-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;update-providers-next-version</text>
+            <g transform="translate(26,22)">
+            <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+            <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+            <circle cx="44" cy="0" r="7" fill="#28c840"/>
+            </g>
+        
+    <g transform="translate(9, 41)" clip-path="url(#breeze-release-management-update-providers-next-version-clip-terminal)">
+    
+    <g class="breeze-release-management-update-providers-next-version-matrix">
+    <text class="breeze-release-management-update-providers-next-version-r1" x="1464" y="20" textLength="12.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-0)">
+</text><text class="breeze-release-management-update-providers-next-version-r2" x="12.2" y="44.4" textLength="73.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-1)">Usage:</text><text class="breeze-release-management-update-providers-next-version-r3" x="97.6" y="44.4" textLength="671" clip-path="url(#breeze-release-management-update-providers-next-version-line-1)">breeze&#160;release-management&#160;update-providers-next-version</text><text class="breeze-r [...]
+</text><text class="breeze-release-management-update-providers-next-version-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-2)">
+</text><text class="breeze-release-management-update-providers-next-version-r1" x="12.2" y="93.2" textLength="805.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-3)">Update&#160;provider&#160;versions&#160;marked&#160;with&#160;&#x27;#&#160;use&#160;next&#160;version&#x27;&#160;comment.</text><text class="breeze-release-management-update-providers-next-version-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#breeze-release-management-update-provider [...]
+</text><text class="breeze-release-management-update-providers-next-version-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-4)">
+</text><text class="breeze-release-management-update-providers-next-version-r5" x="0" y="142" textLength="24.4" clip-path="url(#breeze-release-management-update-providers-next-version-line-5)">╭─</text><text class="breeze-release-management-update-providers-next-version-r5" x="24.4" y="142" textLength="195.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-5)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-update-providers-next-v [...]
+</text><text class="breeze-release-management-update-providers-next-version-r5" x="0" y="166.4" textLength="12.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-6)">│</text><text class="breeze-release-management-update-providers-next-version-r4" x="24.4" y="166.4" textLength="109.8" clip-path="url(#breeze-release-management-update-providers-next-version-line-6)">--verbose</text><text class="breeze-release-management-update-providers-next-version-r6" x="158.6 [...]
+</text><text class="breeze-release-management-update-providers-next-version-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-7)">│</text><text class="breeze-release-management-update-providers-next-version-r4" x="24.4" y="190.8" textLength="73.2" clip-path="url(#breeze-release-management-update-providers-next-version-line-7)">--help</text><text class="breeze-release-management-update-providers-next-version-r6" x="158.6" y= [...]
+</text><text class="breeze-release-management-update-providers-next-version-r5" x="0" y="215.2" textLength="1464" clip-path="url(#breeze-release-management-update-providers-next-version-line-8)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-update-providers-next-version-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#breeze-release-management-update-providers-n [...]
+</text>
+    </g>
+    </g>
+</svg>
diff --git a/dev/breeze/doc/images/output_release-management_update-providers-next-version.txt b/dev/breeze/doc/images/output_release-management_update-providers-next-version.txt
new file mode 100644
index 00000000000..63b432b93ad
--- /dev/null
+++ b/dev/breeze/doc/images/output_release-management_update-providers-next-version.txt
@@ -0,0 +1 @@
+91c2333cf1da8fb531655e616dce32d7
diff --git a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg
index 2c57f9ff605..4f5646195dd 100644
--- a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg
+++ b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.svg
@@ -218,16 +218,16 @@
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-26)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="654.4" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-26)">release-management:publish-docs-to-s3&#160;|&#160;release-management:release-prod-images&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-27)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="678.8" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-27)">release-management:start-rc-process&#160;|&#160;release-management:start-release&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-28)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="703.2" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-28)">release-management:tag-providers&#160;|&#160;release-management:update-constraints&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-29)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="727.6" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-29)">release-management:verify-provider-distributions&#160;|&#160;run&#160;|&#160;sbom&#160;|&#160;sbom:build-all-airflow-images&#160;|&#160;&#160;&#160;&#160;&#160 [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-30)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="752" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-30)">sbom:export-dependency-information&#160;|&#160;sbom:generate-providers-requirements&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-31)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="776.4" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-31)">sbom:update-sbom-information&#160;|&#160;setup&#160;|&#160;setup:autocomplete&#160;|&#160;setup:check-all-params-in-groups&#160;|&#160;&#160;&#160;&#160;&#160; [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-32)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="800.8" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-32)">setup:config&#160;|&#160;setup:regenerate-command-images&#160;|&#160;setup:self-upgrade&#160;|&#160;setup:synchronize-local-mounts&#160;|&#160;</text><text cla [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-33)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="825.2" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-33)">setup:version&#160;|&#160;shell&#160;|&#160;start-airflow&#160;|&#160;testing&#160;|&#160;testing:airflow-ctl-integration-tests&#160;|&#160;&#160;&#160;&#160;& [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-34)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="849.6" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-34)">testing:airflow-ctl-tests&#160;|&#160;testing:core-integration-tests&#160;|&#160;testing:core-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="874" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">testing:docker-compose-tests&#160;|&#160;testing:helm-tests&#160;|&#160;testing:providers-integration-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-36)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="898.4" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-36)">testing:providers-tests&#160;|&#160;testing:python-api-client-tests&#160;|&#160;testing:system-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-37)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="922.8" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-37)">testing:task-sdk-integration-tests&#160;|&#160;testing:task-sdk-tests&#160;|&#160;ui&#160;|&#160;ui:check-translation-completeness&#160;|&#160;</text><text cla [...]
-</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-38)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="947.2" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-38)">workflow-run&#160;|&#160;workflow-run:publish-docs)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-29)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="727.6" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-29)">release-management:update-providers-next-version&#160;|&#160;release-management:verify-provider-distributions&#160;|&#160;&#160;</text><text class="breeze-setu [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-30)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="752" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-30)">run&#160;|&#160;sbom&#160;|&#160;sbom:build-all-airflow-images&#160;|&#160;sbom:export-dependency-information&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-31)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="776.4" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-31)">sbom:generate-providers-requirements&#160;|&#160;sbom:update-sbom-information&#160;|&#160;setup&#160;|&#160;setup:autocomplete&#160;|&#160;&#160;&#160;&#160;&# [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-32)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="800.8" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-32)">setup:check-all-params-in-groups&#160;|&#160;setup:config&#160;|&#160;setup:regenerate-command-images&#160;|&#160;setup:self-upgrade&#160;</text><text class="b [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-33)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="825.2" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-33)">|&#160;setup:synchronize-local-mounts&#160;|&#160;setup:version&#160;|&#160;shell&#160;|&#160;start-airflow&#160;|&#160;testing&#160;|&#160;&#160;&#160;&#160;& [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-34)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="849.6" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-34)">testing:airflow-ctl-integration-tests&#160;|&#160;testing:airflow-ctl-tests&#160;|&#160;testing:core-integration-tests&#160;|&#160;&#160;&#160;</text><text cla [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="874" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-35)">testing:core-tests&#160;|&#160;testing:docker-compose-tests&#160;|&#160;testing:helm-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-36)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="898.4" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-36)">testing:providers-integration-tests&#160;|&#160;testing:providers-tests&#160;|&#160;testing:python-api-client-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;< [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-37)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="922.8" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-37)">testing:system-tests&#160;|&#160;testing:task-sdk-integration-tests&#160;|&#160;testing:task-sdk-tests&#160;|&#160;ui&#160;|&#160;&#160;&#160;&#160;&#160;&#160 [...]
+</text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-38)">│</text><text class="breeze-setup-check-all-params-in-groups-r6" x="183" y="947.2" textLength="1256.6" clip-path="url(#breeze-setup-check-all-params-in-groups-line-38)">ui:check-translation-completeness&#160;|&#160;workflow-run&#160;|&#160;workflow-run:publish-docs)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="971.6" textLength="1464" clip-path="url(#breeze-setup-check-all-params-in-groups-line-39)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-setup-check-all-params-in-groups-r1" x="1464" y="971.6" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-39)">
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="996" textLength="24.4" clip-path="url(#breeze-setup-check-all-params-in-groups-line-40)">╭─</text><text class="breeze-setup-check-all-params-in-groups-r5" x="24.4" y="996" textLength="195.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-40)">&#160;Common&#160;options&#160;</text><text class="breeze-setup-check-all-params-in-groups-r5" x="219.6" y="996" textLength="1220" clip-path="url(#breeze-setup-ch [...]
 </text><text class="breeze-setup-check-all-params-in-groups-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-setup-check-all-params-in-groups-line-41)">│</text><text class="breeze-setup-check-all-params-in-groups-r4" x="24.4" y="1020.4" textLength="109.8" clip-path="url(#breeze-setup-check-all-params-in-groups-line-41)">--verbose</text><text class="breeze-setup-check-all-params-in-groups-r7" x="158.6" y="1020.4" textLength="24.4" clip-path="url(#breeze-setup-check-all-params [...]
diff --git a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt
index 9c86645f47d..23a4fa47aa0 100644
--- a/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt
+++ b/dev/breeze/doc/images/output_setup_check-all-params-in-groups.txt
@@ -1 +1 @@
-81b3b38b66743f04103a0fb006418090
+3f7b11d4d7cd31e43d1bb5734e664771
diff --git a/dev/breeze/doc/images/output_setup_regenerate-command-images.svg b/dev/breeze/doc/images/output_setup_regenerate-command-images.svg
index 3ff56e77b57..feae43a75c1 100644
--- a/dev/breeze/doc/images/output_setup_regenerate-command-images.svg
+++ b/dev/breeze/doc/images/output_setup_regenerate-command-images.svg
@@ -235,17 +235,17 @@
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-28)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="703.2" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-28)">release-management:publish-docs&#160;|&#160;release-management:publish-docs-to-s3&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-29)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="727.6" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-29)">release-management:release-prod-images&#160;|&#160;release-management:start-rc-process&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="752" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-30)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="752" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-30)">release-management:start-release&#160;|&#160;release-management:tag-providers&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-31)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="776.4" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-31)">release-management:update-constraints&#160;|&#160;release-management:verify-provider-distributions&#160;|&#160;run&#160;|&#160;&#160;&#160;&#160;</text><text class [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-32)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="800.8" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-32)">sbom&#160;|&#160;sbom:build-all-airflow-images&#160;|&#160;sbom:export-dependency-information&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-33)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="825.2" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-33)">sbom:generate-providers-requirements&#160;|&#160;sbom:update-sbom-information&#160;|&#160;setup&#160;|&#160;setup:autocomplete&#160;|&#160;&#160;</text><text class [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-34)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="849.6" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-34)">setup:check-all-params-in-groups&#160;|&#160;setup:config&#160;|&#160;setup:regenerate-command-images&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-35)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="874" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-35)">setup:self-upgrade&#160;|&#160;setup:synchronize-local-mounts&#160;|&#160;setup:version&#160;|&#160;shell&#160;|&#160;start-airflow&#160;|&#160;&#160;&#160;&#160;&#160 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-36)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="898.4" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-36)">testing&#160;|&#160;testing:airflow-ctl-integration-tests&#160;|&#160;testing:airflow-ctl-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-37)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="922.8" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-37)">testing:core-integration-tests&#160;|&#160;testing:core-tests&#160;|&#160;testing:docker-compose-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-38)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="947.2" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-38)">testing:helm-tests&#160;|&#160;testing:providers-integration-tests&#160;|&#160;testing:providers-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-39)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="971.6" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-39)">testing:python-api-client-tests&#160;|&#160;testing:system-tests&#160;|&#160;testing:task-sdk-integration-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;</t [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-40)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="996" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-40)">testing:task-sdk-tests&#160;|&#160;ui&#160;|&#160;ui:check-translation-completeness&#160;|&#160;workflow-run&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
-</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-41)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="1020.4" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-41)">workflow-run:publish-docs)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-31)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="776.4" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-31)">release-management:update-constraints&#160;|&#160;release-management:update-providers-next-version&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-32)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="800.8" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-32)">release-management:verify-provider-distributions&#160;|&#160;run&#160;|&#160;sbom&#160;|&#160;sbom:build-all-airflow-images&#160;|&#160;&#160;&#160;&#160;&#160;</t [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-33)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="825.2" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-33)">sbom:export-dependency-information&#160;|&#160;sbom:generate-providers-requirements&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="849.6" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-34)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="849.6" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-34)">sbom:update-sbom-information&#160;|&#160;setup&#160;|&#160;setup:autocomplete&#160;|&#160;setup:check-all-params-in-groups&#160;|&#160;&#160;&#160;&#160;&#160;&#16 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="874" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-35)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="874" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-35)">setup:config&#160;|&#160;setup:regenerate-command-images&#160;|&#160;setup:self-upgrade&#160;|&#160;setup:synchronize-local-mounts</text><text class="breeze-setup-rege [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="898.4" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-36)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="898.4" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-36)">|&#160;setup:version&#160;|&#160;shell&#160;|&#160;start-airflow&#160;|&#160;testing&#160;|&#160;testing:airflow-ctl-integration-tests&#160;|&#160;&#160;&#160;&#16 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="922.8" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-37)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="922.8" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-37)">testing:airflow-ctl-tests&#160;|&#160;testing:core-integration-tests&#160;|&#160;testing:core-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#1 [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="947.2" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-38)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="947.2" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-38)">testing:docker-compose-tests&#160;|&#160;testing:helm-tests&#160;|&#160;testing:providers-integration-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="971.6" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-39)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="971.6" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-39)">testing:providers-tests&#160;|&#160;testing:python-api-client-tests&#160;|&#160;testing:system-tests&#160;|&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&# [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="996" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-40)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="996" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-40)">testing:task-sdk-integration-tests&#160;|&#160;testing:task-sdk-tests&#160;|&#160;ui&#160;|&#160;ui:check-translation-completeness</text><text class="breeze-setup-rege [...]
+</text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="1020.4" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-41)">│</text><text class="breeze-setup-regenerate-command-images-r6" x="219.6" y="1020.4" textLength="1220" clip-path="url(#breeze-setup-regenerate-command-images-line-41)">|&#160;workflow-run&#160;|&#160;workflow-run:publish-docs)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="1044.8" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-42)">│</text><text class="breeze-setup-regenerate-command-images-r4" x="24.4" y="1044.8" textLength="146.4" clip-path="url(#breeze-setup-regenerate-command-images-line-42)">--check-only</text><text class="breeze-setup-regenerate-command-images-r1" x="219.6" y="1044.8" textLength="1220" clip-path="url(#breeze-setup-regenerate-command [...]
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="1069.2" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-43)">│</text><text class="breeze-setup-regenerate-command-images-r1" x="219.6" y="1069.2" textLength="170.8" clip-path="url(#breeze-setup-regenerate-command-images-line-43)">together&#160;with&#160;</text><text class="breeze-setup-regenerate-command-images-r4" x="390.4" y="1069.2" textLength="109.8" clip-path="url(#breeze-setup-rege [...]
 </text><text class="breeze-setup-regenerate-command-images-r5" x="0" y="1093.6" textLength="1464" clip-path="url(#breeze-setup-regenerate-command-images-line-44)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-setup-regenerate-command-images-r1" x="1464" y="1093.6" textLength="12.2" clip-path="url(#breeze-setup-regenerate-command-images-line-44)">
diff --git a/dev/breeze/doc/images/output_setup_regenerate-command-images.txt b/dev/breeze/doc/images/output_setup_regenerate-command-images.txt
index 67e7c83308b..cadee85beb4 100644
--- a/dev/breeze/doc/images/output_setup_regenerate-command-images.txt
+++ b/dev/breeze/doc/images/output_setup_regenerate-command-images.txt
@@ -1 +1 @@
-556b9ff80fe6f6f542c869c2f97fa14e
+fd114d5228eb9c7faef40e79e62dacf3
diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index 08086dbf0da..1347125d13a 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -17,7 +17,6 @@
 from __future__ import annotations
 
 import ast
-import contextlib
 import glob
 import operator
 import os
@@ -119,6 +118,7 @@ from airflow_breeze.utils.add_back_references import (
     start_generating_back_references,
 )
 from airflow_breeze.utils.ci_group import ci_group
+from airflow_breeze.utils.click_validators import validate_release_date
 from airflow_breeze.utils.confirm import Answer, user_confirm
 from airflow_breeze.utils.console import MessageType, Output, get_console
 from airflow_breeze.utils.constraints_version_check import constraints_version_check
@@ -157,6 +157,7 @@ from airflow_breeze.utils.path_utils import (
     AIRFLOW_CTL_ROOT_PATH,
     AIRFLOW_CTL_SOURCES_PATH,
     AIRFLOW_DIST_PATH,
+    AIRFLOW_PROVIDERS_LAST_RELEASE_DATE_PATH,
     AIRFLOW_ROOT_PATH,
     OUT_PATH,
     PROVIDER_METADATA_JSON_PATH,
@@ -177,7 +178,7 @@ from airflow_breeze.utils.reproducible import get_source_date_epoch, repack_dete
 from airflow_breeze.utils.run_utils import (
     run_command,
 )
-from airflow_breeze.utils.shared_options import get_dry_run, get_verbose
+from airflow_breeze.utils.shared_options import get_dry_run, get_verbose, set_forced_answer
 from airflow_breeze.utils.version_utils import (
     is_local_package_version,
 )
@@ -236,6 +237,13 @@ PR_PATTERN = re.compile(r".*\(#([0-9]+)\)")
 ISSUE_MATCH_IN_BODY = re.compile(r" #([0-9]+)[^0-9]")
 
 
+def remove_code_blocks(text: str) -> str:
+    """Remove content within code blocks (```...``` and `...`) from text."""
+    text = re.sub(r"```.*?```", "", text, flags=re.DOTALL)
+    text = re.sub(r"`[^`]+`", "", text)
+    return text
+
+
 class VersionedFile(NamedTuple):
     base: str
     version: str
@@ -258,7 +266,7 @@ PYYAML_VERSION = "6.0.3"
 AIRFLOW_BUILD_DOCKERFILE = f"""
 # syntax=docker/dockerfile:1.4
 FROM python:{DEFAULT_PYTHON_MAJOR_MINOR_VERSION}-slim-{ALLOWED_DEBIAN_VERSIONS[0]}
-RUN apt-get update && apt-get install -y --no-install-recommends git curl
+RUN apt-get update && apt-get install -y --no-install-recommends libatomic1 git curl
 RUN pip install uv=={UV_VERSION}
 RUN --mount=type=cache,id=cache-airflow-build-dockerfile-installation,target=/root/.cache/ \
   uv pip install --system ignore pip=={AIRFLOW_PIP_VERSION} hatch=={HATCH_VERSION} \
@@ -775,7 +783,6 @@ def provider_action_summary(description: str, message_type: MessageType, package
     help="Base branch to use as diff for documentation generation (used for releasing from old branch)",
 )
 @option_github_repository
-@argument_provider_distributions
 @option_include_not_ready_providers
 @option_include_removed_providers
 @click.option(
@@ -800,11 +807,25 @@ def provider_action_summary(description: str, message_type: MessageType, package
     is_flag=True,
     help="Skip changelog generation. This is used in prek that updates build-files only.",
 )
+@click.option(
+    "--incremental-update",
+    is_flag=True,
+    help="Runs incremental update only after rebase of earlier branch to check if there are no changes.",
+)
 @click.option(
     "--skip-readme",
     is_flag=True,
     help="Skip readme generation. This is used in prek that updates build-files only.",
 )
+@click.option(
+    "--release-date",
+    type=str,
+    callback=validate_release_date,
+    envvar="RELEASE_DATE",
+    help="Planned release date for the providers release in format "
+    "YYYY-MM-DD[_NN] (e.g., 2025-11-16 or 2025-11-16_01).",
+)
+@argument_provider_distributions
 @option_verbose
 @option_answer
 @option_dry_run
@@ -820,6 +841,8 @@ def prepare_provider_documentation(
     skip_git_fetch: bool,
     skip_changelog: bool,
     skip_readme: bool,
+    incremental_update: bool,
+    release_date: str | None,
 ):
     from airflow_breeze.prepare_providers.provider_documentation import (
         PrepareReleaseDocsChangesOnlyException,
@@ -832,9 +855,15 @@ def prepare_provider_documentation(
         update_release_notes,
     )
 
+    if not release_date and not only_min_version_update:
+        get_console().print("[error]Release date is required unless --only-min-version-update is used![/]")
+        sys.exit(1)
+
     perform_environment_checks()
     fix_ownership_using_docker()
     cleanup_python_generated_files()
+    if incremental_update:
+        set_forced_answer("yes")
     if not provider_distributions:
         provider_distributions = get_available_distributions(
             include_removed=include_removed_providers, include_not_ready=include_not_ready_providers
@@ -938,6 +967,24 @@ def prepare_provider_documentation(
     get_console().print(
         "\n[info]Please review the updated files, classify the changelog entries and commit the changes.\n"
     )
+    if release_date:
+        AIRFLOW_PROVIDERS_LAST_RELEASE_DATE_PATH.write_text(release_date + "\n")
+    if incremental_update:
+        get_console().print(r"\[warning] Generated changes:")
+        run_command(["git", "diff"])
+        get_console().print("\n")
+        get_console().print("[warning]Important")
+        get_console().print(
+            " * Please review manually the changes in changelogs above and move the new changelog "
+            "entries to the right sections."
+        )
+        get_console().print(
+            "* Remove the `Please review ...` comments from the changelogs after moving changeslogs"
+        )
+        get_console().print(
+            "* Update both changelog.rst AND provider.yaml in case the new changes require "
+            "different classification of the upgrade (patchlevel/minor/major)"
+        )
 
 
 def basic_provider_checks(provider_id: str) -> dict[str, Any]:
@@ -969,11 +1016,21 @@ def _build_provider_distributions(
     distribution_format: str,
     skip_tag_check: bool,
     skip_deleting_generated_files: bool,
-):
+) -> bool:
+    """
+    Builds provider distribution.
+
+    :param provider_id: id of the provider package
+    :param package_version_suffix: suffix to append to the package version
+    :param distribution_format: format of the distribution to build (wheel or sdist)
+    :param skip_tag_check: whether to skip tag check
+    :param skip_deleting_generated_files: whether to skip deleting generated files
+    :return: True if package was built, False if it was skipped.
+    """
     if not skip_tag_check:
         should_skip, package_version_suffix = should_skip_the_package(provider_id, package_version_suffix)
         if should_skip:
-            return
+            return False
     get_console().print()
     with ci_group(f"Preparing provider package [special]{provider_id}"):
         get_console().print()
@@ -996,6 +1053,7 @@ def _build_provider_distributions(
             skip_cleanup=skip_deleting_generated_files,
             delete_only_build_and_dist_folders=True,
         )
+    return True
 
 
 @release_management_group.command(
@@ -1033,7 +1091,7 @@ def _build_provider_distributions(
     "--distributions-list",
     envvar="DISTRIBUTIONS_LIST",
     type=str,
-    help="Optional, contains comma-separated list of package ids that are processed for documentation "
+    help="Optional, contains space separated list of package ids that are processed for documentation "
     "building, and document publishing. It is an easier alternative to adding individual packages as"
     " arguments to every command. This overrides the packages passed as arguments.",
 )
@@ -1065,7 +1123,7 @@ def prepare_provider_distributions(
             f"\n[info]Populating provider list from DISTRIBUTIONS_LIST env as {distributions_list}"
         )
         # Override provider_distributions with values from DISTRIBUTIONS_LIST
-        distributions_list_as_tuple = tuple(distributions_list.split(","))
+        distributions_list_as_tuple = tuple(distributions_list.split(" "))
     if provider_distributions and distributions_list_as_tuple:
         get_console().print(
             f"[warning]Both package arguments and --distributions-list / DISTRIBUTIONS_LIST passed. "
@@ -1094,7 +1152,7 @@ def prepare_provider_distributions(
     for provider_id in packages_list:
         try:
             basic_provider_checks(provider_id)
-            _build_provider_distributions(
+            created = _build_provider_distributions(
                 provider_id,
                 version_suffix,
                 distribution_format,
@@ -1111,12 +1169,15 @@ def prepare_provider_distributions(
             suspended_packages.append(provider_id)
         else:
             get_console().print(f"\n[success]Generated package [special]{provider_id}")
-            success_packages.append(provider_id)
+            if created:
+                success_packages.append(provider_id)
+            else:
+                skipped_as_already_released_packages.append(provider_id)
     get_console().print()
     get_console().print("\n[info]Summary of prepared packages:\n")
     provider_action_summary("Success", MessageType.SUCCESS, success_packages)
     provider_action_summary(
-        "Skipped as already released", MessageType.SUCCESS, skipped_as_already_released_packages
+        "Skipped as already released", MessageType.INFO, skipped_as_already_released_packages
     )
     provider_action_summary("Suspended", MessageType.WARNING, suspended_packages)
     provider_action_summary("Wrong setup generated", MessageType.ERROR, wrong_setup_packages)
@@ -1220,18 +1281,26 @@ def run_generate_constraints_in_parallel(
     help="Generates tags for airflow provider releases.",
 )
 @click.option(
-    "--clean-local-tags/--no-clean-local-tags",
+    "--clean-tags/--no-clean-tags",
     default=True,
     is_flag=True,
-    envvar="CLEAN_LOCAL_TAGS",
-    help="Delete local tags that are created due to github connectivity issues to avoid errors. "
-    "The default behaviour would be to clean such local tags.",
+    envvar="CLEAN_TAGS",
+    help="Delete tags (both local and remote) that are created due to github connectivity "
+    "issues to avoid errors. The default behaviour would be to clean both local and remote tags.",
     show_default=True,
 )
+@click.option(
+    "--release-date",
+    type=str,
+    help="Date of the release in YYYY-MM-DD format.",
+    required=True,
+    envvar="RELEASE_DATE",
+)
 @option_dry_run
 @option_verbose
 def tag_providers(
-    clean_local_tags: bool,
+    clean_tags: bool,
+    release_date: str,
 ):
     found_remote = None
     remotes = ["origin", "apache"]
@@ -1249,57 +1318,32 @@ def tag_providers(
         except subprocess.CalledProcessError:
             pass
 
-    release_date = datetime.now().strftime("%Y-%m-%d")
-
     if found_remote is None:
-        raise ValueError("Could not find remote configured to push to apache/airflow")
+        raise ValueError("Could not find the remote configured to push to apache/airflow")
 
+    extra_flags = []
     tags = []
+    if clean_tags:
+        extra_flags.append("--force")
     for file in os.listdir(os.path.join(SOURCE_DIR_PATH, "dist")):
         if file.endswith(".whl"):
             match = re.match(r".*airflow_providers_(.*)-(.*)-py3.*", file)
             if match:
                 provider = f"providers-{match.group(1).replace('_', '-')}"
                 tag = f"{provider}/{match.group(2)}"
-                try:
-                    get_console().print(f"[info]Creating tag: {tag}")
-                    run_command(
-                        ["git", "tag", tag, "-m", f"Release {release_date} of providers"],
-                        check=True,
-                    )
-                    tags.append(tag)
-                except subprocess.CalledProcessError as e:
-                    get_console().print(f"[warning]Failed to create {tag}: {e}")
-                    pass
-    providers_date_tag = f"providers/{release_date}"
+                get_console().print(f"[info]Creating tag: {tag}")
+                run_command(
+                    ["git", "tag", tag, *extra_flags, "-m", f"Release {release_date} of providers"],
+                    check=True,
+                )
+                tags.append(tag)
     if tags:
-        run_command(
-            ["git", "tag", providers_date_tag, "-m", f"Release {release_date} of providers"],
+        push_result = run_command(
+            ["git", "push", found_remote, *extra_flags, *tags],
             check=True,
         )
-        get_console().print()
-        get_console().print("\n[info]The providers release have been tagged with:[/]")
-        get_console().print(providers_date_tag)
-        get_console().print()
-        tags.append(providers_date_tag)
-        try:
-            push_result = run_command(
-                ["git", "push", found_remote, *tags],
-                check=False,
-            )
-            if push_result.returncode == 0:
-                get_console().print("\n[success]Tags pushed successfully.[/]")
-        except subprocess.CalledProcessError:
-            get_console().print("\n[error]Failed to push tags, probably a connectivity issue to GitHub.[/]")
-            if clean_local_tags:
-                for tag in tags:
-                    with contextlib.suppress(subprocess.CalledProcessError):
-                        run_command(["git", "tag", "-d", tag], check=True)
-                get_console().print("\n[success]Cleaning up local tags...[/]")
-            else:
-                get_console().print(
-                    "\n[success]Local tags are not cleaned up, unset CLEAN_LOCAL_TAGS or set to true.[/]"
-                )
+        if push_result.returncode == 0:
+            get_console().print("\n[success]Tags pushed successfully.[/]")
 
 
 @release_management_group.command(
@@ -1799,7 +1843,7 @@ def run_publish_docs_in_parallel(
     "--distributions-list",
     envvar="DISTRIBUTIONS_LIST",
     type=str,
-    help="Optional, contains comma-separated list of package ids that are processed for documentation "
+    help="Optional, contains space separated list of package ids that are processed for documentation "
     "building, and document publishing. It is an easier alternative to adding individual packages as"
     " arguments to every command. This overrides the packages passed as arguments.",
 )
@@ -1830,7 +1874,7 @@ def publish_docs(
             f"\n[info]Populating provider list from DISTRIBUTIONS_LIST env as {distributions_list}"
         )
         # Override doc_packages with values from DISTRIBUTIONS_LIST
-        packages_list_as_tuple = tuple(distributions_list.split(","))
+        packages_list_as_tuple = tuple(distributions_list.split(" "))
     if doc_packages and packages_list_as_tuple:
         get_console().print(
             f"[warning]Both package arguments and --distributions-list / DISTRIBUTIONS_LIST passed. "
@@ -2327,11 +2371,11 @@ VERSION_MATCH = re.compile(r"([0-9]+)\.([0-9]+)\.([0-9]+)(.*)")
 
 def get_suffix_from_package_in_dist(dist_files: list[str], package: str) -> str | None:
     """Get suffix from package prepared in dist folder."""
-    for file in dist_files:
-        if file.startswith(f"apache_airflow_providers_{package.replace('.', '_')}") and file.endswith(
+    for filename in dist_files:
+        if filename.startswith(f"apache_airflow_providers_{package.replace('.', '_')}") and filename.endswith(
             ".tar.gz"
         ):
-            file = file[: -len(".tar.gz")]
+            file = filename[: -len(".tar.gz")]
             version = file.split("-")[-1]
             match = VERSION_MATCH.match(version)
             if match:
@@ -2389,6 +2433,56 @@ def create_github_issue_url(title: str, body: str, labels: Iterable[str]) -> str
     )
 
 
+def get_commented_out_prs_from_provider_changelogs() -> list[int]:
+    """
+    Returns list of PRs that are commented out in the changelog.
+    :return: list of PR numbers that appear only in comments in changelog.rst files in "providers" dir
+    """
+    pr_matcher = re.compile(r".*\(#([0-9]+)\).*")
+    commented_prs = set()
+
+    # Get all provider distributions
+    provider_distributions_metadata = get_provider_distributions_metadata()
+
+    for provider_id in provider_distributions_metadata.keys():
+        provider_details = get_provider_details(provider_id)
+        changelog_path = provider_details.changelog_path
+        print(f"[info]Checking changelog {changelog_path} for PRs to be excluded automatically.")
+        if not changelog_path.exists():
+            continue
+
+        changelog_lines = changelog_path.read_text().splitlines()
+        in_excluded_section = False
+
+        for line in changelog_lines:
+            # Check if we're entering an excluded/commented section
+            if line.strip().startswith(
+                ".. Below changes are excluded from the changelog"
+            ) or line.strip().startswith(".. Review and move the new changes"):
+                in_excluded_section = True
+                continue
+            # Check if we're exiting the excluded section (new version header or regular content)
+            # Version headers are lines that contain only dots (like "4.10.1" followed by "......")
+            # Or lines that start with actual content sections like "Misc", "Features", etc.
+            if (
+                in_excluded_section
+                and line
+                and not line.strip().startswith("..")
+                and not line.strip().startswith("*")
+            ):
+                # end excluded section with empty line
+                if line.strip() == "":
+                    in_excluded_section = False
+
+            # Extract PRs from excluded sections
+            if in_excluded_section and line.strip().startswith("*"):
+                match_result = pr_matcher.search(line)
+                if match_result:
+                    commented_prs.add(int(match_result.group(1)))
+
+    return sorted(commented_prs)
+
+
 @release_management_group.command(
     name="generate-issue-content-providers", help="Generates content for issue to test the release."
 )
@@ -2410,20 +2504,12 @@ def create_github_issue_url(title: str, body: str, labels: Iterable[str]) -> str
     is_flag=True,
     help="Only consider package ids with packages prepared in the dist folder",
 )
-@click.option(
-    "--no-include-browser-link",
-    "include_browser_link",
-    flag_value=False,
-    default=True,
-    help="Do not include browser link to prefill GitHub issue",
-)
 @argument_provider_distributions
 def generate_issue_content_providers(
     disable_progress: bool,
     excluded_pr_list: str,
     github_token: str,
     only_available_in_dist: bool,
-    include_browser_link: bool,
     provider_distributions: list[str],
 ):
     import jinja2
@@ -2443,10 +2529,15 @@ def generate_issue_content_providers(
             excluded_prs = [int(pr) for pr in excluded_pr_list.split(",")]
         else:
             excluded_prs = []
+        commented_prs = get_commented_out_prs_from_provider_changelogs()
+        get_console().print(
+            "[info]Automatically excluding {len(commented_prs)} PRs that are only commented out in changelog:"
+        )
+        excluded_prs.extend(commented_prs)
         all_prs: set[int] = set()
+        all_retrieved_prs: set[int] = set()
         provider_prs: dict[str, list[int]] = {}
-        if only_available_in_dist:
-            files_in_dist = os.listdir(str(AIRFLOW_DIST_PATH))
+        files_in_dist = os.listdir(str(AIRFLOW_DIST_PATH)) if only_available_in_dist else []
         prepared_package_ids = []
         for provider_id in provider_distributions:
             if not only_available_in_dist or is_package_in_dist(files_in_dist, provider_id):
@@ -2464,15 +2555,35 @@ def generate_issue_content_providers(
                     "The changelog file doesn't contain any PRs for the release.\n"
                 )
                 continue
+            all_prs.update(prs)
             provider_prs[provider_id] = [pr for pr in prs if pr not in excluded_prs]
-            all_prs.update(provider_prs[provider_id])
+            all_retrieved_prs.update(provider_prs[provider_id])
+        if not github_token:
+            # Get GitHub token from gh CLI and set it in environment copy
+            gh_token_result = run_command(
+                ["gh", "auth", "token"],
+                capture_output=True,
+                text=True,
+                check=False,
+            )
+            if gh_token_result.returncode == 0:
+                github_token = gh_token_result.stdout.strip()
         g = Github(github_token)
         repo = g.get_repo("apache/airflow")
         pull_requests: dict[int, PullRequest.PullRequest | Issue.Issue] = {}
         linked_issues: dict[int, list[Issue.Issue]] = {}
+        all_prs_len = len(all_prs)
+        all_retrieved_prs_len = len(all_retrieved_prs)
+        get_console().print(
+            f"[info] Found {all_prs_len} PRs in the providers. "
+            f"Retrieving {all_retrieved_prs_len} (excluded {all_prs_len - all_retrieved_prs_len})"
+        )
+        get_console().print(f"Retrieved PRs: {all_retrieved_prs}")
+        excluded_prs = sorted(set(all_prs) - set(all_retrieved_prs))
+        get_console().print(f"Excluded PRs: {excluded_prs}")
         with Progress(console=get_console(), disable=disable_progress) as progress:
-            task = progress.add_task(f"Retrieving {len(all_prs)} PRs ", total=len(all_prs))
-            for pr_number in all_prs:
+            task = progress.add_task(f"Retrieving {all_retrieved_prs_len} PRs ", total=all_retrieved_prs_len)
+            for pr_number in all_retrieved_prs:
                 progress.console.print(
                     f"Retrieving PR#{pr_number}: https://github.com/apache/airflow/pull/{pr_number}"
                 )
@@ -2528,7 +2639,10 @@ def generate_issue_content_providers(
             pull_request_list = [pull_requests[pr] for pr in provider_prs[provider_id] if pr in pull_requests]
             provider_yaml_dict = get_provider_distributions_metadata().get(provider_id)
             if pull_request_list:
-                package_suffix = get_suffix_from_package_in_dist(files_in_dist, provider_id)
+                if only_available_in_dist:
+                    package_suffix = get_suffix_from_package_in_dist(files_in_dist, provider_id)
+                else:
+                    package_suffix = ""
                 providers[provider_id] = ProviderPRInfo(
                     version=provider_yaml_dict["versions"][0],
                     provider_id=provider_id,
@@ -2561,18 +2675,29 @@ def generate_issue_content_providers(
         issue_content += f"All users involved in the PRs:\n{' '.join(users)}"
         syntax = Syntax(issue_content, "markdown", theme="ansi_dark")
         get_console().print(syntax)
-        url_to_create_the_issue = create_github_issue_url(
-            title=f"Status of testing Providers that were prepared on {datetime.now():%B %d, %Y}",
-            body=issue_content,
-            labels=["testing status", "kind:meta"],
-        )
-        if include_browser_link:
-            get_console().print()
-            get_console().print(
-                "[info]You can prefill the issue by copy&pasting this link to browser "
-                "(or Cmd+Click if your terminal supports it):\n"
+        create_issue = user_confirm("Should I create the issue?")
+        if create_issue == Answer.YES:
+            res = run_command(
+                [
+                    "gh",
+                    "issue",
+                    "create",
+                    "-t",
+                    f"Status of testing Providers that were prepared on {datetime.now():%B %d, %Y}",
+                    "-b",
+                    issue_content,
+                    "-l",
+                    "testing status,kind:meta",
+                    "-w",
+                ],
+                check=False,
             )
-            print(url_to_create_the_issue)
+            if res.returncode != 0:
+                get_console().print(
+                    "Failed to create issue. If the error is about 'too long URL' you have "
+                    "to create the issue manually by copy&pasting the above output"
+                )
+                sys.exit(1)
 
 
 def get_git_log_command(
@@ -2891,6 +3016,39 @@ def generate_providers_metadata(
     PROVIDER_METADATA_JSON_PATH.write_text(json.dumps(metadata_dict, indent=4) + "\n")
 
 
+@release_management_group.command(
+    name="update-providers-next-version",
+    help="Update provider versions marked with '# use next version' comment.",
+)
+@option_verbose
+def update_providers_next_version():
+    """
+    Scan all provider pyproject.toml files for dependencies with "# use next version" comment
+    and update them to use the current version from the referenced provider's pyproject.toml.
+    """
+    from airflow_breeze.utils.packages import update_providers_with_next_version_comment
+
+    get_console().print("\n[info]Scanning for providers with '# use next version' comments...\n")
+
+    updates_made = update_providers_with_next_version_comment()
+
+    if updates_made:
+        get_console().print("\n[success]Summary of updates:[/]")
+        for provider_id, dependencies in updates_made.items():
+            get_console().print(f"\n[info]Provider: {provider_id}[/]")
+            for dep_name, dep_info in dependencies.items():
+                get_console().print(f"  • {dep_name}: {dep_info['old_version']} → {dep_info['new_version']}")
+        get_console().print(
+            f"\n[success]Updated {len(updates_made)} provider(s) with "
+            f"{sum(len(deps) for deps in updates_made.values())} dependency change(s).[/]"
+        )
+    else:
+        get_console().print(
+            "\n[info]No updates needed. All providers with '# use next version' "
+            "comments are already using the latest versions.[/]"
+        )
+
+
 def fetch_remote(constraints_repo: Path, remote_name: str) -> None:
     run_command(["git", "fetch", remote_name], cwd=constraints_repo)
 
@@ -3630,6 +3788,18 @@ def prepare_helm_chart_tarball(
     values_content = yaml.safe_load(VALUES_YAML_FILE.read_text())
     airflow_version_in_values = values_content["airflowVersion"]
     default_airflow_tag_in_values = values_content["defaultAirflowTag"]
+
+    # Check if this is an RC version and replace documentation links with staging URLs
+    is_rc_version = version_suffix and "rc" in version_suffix.lower()
+    if is_rc_version:
+        get_console().print(
+            f"[info]RC version detected ({version_suffix}). Replacing documentation links with staging URLs.[/]"
+        )
+        # Replace production URLs with staging URLs for RC versions
+        chart_yaml_file_content = chart_yaml_file_content.replace(
+            "https://airflow.apache.org/", "https://airflow.staged.apache.org/"
+        )
+        get_console().print("[success]Documentation links updated to staging environment for RC version.[/]")
     if ignore_version_check:
         if not version:
             version = version_in_chart
@@ -3761,9 +3931,15 @@ def prepare_helm_chart_tarball(
     envvar="SIGN_EMAIL",
     default="",
 )
+@click.option(
+    "--version-suffix",
+    help="Version suffix used to determine if RC version. For RC versions, documentation links will be replaced with staging URLs.",
+    default="",
+    envvar="VERSION_SUFFIX",
+)
 @option_dry_run
 @option_verbose
-def prepare_helm_chart_package(sign_email: str):
+def prepare_helm_chart_package(sign_email: str, version_suffix: str):
     import yaml
 
     from airflow_breeze.utils.kubernetes_utils import (
@@ -3772,71 +3948,96 @@ def prepare_helm_chart_package(sign_email: str):
         sync_virtualenv,
     )
 
-    chart_yaml_dict = yaml.safe_load(CHART_YAML_FILE.read_text())
-    version = chart_yaml_dict["version"]
-    result = sync_virtualenv(force_venv_setup=False)
-    if result.returncode != 0:
-        sys.exit(result.returncode)
-    make_sure_helm_installed()
-    get_console().print(f"[info]Packaging the chart for Helm Chart {version}[/]")
-    k8s_env = os.environ.copy()
-    k8s_env["PATH"] = str(K8S_BIN_BASE_PATH) + os.pathsep + k8s_env["PATH"]
-    # Tar on modern unix options requires --wildcards parameter to work with globs
-    # See https://github.com/technosophos/helm-gpg/issues/1
-    k8s_env["TAR_OPTIONS"] = "--wildcards"
-    archive_name = f"airflow-{version}.tgz"
-    OUT_PATH.mkdir(parents=True, exist_ok=True)
-    result = run_command(
-        cmd=["helm", "package", "chart", "--dependency-update", "--destination", OUT_PATH.as_posix()],
-        env=k8s_env,
-        check=False,
-    )
-    if result.returncode != 0:
-        get_console().print("[error]Error packaging the chart[/]")
-        sys.exit(result.returncode)
-    AIRFLOW_DIST_PATH.mkdir(parents=True, exist_ok=True)
-    final_archive = AIRFLOW_DIST_PATH / archive_name
-    final_archive.unlink(missing_ok=True)
-    source_archive = OUT_PATH / archive_name
-    result = repack_deterministically(
-        source_archive=source_archive,
-        dest_archive=final_archive,
-        prepend_path=None,
-        timestamp=get_source_date_epoch(CHART_DIR),
-    )
-    if result.returncode != 0:
+    # Check if this is an RC version and temporarily replace documentation links
+    chart_yaml_backup = None
+    is_rc_version = version_suffix and "rc" in version_suffix.lower()
+
+    if is_rc_version:
         get_console().print(
-            f"[error]Error repackaging package for Helm Chart from {source_archive} to {final_archive}[/]"
+            f"[info]RC version detected ({version_suffix}). Temporarily replacing documentation links with staging URLs for packaging.[/]"
         )
-        sys.exit(result.returncode)
-    else:
-        get_console().print(f"[success]Package created in {final_archive}[/]")
-    if sign_email:
-        get_console().print(f"[info]Signing the package with {sign_email}[/]")
-        prov_file = final_archive.with_suffix(".tgz.prov")
-        if prov_file.exists():
-            get_console().print(f"[warning]Removing existing {prov_file}[/]")
-            prov_file.unlink()
-        result = run_command(
-            cmd=["helm", "gpg", "sign", "-u", sign_email, archive_name],
-            cwd=AIRFLOW_DIST_PATH.as_posix(),
-            env=k8s_env,
-            check=False,
+        # Backup original content
+        chart_yaml_backup = CHART_YAML_FILE.read_text()
+        # Replace production URLs with staging URLs for RC versions
+        chart_yaml_content = chart_yaml_backup.replace(
+            "https://airflow.apache.org/", "https://airflow.staged.apache.org/"
+        )
+        CHART_YAML_FILE.write_text(chart_yaml_content)
+        get_console().print(
+            "[success]Documentation links temporarily updated to staging environment for RC version packaging.[/]"
         )
+
+    try:
+        chart_yaml_dict = yaml.safe_load(CHART_YAML_FILE.read_text())
+        version = chart_yaml_dict["version"]
+        result = sync_virtualenv(force_venv_setup=False)
         if result.returncode != 0:
-            get_console().print("[error]Error signing the chart[/]")
             sys.exit(result.returncode)
+        make_sure_helm_installed()
+        get_console().print(f"[info]Packaging the chart for Helm Chart {version}[/]")
+        k8s_env = os.environ.copy()
+        k8s_env["PATH"] = str(K8S_BIN_BASE_PATH) + os.pathsep + k8s_env["PATH"]
+        # Tar on modern unix options requires --wildcards parameter to work with globs
+        # See https://github.com/technosophos/helm-gpg/issues/1
+        k8s_env["TAR_OPTIONS"] = "--wildcards"
+        archive_name = f"airflow-{version}.tgz"
+        OUT_PATH.mkdir(parents=True, exist_ok=True)
         result = run_command(
-            cmd=["helm", "gpg", "verify", archive_name],
-            cwd=AIRFLOW_DIST_PATH.as_posix(),
+            cmd=["helm", "package", "chart", "--dependency-update", "--destination", OUT_PATH.as_posix()],
             env=k8s_env,
             check=False,
         )
         if result.returncode != 0:
-            get_console().print("[error]Error signing the chart[/]")
+            get_console().print("[error]Error packaging the chart[/]")
+            sys.exit(result.returncode)
+        AIRFLOW_DIST_PATH.mkdir(parents=True, exist_ok=True)
+        final_archive = AIRFLOW_DIST_PATH / archive_name
+        final_archive.unlink(missing_ok=True)
+        source_archive = OUT_PATH / archive_name
+        result = repack_deterministically(
+            source_archive=source_archive,
+            dest_archive=final_archive,
+            prepend_path=None,
+            timestamp=get_source_date_epoch(CHART_DIR),
+        )
+        if result.returncode != 0:
+            get_console().print(
+                f"[error]Error repackaging package for Helm Chart from {source_archive} to {final_archive}[/]"
+            )
             sys.exit(result.returncode)
         else:
-            get_console().print(f"[success]Chart signed - the {prov_file} file created.[/]")
+            get_console().print(f"[success]Package created in {final_archive}[/]")
+        if sign_email:
+            get_console().print(f"[info]Signing the package with {sign_email}[/]")
+            prov_file = final_archive.with_suffix(".tgz.prov")
+            if prov_file.exists():
+                get_console().print(f"[warning]Removing existing {prov_file}[/]")
+                prov_file.unlink()
+            result = run_command(
+                cmd=["helm", "gpg", "sign", "-u", sign_email, archive_name],
+                cwd=AIRFLOW_DIST_PATH.as_posix(),
+                env=k8s_env,
+                check=False,
+            )
+            if result.returncode != 0:
+                get_console().print("[error]Error signing the chart[/]")
+                sys.exit(result.returncode)
+            result = run_command(
+                cmd=["helm", "gpg", "verify", archive_name],
+                cwd=AIRFLOW_DIST_PATH.as_posix(),
+                env=k8s_env,
+                check=False,
+            )
+            if result.returncode != 0:
+                get_console().print("[error]Error signing the chart[/]")
+                sys.exit(result.returncode)
+            else:
+                get_console().print(f"[success]Chart signed - the {prov_file} file created.[/]")
+    finally:
+        # Restore original Chart.yaml content if it was modified for RC version
+        if is_rc_version and chart_yaml_backup:
+            CHART_YAML_FILE.write_text(chart_yaml_backup)
+            get_console().print("[info]Restored original Chart.yaml content after packaging.[/]")
 
 
 def generate_issue_content(
@@ -3917,8 +4118,10 @@ def generate_issue_content(
             # Relate so we can find those from the body
             if pr.body:
                 body = " ".join(pr.body.splitlines())
+                body_without_code_blocks = remove_code_blocks(body)
                 linked_issue_numbers = {
-                    int(issue_match.group(1)) for issue_match in ISSUE_MATCH_IN_BODY.finditer(body)
+                    int(issue_match.group(1))
+                    for issue_match in ISSUE_MATCH_IN_BODY.finditer(body_without_code_blocks)
                 }
                 for linked_issue_number in linked_issue_numbers:
                     progress.console.print(
@@ -4128,7 +4331,7 @@ def version_check(
 @option_verbose
 @option_dry_run
 def check_release_files(
-    path: Path,
+    path_to_airflow_svn: Path,
     version: str | None,
     release_date: str | None,
     packages_file: Path | None,
@@ -4167,7 +4370,7 @@ def check_release_files(
         if not release_date:
             console.print("[error]--release-date is required for providers[/]")
             sys.exit(1)
-        directory = path / "providers" / release_date
+        directory = path_to_airflow_svn / "providers" / release_date
     else:
         if not version:
             console.print(f"[error]--version is required for {release_type}[/]")
@@ -4175,13 +4378,13 @@ def check_release_files(
 
         # Determine directory based on release type
         if release_type == "airflow":
-            directory = path / version
+            directory = path_to_airflow_svn / version
         elif release_type == "task-sdk":
-            directory = path / version
+            directory = path_to_airflow_svn / "task-sdk" / version
         elif release_type == "airflow-ctl":
-            directory = path / "airflow-ctl" / version
+            directory = path_to_airflow_svn / "airflow-ctl" / version
         elif release_type == "python-client":
-            directory = path / "clients" / "python" / version
+            directory = path_to_airflow_svn / "clients" / "python" / version
         else:
             console.print(f"[error]Unknown release type: {release_type}[/]")
             sys.exit(1)
@@ -4209,10 +4412,14 @@ def check_release_files(
         )
     elif release_type == "airflow":
         missing_files = check_airflow_release(files, version)
-        create_docker(AIRFLOW_DOCKER.format(version), dockerfile_path)
+        create_docker(AIRFLOW_DOCKER.format(version, version), dockerfile_path)
     elif release_type == "task-sdk":
         missing_files = check_task_sdk_release(files, version)
-        create_docker(TASK_SDK_DOCKER.format(version), dockerfile_path)
+        airflow_version = version.replace("1", "3", 1)
+        create_docker(
+            TASK_SDK_DOCKER.format(version, airflow_version, airflow_version, airflow_version),
+            dockerfile_path,
+        )
     elif release_type == "airflow-ctl":
         missing_files = check_airflow_ctl_release(files, version)
         create_docker(AIRFLOW_CTL_DOCKER.format(version), dockerfile_path)
diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
index 44810eeb64c..5e00c23b866 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
@@ -42,6 +42,7 @@ RELEASE_PROVIDERS_COMMANDS: dict[str, str | list[str]] = {
     "name": "Providers release commands",
     "commands": [
         "prepare-provider-documentation",
+        "update-providers-next-version",
         "prepare-provider-distributions",
         "install-provider-distributions",
         "verify-provider-distributions",
@@ -75,6 +76,7 @@ RELEASE_OTHER_COMMANDS: dict[str, str | list[str]] = {
         "generate-constraints",
         "update-constraints",
         "publish-docs-to-s3",
+        "validate-rc-by-pmc",
         "check-release-files",
     ],
 }
@@ -134,6 +136,7 @@ RELEASE_MANAGEMENT_PARAMETERS: dict[str, list[dict[str, str | list[str]]]] = {
             "name": "Package flags",
             "options": [
                 "--sign-email",
+                "--version-suffix",
             ],
         }
     ],
@@ -240,27 +243,46 @@ RELEASE_MANAGEMENT_PARAMETERS: dict[str, list[dict[str, str | list[str]]]] = {
         {
             "name": "Add tags to providers",
             "options": [
-                "--clean-local-tags",
+                "--clean-tags",
+                "--release-date",
             ],
         },
     ],
     "breeze release-management prepare-provider-documentation": [
         {
-            "name": "Provider documentation preparation flags",
+            "name": "Documentation generation mode",
             "options": [
-                "--base-branch",
-                "--github-repository",
-                "--include-not-ready-providers",
-                "--include-removed-providers",
-                "--non-interactive",
+                "--release-date",
+                "--incremental-update",
                 "--only-min-version-update",
                 "--reapply-templates-only",
+                "--non-interactive",
+            ],
+        },
+        {
+            "name": "Select non-regular providers",
+            "options": [
+                "--include-not-ready-providers",
+                "--include-removed-providers",
+            ],
+        },
+        {
+            "name": "Skip steps",
+            "options": [
                 "--skip-git-fetch",
                 "--skip-changelog",
                 "--skip-readme",
             ],
-        }
+        },
+        {
+            "name": "Advanced options",
+            "options": [
+                "--base-branch",
+                "--github-repository",
+            ],
+        },
     ],
+    "breeze release-management update-providers-next-version": [],
     "breeze release-management prepare-python-client": [
         {
             "name": "Python client preparation flags",
@@ -392,7 +414,6 @@ RELEASE_MANAGEMENT_PARAMETERS: dict[str, list[dict[str, str | list[str]]]] = {
                 "--excluded-pr-list",
                 "--github-token",
                 "--only-available-in-dist",
-                "--no-include-browser-link",
             ],
         }
     ],
@@ -504,6 +525,18 @@ RELEASE_MANAGEMENT_PARAMETERS: dict[str, list[dict[str, str | list[str]]]] = {
             ],
         },
     ],
+    "breeze release-management validate-rc-by-pmc": [
+        {
+            "name": "Validation options",
+            "options": [
+                "--distribution",
+                "--version",
+                "--task-sdk-version",
+                "--path-to-airflow-svn",
+                "--checks",
+            ],
+        },
+    ],
     "breeze release-management check-release-files": [
         {
             "name": "Check release files flags",
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 e5143e64b0e..8c64a413763 100644
--- a/dev/breeze/src/airflow_breeze/utils/check_release_files.py
+++ b/dev/breeze/src/airflow_breeze/utils/check_release_files.py
@@ -33,16 +33,16 @@ RUN cd airflow-core; uv sync --no-sources
 AIRFLOW_DOCKER = """\
 FROM python:3.10
 
-# Upgrade
-RUN pip install "apache-airflow=={}"
+RUN pip install "apache-airflow=={}" \
+    --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-{}/constraints-3.10.txt"
 
 """
 
 TASK_SDK_DOCKER = """\
 FROM python:3.10
 
-# Upgrade
-RUN pip install "apache-airflow-task-sdk=={}"
+RUN pip install "apache-airflow-task-sdk=={}" "apache-airflow-core=={}" "apache-airflow=={}"\
+  --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-{}/constraints-3.10.txt"
 
 """
 
diff --git a/dev/breeze/src/airflow_breeze/utils/click_validators.py b/dev/breeze/src/airflow_breeze/utils/click_validators.py
new file mode 100644
index 00000000000..25f9c0f4f46
--- /dev/null
+++ b/dev/breeze/src/airflow_breeze/utils/click_validators.py
@@ -0,0 +1,52 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import re
+from datetime import datetime
+
+import click
+
+
+def validate_release_date(ctx: click.core.Context, param: click.core.Option, value: str) -> str:
+    """
+    Validate that the date follows YYYY-MM-DD[_NN] format.
+
+    :param ctx: Click context
+    :param param: Click parameter
+    :param value: The value to validate
+    :return: The validated value
+    :raises click.BadParameter: If the value doesn't match the required format
+    """
+    if not value:
+        return value
+
+    # Check if the format matches YYYY-MM-DD or YYYY-MM-DD_NN
+    pattern = r"^\d{4}-\d{2}-\d{2}(_\d{2})?$"
+    if not re.match(pattern, value):
+        raise click.BadParameter(
+            "Date must be in YYYY-MM-DD or YYYY-MM-DD_NN format (e.g., 2025-11-16 or 2025-11-16_01)"
+        )
+
+    # Validate that the date part (YYYY-MM-DD) is a valid date
+    date_part = value.split("_")[0]
+    try:
+        datetime.strptime(date_part, "%Y-%m-%d")
+    except ValueError:
+        raise click.BadParameter(f"Invalid date: {date_part}. Please provide a valid date.")
+
+    return value
diff --git a/dev/breeze/src/airflow_breeze/utils/path_utils.py b/dev/breeze/src/airflow_breeze/utils/path_utils.py
index 098d7776e20..6ee4863a093 100644
--- a/dev/breeze/src/airflow_breeze/utils/path_utils.py
+++ b/dev/breeze/src/airflow_breeze/utils/path_utils.py
@@ -249,6 +249,7 @@ AIRFLOW_UI_DIR = AIRFLOW_CORE_SOURCES_PATH / "airflow" / "ui"
 # Do not delete it - it is used for old commit retrieval from providers
 AIRFLOW_ORIGINAL_PROVIDERS_DIR = AIRFLOW_ROOT_PATH / "airflow" / "providers"
 AIRFLOW_PROVIDERS_ROOT_PATH = AIRFLOW_ROOT_PATH / "providers"
+AIRFLOW_PROVIDERS_LAST_RELEASE_DATE_PATH = AIRFLOW_PROVIDERS_ROOT_PATH / ".last_release_date.txt"
 AIRFLOW_DIST_PATH = AIRFLOW_ROOT_PATH / "dist"
 
 TASK_SDK_ROOT_PATH = AIRFLOW_ROOT_PATH / "task-sdk"
@@ -279,8 +280,18 @@ UI_ASSET_COMPILE_LOCK = UI_CACHE_PATH / ".asset_compile.lock"
 UI_ASSET_OUT_FILE = UI_CACHE_PATH / "asset_compile.out"
 UI_ASSET_OUT_DEV_MODE_FILE = UI_CACHE_PATH / "asset_compile_dev_mode.out"
 UI_ASSET_HASH_PATH = AIRFLOW_ROOT_PATH / ".build" / "ui" / "hash.txt"
+
 UI_NODE_MODULES_PATH = AIRFLOW_CORE_SOURCES_PATH / "airflow" / "ui" / "node_modules"
 UI_DIST_PATH = AIRFLOW_CORE_SOURCES_PATH / "airflow" / "ui" / "dist"
+UI_VITE_MANIFEST_PATH = UI_DIST_PATH / ".vite" / "manifest.json"
+FAST_API_SIMPLE_AUTH_MANAGER_PATH = (
+    AIRFLOW_CORE_SOURCES_PATH / "airflow" / "api_fastapi" / "auth" / "managers" / "simple"
+)
+FAST_API_SIMPLE_AUTH_MANAGER_NODE_MODULES_PATH = FAST_API_SIMPLE_AUTH_MANAGER_PATH / "ui" / "node_modules"
+FAST_API_SIMPLE_AUTH_MANAGER_DIST_PATH = FAST_API_SIMPLE_AUTH_MANAGER_PATH / "ui" / "dist"
+FAST_API_SIMPLE_AUTH_MANAGER_VITE_MANIFEST_PATH = (
+    FAST_API_SIMPLE_AUTH_MANAGER_DIST_PATH / ".vite" / "manifest.json"
+)
 
 DAGS_PATH = AIRFLOW_ROOT_PATH / "dags"
 FILES_PATH = AIRFLOW_ROOT_PATH / "files"


(airflow) 15/32: [v3-1-test] Fix breeze check-release-files Command for Core+Task SDK checks (#59159) (#59163)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 68cca802a89ae566dd306639dd1cbfd1ca238f67
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Sun Dec 7 19:14:18 2025 +0100

    [v3-1-test] Fix breeze check-release-files Command for Core+Task SDK checks (#59159) (#59163)
    
    (cherry picked from commit bc7ce10582a772ef890089fbde3184727d9289f5)
    
    Co-authored-by: Jens Scheffler <95...@users.noreply.github.com>
---
 dev/README_RELEASE_AIRFLOW.md                      |  4 ++--
 ...tput_release-management_check-release-files.svg | 26 +++++++++++++---------
 ...tput_release-management_check-release-files.txt |  2 +-
 .../commands/release_management_commands.py        |  8 ++++---
 4 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/dev/README_RELEASE_AIRFLOW.md b/dev/README_RELEASE_AIRFLOW.md
index 68bb1e2ff4d..9bbfd99bca3 100644
--- a/dev/README_RELEASE_AIRFLOW.md
+++ b/dev/README_RELEASE_AIRFLOW.md
@@ -728,12 +728,12 @@ Optionally you can use the `breeze release-management check-release-files` comma
 present in SVN. This command may also help with verifying installation of the packages.
 
 ```shell script
-breeze release-management check-release-files airflow --version ${VERSION_RC}
+breeze release-management check-release-files airflow --version ${VERSION_RC} --path-to-airflow-svn "${PATH_TO_AIRFLOW_SVN}"
 ```
 
 
 ```shell script
-breeze release-management check-release-files task-sdk --version ${TASK_SDK_VERSION_RC}
+breeze release-management check-release-files task-sdk --version ${TASK_SDK_VERSION_RC} --path-to-airflow-svn "${PATH_TO_AIRFLOW_SVN}/task-sdk"
 ```
 
 ## Licence check
diff --git a/dev/breeze/doc/images/output_release-management_check-release-files.svg b/dev/breeze/doc/images/output_release-management_check-release-files.svg
index 3420812ec6c..c9146196727 100644
--- a/dev/breeze/doc/images/output_release-management_check-release-files.svg
+++ b/dev/breeze/doc/images/output_release-management_check-release-files.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 611.1999999999999" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
     <!-- Generated with Rich https://www.textualize.io -->
     <style>
 
@@ -45,7 +45,7 @@
 
     <defs>
     <clipPath id="breeze-release-management-check-release-files-clip-terminal">
-      <rect x="0" y="0" width="1463.0" height="560.1999999999999" />
+      <rect x="0" y="0" width="1463.0" height="584.5999999999999" />
     </clipPath>
     <clipPath id="breeze-release-management-check-release-files-line-0">
     <rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -113,9 +113,12 @@
 <clipPath id="breeze-release-management-check-release-files-line-21">
     <rect x="0" y="513.9" width="1464" height="24.65"/>
             </clipPath>
+<clipPath id="breeze-release-management-check-release-files-line-22">
+    <rect x="0" y="538.3" width="1464" height="24.65"/>
+            </clipPath>
     </defs>
 
-    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="609.2" rx="8"/><text class="breeze-release-management-check-release-files-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;check-release-files</text>
+    <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="633.6" rx="8"/><text class="breeze-release-management-check-release-files-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command:&#160;release-management&#160;check-release-files</text>
             <g transform="translate(26,22)">
             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -140,14 +143,15 @@
 </text><text class="breeze-release-management-check-release-files-r5" x="0" y="312.8" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-12)">│</text><text class="breeze-release-management-check-release-files-r1" x="390.4" y="312.8" textLength="1049.2" clip-path="url(#breeze-release-management-check-release-files-line-12)">task-sdk,&#160;airflow-ctl,&#160;and&#160;python-client.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160 [...]
 </text><text class="breeze-release-management-check-release-files-r5" x="0" y="337.2" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-13)">│</text><text class="breeze-release-management-check-release-files-r8" x="390.4" y="337.2" textLength="1049.2" clip-path="url(#breeze-release-management-check-release-files-line-13)">(TEXT)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
 </text><text class="breeze-release-management-check-release-files-r5" x="0" y="361.6" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-14)">│</text><text class="breeze-release-management-check-release-files-r4" x="61" y="361.6" textLength="170.8" clip-path="url(#breeze-release-management-check-release-files-line-14)">--release-date</text><text class="breeze-release-management-check-release-files-r1" x="390.4" y="361.6" textLength="793" clip-path="url(# [...]
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="386" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-15)">│</text><text class="breeze-release-management-check-release-files-r4" x="61" y="386" textLength="183" clip-path="url(#breeze-release-management-check-release-files-line-15)">--packages-file</text><text class="breeze-release-management-check-release-files-r1" x="390.4" y="386" textLength="768.6" clip-path="url(#breez [...]
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="410.4" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-16)">│</text><text class="breeze-release-management-check-release-files-r5" x="390.4" y="410.4" textLength="768.6" clip-path="url(#breeze-release-management-check-release-files-line-16)">[default:&#160;packages.txt]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="434.8" textLength="1464" clip-path="url(#breeze-release-management-check-release-files-line-17)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-check-release-files-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-17)">
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="459.2" textLength="24.4" clip-path="url(#breeze-release-management-check-release-files-line-18)">╭─</text><text class="breeze-release-management-check-release-files-r5" x="24.4" y="459.2" textLength="195.2" clip-path="url(#breeze-release-management-check-release-files-line-18)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-check-release-files-r5" x="219.6" y="459.2" textLength="1 [...]
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="483.6" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-19)">│</text><text class="breeze-release-management-check-release-files-r4" x="24.4" y="483.6" textLength="109.8" clip-path="url(#breeze-release-management-check-release-files-line-19)">--verbose</text><text class="breeze-release-management-check-release-files-r7" x="158.6" y="483.6" textLength="24.4" clip-path="url(#br [...]
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-20)">│</text><text class="breeze-release-management-check-release-files-r4" x="24.4" y="508" textLength="109.8" clip-path="url(#breeze-release-management-check-release-files-line-20)">--dry-run</text><text class="breeze-release-management-check-release-files-r7" x="158.6" y="508" textLength="24.4" clip-path="url(#breeze-r [...]
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-21)">│</text><text class="breeze-release-management-check-release-files-r4" x="24.4" y="532.4" textLength="73.2" clip-path="url(#breeze-release-management-check-release-files-line-21)">--help</text><text class="breeze-release-management-check-release-files-r7" x="158.6" y="532.4" textLength="24.4" clip-path="url(#breeze [...]
-</text><text class="breeze-release-management-check-release-files-r5" x="0" y="556.8" textLength="1464" clip-path="url(#breeze-release-management-check-release-files-line-22)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-check-release-files-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-22)">
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="386" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-15)">│</text><text class="breeze-release-management-check-release-files-r4" x="61" y="386" textLength="183" clip-path="url(#breeze-release-management-check-release-files-line-15)">--packages-file</text><text class="breeze-release-management-check-release-files-r1" x="390.4" y="386" textLength="1049.2" clip-path="url(#bree [...]
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="410.4" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-16)">│</text><text class="breeze-release-management-check-release-files-r1" x="390.4" y="410.4" textLength="1049.2" clip-path="url(#breeze-release-management-check-release-files-line-16)">packages.txt&#160;for&#160;providers&#160;releases.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#16 [...]
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="434.8" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-17)">│</text><text class="breeze-release-management-check-release-files-r8" x="390.4" y="434.8" textLength="1049.2" clip-path="url(#breeze-release-management-check-release-files-line-17)">(FILE)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;& [...]
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="459.2" textLength="1464" clip-path="url(#breeze-release-management-check-release-files-line-18)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-check-release-files-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-18)">
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="483.6" textLength="24.4" clip-path="url(#breeze-release-management-check-release-files-line-19)">╭─</text><text class="breeze-release-management-check-release-files-r5" x="24.4" y="483.6" textLength="195.2" clip-path="url(#breeze-release-management-check-release-files-line-19)">&#160;Common&#160;options&#160;</text><text class="breeze-release-management-check-release-files-r5" x="219.6" y="483.6" textLength="1 [...]
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="508" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-20)">│</text><text class="breeze-release-management-check-release-files-r4" x="24.4" y="508" textLength="109.8" clip-path="url(#breeze-release-management-check-release-files-line-20)">--verbose</text><text class="breeze-release-management-check-release-files-r7" x="158.6" y="508" textLength="24.4" clip-path="url(#breeze-r [...]
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-21)">│</text><text class="breeze-release-management-check-release-files-r4" x="24.4" y="532.4" textLength="109.8" clip-path="url(#breeze-release-management-check-release-files-line-21)">--dry-run</text><text class="breeze-release-management-check-release-files-r7" x="158.6" y="532.4" textLength="24.4" clip-path="url(#br [...]
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-22)">│</text><text class="breeze-release-management-check-release-files-r4" x="24.4" y="556.8" textLength="73.2" clip-path="url(#breeze-release-management-check-release-files-line-22)">--help</text><text class="breeze-release-management-check-release-files-r7" x="158.6" y="556.8" textLength="24.4" clip-path="url(#breeze [...]
+</text><text class="breeze-release-management-check-release-files-r5" x="0" y="581.2" textLength="1464" clip-path="url(#breeze-release-management-check-release-files-line-23)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-release-management-check-release-files-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#breeze-release-management-check-release-files-line-23)">
 </text>
     </g>
     </g>
diff --git a/dev/breeze/doc/images/output_release-management_check-release-files.txt b/dev/breeze/doc/images/output_release-management_check-release-files.txt
index 9fc21be66ca..8992bd6747a 100644
--- a/dev/breeze/doc/images/output_release-management_check-release-files.txt
+++ b/dev/breeze/doc/images/output_release-management_check-release-files.txt
@@ -1 +1 @@
-11b529b25ad8eac330722da830792bfb
+bf055c022b0dc0ff31cbb59f9094ca8a
diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index 3f78a043bdc..08086dbf0da 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -4117,9 +4117,8 @@ def version_check(
 @click.option(
     "--packages-file",
     type=click.Path(exists=True, file_okay=True, dir_okay=False, resolve_path=True, path_type=Path),
-    default="packages.txt",
     show_default=True,
-    help="File containing list of packages to check (for providers only).",
+    help="File containing list of packages to check (for providers only). use path to local packages.txt for providers releases.",
 )
 @click.argument(
     "release_type",
@@ -4132,7 +4131,7 @@ def check_release_files(
     path: Path,
     version: str | None,
     release_date: str | None,
-    packages_file: Path,
+    packages_file: Path | None,
     release_type: str,
 ):
     """
@@ -4198,6 +4197,9 @@ def check_release_files(
     missing_files = []
 
     if release_type == "providers":
+        if not packages_file:
+            console.print(f"[error]--packages-file is required for {release_type}[/]")
+            sys.exit(1)
         packages = get_packages(packages_file)
         missing_files = check_providers(files, release_date, packages)
         pips = [f"{name}=={ver}" for name, ver in packages]


(airflow) 02/32: [v3-1-test] Also limit urllib3 to < 2.6.0 in k8s tests - for use in v3-1-tests (#59152) (#59158)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 1fb72831977923651c1731a55d44a532b73f75b3
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Sun Dec 7 16:36:31 2025 +0100

    [v3-1-test] Also limit urllib3 to < 2.6.0 in k8s tests - for use in v3-1-tests (#59152) (#59158)
    
    (cherry picked from commit a129c2cbd713e099d4d7cf15249cf9eb820c23db)
---
 kubernetes-tests/pyproject.toml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kubernetes-tests/pyproject.toml b/kubernetes-tests/pyproject.toml
index bced4f3384d..90ddc85ea62 100644
--- a/kubernetes-tests/pyproject.toml
+++ b/kubernetes-tests/pyproject.toml
@@ -41,6 +41,10 @@ dependencies = [
     "apache-airflow-task-sdk",
     # Requests 3 if it will be released, will be heavily breaking.
     "requests>=2.32.0,<3",
+    # Urllib 2.6.0 breaks kubernetes client because kubernetes client uses deprecated in 2.0.0 and
+    # removed in 2.6.0 `getheaders()` call (instead of `headers` property.
+    # Tracked in https://github.com/kubernetes-client/python/issues/2477
+    "urllib3>=2.1.0,<2.6.0",
 ]
 
 [tool.pytest]


(airflow) 12/32: [v3-1-test] Bump ruff to 0.14.8, uv to 0.9.15 (#59058) (#59079)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 1977f09d201fb52f2abfb5e472f2c1f3d5848b04
Author: Amogh Desai <am...@gmail.com>
AuthorDate: Fri Dec 5 13:57:40 2025 +0530

    [v3-1-test] Bump ruff to 0.14.8, uv to 0.9.15 (#59058) (#59079)
    
    (cherry picked from commit cd255d7)
---
 .github/actions/breeze/action.yml                  |  2 +-
 .github/actions/install-prek/action.yml            |  2 +-
 .github/workflows/basic-tests.yml                  |  2 +-
 .github/workflows/release_dockerhub_image.yml      |  2 +-
 .pre-commit-config.yaml                            |  2 +-
 Dockerfile                                         |  2 +-
 Dockerfile.ci                                      |  2 +-
 airflow-core/docs/best-practices.rst               |  2 +-
 dev/breeze/doc/ci/02_images.md                     |  2 +-
 .../commands/release_management_commands.py        |  2 +-
 dev/breeze/src/airflow_breeze/global_constants.py  |  2 +-
 dev/breeze/uv.lock                                 | 56 +++++++++++-----------
 devel-common/pyproject.toml                        |  2 +-
 pyproject.toml                                     |  2 +-
 scripts/ci/prek/check_imports_in_providers.py      |  2 +-
 scripts/ci/prek/ruff_format.py                     |  2 +-
 scripts/tools/setup_breeze                         |  2 +-
 17 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/.github/actions/breeze/action.yml b/.github/actions/breeze/action.yml
index b6fbacda16e..2eac64d3832 100644
--- a/.github/actions/breeze/action.yml
+++ b/.github/actions/breeze/action.yml
@@ -24,7 +24,7 @@ inputs:
     default: "3.10"
   uv-version:
     description: 'uv version to use'
-    default: "0.9.14"  # Keep this comment to allow automatic replacement of uv version
+    default: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
 outputs:
   host-python-version:
     description: Python version used in host
diff --git a/.github/actions/install-prek/action.yml b/.github/actions/install-prek/action.yml
index 81b91b18a4b..e8160240b87 100644
--- a/.github/actions/install-prek/action.yml
+++ b/.github/actions/install-prek/action.yml
@@ -24,7 +24,7 @@ inputs:
     default: "3.10"
   uv-version:
     description: 'uv version to use'
-    default: "0.9.14"  # Keep this comment to allow automatic replacement of uv version
+    default: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
   prek-version:
     description: 'prek version to use'
     default: "0.2.19"  # Keep this comment to allow automatic replacement of prek version
diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml
index abc5ef8f9c0..d940097c24e 100644
--- a/.github/workflows/basic-tests.yml
+++ b/.github/workflows/basic-tests.yml
@@ -66,7 +66,7 @@ on:  # yamllint disable-line rule:truthy
         type: string
       uv-version:
         description: 'uv version to use'
-        default: "0.9.14"  # Keep this comment to allow automatic replacement of uv version
+        default: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
         type: string
       platform:
         description: 'Platform for the build - linux/amd64 or linux/arm64'
diff --git a/.github/workflows/release_dockerhub_image.yml b/.github/workflows/release_dockerhub_image.yml
index 99e2098bf91..f8dda5e53b5 100644
--- a/.github/workflows/release_dockerhub_image.yml
+++ b/.github/workflows/release_dockerhub_image.yml
@@ -58,7 +58,7 @@ jobs:
       AIRFLOW_VERSION: ${{ github.event.inputs.airflowVersion }}
       AMD_ONLY: ${{ github.event.inputs.amdOnly }}
       LIMIT_PYTHON_VERSIONS: ${{ github.event.inputs.limitPythonVersions }}
-      UV_VERSION: "0.9.14"  # Keep this comment to allow automatic replacement of uv version
+      UV_VERSION: "0.9.15"  # Keep this comment to allow automatic replacement of uv version
     if: contains(fromJSON('[
       "ashb",
       "bugraoz93",
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 421ca4c359f..b1073d99a64 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -350,7 +350,7 @@ repos:
         types_or: [python, pyi]
         args: [--fix]
         require_serial: true
-        additional_dependencies: ['ruff==0.14.7']
+        additional_dependencies: ['ruff==0.14.8']
         exclude: ^airflow-core/tests/unit/dags/test_imports\.py$|^performance/tests/test_.*\.py$
       - id: ruff-format
         name: Run 'ruff format'
diff --git a/Dockerfile b/Dockerfile
index 9b1f3afa64b..15b94ede71a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -56,7 +56,7 @@ ARG AIRFLOW_PYTHON_VERSION="3.12.12"
 # Also use `force pip` label on your PR to swap all places we use `uv` to `pip`
 ARG AIRFLOW_PIP_VERSION=25.3
 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main"
-ARG AIRFLOW_UV_VERSION=0.9.14
+ARG AIRFLOW_UV_VERSION=0.9.15
 ARG AIRFLOW_USE_UV="false"
 ARG UV_HTTP_TIMEOUT="300"
 ARG AIRFLOW_IMAGE_REPOSITORY="https://github.com/apache/airflow"
diff --git a/Dockerfile.ci b/Dockerfile.ci
index e82f35e7da5..ff7b2524fc7 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -1699,7 +1699,7 @@ COPY --from=scripts common.sh install_packaging_tools.sh install_additional_depe
 # Also use `force pip` label on your PR to swap all places we use `uv` to `pip`
 ARG AIRFLOW_PIP_VERSION=25.3
 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main"
-ARG AIRFLOW_UV_VERSION=0.9.14
+ARG AIRFLOW_UV_VERSION=0.9.15
 ARG AIRFLOW_PREK_VERSION="0.2.19"
 
 # UV_LINK_MODE=copy is needed since we are using cache mounted from the host
diff --git a/airflow-core/docs/best-practices.rst b/airflow-core/docs/best-practices.rst
index 1985c2731c6..114375c29b7 100644
--- a/airflow-core/docs/best-practices.rst
+++ b/airflow-core/docs/best-practices.rst
@@ -310,7 +310,7 @@ Installing and Using ruff
 
    .. code-block:: bash
 
-      pip install "ruff>=0.14.7"
+      pip install "ruff>=0.14.8"
 
 2. **Running ruff**: Execute ``ruff`` to check your Dags for potential issues:
 
diff --git a/dev/breeze/doc/ci/02_images.md b/dev/breeze/doc/ci/02_images.md
index 8bcb4f313cd..134bb92db76 100644
--- a/dev/breeze/doc/ci/02_images.md
+++ b/dev/breeze/doc/ci/02_images.md
@@ -443,7 +443,7 @@ can be used for CI images:
 | `ADDITIONAL_DEV_APT_DEPS`         |                             | Additional apt dev dependencies installed in the first part of the image                                          |
 | `ADDITIONAL_DEV_APT_ENV`          |                             | Additional env variables defined when installing dev deps                                                         |
 | `AIRFLOW_PIP_VERSION`             | `25.3`                      | `pip` version used.                                                                                               |
-| `AIRFLOW_UV_VERSION`              | `0.9.14`                    | `uv` version used.                                                                                                |
+| `AIRFLOW_UV_VERSION`              | `0.9.15`                    | `uv` version used.                                                                                                |
 | `AIRFLOW_PREK_VERSION`            | `0.2.19`                    | `prek` version used.                                                                                              |
 | `AIRFLOW_USE_UV`                  | `true`                      | Whether to use UV for installation.                                                                               |
 | `PIP_PROGRESS_BAR`                | `on`                        | Progress bar for PIP installation                                                                                 |
diff --git a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index dfe708f1248..bd6df2494b4 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -246,7 +246,7 @@ class VersionedFile(NamedTuple):
 
 
 AIRFLOW_PIP_VERSION = "25.3"
-AIRFLOW_UV_VERSION = "0.9.14"
+AIRFLOW_UV_VERSION = "0.9.15"
 AIRFLOW_USE_UV = False
 GITPYTHON_VERSION = "3.1.45"
 RICH_VERSION = "14.2.0"
diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py
index 5b47d656add..d411fb6c48f 100644
--- a/dev/breeze/src/airflow_breeze/global_constants.py
+++ b/dev/breeze/src/airflow_breeze/global_constants.py
@@ -213,7 +213,7 @@ if MYSQL_INNOVATION_RELEASE:
 ALLOWED_INSTALL_MYSQL_CLIENT_TYPES = ["mariadb", "mysql"]
 
 PIP_VERSION = "25.3"
-UV_VERSION = "0.9.14"
+UV_VERSION = "0.9.15"
 
 DEFAULT_UV_HTTP_TIMEOUT = 300
 DEFAULT_WSL2_HTTP_TIMEOUT = 900
diff --git a/dev/breeze/uv.lock b/dev/breeze/uv.lock
index b5169061aa6..48dc421af86 100644
--- a/dev/breeze/uv.lock
+++ b/dev/breeze/uv.lock
@@ -245,30 +245,30 @@ wheels = [
 
 [[package]]
 name = "boto3"
-version = "1.42.1"
+version = "1.42.2"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "botocore" },
     { name = "jmespath" },
     { name = "s3transfer" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/28/b2/08e0d2e0ee0a189762e9c803a7980c835d94a8c395660cc115a4a6833f49/boto3-1.42.1.tar.gz", hash = "sha256:137fbea593a30afa1b75656ea1f1ff8796be608a8c77f1b606c4473289679898", size = 112793, upload-time = "2025-12-02T17:28:29.524Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/e4/3b/be2c0175ff58d6abef88467d7e93225231059621181bc0cfd32fd8b05260/boto3-1.42.2.tar.gz", hash = "sha256:2b403f503bfe8486fd273e41f0b5a033d0e8dad5d94c5a5c0669e92272bd4f17", size = 112828, upload-time = "2025-12-03T17:50:22.599Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/0d/04/5da253f071d9409e3b0be0c79118bbad6c99fe8bd96cb7ef500083fc8aa7/boto3-1.42.1-py3-none-any.whl", hash = "sha256:9a8f9799afff600ff5cb43f57a619a5375ea71077ec958bda70e296378da7024", size = 140619, upload-time = "2025-12-02T17:28:27.88Z" },
+    { url = "https://files.pythonhosted.org/packages/54/3f/ba8d7e362ab595279663fdc77902ee46592252ea7210596bdcc3d2eee12b/boto3-1.42.2-py3-none-any.whl", hash = "sha256:e93c55fecfecc6f05de604288d216a49b06a3c2c53421848ca4afad55f0614b7", size = 140622, upload-time = "2025-12-03T17:50:20.106Z" },
 ]
 
 [[package]]
 name = "botocore"
-version = "1.42.1"
+version = "1.42.2"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "jmespath" },
     { name = "python-dateutil" },
     { name = "urllib3" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/8c/b5/3ce4e1eaf86953625b98fdcf40afc40a5682a76e140baf976d5e2dc6a9cc/botocore-1.42.1.tar.gz", hash = "sha256:3337df815c69dd87c314ee29329b8ea411ad3562fb6563d139bbe085dac14ce0", size = 14839894, upload-time = "2025-12-02T17:28:19.053Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/d7/29/1c9b4f73a738d1464c07ccd8b74ed7f21d7f00319bfd6e397a0e897fd61f/botocore-1.42.2.tar.gz", hash = "sha256:3dbeba76168764219cbe392aa67cbc9265cfa05b09970ed5f2e0c786b8ac5010", size = 14843197, upload-time = "2025-12-03T17:50:11.065Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/25/a7/2e36617497b7f1af8bde00b3a737688eaa4017ea3657a0be64ef7cc0baa9/botocore-1.42.1-py3-none-any.whl", hash = "sha256:9d49f5197487f9f71daa9c5397f81484ffcc0dc1cf89a63e94ae3e5a27faa98c", size = 14513092, upload-time = "2025-12-02T17:28:15.559Z" },
+    { url = "https://files.pythonhosted.org/packages/83/b3/4d413a69696a5d096af3f27c91e40f841886aecd849ee62dbb366c50d7ae/botocore-1.42.2-py3-none-any.whl", hash = "sha256:8bb3f0ce39c6a7f63b404a2632ab1a5189187b27317c7b97fe45494677633b5d", size = 14517436, upload-time = "2025-12-03T17:50:07.589Z" },
 ]
 
 [[package]]
@@ -2022,28 +2022,28 @@ wheels = [
 
 [[package]]
 name = "uv"
-version = "0.9.14"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/93/77/36977111f1a7a6625ba432959958d284124d5cda678b703b77f1e1c8e8b8/uv-0.9.14.tar.gz", hash = "sha256:e62ae030bb607abe9c2d6d2569c696804fa668a3b176d7cce20cfa1c66012855", size = 3766833, upload-time = "2025-12-01T17:22:51.155Z" }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/1e/f8/05876ea28ef1edd4a4dbcd5c9e44daa7d056bad25b0f114305a49457baa7/uv-0.9.14-py3-none-linux_armv6l.whl", hash = "sha256:876d0cf2a92113e1237ef71a7dc21e2cc82ab0664f98004d61abeb05c944ffd2", size = 20844416, upload-time = "2025-12-01T17:22:42.25Z" },
-    { url = "https://files.pythonhosted.org/packages/67/c0/c88a40306b2d437704e25f19890da1f6f9b42cbe1695de0373e3ca1258d8/uv-0.9.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e14853fb7781251f75cbb200fa2a81f2ac087a7f0647ee8699689198d6496f05", size = 19981109, upload-time = "2025-12-01T17:22:07.422Z" },
-    { url = "https://files.pythonhosted.org/packages/f0/65/6ba20daba11fc88d41cb03fe903d8440618f6033fba511f34c7bd9df02ad/uv-0.9.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:dd90bc5e364a2fdc89499de9c1cffe9036b0318e54644b5664a9c395bb21bb29", size = 18469837, upload-time = "2025-12-01T17:22:19.014Z" },
-    { url = "https://files.pythonhosted.org/packages/e9/a1/245dfacce0e2755b82b00dc5fbaea4a690e3fb7046a779c1fd719896f04b/uv-0.9.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:c086218fe1f3f88281d2f881bbeb5ada062eb4ea5d28292f352e45de38aa125a", size = 20347846, upload-time = "2025-12-01T17:22:35.144Z" },
-    { url = "https://files.pythonhosted.org/packages/03/0d/9314fd85e8ab574c9433b014d49fe233cd8e0ae38274cc5716a9f8291f5e/uv-0.9.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6dc4d37a593e2843df96a32be4cdab682e7abb15552c967277ac29fe8e556cdb", size = 20441070, upload-time = "2025-12-01T17:22:46.793Z" },
-    { url = "https://files.pythonhosted.org/packages/b2/e9/1eab4b0e3b7eb6823a927a86bf34e3e0086c6321d794da4fafc1e168373c/uv-0.9.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7770890958273fe5f6222857be0981e06808f531a2d28cc8da5907b3036fa7dd", size = 21636744, upload-time = "2025-12-01T17:22:28.272Z" },
-    { url = "https://files.pythonhosted.org/packages/4f/ca/3a25e8bce4402d410bdbe5dc327eb9cf1e441f29cde73a7838816b23a14b/uv-0.9.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2a1724160ab2429317ab7d340f95d34c93a4830fef7f2d952795754837fb2e2c", size = 23033527, upload-time = "2025-12-01T17:22:30.643Z" },
-    { url = "https://files.pythonhosted.org/packages/39/44/c3e3ac7e80de643aa34fc70661f668a121fb48cc515e0a263daaf24e92cb/uv-0.9.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:180496428c669244e6af4b4b05f3c450d7976367b4907312d609890a2ee03be5", size = 22666761, upload-time = "2025-12-01T17:22:13.771Z" },
-    { url = "https://files.pythonhosted.org/packages/b9/c7/14eddd397d6333673b1dc15f4f13548afae191b3dbf5a40d25bbf12c2789/uv-0.9.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:144bad91b4c4efd7104e219beab4a238ccf560a87323128f0d6471b85c08915e", size = 21653308, upload-time = "2025-12-01T17:22:21.358Z" },
-    { url = "https://files.pythonhosted.org/packages/38/9e/0ddb21e94fc7fd67547e74aa0cbb042d57f52fe283f3d517d1a8c9e5df66/uv-0.9.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b5a27f528af437d9cd7bd85905095f166d0c37bdf3404a8a900948068e03d6b", size = 21690920, upload-time = "2025-12-01T17:22:32.777Z" },
-    { url = "https://files.pythonhosted.org/packages/17/35/44a7aeafc1cc9b1ec55ab433bed0211c34ca77f230853735c6c8d8683783/uv-0.9.14-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:cbf18113f0e07898af804f6f4a9ef521eb181865a94b7d162431dcae5b55f8fa", size = 20467749, upload-time = "2025-12-01T17:22:11.23Z" },
-    { url = "https://files.pythonhosted.org/packages/dd/f8/6b087904c897f2e96c69c9386fdefbd6c5fdeecab6624c5e972a0e31dd91/uv-0.9.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:18231f386e3f153e9560f535bd224b618f4990c4f417504f915fe95fc5513448", size = 21513786, upload-time = "2025-12-01T17:22:25.953Z" },
-    { url = "https://files.pythonhosted.org/packages/a1/4b/1959897d40affc078eca5812db6bdef0a331e594e8907d336db2e90d0252/uv-0.9.14-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:e2cd3e885e4c30048f9c2c526bd340f6e082ca5fb6bf4516c90671a114746fc3", size = 20406081, upload-time = "2025-12-01T17:22:23.66Z" },
-    { url = "https://files.pythonhosted.org/packages/c7/ce/e7e27f7891e38c98f5c83b3c8068c6265f5dc96c12924f2a0fc31b4eb7ac/uv-0.9.14-py3-none-musllinux_1_1_i686.whl", hash = "sha256:da227183ab9860832533e7f152a83d0d749f8d0156348b68f48773d42f690ff1", size = 20965537, upload-time = "2025-12-01T17:22:16.582Z" },
-    { url = "https://files.pythonhosted.org/packages/71/44/b9cdb4137338b33a419ff4aff70ac00df4a5a68e1b9bd21a59f96caf6c6f/uv-0.9.14-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:70a55f189b2d9ec035194c927f2c0b4f746b251e329a5dc8391ab6a41fe14e1a", size = 21919764, upload-time = "2025-12-01T17:22:37.369Z" },
-    { url = "https://files.pythonhosted.org/packages/66/57/2e294c6d758b48883434ad979e089cfe5ec87584ec7ffee005be359f6035/uv-0.9.14-py3-none-win32.whl", hash = "sha256:06923d5ee88b50dabb364c4fcc2a0de84e079b6a2fb6cc6ca318e74e979affed", size = 19742562, upload-time = "2025-12-01T17:22:49.106Z" },
-    { url = "https://files.pythonhosted.org/packages/f0/2f/81d551db61228adb062ff29dec7634d82091e38f579d56ed27db40bd300e/uv-0.9.14-py3-none-win_amd64.whl", hash = "sha256:c0f18fd246726cdc194357aca50fd13153d719daecd765049f0ff4c2262143d3", size = 21655524, upload-time = "2025-12-01T17:22:39.643Z" },
-    { url = "https://files.pythonhosted.org/packages/ef/91/deb722a8ddb076018aee02ab3bffcdda6f10b7ca96f72aeca06b5efaccec/uv-0.9.14-py3-none-win_arm64.whl", hash = "sha256:d974fcbec84aa7eb4ee1cc7e650a5b8973895a03f6d6f0c61b488e1d1b8179ea", size = 20121260, upload-time = "2025-12-01T17:22:44.502Z" },
+version = "0.9.15"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d0/b8/63e4ad24d7ef24ef1de10cb2db9ff0f74b2cceb4bd71c4b3909297d40967/uv-0.9.15.tar.gz", hash = "sha256:241a57d8ce90273d0ad8460897e1b2250bd4aa6bafe72fd8be07fbc3a7662f3d", size = 3788825, upload-time = "2025-12-03T01:33:06.404Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/fd/e7/5c7fcf7a49884273c18a54b68ffd5f05775cb0e59aeeb2801f2b6d31787b/uv-0.9.15-py3-none-linux_armv6l.whl", hash = "sha256:4ccf2aa7f2e0fcb553dccc8badceb2fc533000e5baf144fd982bb9be88b304b8", size = 20936584, upload-time = "2025-12-03T01:32:58.983Z" },
+    { url = "https://files.pythonhosted.org/packages/30/a8/5c376318f57dd4fc58bb01db870f9e564a689d479ddc0440731933286740/uv-0.9.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:944cd6d500974f9693994ec990c5b263a185e66cbc1cbd230f319445f8330e4e", size = 20000398, upload-time = "2025-12-03T01:33:04.518Z" },
+    { url = "https://files.pythonhosted.org/packages/ca/c7/6af7e5dc21902eb936a54c037650f070cea015d742b3a49e82f53e6f32c4/uv-0.9.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ec4716fee5db65cfc78016d07f6fddb9b1fa29a0471fe67fe6676e2befee3215", size = 18440619, upload-time = "2025-12-03T01:32:56.388Z" },
+    { url = "https://files.pythonhosted.org/packages/88/73/8364801f678ba58d1a31ec9c8e0bfc407b48c0c57e0e3618e8fbf6b285f6/uv-0.9.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:2b9ad2581a90b7b2ed3f5a3b2657c3cf84119bdf101e1a1c49a2f38577eecb1b", size = 20326432, upload-time = "2025-12-03T01:32:53.805Z" },
+    { url = "https://files.pythonhosted.org/packages/89/ed/9c13d81005b00dcc759f7ea4b640b1efff8ecebbf852df90c2f237373ed5/uv-0.9.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d6a837537294e283ddbb18c494dbc085afca3e29d2176059140b7b4e94e485fd", size = 20531552, upload-time = "2025-12-03T01:33:18.894Z" },
+    { url = "https://files.pythonhosted.org/packages/b1/24/99c26056300c83f0d542272c02465937965191739d44bf8654d09d2d296f/uv-0.9.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:214013314564347ad629a5cfcd28b962038fc23c72155d7a798313f6b9f64f81", size = 21428020, upload-time = "2025-12-03T01:33:10.373Z" },
+    { url = "https://files.pythonhosted.org/packages/a2/4a/15dd32d695eae71cb4c09af6e9cbde703674824653c9f2963b068108b344/uv-0.9.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b32c1ac11ea80ab4cc6ea61029880e1319041d2b3783f2478c8eadfc9a9c9d5a", size = 23061719, upload-time = "2025-12-03T01:32:48.914Z" },
+    { url = "https://files.pythonhosted.org/packages/51/02/83c179d6a5cfee0c437dd1d73b515557c6b2b7ab19fb9421420c13b10bc8/uv-0.9.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64d99dfe8af75fed7fd6b7f6a8a81ba26ac88e046c5cb366184c2b53b023b070", size = 22609336, upload-time = "2025-12-03T01:32:41.645Z" },
+    { url = "https://files.pythonhosted.org/packages/a3/77/c620febe2662ab1897c2ef7c95a5424517efc456b77a1f75f6da81b4e542/uv-0.9.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5375c95a70fc76104fc178771cd4a8db1dab55345c7162c3d2d47ca2993c4bb", size = 21663700, upload-time = "2025-12-03T01:32:36.335Z" },
+    { url = "https://files.pythonhosted.org/packages/70/1b/4273d02565a4e86f238e9fee23e6c5c3bb7b5c237c63228e1b72451db224/uv-0.9.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9c1cefdd6e878baa32ff7a7d1ef463690750ff45d899fbb6bd6705e8329b00a", size = 21714799, upload-time = "2025-12-03T01:33:01.785Z" },
+    { url = "https://files.pythonhosted.org/packages/61/ae/29787af8124d821c1a88bb66612c24ff6180309d35348a4915214c5078d3/uv-0.9.15-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:b6d342a4610e7dbc3450c8000313ee7693905ddee12a65a34fdbcd8418a852a5", size = 20454218, upload-time = "2025-12-03T01:33:14.113Z" },
+    { url = "https://files.pythonhosted.org/packages/56/fe/ab906a1e530f0fbb7042e82057d7c08ef46131deb75d5fef2133de6725c5/uv-0.9.15-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:dea4fd678d48b9790234de43b2e5e4a445f9541fd361db7dc1a2cac861c9717a", size = 21549370, upload-time = "2025-12-03T01:32:46.766Z" },
+    { url = "https://files.pythonhosted.org/packages/19/11/20ea6dc5ca56f2ad9a8f1b5674f84c38a45a28ccf880aa7c1abb226355a6/uv-0.9.15-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:bae65f4748cacc20ea7f93b94a9ba82dd5505a98cf61e33d75e2669c6aefbfc5", size = 20502715, upload-time = "2025-12-03T01:32:51.454Z" },
+    { url = "https://files.pythonhosted.org/packages/37/38/ed98b5f48be2aeb63dc8853bc777b739c18277d0b950196b4d46f7b4d74a/uv-0.9.15-py3-none-musllinux_1_1_i686.whl", hash = "sha256:5473c1095a697b7c7996a312232f78e81cf71e5afc30c889e46a486fe298d853", size = 20890379, upload-time = "2025-12-03T01:32:28.035Z" },
+    { url = "https://files.pythonhosted.org/packages/dd/50/a97468ed93b80a50ea97a717662be4b841e7149bc68197ded087bcdd9e36/uv-0.9.15-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a0ef2e2bcf807aebd70e3a87bde618d0a01f07f627f5da0b0b457d7be2124843", size = 21921653, upload-time = "2025-12-03T01:32:31.016Z" },
+    { url = "https://files.pythonhosted.org/packages/94/e8/ad85878d4e789c40b75c9f670eba52c7e5e63393f31e1c1a7246849595a2/uv-0.9.15-py3-none-win32.whl", hash = "sha256:5efa39d9085f918d17869e43471ccd4526372e71d945b8d7cd3c8867ce6eab33", size = 19762699, upload-time = "2025-12-03T01:32:39.104Z" },
+    { url = "https://files.pythonhosted.org/packages/bc/37/e15a46f880b2c230f7d6934f046825ebe547f90008984c861e84e2ef34c4/uv-0.9.15-py3-none-win_amd64.whl", hash = "sha256:e46f36c80353fb406d4c0fb2cfe1953b4a01bfb3fc5b88dd4f763641b8899f1a", size = 21758441, upload-time = "2025-12-03T01:32:33.722Z" },
+    { url = "https://files.pythonhosted.org/packages/9a/fe/af3595c25dfaa85daff11ed0c8ca0fc1d088a426c65ef93d3751490673fd/uv-0.9.15-py3-none-win_arm64.whl", hash = "sha256:8f14456f357ebbf3f494ae5af41e9b306ba66ecc81cb2304095b38d99a1f7d28", size = 20203340, upload-time = "2025-12-03T01:32:44.184Z" },
 ]
 
 [[package]]
diff --git a/devel-common/pyproject.toml b/devel-common/pyproject.toml
index a7288a8b8f0..498296d3f5b 100644
--- a/devel-common/pyproject.toml
+++ b/devel-common/pyproject.toml
@@ -35,7 +35,7 @@ dependencies = [
     "kgb>=7.2.0",
     "requests_mock>=1.11.0",
     "rich>=13.6.0",
-    "ruff==0.14.7",
+    "ruff==0.14.8",
     "semver>=3.0.2",
     "typer-slim>=0.15.1",
     # limited due to changes needed https://github.com/apache/airflow/issues/58470
diff --git a/pyproject.toml b/pyproject.toml
index 6c208f5b11e..7a57293a2d9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -533,7 +533,7 @@ packages = []
     "apache-airflow-providers-amazon[s3fs]",
 ]
 "uv" = [
-    "uv>=0.9.14",
+    "uv>=0.9.15",
 ]
 
 
diff --git a/scripts/ci/prek/check_imports_in_providers.py b/scripts/ci/prek/check_imports_in_providers.py
index 52bd3110dcb..b99d03570a9 100755
--- a/scripts/ci/prek/check_imports_in_providers.py
+++ b/scripts/ci/prek/check_imports_in_providers.py
@@ -19,7 +19,7 @@
 # requires-python = ">=3.10,<3.11"
 # dependencies = [
 #   "rich>=13.6.0",
-#   "ruff==0.14.7",
+#   "ruff==0.14.8",
 # ]
 # ///
 from __future__ import annotations
diff --git a/scripts/ci/prek/ruff_format.py b/scripts/ci/prek/ruff_format.py
index c10865560cd..bb04f2e981b 100755
--- a/scripts/ci/prek/ruff_format.py
+++ b/scripts/ci/prek/ruff_format.py
@@ -18,7 +18,7 @@
 # /// script
 # requires-python = ">=3.10,<3.11"
 # dependencies = [
-#   "ruff==0.14.7",
+#   "ruff==0.14.8",
 # ]
 # ///
 
diff --git a/scripts/tools/setup_breeze b/scripts/tools/setup_breeze
index 41636efb611..28780080114 100755
--- a/scripts/tools/setup_breeze
+++ b/scripts/tools/setup_breeze
@@ -27,7 +27,7 @@ COLOR_YELLOW=$'\e[33m'
 COLOR_BLUE=$'\e[34m'
 COLOR_RESET=$'\e[0m'
 
-UV_VERSION="0.9.14"
+UV_VERSION="0.9.15"
 
 function manual_instructions() {
     echo


(airflow) 19/32: [v3-1-test] fix flaky TestEmrCreateJobFlowOperator (#59128) (#59137)

Posted by ep...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 3f15542f036d4c45462b991bec10f0b2ef413849
Author: Jason(Zhe-You) Liu <68...@users.noreply.github.com>
AuthorDate: Mon Dec 8 06:23:11 2025 +0800

    [v3-1-test] fix flaky TestEmrCreateJobFlowOperator (#59128) (#59137)
    
    (cherry picked from commit 97cf3c7)
    
    Co-authored-by: Henry Chen <10...@users.noreply.github.com>
---
 devel-common/src/tests_common/test_utils/db.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/devel-common/src/tests_common/test_utils/db.py b/devel-common/src/tests_common/test_utils/db.py
index 63b9d93d3b0..3741b788cf6 100644
--- a/devel-common/src/tests_common/test_utils/db.py
+++ b/devel-common/src/tests_common/test_utils/db.py
@@ -252,9 +252,9 @@ def clear_db_dags():
             session.query(DagFavorite).delete()
         session.query(DagTag).delete()
         session.query(DagOwnerAttributes).delete()
-        session.query(
-            DagRun
-        ).delete()  # todo: this should not be necessary because the fk to DagVersion should be ON DELETE SET NULL
+        session.query(DagRun).delete(
+            synchronize_session=False
+        )  # todo: this should not be necessary because the fk to DagVersion should be ON DELETE SET NULL
         session.query(DagModel).delete()