From 60e23cc6241783d926644831c1a15fc45f1c761e Mon Sep 17 00:00:00 2001 From: Dev-iL <6509619+Dev-iL@users.noreply.github.com> Date: Fri, 6 Mar 2026 09:38:51 +0200 Subject: [PATCH 01/50] fix: Unhandled Exception in remote logging if connection doesn't exist(#59801) (#62979) Cherry-picked from 3428dc9 with conflict resolution: - context.py: Added `import inspect` (skip `import functools` as `from functools import cache` already exists) - supervisor.py: Adopted early-return pattern and explicit `del` for GC, kept simpler env var handling (no `_AIRFLOW_PROCESS_CONTEXT` which doesn't exist in v3-1-test) - test_supervisor.py: Replaced `@pytest.mark.xfail` workaround with proper `use_real_secrets_backends` fixture Co-authored-by: Claude Opus 4.6 --- task-sdk/src/airflow/sdk/api/client.py | 3 +- .../src/airflow/sdk/execution_time/context.py | 8 +++- .../airflow/sdk/execution_time/supervisor.py | 37 +++++++++++-------- .../task_sdk/execution_time/test_secrets.py | 22 ++++++++++- .../execution_time/test_supervisor.py | 31 +++++++++++++++- 5 files changed, 79 insertions(+), 22 deletions(-) diff --git a/task-sdk/src/airflow/sdk/api/client.py b/task-sdk/src/airflow/sdk/api/client.py index 2ef50a72ff796..8d9e48d612941 100644 --- a/task-sdk/src/airflow/sdk/api/client.py +++ b/task-sdk/src/airflow/sdk/api/client.py @@ -848,7 +848,8 @@ def __init__(self, *, base_url: str | None, dry_run: bool = False, token: str, * kwargs.setdefault("base_url", "dry-run://server") else: kwargs["base_url"] = base_url - kwargs["verify"] = self._get_ssl_context_cached(certifi.where(), API_SSL_CERT_PATH) + # Call via the class to avoid binding lru_cache wires to this instance. + kwargs["verify"] = type(self)._get_ssl_context_cached(certifi.where(), API_SSL_CERT_PATH) # Set timeout if not explicitly provided kwargs.setdefault("timeout", API_TIMEOUT) diff --git a/task-sdk/src/airflow/sdk/execution_time/context.py b/task-sdk/src/airflow/sdk/execution_time/context.py index 379a13a930e55..512468bb48668 100644 --- a/task-sdk/src/airflow/sdk/execution_time/context.py +++ b/task-sdk/src/airflow/sdk/execution_time/context.py @@ -18,6 +18,7 @@ import collections import contextlib +import inspect from collections.abc import Generator, Iterable, Iterator, Mapping, Sequence from functools import cache from typing import TYPE_CHECKING, Any, Generic, TypeVar, overload @@ -197,8 +198,11 @@ async def _async_get_connection(conn_id: str) -> Connection: for secrets_backend in backends: try: # Use async method if available, otherwise wrap sync method - if hasattr(secrets_backend, "aget_connection"): - conn = await secrets_backend.aget_connection(conn_id) # type: ignore[assignment] + # getattr avoids triggering AsyncMock coroutine creation under Python 3.13 + async_method = getattr(secrets_backend, "aget_connection", None) + if async_method is not None: + maybe_awaitable = async_method(conn_id) + conn = await maybe_awaitable if inspect.isawaitable(maybe_awaitable) else maybe_awaitable else: conn = await sync_to_async(secrets_backend.get_connection)(conn_id) # type: ignore[assignment] diff --git a/task-sdk/src/airflow/sdk/execution_time/supervisor.py b/task-sdk/src/airflow/sdk/execution_time/supervisor.py index 206bf3b687802..0b02d215f27b0 100644 --- a/task-sdk/src/airflow/sdk/execution_time/supervisor.py +++ b/task-sdk/src/airflow/sdk/execution_time/supervisor.py @@ -36,14 +36,7 @@ from datetime import datetime, timezone from http import HTTPStatus from socket import socket, socketpair -from typing import ( - TYPE_CHECKING, - BinaryIO, - ClassVar, - NoReturn, - TextIO, - cast, -) +from typing import TYPE_CHECKING, BinaryIO, ClassVar, NoReturn, TextIO, cast from urllib.parse import urlparse from uuid import UUID @@ -898,17 +891,29 @@ def _remote_logging_conn(client: Client): # Fetch connection details on-demand without caching the entire API client instance conn = _fetch_remote_logging_conn(conn_id, client) - if conn: - key = f"AIRFLOW_CONN_{conn_id.upper()}" - old = os.getenv(key) - os.environ[key] = conn.get_uri() + if not conn: try: yield finally: - if old is None: - del os.environ[key] - else: - os.environ[key] = old + # Ensure we don't leak the caller's client when no connection was fetched. + del conn + del client + return + + key = f"AIRFLOW_CONN_{conn_id.upper()}" + old = os.getenv(key) + os.environ[key] = conn.get_uri() + try: + yield + finally: + if old is None: + del os.environ[key] + else: + os.environ[key] = old + + # Explicitly drop local references so the caller's client can be garbage collected. + del conn + del client @attrs.define(kw_only=True) diff --git a/task-sdk/tests/task_sdk/execution_time/test_secrets.py b/task-sdk/tests/task_sdk/execution_time/test_secrets.py index b19ab3b1003ab..8f9745b0ffeca 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_secrets.py +++ b/task-sdk/tests/task_sdk/execution_time/test_secrets.py @@ -144,9 +144,29 @@ def test_runtime_error_triggers_greenback_fallback(self, mocker, mock_supervisor # Mock the greenback and asyncio modules that are imported inside the exception handler mocker.patch("greenback.has_portal", return_value=True) - mock_greenback_await = mocker.patch("greenback.await_", return_value=expected_conn) mocker.patch("asyncio.current_task") + # Mock greenback.await_ to actually await the coroutine it receives. + # This prevents Python 3.13 RuntimeWarning about unawaited coroutines. + import asyncio + + def greenback_await_side_effect(coro): + loop = asyncio.new_event_loop() + try: + return loop.run_until_complete(coro) + finally: + loop.close() + + mock_greenback_await = mocker.patch("greenback.await_", side_effect=greenback_await_side_effect) + + # Mock aget_connection to return the expected connection directly. + # We need to mock this because the real aget_connection would try to + # use SUPERVISOR_COMMS.asend which is not set up for this test. + async def mock_aget_connection(self, conn_id): + return expected_conn + + mocker.patch.object(ExecutionAPISecretsBackend, "aget_connection", mock_aget_connection) + backend = ExecutionAPISecretsBackend() conn = backend.get_connection("databricks_default") diff --git a/task-sdk/tests/task_sdk/execution_time/test_supervisor.py b/task-sdk/tests/task_sdk/execution_time/test_supervisor.py index ba3c51669311e..c7b54666a1e0c 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_supervisor.py +++ b/task-sdk/tests/task_sdk/execution_time/test_supervisor.py @@ -225,8 +225,35 @@ class TestWatchedSubprocess: def disable_log_upload(self, spy_agency): spy_agency.spy_on(ActivitySubprocess._upload_logs, call_original=False) - # TODO: Investigate and fix it after 3.1.0 - @pytest.mark.xfail(reason="Fails on Py 3.12 with multi-threading error only in tests.") + @pytest.fixture(autouse=True) + def use_real_secrets_backends(self, monkeypatch): + """ + Ensure that real secrets backend instances are used instead of mocks. + + This prevents Python 3.13 RuntimeWarning when hasattr checks async methods + on mocked backends. The warning occurs because hasattr on AsyncMock creates + unawaited coroutines. + + This fixture ensures test isolation when running in parallel with pytest-xdist, + regardless of what other tests patch. + """ + import importlib + + import airflow.sdk.execution_time.secrets.execution_api as execution_api_module + from airflow.secrets.environment_variables import EnvironmentVariablesBackend + + fresh_execution_backend = importlib.reload(execution_api_module).ExecutionAPISecretsBackend + + # Ensure downstream imports see the restored class instead of any AsyncMock left by other tests + import airflow.sdk.execution_time.secrets as secrets_package + + monkeypatch.setattr(secrets_package, "ExecutionAPISecretsBackend", fresh_execution_backend) + + monkeypatch.setattr( + "airflow.sdk.execution_time.supervisor.ensure_secrets_backend_loaded", + lambda: [EnvironmentVariablesBackend(), fresh_execution_backend()], + ) + def test_reading_from_pipes(self, captured_logs, time_machine, client_with_ti_start): def subprocess_main(): # This is run in the subprocess! From 6e2fdc2a4d48ad1eba04a293db41181aa18f3b38 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Fri, 6 Mar 2026 20:28:55 +0800 Subject: [PATCH 02/50] CI: Upgrade important CI environment (#62981) --- .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 +- .../src/airflow_breeze/global_constants.py | 2 +- dev/breeze/uv.lock | 242 +++++++++--------- 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, 137 insertions(+), 137 deletions(-) diff --git a/.github/actions/breeze/action.yml b/.github/actions/breeze/action.yml index eb0085390bf6b..a013341f1289c 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.10.7" # Keep this comment to allow automatic replacement of uv version + default: "0.10.8" # 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 79ba6a1db1671..67471bc3ad4de 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.10.7" # Keep this comment to allow automatic replacement of uv version + default: "0.10.8" # Keep this comment to allow automatic replacement of uv version prek-version: description: 'prek version to use' default: "0.3.4" # 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 34cf1bcb7ffc1..fb6450f4680cb 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.10.7" # Keep this comment to allow automatic replacement of uv version + default: "0.10.8" # 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 b6099163a84bc..1e578a4f93ef4 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.10.7" # Keep this comment to allow automatic replacement of uv version + UV_VERSION: "0.10.8" # 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 79821d63f298f..fbe4f7c810188 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -408,7 +408,7 @@ repos: types_or: [python, pyi] args: [--fix] require_serial: true - additional_dependencies: ['ruff==0.15.4'] + additional_dependencies: ['ruff==0.15.5'] 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 e4fd516b5dc6f..4a37dba420d22 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,7 +58,7 @@ ARG AIRFLOW_PYTHON_VERSION="3.12.13" # Also use `force pip` label on your PR to swap all places we use `uv` to `pip` ARG AIRFLOW_PIP_VERSION=26.0.1 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main" -ARG AIRFLOW_UV_VERSION=0.10.7 +ARG AIRFLOW_UV_VERSION=0.10.8 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 0795a68222dce..956660bd22d8f 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1728,7 +1728,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=26.0.1 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main" -ARG AIRFLOW_UV_VERSION=0.10.7 +ARG AIRFLOW_UV_VERSION=0.10.8 ARG AIRFLOW_PREK_VERSION="0.3.4" # 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 cafd8d4895e55..6d11e0ccc0209 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.15.4" + pip install "ruff>=0.15.5" 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 4b184d6fbed28..ac9772f4a0f10 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` | `26.0.1` | `pip` version used. | -| `AIRFLOW_UV_VERSION` | `0.10.7` | `uv` version used. | +| `AIRFLOW_UV_VERSION` | `0.10.8` | `uv` version used. | | `AIRFLOW_PREK_VERSION` | `0.3.4` | `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 464472bfe136f..86e0da897ed12 100644 --- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py +++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py @@ -254,7 +254,7 @@ class VersionedFile(NamedTuple): AIRFLOW_PIP_VERSION = "26.0.1" -AIRFLOW_UV_VERSION = "0.10.7" +AIRFLOW_UV_VERSION = "0.10.8" AIRFLOW_USE_UV = False GITPYTHON_VERSION = "3.1.46" RICH_VERSION = "14.3.3" diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py index 151ae6944ba99..b992383eca699 100644 --- a/dev/breeze/src/airflow_breeze/global_constants.py +++ b/dev/breeze/src/airflow_breeze/global_constants.py @@ -213,7 +213,7 @@ ALLOWED_INSTALL_MYSQL_CLIENT_TYPES = ["mariadb", "mysql"] PIP_VERSION = "26.0.1" -UV_VERSION = "0.10.7" +UV_VERSION = "0.10.8" DEFAULT_UV_HTTP_TIMEOUT = 300 DEFAULT_WSL2_HTTP_TIMEOUT = 900 diff --git a/dev/breeze/uv.lock b/dev/breeze/uv.lock index b848f8ab77791..0b2ac146fe6cf 100644 --- a/dev/breeze/uv.lock +++ b/dev/breeze/uv.lock @@ -260,30 +260,30 @@ wheels = [ [[package]] name = "boto3" -version = "1.42.59" +version = "1.42.62" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b0/4e/499cb52aaee9468c346bcc1158965e24e72b4e2a20052725b680e0ac949b/boto3-1.42.59.tar.gz", hash = "sha256:6c4a14a4eb37b58a9048901bdeefbe1c529638b73e8f55413319a25f010ca211", size = 112725, upload-time = "2026-02-27T20:25:33.228Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/7e/c952803c8900f14e6f6158fddbd35da5afb2e3fa68bf498a761e6ba2c2ae/boto3-1.42.62.tar.gz", hash = "sha256:6b26ff56c458685caec3d42adde0549f6a55410e557e1f51bebde5c8abcf3037", size = 112848, upload-time = "2026-03-05T21:20:37.755Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/c0/22d868b9408dc5a33935a72896ec8d638b2766c459668d1b37c3e5ac2066/boto3-1.42.59-py3-none-any.whl", hash = "sha256:7a66e3e8e2087ea4403e135e9de592e6d63fc9a91080d8dac415bb74df873a72", size = 140557, upload-time = "2026-02-27T20:25:31.774Z" }, + { url = "https://files.pythonhosted.org/packages/1f/68/b5e82dedd9c8d53a9542df4e3475d2d3ec331eef4a4a801e9c5fa98b583a/boto3-1.42.62-py3-none-any.whl", hash = "sha256:eef0ee08f30e5ed16d8296719808801a827fa0f3126a3e2a9ef9be9eb5e6a313", size = 140556, upload-time = "2026-03-05T21:20:35.354Z" }, ] [[package]] name = "botocore" -version = "1.42.59" +version = "1.42.62" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/45/ae/50fb33bdf1911c216d50f98d989dd032a506f054cf829ebd737c6fa7e3e6/botocore-1.42.59.tar.gz", hash = "sha256:5314f19e1da8fc0ebc41bdb8bbe17c9a7397d87f4d887076ac8bdef972a34138", size = 14950271, upload-time = "2026-02-27T20:25:20.614Z" } +sdist = { url = "https://files.pythonhosted.org/packages/af/e7/031f2f03f22817f8a8def7ad1caa138979c20ac35062b055274e0a505c3f/botocore-1.42.62.tar.gz", hash = "sha256:c210dc93b0b81bf72cfe745a7b1c8df765d04bd90b4ac6c8707fbb6714141dae", size = 14966114, upload-time = "2026-03-05T21:20:25.518Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/df/9d52819e0d804ead073d53ab1823bc0f0cb172a250fba31107b0b43fbb04/botocore-1.42.59-py3-none-any.whl", hash = "sha256:d2f2ff7ecc31e86ef46b5daee112cfbca052c13801285fb23af909f7bff5b657", size = 14619293, upload-time = "2026-02-27T20:25:17.455Z" }, + { url = "https://files.pythonhosted.org/packages/8d/57/9bc5c1aad3a354dd7da54ba52d43ee821badb3deedbea4c5117c4bd05eab/botocore-1.42.62-py3-none-any.whl", hash = "sha256:86d327fded96775268ffe8d8bd6ed96c4a1db86cf24eb64ff85233db12dbc287", size = 14638389, upload-time = "2026-03-05T21:20:22.359Z" }, ] [[package]] @@ -379,91 +379,91 @@ wheels = [ [[package]] name = "charset-normalizer" -version = "3.4.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d", size = 209709, upload-time = "2025-10-14T04:40:11.385Z" }, - { url = "https://files.pythonhosted.org/packages/5c/af/1f9d7f7faafe2ddfb6f72a2e07a548a629c61ad510fe60f9630309908fef/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8", size = 148814, upload-time = "2025-10-14T04:40:13.135Z" }, - { url = "https://files.pythonhosted.org/packages/79/3d/f2e3ac2bbc056ca0c204298ea4e3d9db9b4afe437812638759db2c976b5f/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad", size = 144467, upload-time = "2025-10-14T04:40:14.728Z" }, - { url = "https://files.pythonhosted.org/packages/ec/85/1bf997003815e60d57de7bd972c57dc6950446a3e4ccac43bc3070721856/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8", size = 162280, upload-time = "2025-10-14T04:40:16.14Z" }, - { url = "https://files.pythonhosted.org/packages/3e/8e/6aa1952f56b192f54921c436b87f2aaf7c7a7c3d0d1a765547d64fd83c13/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d", size = 159454, upload-time = "2025-10-14T04:40:17.567Z" }, - { url = "https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313", size = 153609, upload-time = "2025-10-14T04:40:19.08Z" }, - { url = "https://files.pythonhosted.org/packages/64/91/6a13396948b8fd3c4b4fd5bc74d045f5637d78c9675585e8e9fbe5636554/charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e", size = 151849, upload-time = "2025-10-14T04:40:20.607Z" }, - { url = "https://files.pythonhosted.org/packages/b7/7a/59482e28b9981d105691e968c544cc0df3b7d6133152fb3dcdc8f135da7a/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93", size = 151586, upload-time = "2025-10-14T04:40:21.719Z" }, - { url = "https://files.pythonhosted.org/packages/92/59/f64ef6a1c4bdd2baf892b04cd78792ed8684fbc48d4c2afe467d96b4df57/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0", size = 145290, upload-time = "2025-10-14T04:40:23.069Z" }, - { url = "https://files.pythonhosted.org/packages/6b/63/3bf9f279ddfa641ffa1962b0db6a57a9c294361cc2f5fcac997049a00e9c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84", size = 163663, upload-time = "2025-10-14T04:40:24.17Z" }, - { url = "https://files.pythonhosted.org/packages/ed/09/c9e38fc8fa9e0849b172b581fd9803bdf6e694041127933934184e19f8c3/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e", size = 151964, upload-time = "2025-10-14T04:40:25.368Z" }, - { url = "https://files.pythonhosted.org/packages/d2/d1/d28b747e512d0da79d8b6a1ac18b7ab2ecfd81b2944c4c710e166d8dd09c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db", size = 161064, upload-time = "2025-10-14T04:40:26.806Z" }, - { url = "https://files.pythonhosted.org/packages/bb/9a/31d62b611d901c3b9e5500c36aab0ff5eb442043fb3a1c254200d3d397d9/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6", size = 155015, upload-time = "2025-10-14T04:40:28.284Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f3/107e008fa2bff0c8b9319584174418e5e5285fef32f79d8ee6a430d0039c/charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f", size = 99792, upload-time = "2025-10-14T04:40:29.613Z" }, - { url = "https://files.pythonhosted.org/packages/eb/66/e396e8a408843337d7315bab30dbf106c38966f1819f123257f5520f8a96/charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d", size = 107198, upload-time = "2025-10-14T04:40:30.644Z" }, - { url = "https://files.pythonhosted.org/packages/b5/58/01b4f815bf0312704c267f2ccb6e5d42bcc7752340cd487bc9f8c3710597/charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69", size = 100262, upload-time = "2025-10-14T04:40:32.108Z" }, - { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, - { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, - { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, - { url = "https://files.pythonhosted.org/packages/62/8b/171935adf2312cd745d290ed93cf16cf0dfe320863ab7cbeeae1dcd6535f/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", size = 160863, upload-time = "2025-10-14T04:40:37.188Z" }, - { url = "https://files.pythonhosted.org/packages/09/73/ad875b192bda14f2173bfc1bc9a55e009808484a4b256748d931b6948442/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", size = 157837, upload-time = "2025-10-14T04:40:38.435Z" }, - { url = "https://files.pythonhosted.org/packages/6d/fc/de9cce525b2c5b94b47c70a4b4fb19f871b24995c728e957ee68ab1671ea/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", size = 151550, upload-time = "2025-10-14T04:40:40.053Z" }, - { url = "https://files.pythonhosted.org/packages/55/c2/43edd615fdfba8c6f2dfbd459b25a6b3b551f24ea21981e23fb768503ce1/charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", size = 149162, upload-time = "2025-10-14T04:40:41.163Z" }, - { url = "https://files.pythonhosted.org/packages/03/86/bde4ad8b4d0e9429a4e82c1e8f5c659993a9a863ad62c7df05cf7b678d75/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", size = 150019, upload-time = "2025-10-14T04:40:42.276Z" }, - { url = "https://files.pythonhosted.org/packages/1f/86/a151eb2af293a7e7bac3a739b81072585ce36ccfb4493039f49f1d3cae8c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", size = 143310, upload-time = "2025-10-14T04:40:43.439Z" }, - { url = "https://files.pythonhosted.org/packages/b5/fe/43dae6144a7e07b87478fdfc4dbe9efd5defb0e7ec29f5f58a55aeef7bf7/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", size = 162022, upload-time = "2025-10-14T04:40:44.547Z" }, - { url = "https://files.pythonhosted.org/packages/80/e6/7aab83774f5d2bca81f42ac58d04caf44f0cc2b65fc6db2b3b2e8a05f3b3/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", size = 149383, upload-time = "2025-10-14T04:40:46.018Z" }, - { url = "https://files.pythonhosted.org/packages/4f/e8/b289173b4edae05c0dde07f69f8db476a0b511eac556dfe0d6bda3c43384/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", size = 159098, upload-time = "2025-10-14T04:40:47.081Z" }, - { url = "https://files.pythonhosted.org/packages/d8/df/fe699727754cae3f8478493c7f45f777b17c3ef0600e28abfec8619eb49c/charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", size = 152991, upload-time = "2025-10-14T04:40:48.246Z" }, - { url = "https://files.pythonhosted.org/packages/1a/86/584869fe4ddb6ffa3bd9f491b87a01568797fb9bd8933f557dba9771beaf/charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", size = 99456, upload-time = "2025-10-14T04:40:49.376Z" }, - { url = "https://files.pythonhosted.org/packages/65/f6/62fdd5feb60530f50f7e38b4f6a1d5203f4d16ff4f9f0952962c044e919a/charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", size = 106978, upload-time = "2025-10-14T04:40:50.844Z" }, - { url = "https://files.pythonhosted.org/packages/7a/9d/0710916e6c82948b3be62d9d398cb4fcf4e97b56d6a6aeccd66c4b2f2bd5/charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", size = 99969, upload-time = "2025-10-14T04:40:52.272Z" }, - { url = "https://files.pythonhosted.org/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", size = 208425, upload-time = "2025-10-14T04:40:53.353Z" }, - { url = "https://files.pythonhosted.org/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", size = 148162, upload-time = "2025-10-14T04:40:54.558Z" }, - { url = "https://files.pythonhosted.org/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", size = 144558, upload-time = "2025-10-14T04:40:55.677Z" }, - { url = "https://files.pythonhosted.org/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", size = 161497, upload-time = "2025-10-14T04:40:57.217Z" }, - { url = "https://files.pythonhosted.org/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", size = 159240, upload-time = "2025-10-14T04:40:58.358Z" }, - { url = "https://files.pythonhosted.org/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", size = 153471, upload-time = "2025-10-14T04:40:59.468Z" }, - { url = "https://files.pythonhosted.org/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", size = 150864, upload-time = "2025-10-14T04:41:00.623Z" }, - { url = "https://files.pythonhosted.org/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", size = 150647, upload-time = "2025-10-14T04:41:01.754Z" }, - { url = "https://files.pythonhosted.org/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", size = 145110, upload-time = "2025-10-14T04:41:03.231Z" }, - { url = "https://files.pythonhosted.org/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", size = 162839, upload-time = "2025-10-14T04:41:04.715Z" }, - { url = "https://files.pythonhosted.org/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", size = 150667, upload-time = "2025-10-14T04:41:05.827Z" }, - { url = "https://files.pythonhosted.org/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", size = 160535, upload-time = "2025-10-14T04:41:06.938Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", size = 154816, upload-time = "2025-10-14T04:41:08.101Z" }, - { url = "https://files.pythonhosted.org/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", size = 99694, upload-time = "2025-10-14T04:41:09.23Z" }, - { url = "https://files.pythonhosted.org/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", size = 107131, upload-time = "2025-10-14T04:41:10.467Z" }, - { url = "https://files.pythonhosted.org/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", size = 100390, upload-time = "2025-10-14T04:41:11.915Z" }, - { url = "https://files.pythonhosted.org/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", size = 208091, upload-time = "2025-10-14T04:41:13.346Z" }, - { url = "https://files.pythonhosted.org/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", size = 147936, upload-time = "2025-10-14T04:41:14.461Z" }, - { url = "https://files.pythonhosted.org/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", size = 144180, upload-time = "2025-10-14T04:41:15.588Z" }, - { url = "https://files.pythonhosted.org/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", size = 161346, upload-time = "2025-10-14T04:41:16.738Z" }, - { url = "https://files.pythonhosted.org/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", size = 158874, upload-time = "2025-10-14T04:41:17.923Z" }, - { url = "https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", size = 153076, upload-time = "2025-10-14T04:41:19.106Z" }, - { url = "https://files.pythonhosted.org/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", size = 150601, upload-time = "2025-10-14T04:41:20.245Z" }, - { url = "https://files.pythonhosted.org/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", size = 150376, upload-time = "2025-10-14T04:41:21.398Z" }, - { url = "https://files.pythonhosted.org/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", size = 144825, upload-time = "2025-10-14T04:41:22.583Z" }, - { url = "https://files.pythonhosted.org/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", size = 162583, upload-time = "2025-10-14T04:41:23.754Z" }, - { url = "https://files.pythonhosted.org/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", size = 150366, upload-time = "2025-10-14T04:41:25.27Z" }, - { url = "https://files.pythonhosted.org/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", size = 160300, upload-time = "2025-10-14T04:41:26.725Z" }, - { url = "https://files.pythonhosted.org/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", size = 154465, upload-time = "2025-10-14T04:41:28.322Z" }, - { url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" }, - { url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" }, - { url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" }, - { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" }, - { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" }, - { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" }, - { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" }, - { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" }, - { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" }, - { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" }, - { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" }, - { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" }, - { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" }, - { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" }, - { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" }, - { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" }, - { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" }, - { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/35/02daf95b9cd686320bb622eb148792655c9412dbb9b67abb5694e5910a24/charset_normalizer-3.4.5.tar.gz", hash = "sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644", size = 134804, upload-time = "2026-03-06T06:03:19.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/21/a2b1505639008ba2e6ef03733a81fc6cfd6a07ea6139a2b76421230b8dad/charset_normalizer-3.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765", size = 283319, upload-time = "2026-03-06T06:00:26.433Z" }, + { url = "https://files.pythonhosted.org/packages/70/67/df234c29b68f4e1e095885c9db1cb4b69b8aba49cf94fac041db4aaf1267/charset_normalizer-3.4.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990", size = 189974, upload-time = "2026-03-06T06:00:28.222Z" }, + { url = "https://files.pythonhosted.org/packages/df/7f/fc66af802961c6be42e2c7b69c58f95cbd1f39b0e81b3365d8efe2a02a04/charset_normalizer-3.4.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2", size = 207866, upload-time = "2026-03-06T06:00:29.769Z" }, + { url = "https://files.pythonhosted.org/packages/c9/23/404eb36fac4e95b833c50e305bba9a241086d427bb2167a42eac7c4f7da4/charset_normalizer-3.4.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765", size = 203239, upload-time = "2026-03-06T06:00:31.086Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2f/8a1d989bfadd120c90114ab33e0d2a0cbde05278c1fc15e83e62d570f50a/charset_normalizer-3.4.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d", size = 196529, upload-time = "2026-03-06T06:00:32.608Z" }, + { url = "https://files.pythonhosted.org/packages/a5/0c/c75f85ff7ca1f051958bb518cd43922d86f576c03947a050fbedfdfb4f15/charset_normalizer-3.4.5-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8", size = 184152, upload-time = "2026-03-06T06:00:33.93Z" }, + { url = "https://files.pythonhosted.org/packages/f9/20/4ed37f6199af5dde94d4aeaf577f3813a5ec6635834cda1d957013a09c76/charset_normalizer-3.4.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412", size = 195226, upload-time = "2026-03-06T06:00:35.469Z" }, + { url = "https://files.pythonhosted.org/packages/28/31/7ba1102178cba7c34dcc050f43d427172f389729e356038f0726253dd914/charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2", size = 192933, upload-time = "2026-03-06T06:00:36.83Z" }, + { url = "https://files.pythonhosted.org/packages/4b/23/f86443ab3921e6a60b33b93f4a1161222231f6c69bc24fb18f3bee7b8518/charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1", size = 185647, upload-time = "2026-03-06T06:00:38.367Z" }, + { url = "https://files.pythonhosted.org/packages/82/44/08b8be891760f1f5a6d23ce11d6d50c92981603e6eb740b4f72eea9424e2/charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4", size = 209533, upload-time = "2026-03-06T06:00:41.931Z" }, + { url = "https://files.pythonhosted.org/packages/3b/5f/df114f23406199f8af711ddccfbf409ffbc5b7cdc18fa19644997ff0c9bb/charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f", size = 195901, upload-time = "2026-03-06T06:00:43.978Z" }, + { url = "https://files.pythonhosted.org/packages/07/83/71ef34a76fe8aa05ff8f840244bda2d61e043c2ef6f30d200450b9f6a1be/charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550", size = 204950, upload-time = "2026-03-06T06:00:45.202Z" }, + { url = "https://files.pythonhosted.org/packages/58/40/0253be623995365137d7dc68e45245036207ab2227251e69a3d93ce43183/charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2", size = 198546, upload-time = "2026-03-06T06:00:46.481Z" }, + { url = "https://files.pythonhosted.org/packages/ed/5c/5f3cb5b259a130895ef5ae16b38eaf141430fa3f7af50cd06c5d67e4f7b2/charset_normalizer-3.4.5-cp310-cp310-win32.whl", hash = "sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475", size = 132516, upload-time = "2026-03-06T06:00:47.924Z" }, + { url = "https://files.pythonhosted.org/packages/a5/c3/84fb174e7770f2df2e1a2115090771bfbc2227fb39a765c6d00568d1aab4/charset_normalizer-3.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05", size = 142906, upload-time = "2026-03-06T06:00:49.389Z" }, + { url = "https://files.pythonhosted.org/packages/d7/b2/6f852f8b969f2cbd0d4092d2e60139ab1af95af9bb651337cae89ec0f684/charset_normalizer-3.4.5-cp310-cp310-win_arm64.whl", hash = "sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064", size = 133258, upload-time = "2026-03-06T06:00:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/8f/9e/bcec3b22c64ecec47d39bf5167c2613efd41898c019dccd4183f6aa5d6a7/charset_normalizer-3.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694", size = 279531, upload-time = "2026-03-06T06:00:52.252Z" }, + { url = "https://files.pythonhosted.org/packages/58/12/81fd25f7e7078ab5d1eedbb0fac44be4904ae3370a3bf4533c8f2d159acd/charset_normalizer-3.4.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5", size = 188006, upload-time = "2026-03-06T06:00:53.8Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6e/f2d30e8c27c1b0736a6520311982cf5286cfc7f6cac77d7bc1325e3a23f2/charset_normalizer-3.4.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281", size = 205085, upload-time = "2026-03-06T06:00:55.311Z" }, + { url = "https://files.pythonhosted.org/packages/d0/90/d12cefcb53b5931e2cf792a33718d7126efb116a320eaa0742c7059a95e4/charset_normalizer-3.4.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923", size = 200545, upload-time = "2026-03-06T06:00:56.532Z" }, + { url = "https://files.pythonhosted.org/packages/03/f4/44d3b830a20e89ff82a3134912d9a1cf6084d64f3b95dcad40f74449a654/charset_normalizer-3.4.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81", size = 193863, upload-time = "2026-03-06T06:00:57.823Z" }, + { url = "https://files.pythonhosted.org/packages/25/4b/f212119c18a6320a9d4a730d1b4057875cdeabf21b3614f76549042ef8a8/charset_normalizer-3.4.5-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497", size = 181827, upload-time = "2026-03-06T06:00:59.323Z" }, + { url = "https://files.pythonhosted.org/packages/74/00/b26158e48b425a202a92965f8069e8a63d9af1481dfa206825d7f74d2a3c/charset_normalizer-3.4.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c", size = 191085, upload-time = "2026-03-06T06:01:00.546Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c2/1c1737bf6fd40335fe53d28fe49afd99ee4143cc57a845e99635ce0b9b6d/charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e", size = 190688, upload-time = "2026-03-06T06:01:02.479Z" }, + { url = "https://files.pythonhosted.org/packages/5a/3d/abb5c22dc2ef493cd56522f811246a63c5427c08f3e3e50ab663de27fcf4/charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f", size = 183077, upload-time = "2026-03-06T06:01:04.231Z" }, + { url = "https://files.pythonhosted.org/packages/44/33/5298ad4d419a58e25b3508e87f2758d1442ff00c2471f8e0403dab8edad5/charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e", size = 206706, upload-time = "2026-03-06T06:01:05.773Z" }, + { url = "https://files.pythonhosted.org/packages/7b/17/51e7895ac0f87c3b91d276a449ef09f5532a7529818f59646d7a55089432/charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af", size = 191665, upload-time = "2026-03-06T06:01:07.473Z" }, + { url = "https://files.pythonhosted.org/packages/90/8f/cce9adf1883e98906dbae380d769b4852bb0fa0004bc7d7a2243418d3ea8/charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85", size = 201950, upload-time = "2026-03-06T06:01:08.973Z" }, + { url = "https://files.pythonhosted.org/packages/08/ca/bce99cd5c397a52919e2769d126723f27a4c037130374c051c00470bcd38/charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f", size = 195830, upload-time = "2026-03-06T06:01:10.155Z" }, + { url = "https://files.pythonhosted.org/packages/87/4f/2e3d023a06911f1281f97b8f036edc9872167036ca6f55cc874a0be6c12c/charset_normalizer-3.4.5-cp311-cp311-win32.whl", hash = "sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4", size = 132029, upload-time = "2026-03-06T06:01:11.706Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1f/a853b73d386521fd44b7f67ded6b17b7b2367067d9106a5c4b44f9a34274/charset_normalizer-3.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a", size = 142404, upload-time = "2026-03-06T06:01:12.865Z" }, + { url = "https://files.pythonhosted.org/packages/b4/10/dba36f76b71c38e9d391abe0fd8a5b818790e053c431adecfc98c35cd2a9/charset_normalizer-3.4.5-cp311-cp311-win_arm64.whl", hash = "sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c", size = 132796, upload-time = "2026-03-06T06:01:14.106Z" }, + { url = "https://files.pythonhosted.org/packages/9c/b6/9ee9c1a608916ca5feae81a344dffbaa53b26b90be58cc2159e3332d44ec/charset_normalizer-3.4.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade", size = 280976, upload-time = "2026-03-06T06:01:15.276Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d8/a54f7c0b96f1df3563e9190f04daf981e365a9b397eedfdfb5dbef7e5c6c/charset_normalizer-3.4.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54", size = 189356, upload-time = "2026-03-06T06:01:16.511Z" }, + { url = "https://files.pythonhosted.org/packages/42/69/2bf7f76ce1446759a5787cb87d38f6a61eb47dbbdf035cfebf6347292a65/charset_normalizer-3.4.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467", size = 206369, upload-time = "2026-03-06T06:01:17.853Z" }, + { url = "https://files.pythonhosted.org/packages/10/9c/949d1a46dab56b959d9a87272482195f1840b515a3380e39986989a893ae/charset_normalizer-3.4.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60", size = 203285, upload-time = "2026-03-06T06:01:19.473Z" }, + { url = "https://files.pythonhosted.org/packages/67/5c/ae30362a88b4da237d71ea214a8c7eb915db3eec941adda511729ac25fa2/charset_normalizer-3.4.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d", size = 196274, upload-time = "2026-03-06T06:01:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b2/07/c9f2cb0e46cb6d64fdcc4f95953747b843bb2181bda678dc4e699b8f0f9a/charset_normalizer-3.4.5-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e", size = 184715, upload-time = "2026-03-06T06:01:22.194Z" }, + { url = "https://files.pythonhosted.org/packages/36/64/6b0ca95c44fddf692cd06d642b28f63009d0ce325fad6e9b2b4d0ef86a52/charset_normalizer-3.4.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f", size = 193426, upload-time = "2026-03-06T06:01:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/50/bc/a730690d726403743795ca3f5bb2baf67838c5fea78236098f324b965e40/charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc", size = 191780, upload-time = "2026-03-06T06:01:25.053Z" }, + { url = "https://files.pythonhosted.org/packages/97/4f/6c0bc9af68222b22951552d73df4532b5be6447cee32d58e7e8c74ecbb7b/charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95", size = 185805, upload-time = "2026-03-06T06:01:26.294Z" }, + { url = "https://files.pythonhosted.org/packages/dd/b9/a523fb9b0ee90814b503452b2600e4cbc118cd68714d57041564886e7325/charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a", size = 208342, upload-time = "2026-03-06T06:01:27.55Z" }, + { url = "https://files.pythonhosted.org/packages/4d/61/c59e761dee4464050713e50e27b58266cc8e209e518c0b378c1580c959ba/charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac", size = 193661, upload-time = "2026-03-06T06:01:29.051Z" }, + { url = "https://files.pythonhosted.org/packages/1c/43/729fa30aad69783f755c5ad8649da17ee095311ca42024742701e202dc59/charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1", size = 204819, upload-time = "2026-03-06T06:01:30.298Z" }, + { url = "https://files.pythonhosted.org/packages/87/33/d9b442ce5a91b96fc0840455a9e49a611bbadae6122778d0a6a79683dd31/charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98", size = 198080, upload-time = "2026-03-06T06:01:31.478Z" }, + { url = "https://files.pythonhosted.org/packages/56/5a/b8b5a23134978ee9885cee2d6995f4c27cc41f9baded0a9685eabc5338f0/charset_normalizer-3.4.5-cp312-cp312-win32.whl", hash = "sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262", size = 132630, upload-time = "2026-03-06T06:01:33.056Z" }, + { url = "https://files.pythonhosted.org/packages/70/53/e44a4c07e8904500aec95865dc3f6464dc3586a039ef0df606eb3ac38e35/charset_normalizer-3.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636", size = 142856, upload-time = "2026-03-06T06:01:34.489Z" }, + { url = "https://files.pythonhosted.org/packages/ea/aa/c5628f7cad591b1cf45790b7a61483c3e36cf41349c98af7813c483fd6e8/charset_normalizer-3.4.5-cp312-cp312-win_arm64.whl", hash = "sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02", size = 132982, upload-time = "2026-03-06T06:01:35.641Z" }, + { url = "https://files.pythonhosted.org/packages/f5/48/9f34ec4bb24aa3fdba1890c1bddb97c8a4be1bd84ef5c42ac2352563ad05/charset_normalizer-3.4.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23", size = 280788, upload-time = "2026-03-06T06:01:37.126Z" }, + { url = "https://files.pythonhosted.org/packages/0e/09/6003e7ffeb90cc0560da893e3208396a44c210c5ee42efff539639def59b/charset_normalizer-3.4.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8", size = 188890, upload-time = "2026-03-06T06:01:38.73Z" }, + { url = "https://files.pythonhosted.org/packages/42/1e/02706edf19e390680daa694d17e2b8eab4b5f7ac285e2a51168b4b22ee6b/charset_normalizer-3.4.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d", size = 206136, upload-time = "2026-03-06T06:01:40.016Z" }, + { url = "https://files.pythonhosted.org/packages/c7/87/942c3def1b37baf3cf786bad01249190f3ca3d5e63a84f831e704977de1f/charset_normalizer-3.4.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce", size = 202551, upload-time = "2026-03-06T06:01:41.522Z" }, + { url = "https://files.pythonhosted.org/packages/94/0a/af49691938dfe175d71b8a929bd7e4ace2809c0c5134e28bc535660d5262/charset_normalizer-3.4.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819", size = 195572, upload-time = "2026-03-06T06:01:43.208Z" }, + { url = "https://files.pythonhosted.org/packages/20/ea/dfb1792a8050a8e694cfbde1570ff97ff74e48afd874152d38163d1df9ae/charset_normalizer-3.4.5-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d", size = 184438, upload-time = "2026-03-06T06:01:44.755Z" }, + { url = "https://files.pythonhosted.org/packages/72/12/c281e2067466e3ddd0595bfaea58a6946765ace5c72dfa3edc2f5f118026/charset_normalizer-3.4.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763", size = 193035, upload-time = "2026-03-06T06:01:46.051Z" }, + { url = "https://files.pythonhosted.org/packages/ba/4f/3792c056e7708e10464bad0438a44708886fb8f92e3c3d29ec5e2d964d42/charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9", size = 191340, upload-time = "2026-03-06T06:01:47.547Z" }, + { url = "https://files.pythonhosted.org/packages/e7/86/80ddba897127b5c7a9bccc481b0cd36c8fefa485d113262f0fe4332f0bf4/charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c", size = 185464, upload-time = "2026-03-06T06:01:48.764Z" }, + { url = "https://files.pythonhosted.org/packages/4d/00/b5eff85ba198faacab83e0e4b6f0648155f072278e3b392a82478f8b988b/charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67", size = 208014, upload-time = "2026-03-06T06:01:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/c8/11/d36f70be01597fd30850dde8a1269ebc8efadd23ba5785808454f2389bde/charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3", size = 193297, upload-time = "2026-03-06T06:01:51.933Z" }, + { url = "https://files.pythonhosted.org/packages/1a/1d/259eb0a53d4910536c7c2abb9cb25f4153548efb42800c6a9456764649c0/charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf", size = 204321, upload-time = "2026-03-06T06:01:53.887Z" }, + { url = "https://files.pythonhosted.org/packages/84/31/faa6c5b9d3688715e1ed1bb9d124c384fe2fc1633a409e503ffe1c6398c1/charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6", size = 197509, upload-time = "2026-03-06T06:01:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/fd/a5/c7d9dd1503ffc08950b3260f5d39ec2366dd08254f0900ecbcf3a6197c7c/charset_normalizer-3.4.5-cp313-cp313-win32.whl", hash = "sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f", size = 132284, upload-time = "2026-03-06T06:01:57.812Z" }, + { url = "https://files.pythonhosted.org/packages/b9/0f/57072b253af40c8aa6636e6de7d75985624c1eb392815b2f934199340a89/charset_normalizer-3.4.5-cp313-cp313-win_amd64.whl", hash = "sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7", size = 142630, upload-time = "2026-03-06T06:01:59.062Z" }, + { url = "https://files.pythonhosted.org/packages/31/41/1c4b7cc9f13bd9d369ce3bc993e13d374ce25fa38a2663644283ecf422c1/charset_normalizer-3.4.5-cp313-cp313-win_arm64.whl", hash = "sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36", size = 133254, upload-time = "2026-03-06T06:02:00.281Z" }, + { url = "https://files.pythonhosted.org/packages/43/be/0f0fd9bb4a7fa4fb5067fb7d9ac693d4e928d306f80a0d02bde43a7c4aee/charset_normalizer-3.4.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873", size = 280232, upload-time = "2026-03-06T06:02:01.508Z" }, + { url = "https://files.pythonhosted.org/packages/28/02/983b5445e4bef49cd8c9da73a8e029f0825f39b74a06d201bfaa2e55142a/charset_normalizer-3.4.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f", size = 189688, upload-time = "2026-03-06T06:02:02.857Z" }, + { url = "https://files.pythonhosted.org/packages/d0/88/152745c5166437687028027dc080e2daed6fe11cfa95a22f4602591c42db/charset_normalizer-3.4.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4", size = 206833, upload-time = "2026-03-06T06:02:05.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0f/ebc15c8b02af2f19be9678d6eed115feeeccc45ce1f4b098d986c13e8769/charset_normalizer-3.4.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee", size = 202879, upload-time = "2026-03-06T06:02:06.446Z" }, + { url = "https://files.pythonhosted.org/packages/38/9c/71336bff6934418dc8d1e8a1644176ac9088068bc571da612767619c97b3/charset_normalizer-3.4.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66", size = 195764, upload-time = "2026-03-06T06:02:08.763Z" }, + { url = "https://files.pythonhosted.org/packages/b7/95/ce92fde4f98615661871bc282a856cf9b8a15f686ba0af012984660d480b/charset_normalizer-3.4.5-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362", size = 183728, upload-time = "2026-03-06T06:02:10.137Z" }, + { url = "https://files.pythonhosted.org/packages/1c/e7/f5b4588d94e747ce45ae680f0f242bc2d98dbd4eccfab73e6160b6893893/charset_normalizer-3.4.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7", size = 192937, upload-time = "2026-03-06T06:02:11.663Z" }, + { url = "https://files.pythonhosted.org/packages/f9/29/9d94ed6b929bf9f48bf6ede6e7474576499f07c4c5e878fb186083622716/charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d", size = 192040, upload-time = "2026-03-06T06:02:13.489Z" }, + { url = "https://files.pythonhosted.org/packages/15/d2/1a093a1cf827957f9445f2fe7298bcc16f8fc5e05c1ed2ad1af0b239035e/charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6", size = 184107, upload-time = "2026-03-06T06:02:14.83Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7d/82068ce16bd36135df7b97f6333c5d808b94e01d4599a682e2337ed5fd14/charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39", size = 208310, upload-time = "2026-03-06T06:02:16.165Z" }, + { url = "https://files.pythonhosted.org/packages/84/4e/4dfb52307bb6af4a5c9e73e482d171b81d36f522b21ccd28a49656baa680/charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6", size = 192918, upload-time = "2026-03-06T06:02:18.144Z" }, + { url = "https://files.pythonhosted.org/packages/08/a4/159ff7da662cf7201502ca89980b8f06acf3e887b278956646a8aeb178ab/charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94", size = 204615, upload-time = "2026-03-06T06:02:19.821Z" }, + { url = "https://files.pythonhosted.org/packages/d6/62/0dd6172203cb6b429ffffc9935001fde42e5250d57f07b0c28c6046deb6b/charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e", size = 197784, upload-time = "2026-03-06T06:02:21.86Z" }, + { url = "https://files.pythonhosted.org/packages/c7/5e/1aab5cb737039b9c59e63627dc8bbc0d02562a14f831cc450e5f91d84ce1/charset_normalizer-3.4.5-cp314-cp314-win32.whl", hash = "sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2", size = 133009, upload-time = "2026-03-06T06:02:23.289Z" }, + { url = "https://files.pythonhosted.org/packages/40/65/e7c6c77d7aaa4c0d7974f2e403e17f0ed2cb0fc135f77d686b916bf1eead/charset_normalizer-3.4.5-cp314-cp314-win_amd64.whl", hash = "sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa", size = 143511, upload-time = "2026-03-06T06:02:26.195Z" }, + { url = "https://files.pythonhosted.org/packages/ba/91/52b0841c71f152f563b8e072896c14e3d83b195c188b338d3cc2e582d1d4/charset_normalizer-3.4.5-cp314-cp314-win_arm64.whl", hash = "sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4", size = 133775, upload-time = "2026-03-06T06:02:27.473Z" }, + { url = "https://files.pythonhosted.org/packages/c5/60/3a621758945513adfd4db86827a5bafcc615f913dbd0b4c2ed64a65731be/charset_normalizer-3.4.5-py3-none-any.whl", hash = "sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0", size = 55455, upload-time = "2026-03-06T06:03:17.827Z" }, ] [[package]] @@ -662,7 +662,7 @@ wheels = [ [[package]] name = "google-api-python-client" -version = "2.191.0" +version = "2.192.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "google-api-core" }, @@ -671,9 +671,9 @@ dependencies = [ { name = "httplib2" }, { name = "uritemplate" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/58/7d0843b7419a5ac51a27965e7233ef7c26ad693b490a74ab26548d0fd231/google_api_python_client-2.191.0.tar.gz", hash = "sha256:858c22fd46f51a65cee365a78aec2054e6d47b50434bee4ba62e91ac0944aea1", size = 14195310, upload-time = "2026-03-02T16:58:59.965Z" } +sdist = { url = "https://files.pythonhosted.org/packages/85/d8/489052a40935e45b9b5b3d6accc14b041360c1507bdc659c2e1a19aaa3ff/google_api_python_client-2.192.0.tar.gz", hash = "sha256:d48cfa6078fadea788425481b007af33fe0ab6537b78f37da914fb6fc112eb27", size = 14209505, upload-time = "2026-03-05T15:17:01.598Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/a4/da3a66c90f94b9eb433f0844f1bf79b5789bfa0859e55c0cd02c1139fed8/google_api_python_client-2.191.0-py3-none-any.whl", hash = "sha256:0768dde3202121abb3e897c4ee5150e58a25f32ee843780f6bee636dccc7ef23", size = 14769138, upload-time = "2026-03-02T16:58:57.665Z" }, + { url = "https://files.pythonhosted.org/packages/e0/76/ec4128f00fefb9011635ae2abc67d7dacd05c8559378f8f05f0c907c38d8/google_api_python_client-2.192.0-py3-none-any.whl", hash = "sha256:63a57d4457cd97df1d63eb89c5fda03c5a50588dcbc32c0115dd1433c08f4b62", size = 14783267, upload-time = "2026-03-05T15:16:58.804Z" }, ] [[package]] @@ -1203,11 +1203,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.9.2" +version = "4.9.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1b/04/fea538adf7dbbd6d186f551d595961e564a3b6715bdf276b477460858672/platformdirs-4.9.2.tar.gz", hash = "sha256:9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291", size = 28394, upload-time = "2026-02-16T03:56:10.574Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/56/8d4c30c8a1d07013911a8fdbd8f89440ef9f08d07a1b50ab8ca8be5a20f9/platformdirs-4.9.4.tar.gz", hash = "sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934", size = 28737, upload-time = "2026-03-05T18:34:13.271Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl", hash = "sha256:9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd", size = 21168, upload-time = "2026-02-16T03:56:08.891Z" }, + { url = "https://files.pythonhosted.org/packages/63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/platformdirs-4.9.4-py3-none-any.whl", hash = "sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868", size = 21216, upload-time = "2026-03-05T18:34:12.172Z" }, ] [[package]] @@ -1910,11 +1910,11 @@ wheels = [ [[package]] name = "tabulate" -version = "0.9.0" +version = "0.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090, upload-time = "2022-10-06T17:21:48.54Z" } +sdist = { url = "https://files.pythonhosted.org/packages/46/58/8c37dea7bbf769b20d58e7ace7e5edfe65b849442b00ffcdd56be88697c6/tabulate-0.10.0.tar.gz", hash = "sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d", size = 91754, upload-time = "2026-03-04T18:55:34.402Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" }, + { url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" }, ] [[package]] @@ -2071,27 +2071,27 @@ wheels = [ [[package]] name = "uv" -version = "0.10.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/ec/b324a43b55fe59577505478a396cb1d2758487a2e2270c81ccfa4ac6c96d/uv-0.10.7.tar.gz", hash = "sha256:7c3b0133c2d6bd725d5a35ec5e109ebf0d75389943abe826f3d9ea6d6667a375", size = 3922193, upload-time = "2026-02-27T12:33:58.525Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/1b/decff24553325561850d70b75c737076e6fcbcfbf233011a27a33f06e4d9/uv-0.10.7-py3-none-linux_armv6l.whl", hash = "sha256:6a0af6c7a90fd2053edfa2c8ee719078ea906a2d9f4798d3fb3c03378726209a", size = 22497542, upload-time = "2026-02-27T12:33:39.425Z" }, - { url = "https://files.pythonhosted.org/packages/fc/b5/51152c87921bc2576fecb982df4a02ac9cfd7fc934e28114a1232b99eed4/uv-0.10.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b7db0cab77232a7c8856062904fc3b9db22383f1dec7e97a9588fb6c8470f6a", size = 21558860, upload-time = "2026-02-27T12:34:03.362Z" }, - { url = "https://files.pythonhosted.org/packages/5e/15/8365dc2ded350a4ee5fcbbf9b15195cb2b45855114f2a154b5effb6fa791/uv-0.10.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d872d2ff9c9dfba989b5f05f599715bc0f19b94cd0dbf8ae4ad22f8879a66c8c", size = 20212775, upload-time = "2026-02-27T12:33:55.365Z" }, - { url = "https://files.pythonhosted.org/packages/53/a0/ccf25e897f3907b5a6fd899007ff9a80b5bbf151b3a75a375881005611fd/uv-0.10.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:d9b40d03693efda80a41e5d18ac997efdf1094b27fb75471c1a8f51a9ebeffb3", size = 22015584, upload-time = "2026-02-27T12:33:47.374Z" }, - { url = "https://files.pythonhosted.org/packages/fa/3a/5099747954e7774768572d30917bb6bda6b8d465d7a3c49c9bbf7af2a812/uv-0.10.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:e74fe4df9cf31fe84f20b84a0054874635077d31ce20e7de35ff0dd64d498d7b", size = 22100376, upload-time = "2026-02-27T12:34:06.169Z" }, - { url = "https://files.pythonhosted.org/packages/0c/1a/75897fd966b871803cf78019fa31757ced0d54af5ffd7f57bce8b01d64f3/uv-0.10.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c76659fc8bb618dd35cd83b2f479c6f880555a16630a454a251045c4c118ea4", size = 22105202, upload-time = "2026-02-27T12:34:16.972Z" }, - { url = "https://files.pythonhosted.org/packages/b5/1e/0b8caedd66ca911533e18fd051da79a213c792404138812c66043d529b9e/uv-0.10.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d160cceb9468024ca40dc57a180289dfd2024d98e42f2284b9ec44355723b0a", size = 23335601, upload-time = "2026-02-27T12:34:11.161Z" }, - { url = "https://files.pythonhosted.org/packages/69/94/b741af277e39a92e0da07fe48c338eee1429c2607e7a192e41345208bb24/uv-0.10.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c775975d891cb60cf10f00953e61e643fcb9a9139e94c9ef5c805fe36e90477f", size = 24152851, upload-time = "2026-02-27T12:33:33.904Z" }, - { url = "https://files.pythonhosted.org/packages/27/b2/da351ccd02f0fb1aec5f992b886bea1374cce44276a78904348e2669dd78/uv-0.10.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a709e75583231cc1f39567fb3d8d9b4077ff94a64046eb242726300144ed1a4a", size = 23276444, upload-time = "2026-02-27T12:33:36.891Z" }, - { url = "https://files.pythonhosted.org/packages/71/a9/2735cc9dc39457c9cf64d1ce2ba5a9a8ecbb103d0fb64b052bf33ba3d669/uv-0.10.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89de2504407dcf04aece914c6ca3b9d8e60cf9ff39a13031c1df1f7c040cea81", size = 23218464, upload-time = "2026-02-27T12:34:00.904Z" }, - { url = "https://files.pythonhosted.org/packages/20/5f/5f204e9c3f04f5fc844d2f98d80a7de64b6b304af869644ab478d909f6ff/uv-0.10.7-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:9945de1d11c4a5ad77e9c4f36f8b5f9e7c9c3c32999b8bc0e7e579145c3b641c", size = 22092562, upload-time = "2026-02-27T12:34:14.155Z" }, - { url = "https://files.pythonhosted.org/packages/dd/a4/16bebf106e3289a29cc1e1482d551c49bd220983e9b4bc5960142389ad3f/uv-0.10.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:dbe43527f478e2ffa420516aa465f82057763936bbea56f814fd054a9b7f961f", size = 22851312, upload-time = "2026-02-27T12:34:08.651Z" }, - { url = "https://files.pythonhosted.org/packages/d1/7a/953b1da589225d98ca8668412f665c3192f6deed2a0f4bb782b0df18f611/uv-0.10.7-py3-none-musllinux_1_1_i686.whl", hash = "sha256:c0783f327631141501bdc5f31dd2b4c748df7e7f5dc5cdbfc0fbb82da86cc9ca", size = 22543775, upload-time = "2026-02-27T12:33:30.935Z" }, - { url = "https://files.pythonhosted.org/packages/8b/67/e133afdabf76e43989448be1c2ef607f13afc32aa1ee9f6897115dec8417/uv-0.10.7-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:eba438899010522812d3497af586e6eedc94fa2b0ced028f51812f0c10aafb30", size = 23431187, upload-time = "2026-02-27T12:33:42.131Z" }, - { url = "https://files.pythonhosted.org/packages/ba/40/6ffb58ec88a33d6cbe9a606966f9558807f37a50f7be7dc756824df2d04c/uv-0.10.7-py3-none-win32.whl", hash = "sha256:b56d1818aafb2701d92e94f552126fe71d30a13f28712d99345ef5cafc53d874", size = 21524397, upload-time = "2026-02-27T12:33:44.579Z" }, - { url = "https://files.pythonhosted.org/packages/e3/1f/74f4d625db838f716a555908d41777b6357bacc141ddef117a01855e5ef9/uv-0.10.7-py3-none-win_amd64.whl", hash = "sha256:ad0d0ddd9f5407ad8699e3b20fe6c18406cd606336743e246b16914801cfd8b0", size = 23999929, upload-time = "2026-02-27T12:33:49.839Z" }, - { url = "https://files.pythonhosted.org/packages/48/4e/20cbfbcb1a0f48c5c1ca94f6baa0fa00754aafda365da9160c15e3b9c277/uv-0.10.7-py3-none-win_arm64.whl", hash = "sha256:edf732de80c1a9701180ef8c7a2fa926a995712e4a34ae8c025e090f797c2e0b", size = 22353084, upload-time = "2026-02-27T12:33:52.792Z" }, +version = "0.10.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/e7/600a90d4662dbd8414c1f6b709c8c79075d37d2044f72b94acbfaf29baad/uv-0.10.8.tar.gz", hash = "sha256:4b23242b5224c7eaea481ce6c6dbc210f0eafb447cf60211633980947cd23de4", size = 3936600, upload-time = "2026-03-03T21:35:22.386Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/6c/8ef256575242d5f3869c5a445ffd4363b91a89acb34a3e043bec2ad5a1be/uv-0.10.8-py3-none-linux_armv6l.whl", hash = "sha256:d214c82c7c14dd23f9aeb609d03070b8ea2b2f0cf249c9321cbbb5375a17e5df", size = 22461003, upload-time = "2026-03-03T21:35:20.093Z" }, + { url = "https://files.pythonhosted.org/packages/c9/fb/fd0656a92e6b9c4f92ddba7dcd76bd87469be500755125e06fea853dc212/uv-0.10.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d1315c3901c5859aec2c5b4a17da4c5410d17f6890890f9f1a31f25aa0fa9ace", size = 21549446, upload-time = "2026-03-03T21:35:58.203Z" }, + { url = "https://files.pythonhosted.org/packages/64/b9/1a4105df3afe7af99791f5b00fb037d85b2e3aaa1227e95878538d51ecf3/uv-0.10.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a253e5d2cae9e02654de31918b610dfc8f1f16a33f34046603757820bc45ee1b", size = 20222180, upload-time = "2026-03-03T21:35:46.984Z" }, + { url = "https://files.pythonhosted.org/packages/c5/72/6e98e0f8b3fe80cb881c36492dca6d932fbb05f956dfdccbdb8ebe4ceff4/uv-0.10.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:57a24e15fd9dd4a36bcec2ccbe4b26d2a172c109e954a8940f5e8a8b965dae74", size = 22064813, upload-time = "2026-03-03T21:35:17.108Z" }, + { url = "https://files.pythonhosted.org/packages/71/b6/737da8577f4b1799f7024f6cd98fffcac77076a1b078b277cffc84946e96/uv-0.10.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:675dc659195f9b9811ef5534eb3f16459fc88e109aefacbc91c07751b5b9715a", size = 22064861, upload-time = "2026-03-03T21:35:25.067Z" }, + { url = "https://files.pythonhosted.org/packages/7e/21/464ee3cd81f44345953cb26dd49870811f7647f3074f7651775cadb2158b/uv-0.10.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:18d2968b0a50111c2fc6b782f7c63ded4f461c44efab537f552cf565f9aaae25", size = 22054515, upload-time = "2026-03-03T21:35:44.572Z" }, + { url = "https://files.pythonhosted.org/packages/11/2c/1c592d7b843ffa999502116b0dc573732b40cb37061a4acc741dcdb181da/uv-0.10.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed3c7ebb6f757cddedb56dec3d7c745e5ea7310b11e12ae1c28f1e8172e7bbf", size = 23433992, upload-time = "2026-03-03T21:35:36.886Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e2/2b716f0613746138294598668bbe65295a8da3d8fa104a756dec6284bf3c/uv-0.10.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffaf115501e33be0d4f13cb5b7c2b46b031d4c679a6109e24a7edfb719c44c6c", size = 24257250, upload-time = "2026-03-03T21:35:49.954Z" }, + { url = "https://files.pythonhosted.org/packages/3e/4d/0165e82cd1117cd6f8a7d9a2122c23cc091f7cf738aa4a2a54579420a08f/uv-0.10.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0209ee8cb573e113ff4a760360f28448f9ebcdcf9c91ca49e872821de5d2d054", size = 23338918, upload-time = "2026-03-03T21:35:33.795Z" }, + { url = "https://files.pythonhosted.org/packages/20/74/652129a25145732482bb0020602507f52d9a5ca0e1a40ddd6deb27402333/uv-0.10.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11dc790f732dc5fee61f0f6bd998fc2e9c200df1082245604ac091c32c23a523", size = 23259370, upload-time = "2026-03-03T21:35:39.478Z" }, + { url = "https://files.pythonhosted.org/packages/19/c5/6e5923d6c9e3b50dc8542647bea692b7c227a9489f59ddff4fdfb20d8459/uv-0.10.8-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:e26f8c35684face38db814d452dd1a2181152dbf7f7b2de1f547e6ba0c378d67", size = 22174747, upload-time = "2026-03-03T21:35:42.081Z" }, + { url = "https://files.pythonhosted.org/packages/92/cd/eee9e1883888327d07f51e7595ed5952e0bca2dc79d1c03b8a6e4309553e/uv-0.10.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:385add107d40c43dc00ca8c1a21ecf43101f846f8339eb7026bf6c9f6df7760d", size = 22893359, upload-time = "2026-03-03T21:35:30.802Z" }, + { url = "https://files.pythonhosted.org/packages/bf/36/407a22917e55ce5cc2e7af956e3b9d91648a96558858acef84e3c50d5ca8/uv-0.10.8-py3-none-musllinux_1_1_i686.whl", hash = "sha256:24e8eb28c4f05acb38e60fefe2a2b15f4283a3849ce580bf2a62aca0a13123b3", size = 22637451, upload-time = "2026-03-03T21:35:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/21/d5/dabef9914e1ff27ad95e4b1daf59cd97c80e26a44c04c2870bcca7c83fc0/uv-0.10.8-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:73a8c1a1fceac73cd983dcc0a64f4f94f5fd1e5428681a5a76132574264504fb", size = 23480991, upload-time = "2026-03-03T21:35:52.809Z" }, + { url = "https://files.pythonhosted.org/packages/2f/c0/1a4a45a9246f087e9446d0d804a436f6ee0befeaef731b04d1b2802d9d8f/uv-0.10.8-py3-none-win32.whl", hash = "sha256:9f344fdb34938ce35e9211a1b866adfa0c7f043967652ed1431917514aeec062", size = 21579030, upload-time = "2026-03-03T21:35:28.176Z" }, + { url = "https://files.pythonhosted.org/packages/a4/2b/b29510efa1e6f409db105dbdafbd942ca3a2b638bef682ff2e5b9f6e4021/uv-0.10.8-py3-none-win_amd64.whl", hash = "sha256:1e63015284ed28c2112717256c328513215fb966a57c5870788eac2e8f949f28", size = 23944828, upload-time = "2026-03-03T21:36:00.763Z" }, + { url = "https://files.pythonhosted.org/packages/3f/9e/b5a11b0523171c0103c4fed54da76685a765ad4d3215e8220facfd24aed9/uv-0.10.8-py3-none-win_arm64.whl", hash = "sha256:a80284f46b6f2e0b3d03eb7c2d43e17139a4ec313e8b9f56a71efafc996804cb", size = 22322224, upload-time = "2026-03-03T21:35:14.148Z" }, ] [[package]] diff --git a/devel-common/pyproject.toml b/devel-common/pyproject.toml index bd658ba65b09c..326ebe9853b78 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.15.4", + "ruff==0.15.5", "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 869bd0babf08c..84a7f84f5b955 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -530,7 +530,7 @@ packages = [] "apache-airflow-providers-amazon[s3fs]", ] "uv" = [ - "uv>=0.10.7", + "uv>=0.10.8", ] diff --git a/scripts/ci/prek/check_imports_in_providers.py b/scripts/ci/prek/check_imports_in_providers.py index 44b1e0d67f40d..978aa990002c6 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.15.4", +# "ruff==0.15.5", # ] # /// from __future__ import annotations diff --git a/scripts/ci/prek/ruff_format.py b/scripts/ci/prek/ruff_format.py index 951f82fff3e95..b089ff41a19ed 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.15.4", +# "ruff==0.15.5", # ] # /// diff --git a/scripts/tools/setup_breeze b/scripts/tools/setup_breeze index a277a9c2d6cec..7f2d54ccea7db 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.10.7" +UV_VERSION="0.10.8" function manual_instructions() { echo From fde99ab40339da1852d295c5c3f8f496cdccaf5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 08:40:26 -0500 Subject: [PATCH 03/50] chore(deps-dev): bump the core-ui-package-updates group across 1 directory with 3 updates (#62968) Bumps the core-ui-package-updates group with 1 update in the /airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui directory: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin). Updates `@typescript-eslint/eslint-plugin` from 8.50.0 to 8.56.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.50.0 to 8.56.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/parser) Updates `ts-morph` from 23.0.0 to 27.0.2 - [Release notes](https://github.com/dsherret/ts-morph/releases) - [Commits](https://github.com/dsherret/ts-morph/compare/23.0.0...27.0.2) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: "@typescript-eslint/parser" dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: ts-morph dependency-version: 27.0.2 dependency-type: direct:development update-type: version-update:semver-major dependency-group: core-ui-package-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../auth/managers/simple/ui/package-lock.json | 1536 ++++++++--------- .../auth/managers/simple/ui/pnpm-lock.yaml | 17 - 2 files changed, 703 insertions(+), 850 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json index c93585c4a8345..1113b9c475c6c 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json @@ -19,7 +19,7 @@ "react-router-dom": "^7.13.1" }, "devDependencies": { - "@7nohe/openapi-react-query-codegen": "^2.0.0", + "@7nohe/openapi-react-query-codegen": "^1.6.2", "@eslint/compat": "^2.0.2", "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.9.0", @@ -28,9 +28,9 @@ "@trivago/prettier-plugin-sort-imports": "^6.0.2", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@typescript-eslint/eslint-plugin": "8.50.0", - "@typescript-eslint/parser": "8.50.0", - "@typescript-eslint/utils": "^8.50.0", + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", + "@typescript-eslint/utils": "^8.56.1", "@vitejs/plugin-react-swc": "^4.2.3", "eslint": "^10.0.2", "eslint-config-prettier": "^10.1.8", @@ -43,6 +43,7 @@ "eslint-plugin-unicorn": "^63.0.0", "happy-dom": "^20.7.0", "prettier": "^3.8.1", + "ts-morph": "^27.0.2", "typescript": "~5.9.3", "typescript-eslint": "^8.56.1", "vite": "^7.3.1", @@ -51,18 +52,16 @@ } }, "node_modules/@7nohe/openapi-react-query-codegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@7nohe/openapi-react-query-codegen/-/openapi-react-query-codegen-2.0.0.tgz", - "integrity": "sha512-RZKQNK36xiziPzio9msj72gVuQq/d5WfiUI6cExCQuMOZUhdG2nEVdt1EunI3wc7msHX3oxVfxJGjMdn8ydz7w==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@7nohe/openapi-react-query-codegen/-/openapi-react-query-codegen-1.6.2.tgz", + "integrity": "sha512-hiemrj2XDypRpsqBLjliIIhLxH5NzCsbUW5km7XVRvlC3J+oIc7EBG+LqMSGWj1T6zG1eqFFc+/qXXC3eKPptA==", "dev": true, "license": "MIT", "workspaces": [ "examples/*" ], "dependencies": { - "@hey-api/client-fetch": "0.4.0", - "@hey-api/openapi-ts": "0.53.8", - "cross-spawn": "^7.0.3" + "@hey-api/openapi-ts": "0.52.0" }, "bin": { "openapi-rq": "dist/cli.mjs" @@ -73,7 +72,8 @@ }, "peerDependencies": { "commander": "12.x", - "ts-morph": "23.x", + "glob": "10.x", + "ts-morph": "22.x", "typescript": "5.x" } }, @@ -84,9 +84,9 @@ "dev": true }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", - "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", + "version": "11.6.4", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.4.tgz", + "integrity": "sha512-9K6xOqeevacvweLGik6LnZCb1fBtCOSIWQs8d096XGeqoLKC33UVMGz9+77Gw44KvbH4pKcQPWo4ZpxkXYj05w==", "dev": true, "license": "MIT", "dependencies": { @@ -1237,23 +1237,16 @@ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", "license": "MIT" }, - "node_modules/@hey-api/client-fetch": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.4.0.tgz", - "integrity": "sha512-T8T3yCl2+AiVVDP6tvfnU/rXOkEHddMTOYCZXUVbydj7URVErh5BelIa8UWBkFYZBP2/mi2nViScNhe9eBolPw==", - "deprecated": "Starting with v0.73.0, this package is bundled directly inside @hey-api/openapi-ts.", - "dev": true, - "license": "MIT" - }, "node_modules/@hey-api/openapi-ts": { - "version": "0.53.8", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.53.8.tgz", - "integrity": "sha512-UbiaIq+JNgG00N/iWYk+LSivOBgWsfGxEHDleWEgQcQr3q7oZJTKL8oH87+KkFDDbUngm1g8lnKI/zLdu1aElQ==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.52.0.tgz", + "integrity": "sha512-DA3Zf5ONxMK1PUkK88lAuYbXMgn5BvU5sjJdTAO2YOn6Eu/9ovilBztMzvu8pyY44PmL3n4ex4+f+XIwvgfhvw==", "dev": true, "license": "MIT", "dependencies": { - "@apidevtools/json-schema-ref-parser": "11.7.0", - "c12": "2.0.1", + "@apidevtools/json-schema-ref-parser": "11.6.4", + "c12": "1.11.1", + "camelcase": "8.0.0", "commander": "12.1.0", "handlebars": "4.7.8" }, @@ -1347,6 +1340,25 @@ "@swc/helpers": "^0.5.0" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1400,50 +1412,24 @@ "dev": true, "license": "MIT" }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@pandacss/is-valid-prop": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-1.8.2.tgz", "integrity": "sha512-wfZ4kzvHXQ9pG3wuIGTUCcbC7Op8pqIQZNIRY/bqWQu67WTHxZUHUPSZgQMhguI8Tz4ot+DNf4Qhha0bhLvNEQ==", "license": "MIT" }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pkgr/core": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", @@ -2188,59 +2174,51 @@ } }, "node_modules/@ts-morph/common": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.24.0.tgz", - "integrity": "sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.28.1.tgz", + "integrity": "sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "fast-glob": "^3.3.2", - "minimatch": "^9.0.4", - "mkdirp": "^3.0.1", - "path-browserify": "^1.0.1" + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1", + "tinyglobby": "^0.2.14" } }, - "node_modules/@ts-morph/common/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/@ts-morph/common/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0" + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/@ts-morph/common/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, - "license": "ISC", - "peer": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.2" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "18 || 20 || >=22" } }, - "node_modules/@ts-morph/common/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "mkdirp": "dist/cjs/src/bin.js" + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=10" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2354,20 +2332,20 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.0.tgz", - "integrity": "sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.50.0", - "@typescript-eslint/type-utils": "8.50.0", - "@typescript-eslint/utils": "8.50.0", - "@typescript-eslint/visitor-keys": "8.50.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2377,21 +2355,33 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.50.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/project-service": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", - "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.50.0", - "@typescript-eslint/types": "^8.50.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2401,15 +2391,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", - "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", + "debug": "^4.4.3" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2421,18 +2417,15 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.0.tgz", - "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/typescript-estree": "8.50.0", - "@typescript-eslint/utils": "8.50.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2440,16 +2433,12 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", - "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, "license": "MIT", "engines": { @@ -2458,24 +2447,23 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", - "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.50.0", - "@typescript-eslint/tsconfig-utils": "8.50.0", - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/visitor-keys": "8.50.0", - "debug": "^4.3.4", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2485,42 +2473,40 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", - "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", + "node_modules/@typescript-eslint/types": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.50.0", - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/typescript-estree": "8.50.0" - }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", - "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.50.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2528,56 +2514,61 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, "engines": { - "node": ">= 4" + "node": "18 || 20 || >=22" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.0.tgz", - "integrity": "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==", + "node_modules/@typescript-eslint/utils": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.50.0", - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/typescript-estree": "8.50.0", - "@typescript-eslint/visitor-keys": "8.50.0", - "debug": "^4.3.4" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2587,20 +2578,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", - "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.50.0", - "@typescript-eslint/types": "^8.50.0", - "debug": "^4.3.4" + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2608,377 +2598,16 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", - "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", - "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", - "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.50.0", - "@typescript-eslint/tsconfig-utils": "8.50.0", - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/visitor-keys": "8.50.0", - "debug": "^4.3.4", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", - "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.50.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", - "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.1", - "@typescript-eslint/types": "^8.56.1", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.0.tgz", - "integrity": "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.50.0", - "@typescript-eslint/visitor-keys": "8.50.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/types": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", - "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", - "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.50.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", - "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", - "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/utils": "8.56.1", - "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", - "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", - "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.56.1", - "@typescript-eslint/tsconfig-utils": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", - "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", - "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", - "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.56.1", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -4116,11 +3745,26 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.0", @@ -4381,6 +4025,19 @@ "node": ">=6.0.0" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4397,7 +4054,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -4453,27 +4110,27 @@ } }, "node_modules/c12": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz", - "integrity": "sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/c12/-/c12-1.11.1.tgz", + "integrity": "sha512-KDU0TvSvVdaYcQKQ6iPHATGz/7p/KiVjPg4vQrB6Jg/wX9R0yl5RZxWm9IoZqaIHD2+6PZd81+KMGwRr/lRIUg==", "dev": true, "license": "MIT", "dependencies": { - "chokidar": "^4.0.1", + "chokidar": "^3.6.0", "confbox": "^0.1.7", "defu": "^6.1.4", "dotenv": "^16.4.5", "giget": "^1.2.3", - "jiti": "^2.3.0", + "jiti": "^1.21.6", "mlly": "^1.7.1", - "ohash": "^1.1.4", + "ohash": "^1.1.3", "pathe": "^1.1.2", "perfect-debounce": "^1.0.0", - "pkg-types": "^1.2.0", + "pkg-types": "^1.1.1", "rc9": "^2.1.2" }, "peerDependencies": { - "magicast": "^0.3.5" + "magicast": "^0.3.4" }, "peerDependenciesMeta": { "magicast": { @@ -4481,6 +4138,16 @@ } } }, + "node_modules/c12/node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -4539,6 +4206,19 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001776", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", @@ -4595,19 +4275,41 @@ "license": "MIT" }, "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/chownr": { @@ -4674,8 +4376,7 @@ "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", @@ -5023,6 +4724,14 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/electron-to-chromium": { "version": "1.5.307", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", @@ -5834,36 +5543,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "peer": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -5877,16 +5556,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/fastq": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", - "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", - "dev": true, - "peer": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -5904,7 +5573,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6002,6 +5671,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", @@ -6188,6 +5875,29 @@ "dev": true, "license": "MIT" }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -6200,6 +5910,34 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", @@ -6526,6 +6264,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -6646,6 +6397,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-function": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", @@ -6695,7 +6457,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -6893,6 +6655,23 @@ "node": ">= 0.4" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/javascript-natural-sort": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", @@ -6900,26 +6679,17 @@ "dev": true, "license": "MIT" }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -7121,30 +6891,6 @@ "node": ">= 0.4" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "peer": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -7199,13 +6945,14 @@ } }, "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", + "peer": true, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/minizlib": { @@ -7339,6 +7086,16 @@ "dev": true, "license": "MIT" }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/nypm": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.4.tgz", @@ -7558,6 +7315,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7610,8 +7375,7 @@ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", @@ -7636,6 +7400,32 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC", + "peer": true + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -7675,7 +7465,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "peer": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -7866,27 +7656,6 @@ "node": ">=6" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peer": true - }, "node_modules/rc9": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", @@ -7993,17 +7762,16 @@ } }, "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 14.18.0" + "dependencies": { + "picomatch": "^2.2.1" }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">=8.10.0" } }, "node_modules/redent": { @@ -8120,17 +7888,6 @@ "node": ">=4" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "peer": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rollup": { "version": "4.48.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.48.1.tgz", @@ -8171,30 +7928,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peer": true, - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-array-concat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", @@ -8427,6 +8160,20 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -8459,6 +8206,64 @@ "dev": true, "license": "MIT" }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -8572,6 +8377,52 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -8649,6 +8500,16 @@ "node": ">=10" } }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -8659,7 +8520,8 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tinyglobby": { "version": "0.2.15", @@ -8724,7 +8586,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -8746,15 +8608,14 @@ } }, "node_modules/ts-morph": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-23.0.0.tgz", - "integrity": "sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug==", + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-27.0.2.tgz", + "integrity": "sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@ts-morph/common": "~0.24.0", - "code-block-writer": "^13.0.1" + "@ts-morph/common": "~0.28.1", + "code-block-writer": "^13.0.3" } }, "node_modules/tslib": { @@ -8891,88 +8752,6 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", - "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/type-utils": "8.56.1", - "@typescript-eslint/utils": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.56.1", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", - "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", - "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/ufo": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", @@ -9445,6 +9224,97 @@ "dev": true, "license": "MIT" }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/ws": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml index 89d4ad356c10d..4d1fb8a854821 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml @@ -597,79 +597,66 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} @@ -733,28 +720,24 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [glibc] '@swc/core-linux-arm64-musl@1.15.18': resolution: {integrity: sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [musl] '@swc/core-linux-x64-gnu@1.15.18': resolution: {integrity: sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==} engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [glibc] '@swc/core-linux-x64-musl@1.15.18': resolution: {integrity: sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==} engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [musl] '@swc/core-win32-arm64-msvc@1.15.18': resolution: {integrity: sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==} From 2670d90aae3ff7db8de59a048ae70807ea8ae7fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:51:07 +0200 Subject: [PATCH 04/50] [v3-1-test] fix: gracefully handle 404 from worker log server for historical retry attempts (#62475) (#63000) * fix: gracefully handle 404 from worker log server for historical retry attempts (cherry picked from commit 25e9284a1ded0cf3bdd819591894c50b743d479a) Co-authored-by: Pradeep Kalluri <128097794+kalluripradeep@users.noreply.github.com> --- .../airflow/utils/log/file_task_handler.py | 18 ++++ .../unit/utils/log/test_file_task_handler.py | 92 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 airflow-core/tests/unit/utils/log/test_file_task_handler.py diff --git a/airflow-core/src/airflow/utils/log/file_task_handler.py b/airflow-core/src/airflow/utils/log/file_task_handler.py index 432ecffd46055..adc393c1689aa 100644 --- a/airflow-core/src/airflow/utils/log/file_task_handler.py +++ b/airflow-core/src/airflow/utils/log/file_task_handler.py @@ -895,9 +895,27 @@ def _read_from_logs_server( "See more at https://airflow.apache.org/docs/apache-airflow/" "stable/configurations-ref.html#secret-key" ) + elif response.status_code == 404: + # Log file not found on the worker's log server. + # This typically happens when a task retried on a different worker + # and the original worker's logs are no longer accessible. + # Fall back to local filesystem read if available. + worker_log_full_path = Path(self.local_base, worker_log_rel_path) + fallback_sources, fallback_streams = self._read_from_local(worker_log_full_path) + if fallback_sources: + sources.extend(fallback_sources) + log_streams.extend(fallback_streams) + else: + sources.append( + f"Log file not found on worker '{ti.hostname}'. " + f"This attempt may have run on a different worker whose logs " + f"are no longer accessible. " + f"Consider configuring remote logging (S3, GCS, etc.) for log persistence." + ) else: # Check if the resource was properly fetched response.raise_for_status() + if int(response.headers.get("Content-Length", 0)) > 0: sources.append(url) log_streams.append( diff --git a/airflow-core/tests/unit/utils/log/test_file_task_handler.py b/airflow-core/tests/unit/utils/log/test_file_task_handler.py new file mode 100644 index 0000000000000..cdda0e66de84c --- /dev/null +++ b/airflow-core/tests/unit/utils/log/test_file_task_handler.py @@ -0,0 +1,92 @@ +# +# 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 + +from pathlib import Path +from unittest.mock import MagicMock, patch + +from airflow.utils.log.file_task_handler import FileTaskHandler + + +class TestFileTaskHandlerLogServer: + """Tests for _read_from_logs_server 404 handling.""" + + def setup_method(self): + self.handler = FileTaskHandler(base_log_folder="/tmp/test_logs") + + self.ti = MagicMock() + self.ti.hostname = "worker-1" + self.ti.triggerer_job = None + self.ti.task = None + + @patch("airflow.utils.log.file_task_handler._fetch_logs_from_service") + @patch.object(FileTaskHandler, "_get_log_retrieval_url") + @patch.object(FileTaskHandler, "_read_from_local") + def test_404_falls_back_to_local_when_available(self, mock_read_local, mock_get_url, mock_fetch): + """When log server returns 404 and local logs exist, use local logs.""" + mock_get_url.return_value = ("http://worker-1/log", "dag/run/task/1.log") + + mock_response = MagicMock() + mock_response.status_code = 404 + mock_fetch.return_value = mock_response + + mock_stream = MagicMock() + mock_read_local.return_value = (["/tmp/test_logs/dag/run/task/1.log"], [mock_stream]) + + sources, streams = self.handler._read_from_logs_server(self.ti, "dag/run/task/1.log") + + assert sources == ["/tmp/test_logs/dag/run/task/1.log"] + assert streams == [mock_stream] + mock_read_local.assert_called_once_with(Path("/tmp/test_logs", "dag/run/task/1.log")) + + @patch("airflow.utils.log.file_task_handler._fetch_logs_from_service") + @patch.object(FileTaskHandler, "_get_log_retrieval_url") + @patch.object(FileTaskHandler, "_read_from_local") + def test_404_shows_clear_message_when_no_local_fallback(self, mock_read_local, mock_get_url, mock_fetch): + """When log server returns 404 and no local logs exist, show helpful message.""" + mock_get_url.return_value = ("http://worker-1/log", "dag/run/task/1.log") + + mock_response = MagicMock() + mock_response.status_code = 404 + mock_fetch.return_value = mock_response + + mock_read_local.return_value = ([], []) + + sources, streams = self.handler._read_from_logs_server(self.ti, "dag/run/task/1.log") + + assert len(sources) == 1 + assert "worker-1" in sources[0] + assert "no longer accessible" in sources[0] + assert "remote logging" in sources[0] + assert streams == [] + + @patch("airflow.utils.log.file_task_handler._fetch_logs_from_service") + @patch.object(FileTaskHandler, "_get_log_retrieval_url") + def test_403_shows_secret_key_message(self, mock_get_url, mock_fetch): + """When log server returns 403, show secret key configuration message.""" + mock_get_url.return_value = ("http://worker-1/log", "dag/run/task/1.log") + + mock_response = MagicMock() + mock_response.status_code = 403 + mock_fetch.return_value = mock_response + + sources, streams = self.handler._read_from_logs_server(self.ti, "dag/run/task/1.log") + + assert len(sources) == 1 + assert "secret_key" in sources[0] + assert streams == [] From 77b9315fecf90915e0e7000cc2887f72fd737e4e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 10:13:02 -0800 Subject: [PATCH 05/50] [v3-1-test] Remove issue_number option from newsfragment guidance in PR template (#63006) (#63012) The CI workflow added in #62975 validates that newsfragment filenames use the PR number, so allowing issue numbers would cause false CI failures. Align the PR template with the contributing docs and the new validation. (cherry picked from commit 41969f4cf7cbff91ebd834f5f1fd7ea53c039915) Co-authored-by: Xiaodong DENG --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3536ffd1e949a..2b6318dc973e8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -39,4 +39,4 @@ Generated-by: [Tool Name] following [the guidelines](https://github.com/apache/a * Read the **[Pull Request Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)** for more information. Note: commit author/co-author name and email in commits become permanently public when merged. * For fundamental code changes, an Airflow Improvement Proposal ([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals)) is needed. * When adding dependency, check compliance with the [ASF 3rd Party License Policy](https://www.apache.org/legal/resolved.html#category-x). -* For significant user-facing changes create newsfragment: `{pr_number}.significant.rst` or `{issue_number}.significant.rst`, in [airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments). +* For significant user-facing changes create newsfragment: `{pr_number}.significant.rst`, in [airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments). You can add this file in a follow-up commit after the PR is created so you know the PR number. From e250a6c99921b4dddd1a3285a5d50ffe05607065 Mon Sep 17 00:00:00 2001 From: Bugra Ozturk Date: Fri, 6 Mar 2026 19:34:17 +0100 Subject: [PATCH 06/50] [v3-1-test] CI: Upgrade important CI environment (#62989) (#63005) * [v3-1-test] CI: Upgrade important CI environment (#62989) (cherry picked from commit 60b52b78d74b0eab02e7b7597f947df32adbfd1b) Co-authored-by: Jarek Potiuk * Fix rebase --------- Co-authored-by: Jarek Potiuk --- Dockerfile.ci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.ci b/Dockerfile.ci index 956660bd22d8f..c9e3c2ede38d0 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1579,7 +1579,7 @@ ENV DEV_APT_COMMAND=${DEV_APT_COMMAND} \ ARG AIRFLOW_PYTHON_VERSION="3.12.13" ENV AIRFLOW_PYTHON_VERSION=${AIRFLOW_PYTHON_VERSION} -ENV GOLANG_MAJOR_MINOR_VERSION="1.25.5" +ENV GOLANG_MAJOR_MINOR_VERSION="1.26.1" COPY --from=scripts install_os_dependencies.sh /scripts/docker/ From 1926446bda257e89adfc2d0e5f5e8c8d0a4d6ce6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 12:05:26 +0100 Subject: [PATCH 07/50] [v3-1-test] Align integration LocalStack docker-compose with e2e LocalStack config (#62980) (#62993) (cherry picked from commit 6722c4b3559259591cdc69f76319e1811602956e) Co-authored-by: Jason(Zhe-You) Liu <68415893+jason810496@users.noreply.github.com> --- scripts/ci/docker-compose/integration-localstack.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/ci/docker-compose/integration-localstack.yml b/scripts/ci/docker-compose/integration-localstack.yml index 68560bb047698..bb1ef2f5a3d86 100644 --- a/scripts/ci/docker-compose/integration-localstack.yml +++ b/scripts/ci/docker-compose/integration-localstack.yml @@ -27,8 +27,17 @@ services: environment: # LocalStack configuration: https://docs.localstack.cloud/references/configuration/ - DEBUG=${DEBUG:-0} + - AWS_ACCESS_KEY_ID=test + - AWS_SECRET_ACCESS_KEY=test + - AWS_DEFAULT_REGION=us-east-1 volumes: - "/var/run/docker.sock:/var/run/docker.sock" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:4566/_localstack/health"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 10s airflow: environment: From 1b7cde4f2a4acb497954fdeada4033cf4c571af6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 21:21:11 +0100 Subject: [PATCH 08/50] [v3-1-test] Fallback to no constraint builds for docker-context-files installation (#63051) (#63057) When building PROD from docker-context-files - i.e. when we run main build with providers built from sources, we should fall back to no constraints build when there is a conflict with constraints. This is a follow up after #62378 (cherry picked from commit fef2e62d6b730a31f5050295d9d1193d63e92fe7) Co-authored-by: Jarek Potiuk --- Dockerfile | 22 +++++++++++++++++-- .../install_from_docker_context_files.sh | 22 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4a37dba420d22..4ae1247f4adc7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -993,10 +993,28 @@ function install_airflow_and_providers_from_docker_context_files(){ fi set -x - ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} \ + if ! ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} \ ${ADDITIONAL_PIP_INSTALL_FLAGS} \ "${flags[@]}" \ - "${install_airflow_distribution[@]}" "${install_airflow_core_distribution[@]}" "${airflow_distributions[@]}" + "${install_airflow_distribution[@]}" "${install_airflow_core_distribution[@]}" "${airflow_distributions[@]}"; then + set +x + if [[ ${AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION} != "true" ]]; then + echo + echo "${COLOR_RED}Failing because constraints installation failed and fallback is disabled.${COLOR_RESET}" + echo + exit 1 + fi + echo + echo "${COLOR_YELLOW}Likely there are new dependencies conflicting with constraints.${COLOR_RESET}" + echo + echo "${COLOR_BLUE}Falling back to no-constraints installation.${COLOR_RESET}" + echo + set -x + ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} \ + ${ADDITIONAL_PIP_INSTALL_FLAGS} \ + "${install_airflow_distribution[@]}" "${install_airflow_core_distribution[@]}" \ + "${airflow_distributions[@]}" + fi set +x common::install_packaging_tools # We use pip check here to make sure that whatever `uv` installs, is also "correct" according to `pip` diff --git a/scripts/docker/install_from_docker_context_files.sh b/scripts/docker/install_from_docker_context_files.sh index 987582f35b6ea..0dc4262aa1ac9 100644 --- a/scripts/docker/install_from_docker_context_files.sh +++ b/scripts/docker/install_from_docker_context_files.sh @@ -116,10 +116,28 @@ function install_airflow_and_providers_from_docker_context_files(){ fi set -x - ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} \ + if ! ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} \ ${ADDITIONAL_PIP_INSTALL_FLAGS} \ "${flags[@]}" \ - "${install_airflow_distribution[@]}" "${install_airflow_core_distribution[@]}" "${airflow_distributions[@]}" + "${install_airflow_distribution[@]}" "${install_airflow_core_distribution[@]}" "${airflow_distributions[@]}"; then + set +x + if [[ ${AIRFLOW_FALLBACK_NO_CONSTRAINTS_INSTALLATION} != "true" ]]; then + echo + echo "${COLOR_RED}Failing because constraints installation failed and fallback is disabled.${COLOR_RESET}" + echo + exit 1 + fi + echo + echo "${COLOR_YELLOW}Likely there are new dependencies conflicting with constraints.${COLOR_RESET}" + echo + echo "${COLOR_BLUE}Falling back to no-constraints installation.${COLOR_RESET}" + echo + set -x + ${PACKAGING_TOOL_CMD} install ${EXTRA_INSTALL_FLAGS} \ + ${ADDITIONAL_PIP_INSTALL_FLAGS} \ + "${install_airflow_distribution[@]}" "${install_airflow_core_distribution[@]}" \ + "${airflow_distributions[@]}" + fi set +x common::install_packaging_tools # We use pip check here to make sure that whatever `uv` installs, is also "correct" according to `pip` From d508ff4a0ab115cfd66521c8ff817d4c81e37a7f Mon Sep 17 00:00:00 2001 From: Bugra Ozturk Date: Sat, 7 Mar 2026 21:39:33 +0100 Subject: [PATCH 09/50] Fill Turkish Translation Gap in v3-1-test (#63010) --- .../src/airflow/ui/public/i18n/locales/tr/common.json | 10 +--------- .../airflow/ui/public/i18n/locales/tr/components.json | 4 ++++ .../src/airflow/ui/public/i18n/locales/tr/dag.json | 6 ++++++ 3 files changed, 11 insertions(+), 9 deletions(-) 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 32c66539b6473..1024676c131b6 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 @@ -145,15 +145,6 @@ "placeholder": "Not ekle...", "taskInstance": "Görev ÖrneÄŸi Notu" }, - "pools": { - "deferred": "ErtelenmiÅŸ", - "open": "Açık", - "pools_one": "Havuz", - "pools_other": "Havuzlar", - "queued": "Kuyrukta", - "running": "Çalışıyor", - "scheduled": "Planlanmış" - }, "reset": "Sıfırla", "runId": "Çalıştırma KimliÄŸi", "runTypes": { @@ -192,6 +183,7 @@ "failed": "BaÅŸarısız", "no_status": "Durum Yok", "none": "Durum Yok", + "open": "Açık", "planned": "Planlanmış", "queued": "Kuyrukta", "removed": "Kaldırılmış", diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json index b40523e33065e..67b2f0f2b954a 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/components.json @@ -10,6 +10,7 @@ "maxRuns": "Maksimum Aktif Çalıştırma", "missingAndErroredRuns": "Eksik ve Hata Almış Dag Çalıştırmaları", "missingRuns": "Eksik Dag Çalıştırmaları", + "permissionDenied": "Ön çalıştırma baÅŸarısız oldu: İzin reddedildi. Lütfen gerekli izinlere sahip olduÄŸunuzdan emin olun.", "reprocessBehavior": "Yeniden İşleme Davranışı", "run": "Geriye Dönük Çalıştır", "selectDescription": "Bu Dag'ı bir tarih aralığı için çalıştır", @@ -116,6 +117,9 @@ "selectLabel": "Tek Çalıştırma", "title": "Dag Tetikle", "toaster": { + "error": { + "title": "Dag tetikleme baÅŸarısız oldu." + }, "success": { "description": "Dag çalıştırması baÅŸarıyla tetiklendi.", "title": "Dag Çalıştırması Tetiklendi" diff --git a/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json b/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json index 987391a63da96..a4e04fd52e7d2 100644 --- a/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json +++ b/airflow-core/src/airflow/ui/public/i18n/locales/tr/dag.json @@ -73,6 +73,12 @@ "navigation": "Gezin: {{arrow}}", "toggleGroup": "Grubu aç/kapat: Space" }, + "notFound": { + "back": "Geri Dön", + "backToDags": "Dag'lere Geri Dön", + "message": "Dag \"{{dagId}}\" veri tabanında mevcut deÄŸil.", + "title": "Dag Bulunamadı" + }, "overview": { "buttons": { "failedRun_one": "BaÅŸarısız Çalıştırma", From 21dae80b50744cd1f7a87ed198de2a942d9ab33d Mon Sep 17 00:00:00 2001 From: Vincent <97131062+vincbeck@users.noreply.github.com> Date: Sun, 8 Mar 2026 04:27:31 -0400 Subject: [PATCH 10/50] Remove global from FastAPI app.py (#59772) (#62997) * Remove global from FastAPI app.py * Remove global from FastAPI app.py Co-authored-by: Jens Scheffler <95105677+jscheffl@users.noreply.github.com> --- airflow-core/src/airflow/api_fastapi/app.py | 26 ++++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/app.py b/airflow-core/src/airflow/api_fastapi/app.py index 1720c9f08ecdf..3a61c7895c7b2 100644 --- a/airflow-core/src/airflow/api_fastapi/app.py +++ b/airflow-core/src/airflow/api_fastapi/app.py @@ -18,6 +18,7 @@ import logging from contextlib import AsyncExitStack, asynccontextmanager +from functools import cache from typing import TYPE_CHECKING, cast from urllib.parse import urlsplit @@ -64,8 +65,9 @@ def get_cookie_path() -> str: log = logging.getLogger(__name__) -app: FastAPI | None = None -auth_manager: BaseAuthManager | None = None + +class _AuthManagerState: + instance: BaseAuthManager | None = None @asynccontextmanager @@ -117,19 +119,16 @@ def create_app(apps: str = "all") -> FastAPI: return app +@cache def cached_app(config=None, testing=False, apps="all") -> FastAPI: """Return cached instance of Airflow API app.""" - global app - if not app: - app = create_app(apps=apps) - return app + return create_app(apps=apps) def purge_cached_app() -> None: """Remove the cached version of the app and auth_manager in global state.""" - global app, auth_manager - app = None - auth_manager = None + cached_app.cache_clear() + _AuthManagerState.instance = None def get_auth_manager_cls() -> type[BaseAuthManager]: @@ -150,10 +149,9 @@ def get_auth_manager_cls() -> type[BaseAuthManager]: def create_auth_manager() -> BaseAuthManager: """Create the auth manager.""" - global auth_manager auth_manager_cls = get_auth_manager_cls() - auth_manager = auth_manager_cls() - return auth_manager + _AuthManagerState.instance = auth_manager_cls() + return _AuthManagerState.instance def init_auth_manager(app: FastAPI | None = None) -> BaseAuthManager: @@ -171,12 +169,12 @@ def init_auth_manager(app: FastAPI | None = None) -> BaseAuthManager: def get_auth_manager() -> BaseAuthManager: """Return the auth manager, provided it's been initialized before.""" - if auth_manager is None: + if _AuthManagerState.instance is None: raise RuntimeError( "Auth Manager has not been initialized yet. " "The `init_auth_manager` method needs to be called first." ) - return auth_manager + return _AuthManagerState.instance def init_plugins(app: FastAPI) -> None: From 1fdb42e4d462e0df1fb66a6b694dd4dbae6c2c49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 10:40:47 +0100 Subject: [PATCH 11/50] chore(deps): bump actions/setup-java from 4.7.1 to 5.2.0 (#63102) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4.7.1 to 5.2.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/c5195efecf7bdfc987ee8bae7a71cb8b11521c00...be666c2fcd27ec809703dec50e508c2fdc7f6654) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: 5.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/basic-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index fb6450f4680cb..2d4866ba4f8a9 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -111,7 +111,7 @@ jobs: - name: "Install SVN" run: sudo apt-get update && sudo apt-get install -y subversion - name: "Install Java (for Apache RAT)" - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: 'temurin' java-version: '17' From 9e4021468c21cf8a2c74ee0f5e3e29464c1836ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 10:41:50 +0100 Subject: [PATCH 12/50] chore(deps): bump actions/stale from 9.1.0 to 10.2.0 (#63099) Bumps [actions/stale](https://github.com/actions/stale) from 9.1.0 to 10.2.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/5bef64f19d7facfb25b37b414482c7164d639639...b5d41d4e1d5dceea10e7104786b73624c18a190f) --- updated-dependencies: - dependency-name: actions/stale dependency-version: 10.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/recheck-old-bug-report.yml | 2 +- .github/workflows/stale.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/recheck-old-bug-report.yml b/.github/workflows/recheck-old-bug-report.yml index c245f73923216..907f2fda1c13f 100644 --- a/.github/workflows/recheck-old-bug-report.yml +++ b/.github/workflows/recheck-old-bug-report.yml @@ -28,7 +28,7 @@ jobs: recheck-old-bug-report: runs-on: ["ubuntu-22.04"] steps: - - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 with: only-issue-labels: 'kind:bug' stale-issue-label: 'Stale Bug Report' diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 5724a17314aec..7e6d2a8726d8f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -29,7 +29,7 @@ jobs: stale: runs-on: ["ubuntu-22.04"] steps: - - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 with: stale-pr-message: > This pull request has been automatically marked as stale because it has not had From 6bbcc7c780a8fe11c8718e175ab2b8d1897ea039 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 10:42:11 +0100 Subject: [PATCH 13/50] chore(deps): bump actions/checkout from 4.2.2 to 6.0.2 (#63096) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 6.0.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/11bd71901bbe5b1630ceea73d27597364c9af683...de0fac2e4500dabe0009e67214ff5f5447ce83dd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../workflows/additional-ci-image-checks.yml | 2 +- .../workflows/additional-prod-image-tests.yml | 8 +++---- .../workflows/airflow-distributions-tests.yml | 2 +- .github/workflows/backport-cli.yml | 2 +- .github/workflows/basic-tests.yml | 22 +++++++++---------- .github/workflows/ci-amd-arm.yml | 10 ++++----- .github/workflows/ci-image-build.yml | 2 +- .github/workflows/ci-image-checks.yml | 12 +++++----- .github/workflows/ci-notification.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/finalize-tests.yml | 6 ++--- .github/workflows/generate-constraints.yml | 2 +- .github/workflows/helm-tests.yml | 4 ++-- .../workflows/integration-system-tests.yml | 6 ++--- .github/workflows/k8s-tests.yml | 2 +- .github/workflows/news-fragment.yml | 2 +- .github/workflows/prod-image-build.yml | 4 ++-- .github/workflows/publish-docs-to-s3.yml | 8 +++---- .github/workflows/push-image-cache.yml | 4 ++-- .github/workflows/release_dockerhub_image.yml | 2 +- .../release_single_dockerhub_image.yml | 4 ++-- .github/workflows/run-unit-tests.yml | 2 +- .github/workflows/test-providers.yml | 4 ++-- 23 files changed, 57 insertions(+), 57 deletions(-) diff --git a/.github/workflows/additional-ci-image-checks.yml b/.github/workflows/additional-ci-image-checks.yml index 0dfd92b793ee8..6a33cea24a937 100644 --- a/.github/workflows/additional-ci-image-checks.yml +++ b/.github/workflows/additional-ci-image-checks.yml @@ -135,7 +135,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/additional-prod-image-tests.yml b/.github/workflows/additional-prod-image-tests.yml index c7d4bde61c8db..e37da4a47dc1e 100644 --- a/.github/workflows/additional-prod-image-tests.yml +++ b/.github/workflows/additional-prod-image-tests.yml @@ -107,7 +107,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 persist-credentials: false @@ -145,7 +145,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 persist-credentials: false @@ -176,7 +176,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 persist-credentials: false @@ -207,7 +207,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 persist-credentials: false diff --git a/.github/workflows/airflow-distributions-tests.yml b/.github/workflows/airflow-distributions-tests.yml index db69ee894de6a..f35b8895054ff 100644 --- a/.github/workflows/airflow-distributions-tests.yml +++ b/.github/workflows/airflow-distributions-tests.yml @@ -89,7 +89,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ matrix.python-version }}" diff --git a/.github/workflows/backport-cli.yml b/.github/workflows/backport-cli.yml index 42f8178868267..9ed750a5fbc57 100644 --- a/.github/workflows/backport-cli.yml +++ b/.github/workflows/backport-cli.yml @@ -53,7 +53,7 @@ jobs: steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" id: checkout-for-backport - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: true fetch-depth: 0 diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index 2d4866ba4f8a9..a086ff21d2c16 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -83,7 +83,7 @@ jobs: - name: "Cleanup repo" shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # Need to fetch all history for selective checks tests fetch-depth: 0 @@ -102,7 +102,7 @@ jobs: - name: "Cleanup repo" shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false @@ -130,7 +130,7 @@ jobs: runs-on: ${{ fromJSON(inputs.runners) }} steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 1 persist-credentials: false @@ -151,7 +151,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup pnpm @@ -213,7 +213,7 @@ jobs: runs-on: ${{ fromJSON(inputs.runners) }} steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" @@ -234,7 +234,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" @@ -248,7 +248,7 @@ jobs: platform: ${{ inputs.platform }} save-cache: true - name: Fetch incoming commit ${{ github.sha }} with its parent - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 2 @@ -269,7 +269,7 @@ jobs: runs-on: ["windows-2025"] steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 persist-credentials: false @@ -286,7 +286,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" @@ -371,7 +371,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" @@ -418,7 +418,7 @@ jobs: FORCE_COLOR: 1 steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install uv" diff --git a/.github/workflows/ci-amd-arm.yml b/.github/workflows/ci-amd-arm.yml index f64e2bbd90e91..bef790698f411 100644 --- a/.github/workflows/ci-amd-arm.yml +++ b/.github/workflows/ci-amd-arm.yml @@ -137,11 +137,11 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Fetch incoming commit ${{ github.sha }} with its parent - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 2 @@ -192,7 +192,7 @@ jobs: if: needs.build-info.outputs.platform == 'linux/amd64' steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install prek" @@ -831,7 +831,7 @@ jobs: VERBOSE: "true" steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false # keep this in sync with go.mod in go-sdk/ @@ -972,7 +972,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" diff --git a/.github/workflows/ci-image-build.yml b/.github/workflows/ci-image-build.yml index 2083f7bfa28c7..d1415ed53fcf8 100644 --- a/.github/workflows/ci-image-build.yml +++ b/.github/workflows/ci-image-build.yml @@ -118,7 +118,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout target branch" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" diff --git a/.github/workflows/ci-image-checks.yml b/.github/workflows/ci-image-checks.yml index f4e302ab17036..665b78ced44ac 100644 --- a/.github/workflows/ci-image-checks.yml +++ b/.github/workflows/ci-image-checks.yml @@ -136,7 +136,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -184,7 +184,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" @@ -238,7 +238,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -301,7 +301,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -393,12 +393,12 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 persist-credentials: false - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: "apache/airflow-client-python" fetch-depth: 1 diff --git a/.github/workflows/ci-notification.yml b/.github/workflows/ci-notification.yml index 3b5fdfd31e5a5..298c3fbeac139 100644 --- a/.github/workflows/ci-notification.yml +++ b/.github/workflows/ci-notification.yml @@ -41,7 +41,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 28c8cfae81a07..e06caa5dfb03b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -47,7 +47,7 @@ jobs: security-events: write steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff --git a/.github/workflows/finalize-tests.yml b/.github/workflows/finalize-tests.yml index 6a6ae7d6b2e99..0d9287f23f4fc 100644 --- a/.github/workflows/finalize-tests.yml +++ b/.github/workflows/finalize-tests.yml @@ -99,7 +99,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # Needed to perform push action persist-credentials: false @@ -107,7 +107,7 @@ jobs: id: constraints-branch run: ./scripts/ci/constraints/ci_branch_constraints.sh >> ${GITHUB_OUTPUT} - name: Checkout ${{ steps.constraints-branch.outputs.branch }} - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: "constraints" ref: ${{ steps.constraints-branch.outputs.branch }} @@ -146,7 +146,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ matrix.python-version }}" diff --git a/.github/workflows/generate-constraints.yml b/.github/workflows/generate-constraints.yml index 58b87a96b4f9e..381d09030165c 100644 --- a/.github/workflows/generate-constraints.yml +++ b/.github/workflows/generate-constraints.yml @@ -75,7 +75,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ matrix.python-version }}" diff --git a/.github/workflows/helm-tests.yml b/.github/workflows/helm-tests.yml index ae78d644e6a95..1f8cb07abf843 100644 --- a/.github/workflows/helm-tests.yml +++ b/.github/workflows/helm-tests.yml @@ -68,7 +68,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -95,7 +95,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/integration-system-tests.yml b/.github/workflows/integration-system-tests.yml index 977243ecf75bb..d62a383a1e5c8 100644 --- a/.github/workflows/integration-system-tests.yml +++ b/.github/workflows/integration-system-tests.yml @@ -97,7 +97,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -147,7 +147,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" @@ -192,7 +192,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}" diff --git a/.github/workflows/k8s-tests.yml b/.github/workflows/k8s-tests.yml index 47bd7ba83211e..59bf63c92a54b 100644 --- a/.github/workflows/k8s-tests.yml +++ b/.github/workflows/k8s-tests.yml @@ -80,7 +80,7 @@ jobs: echo "PYTHON_MAJOR_MINOR_VERSION=${KUBERNETES_COMBO}" | sed 's/-.*//' >> $GITHUB_ENV echo "KUBERNETES_VERSION=${KUBERNETES_COMBO}" | sed 's/=[^-]*-/=/' >> $GITHUB_ENV - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" diff --git a/.github/workflows/news-fragment.yml b/.github/workflows/news-fragment.yml index 45efd3364ea6d..6fd8c73d40ee7 100644 --- a/.github/workflows/news-fragment.yml +++ b/.github/workflows/news-fragment.yml @@ -30,7 +30,7 @@ jobs: if: "contains(github.event.pull_request.labels.*.name, 'airflow3.0:breaking')" steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false # `towncrier check` runs `git diff --name-only origin/main...`, which diff --git a/.github/workflows/prod-image-build.yml b/.github/workflows/prod-image-build.yml index 93eb251cf0d63..7c3d2f1f13aa4 100644 --- a/.github/workflows/prod-image-build.yml +++ b/.github/workflows/prod-image-build.yml @@ -125,7 +125,7 @@ jobs: run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" if: inputs.upload-package-artifact == 'true' - name: "Checkout target branch" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Make /mnt writeable" @@ -213,7 +213,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout target branch" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Make /mnt writeable" diff --git a/.github/workflows/publish-docs-to-s3.yml b/.github/workflows/publish-docs-to-s3.yml index ddac8d7532598..e48c860b55089 100644 --- a/.github/workflows/publish-docs-to-s3.yml +++ b/.github/workflows/publish-docs-to-s3.yml @@ -177,7 +177,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout current version first to clean-up stuff" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false path: current-version @@ -185,7 +185,7 @@ jobs: # This will take longer as we need to rebuild CI image and it will not use cache # but it will build the CI image from the version of Airflow that is used to check out things - name: "Checkout ${{ inputs.ref }} " - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false ref: ${{ inputs.ref }} @@ -242,7 +242,7 @@ jobs: run: > breeze build-docs ${INCLUDE_DOCS} --docs-only - name: "Checkout current version to run SBOM generation" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false fetch-depth: 0 @@ -324,7 +324,7 @@ jobs: # This will take longer as we need to rebuild CI image and it will not use cache # but it will build the CI image from the version of Airflow that is used to check out things - name: "Checkout ${{ inputs.ref }} " - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Make /mnt writeable and cleanup" diff --git a/.github/workflows/push-image-cache.yml b/.github/workflows/push-image-cache.yml index 69ee1145361a0..56d3cd1241b1d 100644 --- a/.github/workflows/push-image-cache.yml +++ b/.github/workflows/push-image-cache.yml @@ -113,7 +113,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" @@ -182,7 +182,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" diff --git a/.github/workflows/release_dockerhub_image.yml b/.github/workflows/release_dockerhub_image.yml index 1e578a4f93ef4..315759808d1d4 100644 --- a/.github/workflows/release_dockerhub_image.yml +++ b/.github/workflows/release_dockerhub_image.yml @@ -87,7 +87,7 @@ jobs: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/release_single_dockerhub_image.yml b/.github/workflows/release_single_dockerhub_image.yml index 5f62be975c4b8..a628c74a275e9 100644 --- a/.github/workflows/release_single_dockerhub_image.yml +++ b/.github/workflows/release_single_dockerhub_image.yml @@ -76,7 +76,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" @@ -170,7 +170,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Install Breeze" diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml index 412e743146eb7..4a5789f44cf57 100644 --- a/.github/workflows/run-unit-tests.yml +++ b/.github/workflows/run-unit-tests.yml @@ -182,7 +182,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Make /mnt writeable" diff --git a/.github/workflows/test-providers.yml b/.github/workflows/test-providers.yml index 264f75e759be6..36fa445b53f0c 100644 --- a/.github/workflows/test-providers.yml +++ b/.github/workflows/test-providers.yml @@ -89,7 +89,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" @@ -188,7 +188,7 @@ jobs: shell: bash run: docker run -v "${GITHUB_WORKSPACE}:/workspace" -u 0:0 bash -c "rm -rf /workspace/*" - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: "Free up disk space" From 6c9bfdf5d53a0bed8e31b3dd395d5f938252d9df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 10:43:49 +0100 Subject: [PATCH 14/50] chore(deps): bump actions/setup-python from 5.6.0 to 6.2.0 (#63098) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.6.0 to 6.2.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/a26af69be951a213d495a4c3e4e4022e16d87065...a309ff8b426b58ec0e2a45f0f869d46889d02405) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-amd-arm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-amd-arm.yml b/.github/workflows/ci-amd-arm.yml index bef790698f411..f06b446b639dc 100644 --- a/.github/workflows/ci-amd-arm.yml +++ b/.github/workflows/ci-amd-arm.yml @@ -984,7 +984,7 @@ jobs: path: ./artifacts pattern: test-warnings-* - name: "Setup python" - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "${{ inputs.default-python-version }}" - name: "Summarize all warnings" From 1d9f015c0079995621f0f9f897227a6834d6d1a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 10:44:35 +0100 Subject: [PATCH 15/50] chore(deps): bump actions/github-script from 7.0.1 to 8.0.0 (#63090) Bumps [actions/github-script](https://github.com/actions/github-script) from 7.0.1 to 8.0.0. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/60a0d83039c74a4aee543508d2ffcb1c3799cdea...ed597411d8f924073f98dfc5c65a23a2325f34cd) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/automatic-backport.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automatic-backport.yml b/.github/workflows/automatic-backport.yml index 986c31cae4a51..2abe2b8f3824b 100644 --- a/.github/workflows/automatic-backport.yml +++ b/.github/workflows/automatic-backport.yml @@ -45,7 +45,7 @@ jobs: - name: Find PR information id: pr-info - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 185e58cc423e22bc4004ed984ee556327baa3cff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 16:07:33 +0100 Subject: [PATCH 16/50] [v3-1-test] Split npm dependabot minor+patch and major version PRs (#62889) (#63007) * Ignore major npm dependabot upgrades * Move major versions to different group (cherry picked from commit a2e3613cd074017db1241f75f99f27f2d0b955dd) Co-authored-by: Brent Bovenzi --- .github/dependabot.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index af0b44bf8fbe4..021aff77f9542 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -48,6 +48,15 @@ updates: core-ui-package-updates: patterns: - "*" + update-types: + - "minor" + - "patch" + major-version-updates: + patterns: + - "*" + applies-to: security-updates + update-types: + - "major" - package-ecosystem: npm cooldown: @@ -60,6 +69,15 @@ updates: core-ui-package-updates: patterns: - "*" + update-types: + - "minor" + - "patch" + major-version-updates: + patterns: + - "*" + applies-to: security-updates + update-types: + - "major" - package-ecosystem: npm cooldown: @@ -72,6 +90,15 @@ updates: ui-plugin-template-package-updates: patterns: - "*" + update-types: + - "minor" + - "patch" + ui-plugin-template-major-version-updates: + patterns: + - "*" + applies-to: security-updates + update-types: + - "major" - package-ecosystem: npm cooldown: @@ -134,6 +161,9 @@ updates: update-types: - "minor" - "patch" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] - package-ecosystem: npm cooldown: @@ -150,6 +180,9 @@ updates: update-types: - "minor" - "patch" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] # Repeat dependency updates on 2.11 branch as well - package-ecosystem: pip From bb080f02584a392af4800de511169d42f204dcfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:22:23 +0100 Subject: [PATCH 17/50] chore(deps): bump the core-ui-package-updates group across 1 directory with 2 updates (#63069) Bumps the core-ui-package-updates group with 2 updates in the /airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui directory: [@chakra-ui/react](https://github.com/chakra-ui/chakra-ui/tree/HEAD/packages/react) and [happy-dom](https://github.com/capricorn86/happy-dom). Updates `@chakra-ui/react` from 3.33.0 to 3.34.0 - [Release notes](https://github.com/chakra-ui/chakra-ui/releases) - [Changelog](https://github.com/chakra-ui/chakra-ui/blob/main/packages/react/CHANGELOG.md) - [Commits](https://github.com/chakra-ui/chakra-ui/commits/@chakra-ui/react@3.34.0/packages/react) Updates `happy-dom` from 20.7.0 to 20.8.3 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v20.7.0...v20.8.3) --- updated-dependencies: - dependency-name: "@chakra-ui/react" dependency-version: 3.34.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: happy-dom dependency-version: 20.8.3 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../auth/managers/simple/ui/package.json | 4 +- .../auth/managers/simple/ui/pnpm-lock.yaml | 64 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json index bc466acd35812..53d8f9d98ab47 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package.json @@ -15,7 +15,7 @@ "coverage": "vitest run --coverage" }, "dependencies": { - "@chakra-ui/react": "^3.33.0", + "@chakra-ui/react": "^3.34.0", "@tanstack/react-query": "^5.90.21", "axios": "^1.13.5", "next-themes": "^0.4.6", @@ -48,7 +48,7 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-unicorn": "^63.0.0", - "happy-dom": "^20.7.0", + "happy-dom": "^20.8.3", "prettier": "^3.8.1", "ts-morph": "^27.0.2", "typescript": "~5.9.3", diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml index 4d1fb8a854821..13f042439aa91 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: .: dependencies: '@chakra-ui/react': - specifier: ^3.33.0 - version: 3.33.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^3.34.0 + version: 3.34.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/react-query': specifier: ^5.90.21 version: 5.90.21(react@19.2.4) @@ -80,7 +80,7 @@ importers: version: 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-react-swc': specifier: ^4.2.3 - version: 4.2.3(@swc/helpers@0.5.19)(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)) + version: 4.2.3(@swc/helpers@0.5.19)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)) eslint: specifier: ^10.0.2 version: 10.0.2(jiti@2.6.1) @@ -109,8 +109,8 @@ importers: specifier: ^63.0.0 version: 63.0.0(eslint@10.0.2(jiti@2.6.1)) happy-dom: - specifier: ^20.7.0 - version: 20.7.0 + specifier: ^20.8.3 + version: 20.8.3 prettier: specifier: ^3.8.1 version: 3.8.1 @@ -125,13 +125,13 @@ importers: version: 8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3) vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@25.3.3)(jiti@2.6.1) + version: 7.3.1(@types/node@25.3.5)(jiti@2.6.1) vite-plugin-css-injected-by-js: specifier: ^4.0.1 - version: 4.0.1(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)) + version: 4.0.1(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@25.3.3)(happy-dom@20.7.0)(jiti@2.6.1) + version: 4.0.18(@types/node@25.3.5)(happy-dom@20.8.3)(jiti@2.6.1) packages: @@ -229,8 +229,8 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} - '@chakra-ui/react@3.33.0': - resolution: {integrity: sha512-HNbUFsFABjVL5IHBxsqtuT+AH/vQT1+xsEWrxnG0GBM2VjlzlMqlqCxNiDyQOsjLZXQC1ciCMbzPNcSCc63Y9w==} + '@chakra-ui/react@3.34.0': + resolution: {integrity: sha512-VLhpVwv5IVxhwajO10KnS1VQT4hDqQMQP/A796Ya+uVu8AdoSX+5HHyTLTkYIeXIDMe0xLqJfov04OBKbBchJA==} peerDependencies: '@emotion/react': '>=11' react: '>=18' @@ -849,8 +849,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@25.3.3': - resolution: {integrity: sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==} + '@types/node@25.3.5': + resolution: {integrity: sha512-oX8xrhvpiyRCQkG1MFchB09f+cXftgIXb3a7UUa4Y3wpmZPw5tyZGTLWhlESOLq1Rq6oDlc8npVU2/9xiCuXMA==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -1846,8 +1846,8 @@ packages: engines: {node: '>=0.4.7'} hasBin: true - happy-dom@20.7.0: - resolution: {integrity: sha512-hR/uLYQdngTyEfxnOoa+e6KTcfBFyc1hgFj/Cc144A5JJUuHFYqIEBDcD4FeGqUeKLRZqJ9eN9u7/GDjYEgS1g==} + happy-dom@20.8.3: + resolution: {integrity: sha512-lMHQRRwIPyJ70HV0kkFT7jH/gXzSI7yDkQFe07E2flwmNDFoWUTRMKpW2sglsnpeA7b6S2TJPp98EbQxai8eaQ==} engines: {node: '>=20.0.0'} has-bigints@1.1.0: @@ -3056,7 +3056,7 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@chakra-ui/react@3.33.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@chakra-ui/react@3.34.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@ark-ui/react': 5.34.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@emotion/is-prop-valid': 1.4.0 @@ -3560,7 +3560,7 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@25.3.3': + '@types/node@25.3.5': dependencies: undici-types: 7.18.2 @@ -3578,7 +3578,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3))(eslint@10.0.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: @@ -3671,11 +3671,11 @@ snapshots: '@typescript-eslint/types': 8.56.1 eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-react-swc@4.2.3(@swc/helpers@0.5.19)(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1))': + '@vitejs/plugin-react-swc@4.2.3(@swc/helpers@0.5.19)(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.2 '@swc/core': 1.15.18(@swc/helpers@0.5.19) - vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1) transitivePeerDependencies: - '@swc/helpers' @@ -3688,13 +3688,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1) '@vitest/pretty-format@4.0.18': dependencies: @@ -5088,9 +5088,9 @@ snapshots: optionalDependencies: uglify-js: 3.19.3 - happy-dom@20.7.0: + happy-dom@20.8.3: dependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 '@types/whatwg-mimetype': 3.0.2 '@types/ws': 8.18.1 entities: 7.0.1 @@ -6013,11 +6013,11 @@ snapshots: dependencies: punycode: 2.3.1 - vite-plugin-css-injected-by-js@4.0.1(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)): + vite-plugin-css-injected-by-js@4.0.1(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)): dependencies: - vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1) - vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1): + vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -6026,14 +6026,14 @@ snapshots: rollup: 4.59.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.3.3 + '@types/node': 25.3.5 fsevents: 2.3.3 jiti: 2.6.1 - vitest@4.0.18(@types/node@25.3.3)(happy-dom@20.7.0)(jiti@2.6.1): + vitest@4.0.18(@types/node@25.3.5)(happy-dom@20.8.3)(jiti@2.6.1): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.3)(jiti@2.6.1)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.3.5)(jiti@2.6.1)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -6050,11 +6050,11 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.3.3)(jiti@2.6.1) + vite: 7.3.1(@types/node@25.3.5)(jiti@2.6.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.3.3 - happy-dom: 20.7.0 + '@types/node': 25.3.5 + happy-dom: 20.8.3 transitivePeerDependencies: - jiti - less From 214f98095ba983ac2b7531c391c483608530c0b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:23:27 +0100 Subject: [PATCH 18/50] chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.0 (#63128) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-amd-arm.yml | 2 +- .github/workflows/ci-image-checks.yml | 2 +- .github/workflows/generate-constraints.yml | 2 +- .github/workflows/helm-tests.yml | 2 +- .github/workflows/k8s-tests.yml | 2 +- .github/workflows/prod-image-build.yml | 2 +- .github/workflows/publish-docs-to-s3.yml | 2 +- .github/workflows/release_single_dockerhub_image.yml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-amd-arm.yml b/.github/workflows/ci-amd-arm.yml index f06b446b639dc..299036c7c96c3 100644 --- a/.github/workflows/ci-amd-arm.yml +++ b/.github/workflows/ci-amd-arm.yml @@ -993,7 +993,7 @@ jobs: --pattern "**/warnings-*.txt" \ --output ./files - name: "Upload artifact for summarized warnings" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: "test-summarized-warnings" path: ./files/warn-summary-*.txt diff --git a/.github/workflows/ci-image-checks.yml b/.github/workflows/ci-image-checks.yml index 665b78ced44ac..23e6dc506d742 100644 --- a/.github/workflows/ci-image-checks.yml +++ b/.github/workflows/ci-image-checks.yml @@ -270,7 +270,7 @@ jobs: # to be responsible for updating it. https://github.com/actions/upload-artifact/issues/506 if: steps.restore-docs-inventory-cache != 'true' && matrix.flag == '--docs-only' - name: "Upload build docs" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: airflow-docs path: './generated/_build' diff --git a/.github/workflows/generate-constraints.yml b/.github/workflows/generate-constraints.yml index 381d09030165c..acb854957453b 100644 --- a/.github/workflows/generate-constraints.yml +++ b/.github/workflows/generate-constraints.yml @@ -123,7 +123,7 @@ jobs: --answer yes --python "${PYTHON_VERSION}" if: inputs.generate-pypi-constraints == 'true' - name: "Upload constraint artifacts" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: constraints-${{ matrix.python-version }} path: ./files/constraints-${{ matrix.python-version }}/constraints-*.txt diff --git a/.github/workflows/helm-tests.yml b/.github/workflows/helm-tests.yml index 1f8cb07abf843..576abf71d1acd 100644 --- a/.github/workflows/helm-tests.yml +++ b/.github/workflows/helm-tests.yml @@ -133,7 +133,7 @@ jobs: breeze release-management generate-issue-content-helm-chart --limit-pr-count 2 --previous-release helm-chart/1.15.0 --current-release helm-chart/1.16.0 --verbose - name: "Upload Helm artifacts" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: Helm artifacts path: ./dist/airflow-* diff --git a/.github/workflows/k8s-tests.yml b/.github/workflows/k8s-tests.yml index 59bf63c92a54b..107a8757fe80f 100644 --- a/.github/workflows/k8s-tests.yml +++ b/.github/workflows/k8s-tests.yml @@ -119,7 +119,7 @@ jobs: - name: "\ Upload KinD logs ${{ matrix.executor }}-${{ matrix.kubernetes-combo }}-\ ${{ matrix.use-standard-naming }}" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: "\ kind-logs-${{ matrix.kubernetes-combo }}-${{ matrix.executor }}-\ diff --git a/.github/workflows/prod-image-build.yml b/.github/workflows/prod-image-build.yml index 7c3d2f1f13aa4..b20b76f7e1a6b 100644 --- a/.github/workflows/prod-image-build.yml +++ b/.github/workflows/prod-image-build.yml @@ -173,7 +173,7 @@ jobs: breeze release-management prepare-airflow-ctl-distributions --distribution-format wheel if: inputs.upload-package-artifact == 'true' - name: "Upload prepared packages as artifacts" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: prod-packages path: ./dist diff --git a/.github/workflows/publish-docs-to-s3.yml b/.github/workflows/publish-docs-to-s3.yml index e48c860b55089..bd6198c6fd915 100644 --- a/.github/workflows/publish-docs-to-s3.yml +++ b/.github/workflows/publish-docs-to-s3.yml @@ -294,7 +294,7 @@ jobs: run: > breeze release-management publish-docs --override-versioned --run-in-parallel ${INCLUDE_DOCS} - name: "Upload build docs" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: airflow-docs path: /mnt/airflow-site diff --git a/.github/workflows/release_single_dockerhub_image.yml b/.github/workflows/release_single_dockerhub_image.yml index a628c74a275e9..0f0cebda8e2b5 100644 --- a/.github/workflows/release_single_dockerhub_image.yml +++ b/.github/workflows/release_single_dockerhub_image.yml @@ -144,7 +144,7 @@ jobs: shell: bash run: find ./dist -name '*.json' - name: "Upload metadata artifact ${{ env.ARTIFACT_NAME }}" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ env.ARTIFACT_NAME }} path: ./dist/metadata-* From 711ed925c813ddd436f2c527a6cadab18d2f20ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:58:41 +0100 Subject: [PATCH 19/50] chore(deps): bump actions/setup-go from 5.5.0 to 6.3.0 (#63124) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.5.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/d35c59abb061a4a6fb18e82ac0862c26744d6ab5...4b73464bb391d4059bd26b0524d20df3927bd417) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-amd-arm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-amd-arm.yml b/.github/workflows/ci-amd-arm.yml index 299036c7c96c3..3b2ad87a3869c 100644 --- a/.github/workflows/ci-amd-arm.yml +++ b/.github/workflows/ci-amd-arm.yml @@ -836,7 +836,7 @@ jobs: persist-credentials: false # keep this in sync with go.mod in go-sdk/ - name: Setup Go - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: go-version: 1.24 cache-dependency-path: go-sdk/go.sum From a866eed745f7103b0e09d5410897fd9d0d31ba59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:59:10 +0100 Subject: [PATCH 20/50] chore(deps): bump aws-actions/configure-aws-credentials (#63123) Bumps [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) from 4.0.1 to 6.0.0. - [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases) - [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/010d0da01d0b5a38af31e9c3470dbfdabdecca3a...8df5847569e6427dd6c4fb1cf565c83acfa8afa7) --- updated-dependencies: - dependency-name: aws-actions/configure-aws-credentials dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-image-checks.yml | 2 +- .github/workflows/publish-docs-to-s3.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-image-checks.yml b/.github/workflows/ci-image-checks.yml index 23e6dc506d742..cf33b4633ecc2 100644 --- a/.github/workflows/ci-image-checks.yml +++ b/.github/workflows/ci-image-checks.yml @@ -358,7 +358,7 @@ jobs: inputs.canary-run == 'true' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1 + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0 with: aws-access-key-id: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/publish-docs-to-s3.yml b/.github/workflows/publish-docs-to-s3.yml index bd6198c6fd915..46db2f9287e18 100644 --- a/.github/workflows/publish-docs-to-s3.yml +++ b/.github/workflows/publish-docs-to-s3.yml @@ -360,7 +360,7 @@ jobs: sudo /tmp/aws/install --update rm -rf /tmp/aws/ - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1 + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0 with: aws-access-key-id: ${{ secrets.DOCS_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DOCS_AWS_SECRET_ACCESS_KEY }} From 0b4e744b2452aaf658e00f04dbdde2983008e284 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 18:59:25 +0100 Subject: [PATCH 21/50] chore(deps): bump actions/setup-node from 4.4.0 to 6.3.0 (#63119) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.4.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/49933ea5288caeca8642d1e84afbd3f7d6820020...53b83947a5a98c8d113130e565377fae1a50d02f) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/basic-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index a086ff21d2c16..6e56d0100a648 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -160,7 +160,7 @@ jobs: version: 9 run_install: false - name: "Setup node" - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 with: node-version: 21 cache: 'pnpm' From 4b772766f83225014b7fe97a0400c553c4eb0e18 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 19:11:02 +0100 Subject: [PATCH 22/50] [v3-1-test] chore(deps): bump actions/setup-go from 5.5.0 to 6.3.0 (#63133) (#63138) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.5.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/d35c59abb061a4a6fb18e82ac0862c26744d6ab5...4b73464bb391d4059bd26b0524d20df3927bd417) (cherry picked from commit 274c2b0e6d3ab570ce780908dd04432704f85f14) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 7273d88ac7340f5070eb5669bcaae6f39a793a18 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Sun, 8 Mar 2026 19:26:36 +0100 Subject: [PATCH 23/50] [v3-1-test] chore(deps): bump actions/download-artifact from 4.3.0 to 8.0.0 (#63065) (#63145) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 8.0.0. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/d3f86a106a0bac45b974a628896c90dbdf5c8093...70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3) (cherry picked from commit 2f4646c3ed566e65ee17e644209893677b01a821) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-amd-arm.yml | 2 +- .github/workflows/ci-image-checks.yml | 2 +- .github/workflows/finalize-tests.yml | 2 +- .github/workflows/prod-image-build.yml | 17 +++++++++++++---- .github/workflows/publish-docs-to-s3.yml | 2 +- .github/workflows/push-image-cache.yml | 2 +- .../release_single_dockerhub_image.yml | 2 +- 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-amd-arm.yml b/.github/workflows/ci-amd-arm.yml index 3b2ad87a3869c..fcf319d708fcb 100644 --- a/.github/workflows/ci-amd-arm.yml +++ b/.github/workflows/ci-amd-arm.yml @@ -979,7 +979,7 @@ jobs: shell: bash run: ./scripts/tools/free_up_disk_space.sh - name: "Download all test warning artifacts from the current build" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: path: ./artifacts pattern: test-warnings-* diff --git a/.github/workflows/ci-image-checks.yml b/.github/workflows/ci-image-checks.yml index cf33b4633ecc2..7d23dce54a7d9 100644 --- a/.github/workflows/ci-image-checks.yml +++ b/.github/workflows/ci-image-checks.yml @@ -312,7 +312,7 @@ jobs: use-uv: ${{ inputs.use-uv }} make-mnt-writeable-and-cleanup: true - name: "Download docs prepared as artifacts" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: airflow-docs path: './generated/_build' diff --git a/.github/workflows/finalize-tests.yml b/.github/workflows/finalize-tests.yml index 0d9287f23f4fc..e814751f1cc79 100644 --- a/.github/workflows/finalize-tests.yml +++ b/.github/workflows/finalize-tests.yml @@ -114,7 +114,7 @@ jobs: persist-credentials: true fetch-depth: 0 - name: "Download constraints from the constraints generated by build CI image" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: pattern: constraints-* path: ./files diff --git a/.github/workflows/prod-image-build.yml b/.github/workflows/prod-image-build.yml index b20b76f7e1a6b..0c9a4162b0436 100644 --- a/.github/workflows/prod-image-build.yml +++ b/.github/workflows/prod-image-build.yml @@ -138,6 +138,13 @@ jobs: shell: bash run: rm -fv ./dist/* ./docker-context-files/* if: inputs.upload-package-artifact == 'true' + - name: "Install prek" + uses: ./.github/actions/install-prek + id: prek + with: + python-version: ${{ matrix.python-version }} + platform: ${{ inputs.platform }} + save-cache: false - name: "Install Breeze" uses: ./.github/actions/breeze if: inputs.upload-package-artifact == 'true' @@ -224,7 +231,7 @@ jobs: shell: bash run: rm -fv ./dist/* ./docker-context-files/* - name: "Download packages prepared as artifacts" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: prod-packages path: ./docker-context-files @@ -235,10 +242,12 @@ jobs: - name: "Show downloaded packages" run: ls -la ./docker-context-files - name: "Download constraints" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: - pattern: constraints-* - path: ./docker-context-files + name: constraints-${{ matrix.python-version }} + path: ./docker-context-files/constraints-${{ matrix.python-version }} + - name: "Show downloaded files" + run: ls -R ./docker-context-files - name: "Show constraints" run: | for file in ./docker-context-files/constraints*/constraints*.txt diff --git a/.github/workflows/publish-docs-to-s3.yml b/.github/workflows/publish-docs-to-s3.yml index 46db2f9287e18..4989b4888cfde 100644 --- a/.github/workflows/publish-docs-to-s3.yml +++ b/.github/workflows/publish-docs-to-s3.yml @@ -333,7 +333,7 @@ jobs: - name: "Install Breeze" uses: ./.github/actions/breeze - name: "Download docs prepared as artifacts" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: airflow-docs path: /mnt/airflow-site diff --git a/.github/workflows/push-image-cache.yml b/.github/workflows/push-image-cache.yml index 56d3cd1241b1d..1d06012e31034 100644 --- a/.github/workflows/push-image-cache.yml +++ b/.github/workflows/push-image-cache.yml @@ -192,7 +192,7 @@ jobs: - name: "Cleanup dist and context file" run: rm -fv ./dist/* ./docker-context-files/* - name: "Download packages prepared as artifacts" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: prod-packages path: ./docker-context-files diff --git a/.github/workflows/release_single_dockerhub_image.yml b/.github/workflows/release_single_dockerhub_image.yml index 0f0cebda8e2b5..d71a5a50d8b3b 100644 --- a/.github/workflows/release_single_dockerhub_image.yml +++ b/.github/workflows/release_single_dockerhub_image.yml @@ -189,7 +189,7 @@ jobs: ACTOR: ${{ github.actor }} run: echo "${GITHUB_TOKEN}" | docker login ghcr.io -u ${ACTOR} --password-stdin - name: "Download metadata artifacts" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: path: ./dist pattern: metadata-${{ inputs.pythonVersion }}-* From 6e99a3e0fdb0ca9ec2c373c223f91e7a1df84f6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 23:06:14 +0100 Subject: [PATCH 24/50] chore(deps): bump the github-actions-updates group with 2 updates (#63157) Bumps the github-actions-updates group with 2 updates: [pnpm/action-setup](https://github.com/pnpm/action-setup) and [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action). Updates `pnpm/action-setup` from 4.0.0 to 4.2.0 - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/fe02b34f77f8bc703788d5817da081398fad5dd2...41ff72655975bd51cab0327fa583b6e92b6d3061) Updates `slackapi/slack-github-action` from 2.0.0 to 2.1.1 - [Release notes](https://github.com/slackapi/slack-github-action/releases) - [Commits](https://github.com/slackapi/slack-github-action/compare/485a9d42d3a73031f12ec201c457e2162c45d02d...91efab103c0de0a537f72a35f6b8cda0ee76bf0a) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: slackapi/slack-github-action dependency-version: 2.1.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/basic-tests.yml | 2 +- .github/workflows/ci-amd-arm.yml | 2 +- .github/workflows/ci-notification.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index 6e56d0100a648..1202d6b1175bc 100644 --- a/.github/workflows/basic-tests.yml +++ b/.github/workflows/basic-tests.yml @@ -155,7 +155,7 @@ jobs: with: persist-credentials: false - name: Setup pnpm - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0 + uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 with: version: 9 run_install: false diff --git a/.github/workflows/ci-amd-arm.yml b/.github/workflows/ci-amd-arm.yml index fcf319d708fcb..99dbeaf15320a 100644 --- a/.github/workflows/ci-amd-arm.yml +++ b/.github/workflows/ci-amd-arm.yml @@ -932,7 +932,7 @@ jobs: steps: - name: Notify Slack id: slack - uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0 + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/ci-notification.yml b/.github/workflows/ci-notification.yml index 298c3fbeac139..e009e380e9277 100644 --- a/.github/workflows/ci-notification.yml +++ b/.github/workflows/ci-notification.yml @@ -58,7 +58,7 @@ jobs: - name: "Send Slack notification" if: steps.find-workflow-run-status.outputs.conclusion == 'failure' id: slack - uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0 + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 with: method: chat.postMessage token: ${{ env.SLACK_BOT_TOKEN }} From 5f57234967bf959732d6c0478126df41e9d79b03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 10:55:34 +0100 Subject: [PATCH 25/50] [v3-1-test] perf: use load_only() in get_dag_runs eager loading to reduce data fetched per task instance (#62482) (#62996) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: use load_only() in eager_load_dag_run_for_validation to reduce data fetched The get_dag_runs API endpoint was slow on large deployments because eager_load_dag_run_for_validation() used selectinload on task_instances and task_instances_histories without restricting which columns were fetched. This caused SQLAlchemy to load all heavyweight columns (executor_config with pickled data, hostname, rendered fields, etc.) for every task instance across every DAG run in the result page — even though only dag_version_id is needed to traverse the association proxy to DagVersion. Add load_only(TaskInstance.dag_version_id) and load_only(TaskInstanceHistory.dag_version_id) to the selectinload chains so the SELECT for task instances fetches only the identity columns and the FK needed to resolve the dag_version relationship, significantly reducing the volume of data transferred from the database on busy deployments. Fixes #62025 * Fix static checks --------- (cherry picked from commit 13af96b80868ef91ca623d35afcd76003bfbda90) Co-authored-by: Lakshmi Sravya <38032391+LakshmiSravyaVedantham@users.noreply.github.com> Co-authored-by: pierrejeambrun --- .../src/airflow/api_fastapi/common/db/dag_runs.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py index 2a5fb76c8b850..a9ccf6031c786 100644 --- a/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py +++ b/airflow-core/src/airflow/api_fastapi/common/db/dag_runs.py @@ -41,13 +41,24 @@ def eager_load_dag_run_for_validation() -> tuple[LoaderOption, ...]: - """Construct the eager loading options necessary for a DagRunResponse object.""" + """ + Construct the eager loading options necessary for a DagRunResponse object. + + For the list endpoint (get_dag_runs), loading all task instance columns is + wasteful because we only need the dag_version_id FK to traverse to DagVersion. + Using load_only() on TaskInstance and TaskInstanceHistory restricts the SELECT + to just the identity columns and dag_version_id, avoiding large intermediate + result sets caused by loading heavyweight columns (executor_config, etc.) for + every task instance across every DAG run returned by the query. + """ return ( joinedload(DagRun.dag_model), selectinload(DagRun.task_instances) + .load_only(TaskInstance.dag_version_id) .joinedload(TaskInstance.dag_version) .joinedload(DagVersion.bundle), selectinload(DagRun.task_instances_histories) + .load_only(TaskInstanceHistory.dag_version_id) .joinedload(TaskInstanceHistory.dag_version) .joinedload(DagVersion.bundle), joinedload(DagRun.dag_run_note), From b3672eae00bcc66bfbc0fb6e2aab579e67d75719 Mon Sep 17 00:00:00 2001 From: Pierre Jeambrun Date: Mon, 9 Mar 2026 10:58:36 +0100 Subject: [PATCH 26/50] perf(api): optimize /ui/dags endpoint serialization (#61483) (#63001) This PR addresses a significant performance issue in the /ui/dags endpoint where page load times scaled poorly with the number of DAGs (12-16 seconds for just 25 DAGs in our testing). Two optimizations are implemented: 1. Cache URLSafeSerializer for file_token generation - Previously, a new URLSafeSerializer was instantiated and conf.get_mandatory_value() was called for every DAG - Now uses @lru_cache to create the serializer once and reuse it 2. Eliminate redundant Pydantic validation in response construction - The original pattern used model_validate -> model_dump -> model_validate which caused triple serialization overhead per DAG - Now validates once with DAGResponse.model_validate(), then uses model_construct() to build DAGWithLatestDagRunsResponse Together, these changes reduced page load time from 12-16 seconds to ~130ms in our dev environment. (cherry picked from commit a915216434cf583b0b54eee129cc9a93b96492b2) Co-authored-by: john-rodriguez-mgni <107643943+john-rodriguez-mgni@users.noreply.github.com> Co-authored-by: Cursor --- .../api_fastapi/core_api/datamodels/dags.py | 17 +++++++++++++++-- .../api_fastapi/core_api/routes/ui/dags.py | 19 +++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py index 4cd3ed93817ea..294092c663995 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/dags.py @@ -20,6 +20,7 @@ import inspect from collections import abc from datetime import datetime, timedelta +from functools import cache from typing import Any from itsdangerous import URLSafeSerializer @@ -38,6 +39,19 @@ from airflow.configuration import conf from airflow.models.dag_version import DagVersion + +@cache +def _get_file_token_serializer() -> URLSafeSerializer: + """ + Return a cached URLSafeSerializer instance. + + Uses @cache for lazy initialization - the serializer is created on first + call rather than at module import time. This avoids issues if the module + is imported before configuration is fully loaded. + """ + return URLSafeSerializer(conf.get_mandatory_value("api", "secret_key")) + + DAG_ALIAS_MAPPING: dict[str, str] = { # The keys are the names in the response, the values are the original names in the model # This is used to map the names in the response to the names in the model @@ -113,12 +127,11 @@ def get_timetable_summary(cls, tts: str | None) -> str | None: @property def file_token(self) -> str: """Return file token.""" - serializer = URLSafeSerializer(conf.get_mandatory_value("api", "secret_key")) payload = { "bundle_name": self.bundle_name, "relative_fileloc": self.relative_fileloc, } - return serializer.dumps(payload) + return _get_file_token_serializer().dumps(payload) class DAGPatchBody(StrictBaseModel): diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py index e1af93e746ebb..b404534cc7f47 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/dags.py @@ -52,7 +52,7 @@ filter_param_factory, ) from airflow.api_fastapi.common.router import AirflowRouter -from airflow.api_fastapi.core_api.datamodels.dags import DAGResponse +from airflow.api_fastapi.core_api.datamodels.dags import DAG_ALIAS_MAPPING, DAGResponse from airflow.api_fastapi.core_api.datamodels.ui.dag_runs import DAGRunLightResponse from airflow.api_fastapi.core_api.datamodels.ui.dags import ( DAGWithLatestDagRunsCollectionResponse, @@ -234,18 +234,25 @@ def get_dags( pending_actions_by_dag_id[dag_id].append(hitl_detail) # aggregate rows by dag_id - dag_runs_by_dag_id: dict[str, DAGWithLatestDagRunsResponse] = { - dag.dag_id: DAGWithLatestDagRunsResponse.model_validate( + # Build the dict dynamically from DAGResponse.model_fields so that new fields + # added to DAGResponse are picked up automatically without code changes here. + dag_runs_by_dag_id: dict[str, DAGWithLatestDagRunsResponse] = {} + for dag in dags: + dag_data = { + DAG_ALIAS_MAPPING.get(field_name, field_name): getattr( + dag, DAG_ALIAS_MAPPING.get(field_name, field_name) + ) + for field_name in DAGResponse.model_fields + } + dag_data.update( { - **DAGResponse.model_validate(dag).model_dump(), "asset_expression": dag.asset_expression, "latest_dag_runs": [], "pending_actions": pending_actions_by_dag_id[dag.dag_id], "is_favorite": dag.dag_id in favorite_dag_ids, } ) - for dag in dags - } + dag_runs_by_dag_id[dag.dag_id] = DAGWithLatestDagRunsResponse.model_validate(dag_data) for row in recent_dag_runs: dag_run_response = DAGRunLightResponse.model_validate(row) From 46ea044eb56be69bea64bc608289f05b81fa246a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 14:28:08 +0200 Subject: [PATCH 27/50] [v3-1-test] Bump astroid>=4 (#63170) (#63174) (cherry picked from commit 0a985eabb8e108795d49333b4544847657d36c1a) Co-authored-by: Elad Kalif <45845474+eladkal@users.noreply.github.com> --- devel-common/pyproject.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/devel-common/pyproject.toml b/devel-common/pyproject.toml index 326ebe9853b78..596ef7bcb64e3 100644 --- a/devel-common/pyproject.toml +++ b/devel-common/pyproject.toml @@ -70,8 +70,7 @@ dependencies = [ "twine>=4.0.2", ] "docs" = [ - # Astroid 4 released 5 Oct 2025 breaks autoapi https://github.com/apache/airflow/issues/56420 - "astroid>=3,<4", + "astroid>=4", "checksumdir>=1.2.0", "rich-click>=1.7.1", "click>=8.1.8", @@ -82,7 +81,7 @@ dependencies = [ "pagefind-bin>=1.5.0a3", "sphinx-airflow-theme@https://airflow.apache.org/sphinx-airflow-theme/sphinx_airflow_theme-0.3.0-py3-none-any.whl", "sphinx-argparse>=0.4.0", - "sphinx-autoapi>=3", + "sphinx-autoapi>=3.8.0", "sphinx-autobuild>=2024.10.2", "sphinx-copybutton>=0.5.2", "sphinx-design>=0.5.0", From bdcd6ec37f6a19b26047ae800948635d47de3c98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 10:03:07 -0400 Subject: [PATCH 28/50] chore(deps): bump the core-ui-package-updates group across 1 directory with 2 updates (#63153) Bumps the core-ui-package-updates group with 1 update in the /airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui directory: [@chakra-ui/react](https://github.com/chakra-ui/chakra-ui/tree/HEAD/packages/react). Updates `@chakra-ui/react` from 3.33.0 to 3.34.0 - [Release notes](https://github.com/chakra-ui/chakra-ui/releases) - [Changelog](https://github.com/chakra-ui/chakra-ui/blob/main/packages/react/CHANGELOG.md) - [Commits](https://github.com/chakra-ui/chakra-ui/commits/@chakra-ui/react@3.34.0/packages/react) Updates `happy-dom` from 20.7.0 to 20.8.3 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v20.7.0...v20.8.3) --- updated-dependencies: - dependency-name: "@chakra-ui/react" dependency-version: 3.34.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: happy-dom dependency-version: 20.8.3 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../auth/managers/simple/ui/package-lock.json | 18 +++++++++--------- .../auth/managers/simple/ui/pnpm-lock.yaml | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json index 1113b9c475c6c..59156ec013bdf 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/package-lock.json @@ -8,7 +8,7 @@ "name": "simple-auth-manager-ui", "version": "0.0.0", "dependencies": { - "@chakra-ui/react": "^3.33.0", + "@chakra-ui/react": "^3.34.0", "@tanstack/react-query": "^5.90.21", "axios": "^1.13.5", "next-themes": "^0.4.6", @@ -41,7 +41,7 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-unicorn": "^63.0.0", - "happy-dom": "^20.7.0", + "happy-dom": "^20.8.3", "prettier": "^3.8.1", "ts-morph": "^27.0.2", "typescript": "~5.9.3", @@ -448,12 +448,12 @@ } }, "node_modules/@chakra-ui/react": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.33.0.tgz", - "integrity": "sha512-HNbUFsFABjVL5IHBxsqtuT+AH/vQT1+xsEWrxnG0GBM2VjlzlMqlqCxNiDyQOsjLZXQC1ciCMbzPNcSCc63Y9w==", + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.34.0.tgz", + "integrity": "sha512-VLhpVwv5IVxhwajO10KnS1VQT4hDqQMQP/A796Ya+uVu8AdoSX+5HHyTLTkYIeXIDMe0xLqJfov04OBKbBchJA==", "license": "MIT", "dependencies": { - "@ark-ui/react": "^5.31.0", + "@ark-ui/react": "^5.34.1", "@emotion/is-prop-valid": "^1.4.0", "@emotion/serialize": "^1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", @@ -6013,9 +6013,9 @@ } }, "node_modules/happy-dom": { - "version": "20.7.0", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.7.0.tgz", - "integrity": "sha512-hR/uLYQdngTyEfxnOoa+e6KTcfBFyc1hgFj/Cc144A5JJUuHFYqIEBDcD4FeGqUeKLRZqJ9eN9u7/GDjYEgS1g==", + "version": "20.8.3", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.8.3.tgz", + "integrity": "sha512-lMHQRRwIPyJ70HV0kkFT7jH/gXzSI7yDkQFe07E2flwmNDFoWUTRMKpW2sglsnpeA7b6S2TJPp98EbQxai8eaQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml index 13f042439aa91..3e4dcd2e75f43 100644 --- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml +++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock.yaml @@ -549,8 +549,8 @@ packages: '@jsdevtools/ono@7.1.3': resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} - '@pandacss/is-valid-prop@1.8.2': - resolution: {integrity: sha512-wfZ4kzvHXQ9pG3wuIGTUCcbC7Op8pqIQZNIRY/bqWQu67WTHxZUHUPSZgQMhguI8Tz4ot+DNf4Qhha0bhLvNEQ==} + '@pandacss/is-valid-prop@1.9.0': + resolution: {integrity: sha512-AZvpXWGyjbHc8TC+YVloQ31Z2c4j2xMvYj6UfVxuZdB5w4c9+4N8wy5R7I/XswNh8e4cfUlkvsEGDXjhJRgypw==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} @@ -3064,7 +3064,7 @@ snapshots: '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.4) '@emotion/utils': 1.4.2 - '@pandacss/is-valid-prop': 1.8.2 + '@pandacss/is-valid-prop': 1.9.0 csstype: 3.2.3 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -3330,7 +3330,7 @@ snapshots: '@jsdevtools/ono@7.1.3': {} - '@pandacss/is-valid-prop@1.8.2': {} + '@pandacss/is-valid-prop@1.9.0': {} '@pkgjs/parseargs@0.11.0': optional: true From 46778c07ccdf88fe5d73ce4a7d8e15b0e122b9a4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:59:57 +0100 Subject: [PATCH 29/50] [v3-1-test] Further limit setuptools after 82.0.1 is released (until redoc fixes it) (#63202) (#63203) (cherry picked from commit b528e502eff321ec07464fc9c0e05ede30c8d5aa) Co-authored-by: Jarek Potiuk --- devel-common/pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devel-common/pyproject.toml b/devel-common/pyproject.toml index 596ef7bcb64e3..f6d32fc99c6eb 100644 --- a/devel-common/pyproject.toml +++ b/devel-common/pyproject.toml @@ -98,7 +98,9 @@ dependencies = [ "sphinxcontrib-redoc>=1.6.0", "sphinxcontrib-serializinghtml>=1.1.5", "sphinxcontrib-spelling>=8.0.0", - "setuptools!=82.0.0", # until https://github.com/sphinx-contrib/redoc/issues/53 is resolved + # setuptools 82.0.0+ causes redoc to fail due to pkg_resources removal + # until https://github.com/sphinx-contrib/redoc/issues/53 is resolved + "setuptools<82.0.0", ] "docs-gen" = [ "diagrams>=0.24.4", From 4da5903b481190b6ac72df909f641f88a1020a26 Mon Sep 17 00:00:00 2001 From: Vincent <97131062+vincbeck@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:02:59 -0400 Subject: [PATCH 30/50] Fix race condition in auth manager initialization (#62431) (#62995) FAB FastAPI routes call get_application_builder() on every request, which creates a new Flask app and invokes init_app(). Concurrent calls race on the singleton auth_manager's appbuilder and security_manager, causing KeyError: 'AUTH_USER_REGISTRATION' and AttributeError. Add _init_app_lock around the critical section in init_app() that mutates the singleton auth_manager state and registers views, so concurrent get_application_builder() calls are serialized. Co-authored-by: Young-Ki Kim --- airflow-core/src/airflow/api_fastapi/app.py | 10 ++++-- .../tests/unit/api_fastapi/test_app.py | 35 +++++++++++++++++++ .../fab/www/extensions/init_appbuilder.py | 33 ++++++++++------- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/app.py b/airflow-core/src/airflow/api_fastapi/app.py index 3a61c7895c7b2..c13ea9ed675a3 100644 --- a/airflow-core/src/airflow/api_fastapi/app.py +++ b/airflow-core/src/airflow/api_fastapi/app.py @@ -17,6 +17,7 @@ from __future__ import annotations import logging +import threading from contextlib import AsyncExitStack, asynccontextmanager from functools import cache from typing import TYPE_CHECKING, cast @@ -68,6 +69,7 @@ def get_cookie_path() -> str: class _AuthManagerState: instance: BaseAuthManager | None = None + _lock = threading.Lock() @asynccontextmanager @@ -148,9 +150,13 @@ def get_auth_manager_cls() -> type[BaseAuthManager]: def create_auth_manager() -> BaseAuthManager: - """Create the auth manager.""" + """Create the auth manager, cached as a thread-safe singleton.""" auth_manager_cls = get_auth_manager_cls() - _AuthManagerState.instance = auth_manager_cls() + if _AuthManagerState.instance is not None and isinstance(_AuthManagerState.instance, auth_manager_cls): + return _AuthManagerState.instance + with _AuthManagerState._lock: + if _AuthManagerState.instance is None or not isinstance(_AuthManagerState.instance, auth_manager_cls): + _AuthManagerState.instance = auth_manager_cls() return _AuthManagerState.instance diff --git a/airflow-core/tests/unit/api_fastapi/test_app.py b/airflow-core/tests/unit/api_fastapi/test_app.py index cd43260211bc5..d4d3e8999cea7 100644 --- a/airflow-core/tests/unit/api_fastapi/test_app.py +++ b/airflow-core/tests/unit/api_fastapi/test_app.py @@ -16,6 +16,7 @@ # under the License. from __future__ import annotations +import threading from unittest import mock import pytest @@ -140,3 +141,37 @@ def test_nested_subpath(self): """When base_url contains a nested subpath, get_cookie_path() should return it.""" with mock.patch.object(app_module, "API_ROOT_PATH", "/org/team-a/airflow/"): assert app_module.get_cookie_path() == "/org/team-a/airflow/" + + +def test_create_auth_manager_thread_safety(): + """Concurrent calls to create_auth_manager must return the same singleton instance.""" + call_count = 0 + singleton = None + + class FakeAuthManager: + def __init__(self): + nonlocal call_count, singleton + call_count += 1 + singleton = self + + app_module.purge_cached_app() + + results = [] + barrier = threading.Barrier(10) + + def call_create_auth_manager(): + barrier.wait() + results.append(app_module.create_auth_manager()) + + with mock.patch.object(app_module, "get_auth_manager_cls", return_value=FakeAuthManager): + threads = [threading.Thread(target=call_create_auth_manager) for _ in range(10)] + for t in threads: + t.start() + for t in threads: + t.join() + + assert len(results) == 10 + assert all(r is singleton for r in results) + assert call_count == 1 + + app_module.purge_cached_app() diff --git a/providers/fab/src/airflow/providers/fab/www/extensions/init_appbuilder.py b/providers/fab/src/airflow/providers/fab/www/extensions/init_appbuilder.py index 5c510984480fa..59b60c9ff6cae 100644 --- a/providers/fab/src/airflow/providers/fab/www/extensions/init_appbuilder.py +++ b/providers/fab/src/airflow/providers/fab/www/extensions/init_appbuilder.py @@ -19,6 +19,7 @@ from __future__ import annotations import logging +import threading from functools import reduce from typing import TYPE_CHECKING @@ -57,6 +58,8 @@ # This module contains code imported from FlaskAppbuilder, so lets use _its_ logger name log = logging.getLogger("flask_appbuilder.base") +_init_app_lock = threading.Lock() + def dynamic_class_import(class_path): """ @@ -197,19 +200,23 @@ def init_app(self, app, session): self._addon_managers = app.config["ADDON_MANAGERS"] self.session = session auth_manager = create_auth_manager() - auth_manager.appbuilder = self - if hasattr(auth_manager, "init_flask_resources"): - auth_manager.init_flask_resources() - if hasattr(auth_manager, "security_manager"): - self.sm = auth_manager.security_manager - else: - self.sm = AirflowSecurityManagerV2(self) - self.bm = BabelManager(self) - self._add_global_static() - self._add_global_filters() - app.before_request(self.sm.before_request) - self._add_admin_views() - self._add_addon_views() + with _init_app_lock: + auth_manager.appbuilder = self + # Invalidate cached security_manager so it binds to the current Flask app. + if "security_manager" in auth_manager.__dict__: + del auth_manager.__dict__["security_manager"] + if hasattr(auth_manager, "init_flask_resources"): + auth_manager.init_flask_resources() + if hasattr(auth_manager, "security_manager"): + self.sm = auth_manager.security_manager + else: + self.sm = AirflowSecurityManagerV2(self) + self.bm = BabelManager(self) + self._add_global_static() + self._add_global_filters() + app.before_request(self.sm.before_request) + self._add_admin_views() + self._add_addon_views() self._init_extension(app) self._swap_url_filter() From edd734b60875b8237a252aac8bc094f05d593855 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 22:06:32 +0100 Subject: [PATCH 31/50] chore(deps): bump github/codeql-action (#63223) Bumps the github-actions-updates group with 1 update: [github/codeql-action](https://github.com/github/codeql-action). Updates `github/codeql-action` from 3.29.0 to 4.32.6 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/ce28f5bb42b7a9f2c824e633a3f6ee835bab6858...0d579ffd059c29b07949a3cce3983f0780820c98) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.32.6 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e06caa5dfb03b..97ca768720c9b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -52,12 +52,12 @@ jobs: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + uses: github/codeql-action/autobuild@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 + uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 From 9cbc32192f5a2c65b461b939338051a83458ef91 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:17:12 +0100 Subject: [PATCH 32/50] [v3-1-test] Clarify docs on max_active_tasks parameter on a Dag (#63217) (#63228) (cherry picked from commit 9ae1875a19a84d8f55948dd85c872ee89ce86036) Co-authored-by: Jens Scheffler <95105677+jscheffl@users.noreply.github.com> --- task-sdk/src/airflow/sdk/definitions/dag.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/task-sdk/src/airflow/sdk/definitions/dag.py b/task-sdk/src/airflow/sdk/definitions/dag.py index e8d954e880a1a..ac96108f123f9 100644 --- a/task-sdk/src/airflow/sdk/definitions/dag.py +++ b/task-sdk/src/airflow/sdk/definitions/dag.py @@ -327,7 +327,7 @@ class DAG: accessible in templates, namespaced under `params`. These params can be overridden at the task level. :param max_active_tasks: the number of task instances allowed to run - concurrently + concurrently per Dag run. Note that in Airflow 2 this was a global limit on the Dag, since Airflow 3 it is per run. :param max_active_runs: maximum number of active DAG runs, beyond this number of DAG runs in a running state, the scheduler won't create new active DAG runs From 8cb7e13dd8f3786a2c2648f3117fe69c851cb7c0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:44:29 +0100 Subject: [PATCH 33/50] [v3-1-test] Fix undefined variable in install_from_external_spec error message (#63233) (#63237) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error message in install_from_external_spec() referenced ${INSTALLATION_METHOD} which does not exist — the correct variable is ${AIRFLOW_INSTALLATION_METHOD}. With set -u active, hitting this error path would crash with an "unbound variable" error instead of printing the intended user-friendly message. The typo was introduced in a1717a652b and carried forward into the inlined copies in both Dockerfiles. (cherry picked from commit 2ab6f9490dfbc205d1176d3d5dc1204d206f5397) Co-authored-by: Xiaodong DENG --- Dockerfile | 2 +- Dockerfile.ci | 2 +- scripts/docker/install_airflow_when_building_images.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4ae1247f4adc7..4f052181f3574 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1202,7 +1202,7 @@ function install_from_external_spec() { installation_command_flags="apache-airflow[${AIRFLOW_EXTRAS}]${AIRFLOW_VERSION_SPECIFICATION}" else echo - echo "${COLOR_RED}The '${INSTALLATION_METHOD}' installation method is not supported${COLOR_RESET}" + echo "${COLOR_RED}The '${AIRFLOW_INSTALLATION_METHOD}' installation method is not supported${COLOR_RESET}" echo echo "${COLOR_YELLOW}Supported methods are ('.', 'apache-airflow')${COLOR_RESET}" echo diff --git a/Dockerfile.ci b/Dockerfile.ci index c9e3c2ede38d0..d871ad2bcc365 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -937,7 +937,7 @@ function install_from_external_spec() { installation_command_flags="apache-airflow[${AIRFLOW_EXTRAS}]${AIRFLOW_VERSION_SPECIFICATION}" else echo - echo "${COLOR_RED}The '${INSTALLATION_METHOD}' installation method is not supported${COLOR_RESET}" + echo "${COLOR_RED}The '${AIRFLOW_INSTALLATION_METHOD}' installation method is not supported${COLOR_RESET}" echo echo "${COLOR_YELLOW}Supported methods are ('.', 'apache-airflow')${COLOR_RESET}" echo diff --git a/scripts/docker/install_airflow_when_building_images.sh b/scripts/docker/install_airflow_when_building_images.sh index 40f5b7cba1575..bec13ca2a5d39 100644 --- a/scripts/docker/install_airflow_when_building_images.sh +++ b/scripts/docker/install_airflow_when_building_images.sh @@ -147,7 +147,7 @@ function install_from_external_spec() { installation_command_flags="apache-airflow[${AIRFLOW_EXTRAS}]${AIRFLOW_VERSION_SPECIFICATION}" else echo - echo "${COLOR_RED}The '${INSTALLATION_METHOD}' installation method is not supported${COLOR_RESET}" + echo "${COLOR_RED}The '${AIRFLOW_INSTALLATION_METHOD}' installation method is not supported${COLOR_RESET}" echo echo "${COLOR_YELLOW}Supported methods are ('.', 'apache-airflow')${COLOR_RESET}" echo From d9aea9b5bb9b2538e3897b6bf44a9ea231cf01c1 Mon Sep 17 00:00:00 2001 From: Pierre Jeambrun Date: Tue, 10 Mar 2026 14:16:38 +0100 Subject: [PATCH 34/50] [v3-1-test] Fix grid view URL for dynamic task groups (#63205) (#63254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Unhandled Exception in remote logging if connection doesn't exist(#59801) (#62979) Cherry-picked from 3428dc9 with conflict resolution: - context.py: Added `import inspect` (skip `import functools` as `from functools import cache` already exists) - supervisor.py: Adopted early-return pattern and explicit `del` for GC, kept simpler env var handling (no `_AIRFLOW_PROCESS_CONTEXT` which doesn't exist in v3-1-test) - test_supervisor.py: Replaced `@pytest.mark.xfail` workaround with proper `use_real_secrets_backends` fixture Co-authored-by: Claude Opus 4.6 * CI: Upgrade important CI environment (#62981) * chore(deps-dev): bump the core-ui-package-updates group across 1 directory with 3 updates (#62968) Bumps the core-ui-package-updates group with 1 update in the /airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui directory: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin). Updates `@typescript-eslint/eslint-plugin` from 8.50.0 to 8.56.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.50.0 to 8.56.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/parser) Updates `ts-morph` from 23.0.0 to 27.0.2 - [Release notes](https://github.com/dsherret/ts-morph/releases) - [Commits](https://github.com/dsherret/ts-morph/compare/23.0.0...27.0.2) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: "@typescript-eslint/parser" dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: ts-morph dependency-version: 27.0.2 dependency-type: direct:development update-type: version-update:semver-major dependency-group: core-ui-package-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [v3-1-test] fix: gracefully handle 404 from worker log server for historical retry attempts (#62475) (#63000) * fix: gracefully handle 404 from worker log server for historical retry attempts (cherry picked from commit 25e9284a1ded0cf3bdd819591894c50b743d479a) Co-authored-by: Pradeep Kalluri <128097794+kalluripradeep@users.noreply.github.com> * [v3-1-test] Remove issue_number option from newsfragment guidance in PR template (#63006) (#63012) The CI workflow added in #62975 validates that newsfragment filenames use the PR number, so allowing issue numbers would cause false CI failures. Align the PR template with the contributing docs and the new validation. (cherry picked from commit 41969f4cf7cbff91ebd834f5f1fd7ea53c039915) Co-authored-by: Xiaodong DENG * [v3-1-test] CI: Upgrade important CI environment (#62989) (#63005) * [v3-1-test] CI: Upgrade important CI environment (#62989) (cherry picked from commit 60b52b78d74b0eab02e7b7597f947df32adbfd1b) Co-authored-by: Jarek Potiuk * Fix rebase --------- Co-authored-by: Jarek Potiuk * [v3-1-test] Align integration LocalStack docker-compose with e2e LocalStack config (#62980) (#62993) (cherry picked from commit 6722c4b3559259591cdc69f76319e1811602956e) Co-authored-by: Jason(Zhe-You) Liu <68415893+jason810496@users.noreply.github.com> * [v3-1-test] Fallback to no constraint builds for docker-context-files installation (#63051) (#63057) When building PROD from docker-context-files - i.e. when we run main build with providers built from sources, we should fall back to no constraints build when there is a conflict with constraints. This is a follow up after #62378 (cherry picked from commit fef2e62d6b730a31f5050295d9d1193d63e92fe7) Co-authored-by: Jarek Potiuk * Fill Turkish Translation Gap in v3-1-test (#63010) * Remove global from FastAPI app.py (#59772) (#62997) * Remove global from FastAPI app.py * Remove global from FastAPI app.py Co-authored-by: Jens Scheffler <95105677+jscheffl@users.noreply.github.com> * chore(deps): bump actions/setup-java from 4.7.1 to 5.2.0 (#63102) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4.7.1 to 5.2.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/c5195efecf7bdfc987ee8bae7a71cb8b11521c00...be666c2fcd27ec809703dec50e508c2fdc7f6654) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: 5.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/stale from 9.1.0 to 10.2.0 (#63099) Bumps [actions/stale](https://github.com/actions/stale) from 9.1.0 to 10.2.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/5bef64f19d7facfb25b37b414482c7164d639639...b5d41d4e1d5dceea10e7104786b73624c18a190f) --- updated-dependencies: - dependency-name: actions/stale dependency-version: 10.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/checkout from 4.2.2 to 6.0.2 (#63096) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 6.0.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/11bd71901bbe5b1630ceea73d27597364c9af683...de0fac2e4500dabe0009e67214ff5f5447ce83dd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/setup-python from 5.6.0 to 6.2.0 (#63098) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.6.0 to 6.2.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/a26af69be951a213d495a4c3e4e4022e16d87065...a309ff8b426b58ec0e2a45f0f869d46889d02405) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/github-script from 7.0.1 to 8.0.0 (#63090) Bumps [actions/github-script](https://github.com/actions/github-script) from 7.0.1 to 8.0.0. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/60a0d83039c74a4aee543508d2ffcb1c3799cdea...ed597411d8f924073f98dfc5c65a23a2325f34cd) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [v3-1-test] Split npm dependabot minor+patch and major version PRs (#62889) (#63007) * Ignore major npm dependabot upgrades * Move major versions to different group (cherry picked from commit a2e3613cd074017db1241f75f99f27f2d0b955dd) Co-authored-by: Brent Bovenzi * chore(deps): bump the core-ui-package-updates group across 1 directory with 2 updates (#63069) Bumps the core-ui-package-updates group with 2 updates in the /airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui directory: [@chakra-ui/react](https://github.com/chakra-ui/chakra-ui/tree/HEAD/packages/react) and [happy-dom](https://github.com/capricorn86/happy-dom). Updates `@chakra-ui/react` from 3.33.0 to 3.34.0 - [Release notes](https://github.com/chakra-ui/chakra-ui/releases) - [Changelog](https://github.com/chakra-ui/chakra-ui/blob/main/packages/react/CHANGELOG.md) - [Commits](https://github.com/chakra-ui/chakra-ui/commits/@chakra-ui/react@3.34.0/packages/react) Updates `happy-dom` from 20.7.0 to 20.8.3 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v20.7.0...v20.8.3) --- updated-dependencies: - dependency-name: "@chakra-ui/react" dependency-version: 3.34.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: happy-dom dependency-version: 20.8.3 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.0 (#63128) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/setup-go from 5.5.0 to 6.3.0 (#63124) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.5.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/d35c59abb061a4a6fb18e82ac0862c26744d6ab5...4b73464bb391d4059bd26b0524d20df3927bd417) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump aws-actions/configure-aws-credentials (#63123) Bumps [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) from 4.0.1 to 6.0.0. - [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases) - [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/010d0da01d0b5a38af31e9c3470dbfdabdecca3a...8df5847569e6427dd6c4fb1cf565c83acfa8afa7) --- updated-dependencies: - dependency-name: aws-actions/configure-aws-credentials dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/setup-node from 4.4.0 to 6.3.0 (#63119) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.4.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/49933ea5288caeca8642d1e84afbd3f7d6820020...53b83947a5a98c8d113130e565377fae1a50d02f) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [v3-1-test] chore(deps): bump actions/setup-go from 5.5.0 to 6.3.0 (#63133) (#63138) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.5.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/d35c59abb061a4a6fb18e82ac0862c26744d6ab5...4b73464bb391d4059bd26b0524d20df3927bd417) (cherry picked from commit 274c2b0e6d3ab570ce780908dd04432704f85f14) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [v3-1-test] chore(deps): bump actions/download-artifact from 4.3.0 to 8.0.0 (#63065) (#63145) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 8.0.0. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/d3f86a106a0bac45b974a628896c90dbdf5c8093...70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3) (cherry picked from commit 2f4646c3ed566e65ee17e644209893677b01a821) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the github-actions-updates group with 2 updates (#63157) Bumps the github-actions-updates group with 2 updates: [pnpm/action-setup](https://github.com/pnpm/action-setup) and [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action). Updates `pnpm/action-setup` from 4.0.0 to 4.2.0 - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/fe02b34f77f8bc703788d5817da081398fad5dd2...41ff72655975bd51cab0327fa583b6e92b6d3061) Updates `slackapi/slack-github-action` from 2.0.0 to 2.1.1 - [Release notes](https://github.com/slackapi/slack-github-action/releases) - [Commits](https://github.com/slackapi/slack-github-action/compare/485a9d42d3a73031f12ec201c457e2162c45d02d...91efab103c0de0a537f72a35f6b8cda0ee76bf0a) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates - dependency-name: slackapi/slack-github-action dependency-version: 2.1.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [v3-1-test] perf: use load_only() in get_dag_runs eager loading to reduce data fetched per task instance (#62482) (#62996) * perf: use load_only() in eager_load_dag_run_for_validation to reduce data fetched The get_dag_runs API endpoint was slow on large deployments because eager_load_dag_run_for_validation() used selectinload on task_instances and task_instances_histories without restricting which columns were fetched. This caused SQLAlchemy to load all heavyweight columns (executor_config with pickled data, hostname, rendered fields, etc.) for every task instance across every DAG run in the result page — even though only dag_version_id is needed to traverse the association proxy to DagVersion. Add load_only(TaskInstance.dag_version_id) and load_only(TaskInstanceHistory.dag_version_id) to the selectinload chains so the SELECT for task instances fetches only the identity columns and the FK needed to resolve the dag_version relationship, significantly reducing the volume of data transferred from the database on busy deployments. Fixes #62025 * Fix static checks --------- (cherry picked from commit 13af96b80868ef91ca623d35afcd76003bfbda90) Co-authored-by: Lakshmi Sravya <38032391+LakshmiSravyaVedantham@users.noreply.github.com> Co-authored-by: pierrejeambrun * perf(api): optimize /ui/dags endpoint serialization (#61483) (#63001) This PR addresses a significant performance issue in the /ui/dags endpoint where page load times scaled poorly with the number of DAGs (12-16 seconds for just 25 DAGs in our testing). Two optimizations are implemented: 1. Cache URLSafeSerializer for file_token generation - Previously, a new URLSafeSerializer was instantiated and conf.get_mandatory_value() was called for every DAG - Now uses @lru_cache to create the serializer once and reuse it 2. Eliminate redundant Pydantic validation in response construction - The original pattern used model_validate -> model_dump -> model_validate which caused triple serialization overhead per DAG - Now validates once with DAGResponse.model_validate(), then uses model_construct() to build DAGWithLatestDagRunsResponse Together, these changes reduced page load time from 12-16 seconds to ~130ms in our dev environment. (cherry picked from commit a915216434cf583b0b54eee129cc9a93b96492b2) Co-authored-by: john-rodriguez-mgni <107643943+john-rodriguez-mgni@users.noreply.github.com> Co-authored-by: Cursor * [v3-1-test] Bump astroid>=4 (#63170) (#63174) (cherry picked from commit 0a985eabb8e108795d49333b4544847657d36c1a) Co-authored-by: Elad Kalif <45845474+eladkal@users.noreply.github.com> * chore(deps): bump the core-ui-package-updates group across 1 directory with 2 updates (#63153) Bumps the core-ui-package-updates group with 1 update in the /airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui directory: [@chakra-ui/react](https://github.com/chakra-ui/chakra-ui/tree/HEAD/packages/react). Updates `@chakra-ui/react` from 3.33.0 to 3.34.0 - [Release notes](https://github.com/chakra-ui/chakra-ui/releases) - [Changelog](https://github.com/chakra-ui/chakra-ui/blob/main/packages/react/CHANGELOG.md) - [Commits](https://github.com/chakra-ui/chakra-ui/commits/@chakra-ui/react@3.34.0/packages/react) Updates `happy-dom` from 20.7.0 to 20.8.3 - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v20.7.0...v20.8.3) --- updated-dependencies: - dependency-name: "@chakra-ui/react" dependency-version: 3.34.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: core-ui-package-updates - dependency-name: happy-dom dependency-version: 20.8.3 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: core-ui-package-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [v3-1-test] Further limit setuptools after 82.0.1 is released (until redoc fixes it) (#63202) (#63203) (cherry picked from commit b528e502eff321ec07464fc9c0e05ede30c8d5aa) Co-authored-by: Jarek Potiuk * Fix race condition in auth manager initialization (#62431) (#62995) FAB FastAPI routes call get_application_builder() on every request, which creates a new Flask app and invokes init_app(). Concurrent calls race on the singleton auth_manager's appbuilder and security_manager, causing KeyError: 'AUTH_USER_REGISTRATION' and AttributeError. Add _init_app_lock around the critical section in init_app() that mutates the singleton auth_manager state and registers views, so concurrent get_application_builder() calls are serialized. Co-authored-by: Young-Ki Kim * chore(deps): bump github/codeql-action (#63223) Bumps the github-actions-updates group with 1 update: [github/codeql-action](https://github.com/github/codeql-action). Updates `github/codeql-action` from 3.29.0 to 4.32.6 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/ce28f5bb42b7a9f2c824e633a3f6ee835bab6858...0d579ffd059c29b07949a3cce3983f0780820c98) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.32.6 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [v3-1-test] Clarify docs on max_active_tasks parameter on a Dag (#63217) (#63228) (cherry picked from commit 9ae1875a19a84d8f55948dd85c872ee89ce86036) Co-authored-by: Jens Scheffler <95105677+jscheffl@users.noreply.github.com> * [v3-1-test] Fix undefined variable in install_from_external_spec error message (#63233) (#63237) The error message in install_from_external_spec() referenced ${INSTALLATION_METHOD} which does not exist — the correct variable is ${AIRFLOW_INSTALLATION_METHOD}. With set -u active, hitting this error path would crash with an "unbound variable" error instead of printing the intended user-friendly message. The typo was introduced in a1717a652b and carried forward into the inlined copies in both Dockerfiles. (cherry picked from commit 2ab6f9490dfbc205d1176d3d5dc1204d206f5397) Co-authored-by: Xiaodong DENG * Fix grid view URL for dynamic task groups (#63205) Dynamic task groups with isMapped=true were getting /mapped appended to their URL in the grid view, producing URLs like /tasks/group/{groupId}/mapped which has no matching route (404). The graph view correctly handles this by not appending /mapped for groups. This fix adds the same guard to buildTaskInstanceUrl. closes: #63197 (cherry picked from commit 7bc23ef3b564b0b6d1069411b38aee01473266fe) --------- Signed-off-by: dependabot[bot] Co-authored-by: Dev-iL <6509619+Dev-iL@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 Co-authored-by: Wei Lee Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Pradeep Kalluri <128097794+kalluripradeep@users.noreply.github.com> Co-authored-by: Xiaodong DENG Co-authored-by: Bugra Ozturk Co-authored-by: Jarek Potiuk Co-authored-by: Jason(Zhe-You) Liu <68415893+jason810496@users.noreply.github.com> Co-authored-by: Vincent <97131062+vincbeck@users.noreply.github.com> Co-authored-by: Jens Scheffler <95105677+jscheffl@users.noreply.github.com> Co-authored-by: Brent Bovenzi Co-authored-by: Lakshmi Sravya <38032391+LakshmiSravyaVedantham@users.noreply.github.com> Co-authored-by: john-rodriguez-mgni <107643943+john-rodriguez-mgni@users.noreply.github.com> Co-authored-by: Cursor Co-authored-by: Elad Kalif <45845474+eladkal@users.noreply.github.com> Co-authored-by: Young-Ki Kim Co-authored-by: Subham --- airflow-core/newsfragments/63205.bugfix.rst | 1 + .../src/airflow/ui/src/utils/links.test.ts | 19 +++++++++++++++++-- .../src/airflow/ui/src/utils/links.ts | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 airflow-core/newsfragments/63205.bugfix.rst diff --git a/airflow-core/newsfragments/63205.bugfix.rst b/airflow-core/newsfragments/63205.bugfix.rst new file mode 100644 index 0000000000000..7e1781bc8ed32 --- /dev/null +++ b/airflow-core/newsfragments/63205.bugfix.rst @@ -0,0 +1 @@ +Fix grid view URL for dynamic task groups producing 404 by not appending ``/mapped`` to group URLs. diff --git a/airflow-core/src/airflow/ui/src/utils/links.test.ts b/airflow-core/src/airflow/ui/src/utils/links.test.ts index 47dd032ebc519..75d175e22a599 100644 --- a/airflow-core/src/airflow/ui/src/utils/links.test.ts +++ b/airflow-core/src/airflow/ui/src/utils/links.test.ts @@ -243,7 +243,7 @@ describe("buildTaskInstanceUrl", () => { }), ).toBe("/dags/new_dag/runs/new_run/tasks/group/new_group"); - // Groups should never preserve tabs even for mapped groups + // Groups should never get /mapped appended — no such route exists for task groups expect( buildTaskInstanceUrl({ currentPathname: "/dags/old/runs/old/tasks/group/old_group/events", @@ -254,6 +254,21 @@ describe("buildTaskInstanceUrl", () => { runId: "new_run", taskId: "new_group", }), - ).toBe("/dags/new_dag/runs/new_run/tasks/group/new_group/mapped/3"); + ).toBe("/dags/new_dag/runs/new_run/tasks/group/new_group"); + }); + + it("should not append /mapped for dynamic task groups from grid view", () => { + // Regression test for https://github.com/apache/airflow/issues/63197 + // Dynamic task groups have isMapped=true but no route exists for group/:groupId/mapped + expect( + buildTaskInstanceUrl({ + currentPathname: "/dags/my_dag/runs/run_1/tasks/group/my_group", + dagId: "my_dag", + isGroup: true, + isMapped: true, + runId: "run_1", + taskId: "my_group", + }), + ).toBe("/dags/my_dag/runs/run_1/tasks/group/my_group"); }); }); diff --git a/airflow-core/src/airflow/ui/src/utils/links.ts b/airflow-core/src/airflow/ui/src/utils/links.ts index 3beafb06afea1..23c438721a5b8 100644 --- a/airflow-core/src/airflow/ui/src/utils/links.ts +++ b/airflow-core/src/airflow/ui/src/utils/links.ts @@ -89,7 +89,7 @@ export const buildTaskInstanceUrl = (params: { let basePath = `/dags/${dagId}/runs/${runId}/tasks/${groupPath}${taskId}`; - if (isMapped) { + if (isMapped && !isGroup) { basePath += `/mapped`; if (mapIndex !== undefined && mapIndex !== "-1") { basePath += `/${mapIndex}`; From 06385323287f1cff41d4ee2dc31a3b76de75f3d4 Mon Sep 17 00:00:00 2001 From: Wei Lee Date: Tue, 10 Mar 2026 23:20:34 +0800 Subject: [PATCH 35/50] fix(migration): disable disable_sqlite_fkeys for migration 0087 (#63256) (#63272) (cherry picked from commit bbf289779ca91f5b03772908743d8a5804487b84) --- airflow-core/docs/img/airflow_erd.sha256 | 2 +- airflow-core/docs/img/airflow_erd.svg | 120 +++++++++--------- ...hange_signed_url_template_from_varchar_.py | 38 +++--- 3 files changed, 79 insertions(+), 81 deletions(-) diff --git a/airflow-core/docs/img/airflow_erd.sha256 b/airflow-core/docs/img/airflow_erd.sha256 index 5b0452f2453de..ea41374282a5f 100644 --- a/airflow-core/docs/img/airflow_erd.sha256 +++ b/airflow-core/docs/img/airflow_erd.sha256 @@ -1 +1 @@ -a222f120b40cc9c82870945a44f9ba6a2aabce378716b5f0ced55c28e57c2bb6 \ No newline at end of file +623beee8d78f46ec2160d0e9142ff89535b67cb1828c5df1f940f1a260ef8046 \ No newline at end of file diff --git a/airflow-core/docs/img/airflow_erd.svg b/airflow-core/docs/img/airflow_erd.svg index 00b4126c30b54..bfc639a1a3ee4 100644 --- a/airflow-core/docs/img/airflow_erd.svg +++ b/airflow-core/docs/img/airflow_erd.svg @@ -238,7 +238,7 @@ NOT NULL - + dag_bundle:name--dag_bundle_team:dag_bundle_name 0..N @@ -383,7 +383,7 @@ NOT NULL - + team:id--dag_bundle_team:team_id 0..N @@ -572,7 +572,7 @@ NOT NULL - + asset_alias:id--asset_alias_asset:alias_id 0..N @@ -595,7 +595,7 @@ NOT NULL - + asset_alias:id--asset_alias_asset_event:alias_id 0..N @@ -676,7 +676,7 @@ NOT NULL - + asset:id--asset_alias_asset:asset_id 0..N @@ -723,18 +723,18 @@ -asset:uri--asset_active:uri - -1 -1 - - - asset:name--asset_active:name 1 1 + + +asset:uri--asset_active:uri + +1 +1 + dag_schedule_asset_reference @@ -762,7 +762,7 @@ NOT NULL - + asset:id--dag_schedule_asset_reference:asset_id 0..N @@ -838,7 +838,7 @@ NOT NULL - + asset:id--task_inlet_asset_reference:asset_id 0..N @@ -915,7 +915,7 @@ NOT NULL - + asset_event:id--asset_alias_asset_event:event_id 0..N @@ -1184,7 +1184,7 @@ [INTEGER] - + trigger:id--deadline:trigger_id 0..N @@ -1254,7 +1254,7 @@ 1 - + dag:dag_id--dag_schedule_asset_reference:dag_id 0..N @@ -1268,7 +1268,7 @@ 1 - + dag:dag_id--task_inlet_asset_reference:dag_id 0..N @@ -1552,7 +1552,7 @@ [TIMESTAMP] - + dag_version:id--dag_run:created_dag_version_id 0..N @@ -1696,7 +1696,7 @@ NOT NULL - + log_template:id--dag_run:log_template_id 0..N @@ -1724,7 +1724,7 @@ 1 - + dag_run:id--deadline:dagrun_id 0..N @@ -1765,7 +1765,7 @@ NOT NULL - + dag_run:id--backfill_dag_run:dag_run_id 0..N @@ -1878,7 +1878,7 @@ {0,1} - + backfill:id--backfill_dag_run:backfill_id 0..N @@ -1992,19 +1992,19 @@ -task_instance:run_id--task_map:run_id - -0..N -1 - - - task_instance:dag_id--task_map:dag_id 0..N 1 + +task_instance:task_id--task_map:task_id + +0..N +1 + + task_instance:map_index--task_map:map_index @@ -2013,10 +2013,10 @@ -task_instance:task_id--task_map:task_id - -0..N -1 +task_instance:run_id--task_map:run_id + +0..N +1 @@ -2115,25 +2115,25 @@ +task_instance:run_id--xcom:run_id + +0..N +1 + + + task_instance:task_id--xcom:task_id 0..N 1 - + task_instance:map_index--xcom:map_index 0..N 1 - - -task_instance:run_id--xcom:run_id - -0..N -1 - task_instance_note @@ -2338,19 +2338,19 @@ -task_instance:map_index--task_instance_history:map_index - -0..N -1 - - - task_instance:run_id--task_instance_history:run_id 0..N 1 + +task_instance:map_index--task_instance_history:map_index + +0..N +1 + + task_instance:dag_id--task_instance_history:dag_id @@ -2394,19 +2394,19 @@ +task_instance:task_id--rendered_task_instance_fields:task_id + +0..N +1 + + + task_instance:map_index--rendered_task_instance_fields:map_index 0..N 1 - -task_instance:dag_id--rendered_task_instance_fields:dag_id - -0..N -1 - - task_instance:run_id--rendered_task_instance_fields:run_id @@ -2415,10 +2415,10 @@ -task_instance:task_id--rendered_task_instance_fields:task_id - -0..N -1 +task_instance:dag_id--rendered_task_instance_fields:dag_id + +0..N +1 diff --git a/airflow-core/src/airflow/migrations/versions/0087_3_1_8_change_signed_url_template_from_varchar_.py b/airflow-core/src/airflow/migrations/versions/0087_3_1_8_change_signed_url_template_from_varchar_.py index 9fae0722c8ca3..7966e10d1f2f2 100644 --- a/airflow-core/src/airflow/migrations/versions/0087_3_1_8_change_signed_url_template_from_varchar_.py +++ b/airflow-core/src/airflow/migrations/versions/0087_3_1_8_change_signed_url_template_from_varchar_.py @@ -30,6 +30,8 @@ import sqlalchemy as sa from alembic import op +from airflow.migrations.utils import disable_sqlite_fkeys + # revision identifiers, used by Alembic. revision = "509b94a1042d" down_revision = "82dbd68e6171" @@ -40,27 +42,23 @@ def upgrade(): """Apply Change signed_url_template from VARCHAR(200) to TEXT.""" - # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table("dag_bundle", schema=None) as batch_op: - batch_op.alter_column( - "signed_url_template", - existing_type=sa.VARCHAR(length=200), - type_=sa.Text(), - existing_nullable=True, - ) - - # ### end Alembic commands ### + with disable_sqlite_fkeys(op): + with op.batch_alter_table("dag_bundle", schema=None) as batch_op: + batch_op.alter_column( + "signed_url_template", + existing_type=sa.VARCHAR(length=200), + type_=sa.Text(), + existing_nullable=True, + ) def downgrade(): """Unapply Change signed_url_template from VARCHAR(200) to TEXT.""" - # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table("dag_bundle", schema=None) as batch_op: - batch_op.alter_column( - "signed_url_template", - existing_type=sa.Text(), - type_=sa.VARCHAR(length=200), - existing_nullable=True, - ) - - # ### end Alembic commands ### + with disable_sqlite_fkeys(op): + with op.batch_alter_table("dag_bundle", schema=None) as batch_op: + batch_op.alter_column( + "signed_url_template", + existing_type=sa.Text(), + type_=sa.VARCHAR(length=200), + existing_nullable=True, + ) From 0447c107f237cb60a6bf9f8f3e62e6fc5203e004 Mon Sep 17 00:00:00 2001 From: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com> Date: Wed, 11 Mar 2026 01:03:04 +0530 Subject: [PATCH 36/50] sync release manager list (#62809) (#63290) (cherry picked from commit d9e1a0ff3c1120a6a42a1057db5db961bbd23461) --- .github/workflows/publish-docs-to-s3.yml | 1 + .github/workflows/release_dockerhub_image.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/publish-docs-to-s3.yml b/.github/workflows/publish-docs-to-s3.yml index 4989b4888cfde..ab10a4e2feccf 100644 --- a/.github/workflows/publish-docs-to-s3.yml +++ b/.github/workflows/publish-docs-to-s3.yml @@ -105,6 +105,7 @@ jobs: "potiuk", "utkarsharma2", "vincbeck", + "vatsrahul1001", ]'), github.event.sender.login) steps: - name: "Input parameters summary" diff --git a/.github/workflows/release_dockerhub_image.yml b/.github/workflows/release_dockerhub_image.yml index 315759808d1d4..ae0b63f0c126e 100644 --- a/.github/workflows/release_dockerhub_image.yml +++ b/.github/workflows/release_dockerhub_image.yml @@ -71,6 +71,7 @@ jobs: "potiuk", "utkarsharma2", "vincbeck", + "vatsrahul1001", ]'), github.event.sender.login) steps: - name: "Input parameters summary" From 6988f6a72a87d73d4119a3717b2ba60866670cbc Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Tue, 10 Mar 2026 20:48:26 +0100 Subject: [PATCH 37/50] CI: Upgrade important CI environment (#63267) --- .github/actions/breeze/action.yml | 2 +- .github/actions/install-prek/action.yml | 4 +- .github/workflows/basic-tests.yml | 2 +- .github/workflows/release_dockerhub_image.yml | 2 +- .pre-commit-config.yaml | 2 +- Dockerfile | 2 +- Dockerfile.ci | 4 +- airflow-core/docs/tutorial/hitl.rst | 2 +- airflow-core/pyproject.toml | 2 +- .../execution_api/routes/task_instances.py | 2 +- .../execution_api/versions/head/test_xcoms.py | 2 +- dev/breeze/doc/ci/02_images.md | 4 +- dev/breeze/pyproject.toml | 2 +- .../commands/release_management_commands.py | 4 +- .../src/airflow_breeze/global_constants.py | 2 +- dev/breeze/uv.lock | 192 +++++++++--------- go-sdk/pkg/api/client.go | 2 +- pyproject.toml | 2 +- scripts/tools/setup_breeze | 2 +- 19 files changed, 118 insertions(+), 118 deletions(-) diff --git a/.github/actions/breeze/action.yml b/.github/actions/breeze/action.yml index a013341f1289c..9699f902e55f1 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.10.8" # Keep this comment to allow automatic replacement of uv version + default: "0.10.9" # 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 67471bc3ad4de..d7d81e4d8ba7c 100644 --- a/.github/actions/install-prek/action.yml +++ b/.github/actions/install-prek/action.yml @@ -24,10 +24,10 @@ inputs: default: "3.10" uv-version: description: 'uv version to use' - default: "0.10.8" # Keep this comment to allow automatic replacement of uv version + default: "0.10.9" # Keep this comment to allow automatic replacement of uv version prek-version: description: 'prek version to use' - default: "0.3.4" # Keep this comment to allow automatic replacement of prek version + default: "0.3.5" # Keep this comment to allow automatic replacement of prek version save-cache: description: "Whether to save prek cache" required: true diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml index 1202d6b1175bc..2f342dd7ac595 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.10.8" # Keep this comment to allow automatic replacement of uv version + default: "0.10.9" # 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 ae0b63f0c126e..0046ffdbca77b 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.10.8" # Keep this comment to allow automatic replacement of uv version + UV_VERSION: "0.10.9" # 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 fbe4f7c810188..74490ef0cc619 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -346,7 +346,7 @@ repos: - --line-length - '99999' - repo: https://github.com/codespell-project/codespell - rev: 63c8f8312b7559622c0d82815639671ae42132ac # frozen: v2.4.1 + rev: 2ccb47ff45ad361a21071a7eedda4c37e6ae8c5a # frozen: v2.4.2 hooks: - id: codespell name: Run codespell diff --git a/Dockerfile b/Dockerfile index 4f052181f3574..f56301017e2eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,7 +58,7 @@ ARG AIRFLOW_PYTHON_VERSION="3.12.13" # Also use `force pip` label on your PR to swap all places we use `uv` to `pip` ARG AIRFLOW_PIP_VERSION=26.0.1 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main" -ARG AIRFLOW_UV_VERSION=0.10.8 +ARG AIRFLOW_UV_VERSION=0.10.9 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 d871ad2bcc365..421b654a343c5 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1728,8 +1728,8 @@ 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=26.0.1 # ARG AIRFLOW_PIP_VERSION="git+https://github.com/pypa/pip.git@main" -ARG AIRFLOW_UV_VERSION=0.10.8 -ARG AIRFLOW_PREK_VERSION="0.3.4" +ARG AIRFLOW_UV_VERSION=0.10.9 +ARG AIRFLOW_PREK_VERSION="0.3.5" # UV_LINK_MODE=copy is needed since we are using cache mounted from the host ENV AIRFLOW_PIP_VERSION=${AIRFLOW_PIP_VERSION} \ diff --git a/airflow-core/docs/tutorial/hitl.rst b/airflow-core/docs/tutorial/hitl.rst index ab5c6ed0175b2..3a5e35c6f7918 100644 --- a/airflow-core/docs/tutorial/hitl.rst +++ b/airflow-core/docs/tutorial/hitl.rst @@ -159,7 +159,7 @@ The method ``HITLOperator.generate_link_to_ui_from_context`` can be used to gene - ``context`` – automatically passed to ``notify`` by the notifier - ``base_url`` – (optional) the base URL of the Airflow UI; if not provided, ``api.base_url`` in the configuration will be used -- ``options`` – (optional) pre-selected options for the UI page +- ``options`` – (optional) preselected options for the UI page - ``params_inputs`` – (optional) pre-loaded inputs for the UI page This makes it easy to include actionable links in notifications or logs. diff --git a/airflow-core/pyproject.toml b/airflow-core/pyproject.toml index d72eb3e14dfc4..f9b24eeb6ec4b 100644 --- a/airflow-core/pyproject.toml +++ b/airflow-core/pyproject.toml @@ -23,7 +23,7 @@ requires = [ "packaging==26.0", "pathspec==1.0.4", "pluggy==1.6.0", - "smmap==5.0.2", + "smmap==5.0.3", "tomli==2.4.0; python_version < '3.11'", "trove-classifiers==2026.1.14.14", ] diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py index 54c777fc59a44..93f8fc153414b 100644 --- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py +++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/task_instances.py @@ -135,7 +135,7 @@ def ti_run( TI.hostname, TI.unixname, TI.pid, - # This selects the raw JSON value, by-passing the deserialization -- we want that to happen on the + # This selects the raw JSON value, bypassing the deserialization -- we want that to happen on the # client column("next_kwargs", JSON), ) diff --git a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py index cf8f80642f7ca..cb84d1ace0a26 100644 --- a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py +++ b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py @@ -385,7 +385,7 @@ def test_xcom_round_trip(self, client, create_task_instance, session, orig_value Test that deserialization works when XCom values are stored directly in the DB with API Server. This tests the case where the XCom value is stored from the Task API where the value is serialized - via Client SDK into JSON object and passed via the API Server to the DB. It by-passes + via Client SDK into JSON object and passed via the API Server to the DB. It bypasses the XComModel.serialize_value and stores valid Python JSON compatible objects to DB. This test is to ensure that the deserialization works correctly in this case as well as diff --git a/dev/breeze/doc/ci/02_images.md b/dev/breeze/doc/ci/02_images.md index ac9772f4a0f10..1f8edf41b2aca 100644 --- a/dev/breeze/doc/ci/02_images.md +++ b/dev/breeze/doc/ci/02_images.md @@ -443,8 +443,8 @@ 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` | `26.0.1` | `pip` version used. | -| `AIRFLOW_UV_VERSION` | `0.10.8` | `uv` version used. | -| `AIRFLOW_PREK_VERSION` | `0.3.4` | `prek` version used. | +| `AIRFLOW_UV_VERSION` | `0.10.9` | `uv` version used. | +| `AIRFLOW_PREK_VERSION` | `0.3.5` | `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 2d746401400e4..fe4c7218ef94f 100644 --- a/dev/breeze/pyproject.toml +++ b/dev/breeze/pyproject.toml @@ -59,7 +59,7 @@ dependencies = [ "jinja2>=3.1.5", "jsonschema>=4.19.1", "packaging>=25.0", - "prek>=0.3.4", + "prek>=0.3.5", "psutil>=5.9.6", "pygithub>=2.1.1", "pytest-xdist>=3.3.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 86e0da897ed12..7db8e41dd48a2 100644 --- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py +++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py @@ -254,11 +254,11 @@ class VersionedFile(NamedTuple): AIRFLOW_PIP_VERSION = "26.0.1" -AIRFLOW_UV_VERSION = "0.10.8" +AIRFLOW_UV_VERSION = "0.10.9" AIRFLOW_USE_UV = False GITPYTHON_VERSION = "3.1.46" RICH_VERSION = "14.3.3" -PREK_VERSION = "0.3.4" +PREK_VERSION = "0.3.5" HATCH_VERSION = "1.16.5" PYYAML_VERSION = "6.0.3" diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py index b992383eca699..35d526c84b293 100644 --- a/dev/breeze/src/airflow_breeze/global_constants.py +++ b/dev/breeze/src/airflow_breeze/global_constants.py @@ -213,7 +213,7 @@ ALLOWED_INSTALL_MYSQL_CLIENT_TYPES = ["mariadb", "mysql"] PIP_VERSION = "26.0.1" -UV_VERSION = "0.10.8" +UV_VERSION = "0.10.9" DEFAULT_UV_HTTP_TIMEOUT = 300 DEFAULT_WSL2_HTTP_TIMEOUT = 900 diff --git a/dev/breeze/uv.lock b/dev/breeze/uv.lock index 0b2ac146fe6cf..71f1d6f21c7de 100644 --- a/dev/breeze/uv.lock +++ b/dev/breeze/uv.lock @@ -74,7 +74,7 @@ requires-dist = [ { name = "jinja2", specifier = ">=3.1.5" }, { name = "jsonschema", specifier = ">=4.19.1" }, { name = "packaging", specifier = ">=25.0" }, - { name = "prek", specifier = ">=0.3.4" }, + { name = "prek", specifier = ">=0.3.5" }, { name = "psutil", specifier = ">=5.9.6" }, { name = "pygithub", specifier = ">=2.1.1" }, { name = "pytest", specifier = ">=9.0.0" }, @@ -216,7 +216,7 @@ wheels = [ [[package]] name = "black" -version = "26.1.0" +version = "26.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -228,62 +228,62 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/88/560b11e521c522440af991d46848a2bde64b5f7202ec14e1f46f9509d328/black-26.1.0.tar.gz", hash = "sha256:d294ac3340eef9c9eb5d29288e96dc719ff269a88e27b396340459dd85da4c58", size = 658785, upload-time = "2026-01-18T04:50:11.993Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/1b/523329e713f965ad0ea2b7a047eeb003007792a0353622ac7a8cb2ee6fef/black-26.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ca699710dece84e3ebf6e92ee15f5b8f72870ef984bf944a57a777a48357c168", size = 1849661, upload-time = "2026-01-18T04:59:12.425Z" }, - { url = "https://files.pythonhosted.org/packages/14/82/94c0640f7285fa71c2f32879f23e609dd2aa39ba2641f395487f24a578e7/black-26.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5e8e75dabb6eb83d064b0db46392b25cabb6e784ea624219736e8985a6b3675d", size = 1689065, upload-time = "2026-01-18T04:59:13.993Z" }, - { url = "https://files.pythonhosted.org/packages/f0/78/474373cbd798f9291ed8f7107056e343fd39fef42de4a51c7fd0d360840c/black-26.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb07665d9a907a1a645ee41a0df8a25ffac8ad9c26cdb557b7b88eeeeec934e0", size = 1751502, upload-time = "2026-01-18T04:59:15.971Z" }, - { url = "https://files.pythonhosted.org/packages/29/89/59d0e350123f97bc32c27c4d79563432d7f3530dca2bff64d855c178af8b/black-26.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:7ed300200918147c963c87700ccf9966dceaefbbb7277450a8d646fc5646bf24", size = 1400102, upload-time = "2026-01-18T04:59:17.8Z" }, - { url = "https://files.pythonhosted.org/packages/e1/bc/5d866c7ae1c9d67d308f83af5462ca7046760158bbf142502bad8f22b3a1/black-26.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c5b7713daea9bf943f79f8c3b46f361cc5229e0e604dcef6a8bb6d1c37d9df89", size = 1207038, upload-time = "2026-01-18T04:59:19.543Z" }, - { url = "https://files.pythonhosted.org/packages/30/83/f05f22ff13756e1a8ce7891db517dbc06200796a16326258268f4658a745/black-26.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3cee1487a9e4c640dc7467aaa543d6c0097c391dc8ac74eb313f2fbf9d7a7cb5", size = 1831956, upload-time = "2026-01-18T04:59:21.38Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f2/b2c570550e39bedc157715e43927360312d6dd677eed2cc149a802577491/black-26.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d62d14ca31c92adf561ebb2e5f2741bf8dea28aef6deb400d49cca011d186c68", size = 1672499, upload-time = "2026-01-18T04:59:23.257Z" }, - { url = "https://files.pythonhosted.org/packages/7a/d7/990d6a94dc9e169f61374b1c3d4f4dd3037e93c2cc12b6f3b12bc663aa7b/black-26.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb1dafbbaa3b1ee8b4550a84425aac8874e5f390200f5502cf3aee4a2acb2f14", size = 1735431, upload-time = "2026-01-18T04:59:24.729Z" }, - { url = "https://files.pythonhosted.org/packages/36/1c/cbd7bae7dd3cb315dfe6eeca802bb56662cc92b89af272e014d98c1f2286/black-26.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:101540cb2a77c680f4f80e628ae98bd2bd8812fb9d72ade4f8995c5ff019e82c", size = 1400468, upload-time = "2026-01-18T04:59:27.381Z" }, - { url = "https://files.pythonhosted.org/packages/59/b1/9fe6132bb2d0d1f7094613320b56297a108ae19ecf3041d9678aec381b37/black-26.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:6f3977a16e347f1b115662be07daa93137259c711e526402aa444d7a88fdc9d4", size = 1207332, upload-time = "2026-01-18T04:59:28.711Z" }, - { url = "https://files.pythonhosted.org/packages/f5/13/710298938a61f0f54cdb4d1c0baeb672c01ff0358712eddaf29f76d32a0b/black-26.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6eeca41e70b5f5c84f2f913af857cf2ce17410847e1d54642e658e078da6544f", size = 1878189, upload-time = "2026-01-18T04:59:30.682Z" }, - { url = "https://files.pythonhosted.org/packages/79/a6/5179beaa57e5dbd2ec9f1c64016214057b4265647c62125aa6aeffb05392/black-26.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd39eef053e58e60204f2cdf059e2442e2eb08f15989eefe259870f89614c8b6", size = 1700178, upload-time = "2026-01-18T04:59:32.387Z" }, - { url = "https://files.pythonhosted.org/packages/8c/04/c96f79d7b93e8f09d9298b333ca0d31cd9b2ee6c46c274fd0f531de9dc61/black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9459ad0d6cd483eacad4c6566b0f8e42af5e8b583cee917d90ffaa3778420a0a", size = 1777029, upload-time = "2026-01-18T04:59:33.767Z" }, - { url = "https://files.pythonhosted.org/packages/49/f9/71c161c4c7aa18bdda3776b66ac2dc07aed62053c7c0ff8bbda8c2624fe2/black-26.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a19915ec61f3a8746e8b10adbac4a577c6ba9851fa4a9e9fbfbcf319887a5791", size = 1406466, upload-time = "2026-01-18T04:59:35.177Z" }, - { url = "https://files.pythonhosted.org/packages/4a/8b/a7b0f974e473b159d0ac1b6bcefffeb6bec465898a516ee5cc989503cbc7/black-26.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:643d27fb5facc167c0b1b59d0315f2674a6e950341aed0fc05cf307d22bf4954", size = 1216393, upload-time = "2026-01-18T04:59:37.18Z" }, - { url = "https://files.pythonhosted.org/packages/79/04/fa2f4784f7237279332aa735cdfd5ae2e7730db0072fb2041dadda9ae551/black-26.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ba1d768fbfb6930fc93b0ecc32a43d8861ded16f47a40f14afa9bb04ab93d304", size = 1877781, upload-time = "2026-01-18T04:59:39.054Z" }, - { url = "https://files.pythonhosted.org/packages/cf/ad/5a131b01acc0e5336740a039628c0ab69d60cf09a2c87a4ec49f5826acda/black-26.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2b807c240b64609cb0e80d2200a35b23c7df82259f80bef1b2c96eb422b4aac9", size = 1699670, upload-time = "2026-01-18T04:59:41.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/7c/b05f22964316a52ab6b4265bcd52c0ad2c30d7ca6bd3d0637e438fc32d6e/black-26.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1de0f7d01cc894066a1153b738145b194414cc6eeaad8ef4397ac9abacf40f6b", size = 1775212, upload-time = "2026-01-18T04:59:42.545Z" }, - { url = "https://files.pythonhosted.org/packages/a6/a3/e8d1526bea0446e040193185353920a9506eab60a7d8beb062029129c7d2/black-26.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:91a68ae46bf07868963671e4d05611b179c2313301bd756a89ad4e3b3db2325b", size = 1409953, upload-time = "2026-01-18T04:59:44.357Z" }, - { url = "https://files.pythonhosted.org/packages/c7/5a/d62ebf4d8f5e3a1daa54adaab94c107b57be1b1a2f115a0249b41931e188/black-26.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:be5e2fe860b9bd9edbf676d5b60a9282994c03fbbd40fe8f5e75d194f96064ca", size = 1217707, upload-time = "2026-01-18T04:59:45.719Z" }, - { url = "https://files.pythonhosted.org/packages/6a/83/be35a175aacfce4b05584ac415fd317dd6c24e93a0af2dcedce0f686f5d8/black-26.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9dc8c71656a79ca49b8d3e2ce8103210c9481c57798b48deeb3a8bb02db5f115", size = 1871864, upload-time = "2026-01-18T04:59:47.586Z" }, - { url = "https://files.pythonhosted.org/packages/a5/f5/d33696c099450b1274d925a42b7a030cd3ea1f56d72e5ca8bbed5f52759c/black-26.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b22b3810451abe359a964cc88121d57f7bce482b53a066de0f1584988ca36e79", size = 1701009, upload-time = "2026-01-18T04:59:49.443Z" }, - { url = "https://files.pythonhosted.org/packages/1b/87/670dd888c537acb53a863bc15abbd85b22b429237d9de1b77c0ed6b79c42/black-26.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53c62883b3f999f14e5d30b5a79bd437236658ad45b2f853906c7cbe79de00af", size = 1767806, upload-time = "2026-01-18T04:59:50.769Z" }, - { url = "https://files.pythonhosted.org/packages/fe/9c/cd3deb79bfec5bcf30f9d2100ffeec63eecce826eb63e3961708b9431ff1/black-26.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:f016baaadc423dc960cdddf9acae679e71ee02c4c341f78f3179d7e4819c095f", size = 1433217, upload-time = "2026-01-18T04:59:52.218Z" }, - { url = "https://files.pythonhosted.org/packages/4e/29/f3be41a1cf502a283506f40f5d27203249d181f7a1a2abce1c6ce188035a/black-26.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:66912475200b67ef5a0ab665011964bf924745103f51977a78b4fb92a9fc1bf0", size = 1245773, upload-time = "2026-01-18T04:59:54.457Z" }, - { url = "https://files.pythonhosted.org/packages/e4/3d/51bdb3ecbfadfaf825ec0c75e1de6077422b4afa2091c6c9ba34fbfc0c2d/black-26.1.0-py3-none-any.whl", hash = "sha256:1054e8e47ebd686e078c0bb0eaf31e6ce69c966058d122f2c0c950311f9f3ede", size = 204010, upload-time = "2026-01-18T04:50:09.978Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/11/5f/25b7b149b8b7d3b958efa4faa56446560408c0f2651108a517526de0320a/black-26.3.0.tar.gz", hash = "sha256:4d438dfdba1c807c6c7c63c4f15794dda0820d2222e7c4105042ac9ddfc5dd0b", size = 664127, upload-time = "2026-03-06T17:42:33.7Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/45/0df73428226c2197b8b1e2ca15654f85cece1efe5f060c910b641a35de4a/black-26.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:135bf8a352e35b3bfba4999c256063d8d86514654599eca7635e914a55d60ec3", size = 1866623, upload-time = "2026-03-06T17:46:07.622Z" }, + { url = "https://files.pythonhosted.org/packages/40/e1/7467fcccf3532853b013bee22c9cdef6aa3314a58ccc73eb5a8a2750e50e/black-26.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6024a2959b6c62c311c564ce23ce0eaa977a50ed52a53f7abc83d2c9eb62b8d8", size = 1703733, upload-time = "2026-03-06T17:46:09.334Z" }, + { url = "https://files.pythonhosted.org/packages/e8/72/ceb0a5091b6dff654f77ee6488b91d45fbea1385338798935eb83090d27e/black-26.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:264144203ea3374542a1591b6fb317561662d074bce5d91ad6afa8d8d3e4ec3d", size = 1768094, upload-time = "2026-03-06T17:46:11.182Z" }, + { url = "https://files.pythonhosted.org/packages/49/cc/6af7e15fb728f30f3e3d4257d2f3d3fe5c5f4ada30b0e8feb92f50118d5c/black-26.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:1a15d1386dce3af3993bf9baeb68d3e492cbb003dae05c3ecf8530a9b75edf85", size = 1413004, upload-time = "2026-03-06T17:46:12.867Z" }, + { url = "https://files.pythonhosted.org/packages/c4/04/7f5ffd40078ab54efa738797e1d547a3fce893f1de212a7a2e65b4a36254/black-26.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:d86a70bf048235aff62a79e229fe5d9e7809c7a05a3dd12982e7ccdc2678e096", size = 1219839, upload-time = "2026-03-06T17:46:14.133Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ec/e4db9f2b2db8226ae20d48b589c69fd64477657bf241c8ccaea3bc4feafa/black-26.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3da07abe65732483e915ab7f9c7c50332c293056436e9519373775d62539607c", size = 1851905, upload-time = "2026-03-06T17:46:15.447Z" }, + { url = "https://files.pythonhosted.org/packages/62/2c/ccecfcbd6a0610ecf554e852a146f053eaeb5b281dd9cb634338518c765e/black-26.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fc9fd683ccabc3dc9791b93db494d93b5c6c03b105453b76d71e5474e9dfa6e7", size = 1689299, upload-time = "2026-03-06T17:46:17.396Z" }, + { url = "https://files.pythonhosted.org/packages/1a/53/8dcb860242012d6da9c6b1b930c3e4c947eb42feb1fc70f2a4e7332c90c5/black-26.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e2c7e2c5ee09ff575869258b2c07064c952637918fc5e15f6ebd45e45eae0aa", size = 1753902, upload-time = "2026-03-06T17:46:19.592Z" }, + { url = "https://files.pythonhosted.org/packages/5d/21/f37b3efcc8cf2d01ec9eb5466598aa53bed2292db236723ac4571e24c4de/black-26.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:a849286bfc3054eaeb233b6df9056fcf969ee18bf7ecb71b0257e838a0f05e6d", size = 1413841, upload-time = "2026-03-06T17:46:20.981Z" }, + { url = "https://files.pythonhosted.org/packages/eb/74/e70f5f2a74301d8f10276b90715699d51d7db1c3dd79cf13966d32ba7b18/black-26.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:c93c83af43cda73ed8265d001214779ab245fa7a861a75b3e43828f4fb1f5657", size = 1220105, upload-time = "2026-03-06T17:46:23.269Z" }, + { url = "https://files.pythonhosted.org/packages/1d/76/b21711045b7f4c4f1774048d0b34dd10a265c42255658b251ce3303ae3c7/black-26.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c2b1e5eec220b419e3591a0aaa6351bd3a9c01fe6291fbaf76d84308eb7a2ede", size = 1895944, upload-time = "2026-03-06T17:46:24.841Z" }, + { url = "https://files.pythonhosted.org/packages/f2/c3/8c56e73283326bc92a36101c660228fff09a2403a57a03cacf3f7f84cf62/black-26.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1bab64de70bccc992432bee56cdffbe004ceeaa07352127c386faa87e81f9261", size = 1718669, upload-time = "2026-03-06T17:46:26.639Z" }, + { url = "https://files.pythonhosted.org/packages/7b/8b/712a3ae8f17c1f3cd6f9ac2fffb167a27192f5c7aba68724e8c4ab8474ad/black-26.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5b6c5f734290803b7b26493ffd734b02b72e6c90d82d45ac4d5b862b9bdf7720", size = 1794844, upload-time = "2026-03-06T17:46:28.334Z" }, + { url = "https://files.pythonhosted.org/packages/ba/5b/ee955040e446df86473287dd24dc69c80dd05e02cc358bca90e22059f7b1/black-26.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7c767396af15b54e1a6aae99ddf241ae97e589f666b1d22c4b6618282a04e4ca", size = 1420461, upload-time = "2026-03-06T17:46:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/12/77/40b8bd44f032bb34c9ebf47ffc5bb47a2520d29e0a4b8a780ab515223b5a/black-26.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:765fd6ddd00f35c55250fdc6b790c272d54ac3f44da719cc42df428269b45980", size = 1229667, upload-time = "2026-03-06T17:46:31.654Z" }, + { url = "https://files.pythonhosted.org/packages/28/c3/21a834ce3de02c64221243f2adac63fa3c3f441efdb3adbf4136b33dfeb0/black-26.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:59754fd8f43ef457be190594c07a52c999e22cb1534dc5344bff1d46fdf1027d", size = 1895195, upload-time = "2026-03-06T17:46:33.12Z" }, + { url = "https://files.pythonhosted.org/packages/1c/f9/212d9697dd78362dadb778d4616b74c8c2cf7f2e4a55aac2adeb0576f2e9/black-26.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1fd94cfee67b8d336761a0b08629a25938e4a491c440951ce517a7209c99b5ff", size = 1718472, upload-time = "2026-03-06T17:46:34.576Z" }, + { url = "https://files.pythonhosted.org/packages/a2/dd/da980b2f512441375b73cb511f38a2c3db4be83ccaa1302b8d39c9fa2dff/black-26.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f7b3e653a90ca1ef4e821c20f8edaee80b649c38d2532ed2e9073a9534b14a7", size = 1793741, upload-time = "2026-03-06T17:46:36.261Z" }, + { url = "https://files.pythonhosted.org/packages/93/11/cd69ae8826fe3bc6eaf525c8c557266d522b258154a2968eb46d6d25fac7/black-26.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:f8fb9d7c2496adc83614856e1f6e55a9ce4b7ae7fc7f45b46af9189ddb493464", size = 1422522, upload-time = "2026-03-06T17:46:37.607Z" }, + { url = "https://files.pythonhosted.org/packages/75/f5/647cf50255203eb286be197925e86eedc101d5409147505db3e463229228/black-26.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:e8618c1d06838f56afbcb3ffa1aa16436cec62b86b38c7b32ca86f53948ffb91", size = 1231807, upload-time = "2026-03-06T17:46:39.072Z" }, + { url = "https://files.pythonhosted.org/packages/ff/77/b197e701f15fd694d20d8ee0001efa2e29eba917aa7c3610ff7b10ae0f88/black-26.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d0c6f64ead44f4369c66f1339ecf68e99b40f2e44253c257f7807c5a3ef0ca32", size = 1889209, upload-time = "2026-03-06T17:46:40.453Z" }, + { url = "https://files.pythonhosted.org/packages/93/85/b4d4924ac898adc2e39fc7a923bed99797535bc16dea4bc63944c3903c2b/black-26.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ed6f0809134e51ec4a7509e069cdfa42bf996bd0fd1df6d3146b907f36e28893", size = 1720830, upload-time = "2026-03-06T17:46:42.009Z" }, + { url = "https://files.pythonhosted.org/packages/00/b1/5c0bf29fe5b43fcc6f3e8480c6566d21a02d4e702b3846944e7daa06dea9/black-26.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc6ac0ea5dd5fa6311ca82edfa3620cba0ed0426022d10d2d5d39aedbf3e1958", size = 1787676, upload-time = "2026-03-06T17:46:43.382Z" }, + { url = "https://files.pythonhosted.org/packages/b8/ce/cc8cf14806c144d6a16512272c537d5450f50675d3e8c038705430e90fd9/black-26.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:884bc0aefa96adabcba0b77b10e9775fd52d4b766e88c44dc6f41f7c82787fc8", size = 1445406, upload-time = "2026-03-06T17:46:44.948Z" }, + { url = "https://files.pythonhosted.org/packages/cf/bb/049ea0fad9f8bdec7b647948adcf74bb720bd71dcb213decd553e05b2699/black-26.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:be3bd02aab5c4ab03703172f5530ddc8fc8b5b7bb8786230e84c9e011cee9ca1", size = 1257945, upload-time = "2026-03-06T17:46:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/39/d7/7360654ba4f8b41afcaeb5aca973cfea5591da75aff79b0a8ae0bb8883f6/black-26.3.0-py3-none-any.whl", hash = "sha256:e825d6b121910dff6f04d7691f826d2449327e8e71c26254c030c4f3d2311985", size = 206848, upload-time = "2026-03-06T17:42:31.133Z" }, ] [[package]] name = "boto3" -version = "1.42.62" +version = "1.42.64" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "botocore" }, { name = "jmespath" }, { name = "s3transfer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f7/7e/c952803c8900f14e6f6158fddbd35da5afb2e3fa68bf498a761e6ba2c2ae/boto3-1.42.62.tar.gz", hash = "sha256:6b26ff56c458685caec3d42adde0549f6a55410e557e1f51bebde5c8abcf3037", size = 112848, upload-time = "2026-03-05T21:20:37.755Z" } +sdist = { url = "https://files.pythonhosted.org/packages/27/3e/3f5f58100340f6576aa93da0fe46cabd91ea19baa746b80bd1d46498b0db/boto3-1.42.64.tar.gz", hash = "sha256:58d47897a26adbc22f6390d133dab772fb606ba72695291a8c9e20cba1c7fd23", size = 112773, upload-time = "2026-03-09T19:52:00.407Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/68/b5e82dedd9c8d53a9542df4e3475d2d3ec331eef4a4a801e9c5fa98b583a/boto3-1.42.62-py3-none-any.whl", hash = "sha256:eef0ee08f30e5ed16d8296719808801a827fa0f3126a3e2a9ef9be9eb5e6a313", size = 140556, upload-time = "2026-03-05T21:20:35.354Z" }, + { url = "https://files.pythonhosted.org/packages/4c/87/2f02a6db0828f4579aedef7e34ec15262e4aa402d31f31bdbc64ae8e471b/boto3-1.42.64-py3-none-any.whl", hash = "sha256:2ca6b472937a54ba74af0b4bede582ba98c070408db1061fc26d5c3aa8e6e7e6", size = 140557, upload-time = "2026-03-09T19:51:57.652Z" }, ] [[package]] name = "botocore" -version = "1.42.62" +version = "1.42.64" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jmespath" }, { name = "python-dateutil" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/af/e7/031f2f03f22817f8a8def7ad1caa138979c20ac35062b055274e0a505c3f/botocore-1.42.62.tar.gz", hash = "sha256:c210dc93b0b81bf72cfe745a7b1c8df765d04bd90b4ac6c8707fbb6714141dae", size = 14966114, upload-time = "2026-03-05T21:20:25.518Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d3/3c/ac4bc939da695d2c648bf28f7b204ab741e4504e81749ccf943403cc07ca/botocore-1.42.64.tar.gz", hash = "sha256:4ee2aece227b9171ace8b749af694a77ab984fceab1639f2626bd0d6fb1aa69d", size = 14967869, upload-time = "2026-03-09T19:51:46.213Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/57/9bc5c1aad3a354dd7da54ba52d43ee821badb3deedbea4c5117c4bd05eab/botocore-1.42.62-py3-none-any.whl", hash = "sha256:86d327fded96775268ffe8d8bd6ed96c4a1db86cf24eb64ff85233db12dbc287", size = 14638389, upload-time = "2026-03-05T21:20:22.359Z" }, + { url = "https://files.pythonhosted.org/packages/33/0f/a0feb9a93da8f583217432dce71ce1940d6d8aa5884bad340872a504ba3f/botocore-1.42.64-py3-none-any.whl", hash = "sha256:f77c5cb76ed30576ed0bc73b591265d03dddffff02a9208d3ee0c790f43d3cd2", size = 14641339, upload-time = "2026-03-09T19:51:41.244Z" }, ] [[package]] @@ -588,11 +588,11 @@ wheels = [ [[package]] name = "filelock" -version = "3.25.0" +version = "3.25.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/77/18/a1fd2231c679dcb9726204645721b12498aeac28e1ad0601038f94b42556/filelock-3.25.0.tar.gz", hash = "sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3", size = 40158, upload-time = "2026-03-01T15:08:45.916Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8b/4c32ecde6bea6486a2a5d05340e695174351ff6b06cf651a74c005f9df00/filelock-3.25.1.tar.gz", hash = "sha256:b9a2e977f794ef94d77cdf7d27129ac648a61f585bff3ca24630c1629f701aa9", size = 40319, upload-time = "2026-03-09T19:38:47.309Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/0b/de6f54d4a8bedfe8645c41497f3c18d749f0bd3218170c667bf4b81d0cdd/filelock-3.25.0-py3-none-any.whl", hash = "sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047", size = 26427, upload-time = "2026-03-01T15:08:44.593Z" }, + { url = "https://files.pythonhosted.org/packages/a9/b8/2f664b56a3b4b32d28d3d106c71783073f712ba43ff6d34b9ea0ce36dc7b/filelock-3.25.1-py3-none-any.whl", hash = "sha256:18972df45473c4aa2c7921b609ee9ca4925910cc3a0fb226c96b92fc224ef7bf", size = 26720, upload-time = "2026-03-09T19:38:45.718Z" }, ] [[package]] @@ -678,16 +678,16 @@ wheels = [ [[package]] name = "google-auth" -version = "2.48.0" +version = "2.49.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "pyasn1-modules" }, { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0c/41/242044323fbd746615884b1c16639749e73665b718209946ebad7ba8a813/google_auth-2.48.0.tar.gz", hash = "sha256:4f7e706b0cd3208a3d940a19a822c37a476ddba5450156c3e6624a71f7c841ce", size = 326522, upload-time = "2026-01-26T19:22:47.157Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/59/7371175bfd949abfb1170aa076352131d7281bd9449c0f978604fc4431c3/google_auth-2.49.0.tar.gz", hash = "sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae", size = 333444, upload-time = "2026-03-06T21:53:06.07Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/1d/d6466de3a5249d35e832a52834115ca9d1d0de6abc22065f049707516d47/google_auth-2.48.0-py3-none-any.whl", hash = "sha256:2e2a537873d449434252a9632c28bfc268b0adb1e53f9fb62afc5333a975903f", size = 236499, upload-time = "2026-01-26T19:22:45.099Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/de64b823b639103de4b63dd193480dce99526bd36be6530c2dba85bf7817/google_auth-2.49.0-py3-none-any.whl", hash = "sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87", size = 240676, upload-time = "2026-03-06T21:52:38.304Z" }, ] [[package]] @@ -718,14 +718,14 @@ wheels = [ [[package]] name = "googleapis-common-protos" -version = "1.72.0" +version = "1.73.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e5/7b/adfd75544c415c487b33061fe7ae526165241c1ea133f9a9125a56b39fd8/googleapis_common_protos-1.72.0.tar.gz", hash = "sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5", size = 147433, upload-time = "2025-11-06T18:29:24.087Z" } +sdist = { url = "https://files.pythonhosted.org/packages/99/96/a0205167fa0154f4a542fd6925bdc63d039d88dab3588b875078107e6f06/googleapis_common_protos-1.73.0.tar.gz", hash = "sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a", size = 147323, upload-time = "2026-03-06T21:53:09.727Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/ab/09169d5a4612a5f92490806649ac8d41e3ec9129c636754575b3553f4ea4/googleapis_common_protos-1.72.0-py3-none-any.whl", hash = "sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038", size = 297515, upload-time = "2025-11-06T18:29:13.14Z" }, + { url = "https://files.pythonhosted.org/packages/69/28/23eea8acd65972bbfe295ce3666b28ac510dfcb115fac089d3edb0feb00a/googleapis_common_protos-1.73.0-py3-none-any.whl", hash = "sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8", size = 297578, upload-time = "2026-03-06T21:52:33.933Z" }, ] [[package]] @@ -898,14 +898,14 @@ wheels = [ [[package]] name = "jaraco-context" -version = "6.1.0" +version = "6.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-tarfile", marker = "python_full_version < '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cb/9c/a788f5bb29c61e456b8ee52ce76dbdd32fd72cd73dd67bc95f42c7a8d13c/jaraco_context-6.1.0.tar.gz", hash = "sha256:129a341b0a85a7db7879e22acd66902fda67882db771754574338898b2d5d86f", size = 15850, upload-time = "2026-01-13T02:53:53.847Z" } +sdist = { url = "https://files.pythonhosted.org/packages/27/7b/c3081ff1af947915503121c649f26a778e1a2101fd525f74aef997d75b7e/jaraco_context-6.1.1.tar.gz", hash = "sha256:bc046b2dc94f1e5532bd02402684414575cc11f565d929b6563125deb0a6e581", size = 15832, upload-time = "2026-03-07T15:46:04.63Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/48/aa685dbf1024c7bd82bede569e3a85f82c32fd3d79ba5fea578f0159571a/jaraco_context-6.1.0-py3-none-any.whl", hash = "sha256:a43b5ed85815223d0d3cfdb6d7ca0d2bc8946f28f30b6f3216bda070f68badda", size = 7065, upload-time = "2026-01-13T02:53:53.031Z" }, + { url = "https://files.pythonhosted.org/packages/f4/49/c152890d49102b280ecf86ba5f80a8c111c3a155dafa3bd24aeb64fde9e1/jaraco_context-6.1.1-py3-none-any.whl", hash = "sha256:0df6a0287258f3e364072c3e40d5411b20cafa30cb28c4839d24319cecf9f808", size = 7005, upload-time = "2026-03-07T15:46:03.515Z" }, ] [[package]] @@ -1221,26 +1221,26 @@ wheels = [ [[package]] name = "prek" -version = "0.3.4" +version = "0.3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c6/51/2324eaad93a4b144853ca1c56da76f357d3a70c7b4fd6659e972d7bb8660/prek-0.3.4.tar.gz", hash = "sha256:56a74d02d8b7dfe3c774ecfcd8c1b4e5f1e1b84369043a8003e8e3a779fce72d", size = 356633, upload-time = "2026-02-28T03:47:13.452Z" } +sdist = { url = "https://files.pythonhosted.org/packages/46/d6/277e002e56eeab3a9d48f1ca4cc067d249d6326fc1783b770d70ad5ae2be/prek-0.3.5.tar.gz", hash = "sha256:ca40b6685a4192256bc807f32237af94bf9b8799c0d708b98735738250685642", size = 374806, upload-time = "2026-03-09T10:35:18.842Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/20/1a964cb72582307c2f1dc7f583caab90f42810ad41551e5220592406a4c3/prek-0.3.4-py3-none-linux_armv6l.whl", hash = "sha256:c35192d6e23fe7406bd2f333d1c7dab1a4b34ab9289789f453170f33550aa74d", size = 4641915, upload-time = "2026-02-28T03:47:03.772Z" }, - { url = "https://files.pythonhosted.org/packages/c5/cb/4a21f37102bac37e415b61818344aa85de8d29a581253afa7db8c08d5a33/prek-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f784d78de72a8bbe58a5fe7bde787c364ae88f0aff5222c5c5c7287876c510a", size = 4649166, upload-time = "2026-02-28T03:47:06.164Z" }, - { url = "https://files.pythonhosted.org/packages/85/9c/a7c0d117a098d57931428bdb60fcb796e0ebc0478c59288017a2e22eca96/prek-0.3.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:50a43f522625e8c968e8c9992accf9e29017abad6c782d6d176b73145ad680b7", size = 4274422, upload-time = "2026-02-28T03:46:59.356Z" }, - { url = "https://files.pythonhosted.org/packages/59/84/81d06df1724d09266df97599a02543d82fde7dfaefd192f09d9b2ccb092f/prek-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:4bbb1d3912a88935f35c6ba4466b4242732e3e3a8c608623c708e83cea85de00", size = 4629873, upload-time = "2026-02-28T03:46:56.419Z" }, - { url = "https://files.pythonhosted.org/packages/09/cd/bb0aefa25cfacd8dbced75b9a9d9945707707867fa5635fb69ae1bbc2d88/prek-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ca4d4134db8f6e8de3c418317becdf428957e3cab271807f475318105fd46d04", size = 4552507, upload-time = "2026-02-28T03:47:05.004Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c0/578a7af4861afb64ec81c03bfdcc1bb3341bb61f2fff8a094ecf13987a56/prek-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fb6395f6eb76133bb1e11fc718db8144522466cdc2e541d05e7813d1bbcae7d", size = 4865929, upload-time = "2026-02-28T03:47:09.231Z" }, - { url = "https://files.pythonhosted.org/packages/fc/48/f169406590028f7698ef2e1ff5bffd92ca05e017636c1163a2f5ef0f8275/prek-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae17813239ddcb4ae7b38418de4d49afff740f48f8e0556029c96f58e350412", size = 5390286, upload-time = "2026-02-28T03:47:10.796Z" }, - { url = "https://files.pythonhosted.org/packages/05/c5/98a73fec052059c3ae06ce105bef67caca42334c56d84e9ef75df72ba152/prek-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a621a690d9c127afc3d21c275030d364d1fbef3296c095068d3ae80a59546e", size = 4891028, upload-time = "2026-02-28T03:47:07.916Z" }, - { url = "https://files.pythonhosted.org/packages/a3/b4/029966e35e59b59c142be7e1d2208ad261709ac1a66aa4a3ce33c5b9f91f/prek-0.3.4-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:d978c31bc3b1f0b3d58895b7c6ac26f077e0ea846da54f46aeee4c7088b1b105", size = 4633986, upload-time = "2026-02-28T03:47:14.351Z" }, - { url = "https://files.pythonhosted.org/packages/1d/27/d122802555745b6940c99fcb41496001c192ddcdf56ec947ec10a0298e05/prek-0.3.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a8e089a030f0a023c22a4bb2ec4ff3fcc153585d701cff67acbfca2f37e173ae", size = 4680722, upload-time = "2026-02-28T03:47:12.224Z" }, - { url = "https://files.pythonhosted.org/packages/34/40/92318c96b3a67b4e62ed82741016ede34d97ea9579d3cc1332b167632222/prek-0.3.4-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:8060c72b764f0b88112616763da9dd3a7c293e010f8520b74079893096160a2f", size = 4535623, upload-time = "2026-02-28T03:46:52.221Z" }, - { url = "https://files.pythonhosted.org/packages/df/f5/6b383d94e722637da4926b4f609d36fe432827bb6f035ad46ee02bde66b6/prek-0.3.4-py3-none-musllinux_1_1_i686.whl", hash = "sha256:65b23268456b5a763278d4e1ec532f2df33918f13ded85869a1ddff761eb9697", size = 4729879, upload-time = "2026-02-28T03:46:57.886Z" }, - { url = "https://files.pythonhosted.org/packages/79/f8/fdc705b807d813fd713ffa4f67f96741542ed1dafbb221206078c06f3df4/prek-0.3.4-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:3975c61139c7b3200e38dc3955e050b0f2615701d3deb9715696a902e850509e", size = 5001569, upload-time = "2026-02-28T03:47:00.892Z" }, - { url = "https://files.pythonhosted.org/packages/84/92/b007a41f58e8192a1e611a21b396ad870d51d7873b7af12068ebae7fc15f/prek-0.3.4-py3-none-win32.whl", hash = "sha256:37449ae82f4dc08b72e542401e3d7318f05d1163e87c31ab260a40f425d6516e", size = 4297057, upload-time = "2026-02-28T03:47:02.219Z" }, - { url = "https://files.pythonhosted.org/packages/bb/dc/bcb02de9b11461e8e0c7d3c8fdf8cfa15ac6efe73472a4375549ba5defd2/prek-0.3.4-py3-none-win_amd64.whl", hash = "sha256:60e9aa86ca65de963510ae28c5d94b9d7a97bcbaa6e4cdb5bf5083ed4c45dc71", size = 4655174, upload-time = "2026-02-28T03:46:53.749Z" }, - { url = "https://files.pythonhosted.org/packages/0b/86/98f5598569f4cd3de7161e266fab6a8981e65555f79d4704810c1502ad0a/prek-0.3.4-py3-none-win_arm64.whl", hash = "sha256:486bdae8f4512d3b4f6eb61b83e5b7595da2adca385af4b2b7823c0ab38d1827", size = 4367817, upload-time = "2026-02-28T03:46:55.264Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a9/16dd8d3a50362ebccffe58518af1f1f571c96f0695d7fcd8bbd386585f58/prek-0.3.5-py3-none-linux_armv6l.whl", hash = "sha256:44b3e12791805804f286d103682b42a84e0f98a2687faa37045e9d3375d3d73d", size = 5105604, upload-time = "2026-03-09T10:35:00.332Z" }, + { url = "https://files.pythonhosted.org/packages/e4/74/bc6036f5bf03860cda66ab040b32737e54802b71a81ec381839deb25df9e/prek-0.3.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e3cb451cc51ac068974557491beb4c7d2d41dfde29ed559c1694c8ce23bf53e8", size = 5506155, upload-time = "2026-03-09T10:35:17.64Z" }, + { url = "https://files.pythonhosted.org/packages/02/d9/a3745c2a10509c63b6a118ada766614dd705efefd08f275804d5c807aa4a/prek-0.3.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ad8f5f0d8da53dc94d00b76979af312b3dacccc9dcbc6417756c5dca3633c052", size = 5100383, upload-time = "2026-03-09T10:35:13.302Z" }, + { url = "https://files.pythonhosted.org/packages/43/8e/de965fc515d39309a332789cd3778161f7bc80cde15070bedf17f9f8cb93/prek-0.3.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:4511e15d34072851ac88e4b2006868fbe13655059ad941d7a0ff9ee17138fd9f", size = 5334913, upload-time = "2026-03-09T10:35:14.813Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8c/44f07e8940256059cfd82520e3cbe0764ab06ddb4aa43148465db00b39ad/prek-0.3.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc0b63b8337e2046f51267facaac63ba755bc14aad53991840a5eccba3e5c28", size = 5033825, upload-time = "2026-03-09T10:35:06.976Z" }, + { url = "https://files.pythonhosted.org/packages/94/85/3ff0f96881ff2360c212d310ff23c3cf5a15b223d34fcfa8cdcef203be69/prek-0.3.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5fc0d78c3896a674aeb8247a83bbda7efec85274dbdfbc978ceff8d37e4ed20", size = 5438586, upload-time = "2026-03-09T10:34:58.779Z" }, + { url = "https://files.pythonhosted.org/packages/79/a5/c6d08d31293400fcb5d427f8e7e6bacfc959988e868ad3a9d97b4d87c4b7/prek-0.3.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64cad21cb9072d985179495b77b312f6b81e7b45357d0c68dc1de66e0408eabc", size = 6359714, upload-time = "2026-03-09T10:34:57.454Z" }, + { url = "https://files.pythonhosted.org/packages/ba/18/321dcff9ece8065d42c8c1c7a53a23b45d2b4330aa70993be75dc5f2822f/prek-0.3.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45ee84199bb48e013bdfde0c84352c17a44cc42d5792681b86d94e9474aab6f8", size = 5717632, upload-time = "2026-03-09T10:35:08.634Z" }, + { url = "https://files.pythonhosted.org/packages/a3/7f/1288226aa381d0cea403157f4e6b64b356e1a745f2441c31dd9d8a1d63da/prek-0.3.5-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:f43275e5d564e18e52133129ebeb5cb071af7ce4a547766c7f025aa0955dfbb6", size = 5339040, upload-time = "2026-03-09T10:35:03.665Z" }, + { url = "https://files.pythonhosted.org/packages/22/94/cfec83df9c2b8e7ed1608087bcf9538a6a77b4c2e7365123e9e0a3162cd1/prek-0.3.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:abcee520d31522bcbad9311f21326b447694cd5edba33618c25fd023fc9865ec", size = 5162586, upload-time = "2026-03-09T10:35:11.564Z" }, + { url = "https://files.pythonhosted.org/packages/13/b7/741d62132f37a5f7cc0fad1168bd31f20dea9628f482f077f569547e0436/prek-0.3.5-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:499c56a94a155790c75a973d351a33f8065579d9094c93f6d451ada5d1e469be", size = 5002933, upload-time = "2026-03-09T10:35:16.347Z" }, + { url = "https://files.pythonhosted.org/packages/6f/83/630a5671df6550fcfa67c54955e8a8174eb9b4d97ac38fb05a362029245b/prek-0.3.5-py3-none-musllinux_1_1_i686.whl", hash = "sha256:de1065b59f194624adc9dea269d4ff6b50e98a1b5bb662374a9adaa496b3c1eb", size = 5304934, upload-time = "2026-03-09T10:35:09.975Z" }, + { url = "https://files.pythonhosted.org/packages/de/79/67a7afd0c0b6c436630b7dba6e586a42d21d5d6e5778fbd9eba7bbd3dd26/prek-0.3.5-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a1c4869e45ee341735d07179da3a79fa2afb5959cef8b3c8a71906eb52dc6933", size = 5829914, upload-time = "2026-03-09T10:35:05.39Z" }, + { url = "https://files.pythonhosted.org/packages/37/47/e2fe13b33e7b5fdd9dd1a312f5440208bfe1be6183e54c5c99c10f27d848/prek-0.3.5-py3-none-win32.whl", hash = "sha256:70b2152ecedc58f3f4f69adc884617b0cf44259f7414c44d6268ea6f107672eb", size = 4836910, upload-time = "2026-03-09T10:35:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ab/dc2a139fd4896d11f39631479ed385e86307af7f54059ebe9414bb0d00c6/prek-0.3.5-py3-none-win_amd64.whl", hash = "sha256:01d031b684f7e1546225393af1268d9b4451a44ef6cb9be4101c85c7862e08db", size = 5234234, upload-time = "2026-03-09T10:35:20.193Z" }, + { url = "https://files.pythonhosted.org/packages/ed/38/f7256b4b7581444f658e909c3b566f51bfabe56c03e80d107a6932d62040/prek-0.3.5-py3-none-win_arm64.whl", hash = "sha256:aa774168e3d868039ff79422bdef2df8d5a016ed804a9914607dcdd3d41da053", size = 5083330, upload-time = "2026-03-09T10:34:55.469Z" }, ] [[package]] @@ -1474,15 +1474,15 @@ wheels = [ [[package]] name = "python-discovery" -version = "1.1.0" +version = "1.1.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/bb/93a3e83bdf9322c7e21cafd092e56a4a17c4d8ef4277b6eb01af1a540a6f/python_discovery-1.1.0.tar.gz", hash = "sha256:447941ba1aed8cc2ab7ee3cb91be5fc137c5bdbb05b7e6ea62fbdcb66e50b268", size = 55674, upload-time = "2026-02-26T09:42:49.668Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7a/16/6f3f5e9258f0733aaca19aa18e298cb3a629ae49363573e78d241abeef59/python_discovery-1.1.2.tar.gz", hash = "sha256:c500bd2153e3afc5f48a61d33ff570b6f3e710d36ceaaf882fa9bbe5cc2cec49", size = 56928, upload-time = "2026-03-09T20:02:28.402Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/54/82a6e2ef37f0f23dccac604b9585bdcbd0698604feb64807dcb72853693e/python_discovery-1.1.0-py3-none-any.whl", hash = "sha256:a162893b8809727f54594a99ad2179d2ede4bf953e12d4c7abc3cc9cdbd1437b", size = 30687, upload-time = "2026-02-26T09:42:48.548Z" }, + { url = "https://files.pythonhosted.org/packages/03/48/8bdfaec240edb1a79b79201eff38b737fc3c29ce59e2e71271bdd8bafdda/python_discovery-1.1.2-py3-none-any.whl", hash = "sha256:d18edd61b382d62f8bcd004a71ebaabc87df31dbefb30aeed59f4fc6afa005be", size = 31486, upload-time = "2026-03-09T20:02:27.277Z" }, ] [[package]] @@ -1901,11 +1901,11 @@ wheels = [ [[package]] name = "smmap" -version = "5.0.2" +version = "5.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329, upload-time = "2025-01-02T07:14:40.909Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/ea/49c993d6dfdd7338c9b1000a0f36817ed7ec84577ae2e52f890d1a4ff909/smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c", size = 22506, upload-time = "2026-03-09T03:43:26.1Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303, upload-time = "2025-01-02T07:14:38.724Z" }, + { url = "https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f", size = 24390, upload-time = "2026-03-09T03:43:24.361Z" }, ] [[package]] @@ -2071,32 +2071,32 @@ wheels = [ [[package]] name = "uv" -version = "0.10.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a3/e7/600a90d4662dbd8414c1f6b709c8c79075d37d2044f72b94acbfaf29baad/uv-0.10.8.tar.gz", hash = "sha256:4b23242b5224c7eaea481ce6c6dbc210f0eafb447cf60211633980947cd23de4", size = 3936600, upload-time = "2026-03-03T21:35:22.386Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/6c/8ef256575242d5f3869c5a445ffd4363b91a89acb34a3e043bec2ad5a1be/uv-0.10.8-py3-none-linux_armv6l.whl", hash = "sha256:d214c82c7c14dd23f9aeb609d03070b8ea2b2f0cf249c9321cbbb5375a17e5df", size = 22461003, upload-time = "2026-03-03T21:35:20.093Z" }, - { url = "https://files.pythonhosted.org/packages/c9/fb/fd0656a92e6b9c4f92ddba7dcd76bd87469be500755125e06fea853dc212/uv-0.10.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d1315c3901c5859aec2c5b4a17da4c5410d17f6890890f9f1a31f25aa0fa9ace", size = 21549446, upload-time = "2026-03-03T21:35:58.203Z" }, - { url = "https://files.pythonhosted.org/packages/64/b9/1a4105df3afe7af99791f5b00fb037d85b2e3aaa1227e95878538d51ecf3/uv-0.10.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a253e5d2cae9e02654de31918b610dfc8f1f16a33f34046603757820bc45ee1b", size = 20222180, upload-time = "2026-03-03T21:35:46.984Z" }, - { url = "https://files.pythonhosted.org/packages/c5/72/6e98e0f8b3fe80cb881c36492dca6d932fbb05f956dfdccbdb8ebe4ceff4/uv-0.10.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:57a24e15fd9dd4a36bcec2ccbe4b26d2a172c109e954a8940f5e8a8b965dae74", size = 22064813, upload-time = "2026-03-03T21:35:17.108Z" }, - { url = "https://files.pythonhosted.org/packages/71/b6/737da8577f4b1799f7024f6cd98fffcac77076a1b078b277cffc84946e96/uv-0.10.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:675dc659195f9b9811ef5534eb3f16459fc88e109aefacbc91c07751b5b9715a", size = 22064861, upload-time = "2026-03-03T21:35:25.067Z" }, - { url = "https://files.pythonhosted.org/packages/7e/21/464ee3cd81f44345953cb26dd49870811f7647f3074f7651775cadb2158b/uv-0.10.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:18d2968b0a50111c2fc6b782f7c63ded4f461c44efab537f552cf565f9aaae25", size = 22054515, upload-time = "2026-03-03T21:35:44.572Z" }, - { url = "https://files.pythonhosted.org/packages/11/2c/1c592d7b843ffa999502116b0dc573732b40cb37061a4acc741dcdb181da/uv-0.10.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed3c7ebb6f757cddedb56dec3d7c745e5ea7310b11e12ae1c28f1e8172e7bbf", size = 23433992, upload-time = "2026-03-03T21:35:36.886Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e2/2b716f0613746138294598668bbe65295a8da3d8fa104a756dec6284bf3c/uv-0.10.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffaf115501e33be0d4f13cb5b7c2b46b031d4c679a6109e24a7edfb719c44c6c", size = 24257250, upload-time = "2026-03-03T21:35:49.954Z" }, - { url = "https://files.pythonhosted.org/packages/3e/4d/0165e82cd1117cd6f8a7d9a2122c23cc091f7cf738aa4a2a54579420a08f/uv-0.10.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0209ee8cb573e113ff4a760360f28448f9ebcdcf9c91ca49e872821de5d2d054", size = 23338918, upload-time = "2026-03-03T21:35:33.795Z" }, - { url = "https://files.pythonhosted.org/packages/20/74/652129a25145732482bb0020602507f52d9a5ca0e1a40ddd6deb27402333/uv-0.10.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11dc790f732dc5fee61f0f6bd998fc2e9c200df1082245604ac091c32c23a523", size = 23259370, upload-time = "2026-03-03T21:35:39.478Z" }, - { url = "https://files.pythonhosted.org/packages/19/c5/6e5923d6c9e3b50dc8542647bea692b7c227a9489f59ddff4fdfb20d8459/uv-0.10.8-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:e26f8c35684face38db814d452dd1a2181152dbf7f7b2de1f547e6ba0c378d67", size = 22174747, upload-time = "2026-03-03T21:35:42.081Z" }, - { url = "https://files.pythonhosted.org/packages/92/cd/eee9e1883888327d07f51e7595ed5952e0bca2dc79d1c03b8a6e4309553e/uv-0.10.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:385add107d40c43dc00ca8c1a21ecf43101f846f8339eb7026bf6c9f6df7760d", size = 22893359, upload-time = "2026-03-03T21:35:30.802Z" }, - { url = "https://files.pythonhosted.org/packages/bf/36/407a22917e55ce5cc2e7af956e3b9d91648a96558858acef84e3c50d5ca8/uv-0.10.8-py3-none-musllinux_1_1_i686.whl", hash = "sha256:24e8eb28c4f05acb38e60fefe2a2b15f4283a3849ce580bf2a62aca0a13123b3", size = 22637451, upload-time = "2026-03-03T21:35:55.677Z" }, - { url = "https://files.pythonhosted.org/packages/21/d5/dabef9914e1ff27ad95e4b1daf59cd97c80e26a44c04c2870bcca7c83fc0/uv-0.10.8-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:73a8c1a1fceac73cd983dcc0a64f4f94f5fd1e5428681a5a76132574264504fb", size = 23480991, upload-time = "2026-03-03T21:35:52.809Z" }, - { url = "https://files.pythonhosted.org/packages/2f/c0/1a4a45a9246f087e9446d0d804a436f6ee0befeaef731b04d1b2802d9d8f/uv-0.10.8-py3-none-win32.whl", hash = "sha256:9f344fdb34938ce35e9211a1b866adfa0c7f043967652ed1431917514aeec062", size = 21579030, upload-time = "2026-03-03T21:35:28.176Z" }, - { url = "https://files.pythonhosted.org/packages/a4/2b/b29510efa1e6f409db105dbdafbd942ca3a2b638bef682ff2e5b9f6e4021/uv-0.10.8-py3-none-win_amd64.whl", hash = "sha256:1e63015284ed28c2112717256c328513215fb966a57c5870788eac2e8f949f28", size = 23944828, upload-time = "2026-03-03T21:36:00.763Z" }, - { url = "https://files.pythonhosted.org/packages/3f/9e/b5a11b0523171c0103c4fed54da76685a765ad4d3215e8220facfd24aed9/uv-0.10.8-py3-none-win_arm64.whl", hash = "sha256:a80284f46b6f2e0b3d03eb7c2d43e17139a4ec313e8b9f56a71efafc996804cb", size = 22322224, upload-time = "2026-03-03T21:35:14.148Z" }, +version = "0.10.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/59/235fa08a6b56de82a45a385dc2bf724502f720f0a9692a1a8cb24aab3e6f/uv-0.10.9.tar.gz", hash = "sha256:31e76ae92e70fec47c3efab0c8094035ad7a578454482415b496fa39fc4d685c", size = 3945685, upload-time = "2026-03-06T21:21:16.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2f/6d/f87f1530d5db4132776d49dddd88b1c77bc08fa7b32bf585b366204e6fc2/uv-0.10.9-py3-none-linux_armv6l.whl", hash = "sha256:0649f83fa0f44f18627c00b2a9a60e5c3486a34799b2c874f2b3945b76048a67", size = 22617914, upload-time = "2026-03-06T21:20:48.282Z" }, + { url = "https://files.pythonhosted.org/packages/6f/34/2e5cd576d312eb1131b615f49ee95ff6efb740965324843617adae729cf2/uv-0.10.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:880dd4cffe4bd184e8871ddf4c7d3c3b042e1f16d2682310644aa8d61eaea3e6", size = 21778779, upload-time = "2026-03-06T21:21:01.804Z" }, + { url = "https://files.pythonhosted.org/packages/89/35/684f641de4de2b20db7d2163c735b2bb211e3b3c84c241706d6448e5e868/uv-0.10.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a7a784254380552398a6baf4149faf5b31a4003275f685c28421cf8197178a08", size = 20384301, upload-time = "2026-03-06T21:21:04.089Z" }, + { url = "https://files.pythonhosted.org/packages/eb/5c/7170cfd1b4af09b435abc5a89ff315af130cf4a5082e5eb1206ee46bba67/uv-0.10.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:5ea0e8598fa012cfa4480ecad4d112bc70f514157c3cc1555a7611c7b6b1ab0a", size = 22226893, upload-time = "2026-03-06T21:20:50.902Z" }, + { url = "https://files.pythonhosted.org/packages/43/5c/68a17934dc8a2897fd7928b1c03c965373a820dc182aad96f1be6cce33a1/uv-0.10.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:2d6b5367e9bf87eca51c0f2ecda26a1ff931e41409977b4f0a420de2f3e617cf", size = 22233832, upload-time = "2026-03-06T21:21:11.748Z" }, + { url = "https://files.pythonhosted.org/packages/00/10/d262172ac59b669ca9c006bcbdb49c1a168cc314a5de576a4bb476dfab4c/uv-0.10.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd04e34db27f9a1d5a0871980edc9f910bb11afbc4abca8234d5a363cbe63c04", size = 22192193, upload-time = "2026-03-06T21:20:59.48Z" }, + { url = "https://files.pythonhosted.org/packages/a2/e6/f75fef1e3e5b0cf3592a4c35ed5128164ef2e6bd6a2570a0782c0baf6d4b/uv-0.10.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:547deb57311fc64e4a6b8336228fca4cb4dcbeabdc6e85f14f7804dcd0bc8cd2", size = 23571687, upload-time = "2026-03-06T21:20:45.403Z" }, + { url = "https://files.pythonhosted.org/packages/31/28/4b1ee6f4aa0e1b935e66b6018691258d1b702ef9c5d8c71e853564ad0a3a/uv-0.10.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0091b6d0b666640d7407a433860184f77667077b73564e86d49c2a851f073a8", size = 24418225, upload-time = "2026-03-06T21:21:09.459Z" }, + { url = "https://files.pythonhosted.org/packages/39/a2/5e67987f8d55eeecca7d8f4e94ac3e973fa1e8aaf426fcb8f442e9f7e2bc/uv-0.10.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81b2286e6fd869e3507971f39d14829c03e2e31caa8ecc6347b0ffacabb95a5b", size = 23555724, upload-time = "2026-03-06T21:20:54.085Z" }, + { url = "https://files.pythonhosted.org/packages/79/34/b104c413079874493eed7bf11838b47b697cf1f0ed7e9de374ea37b4e4e0/uv-0.10.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c9d6deb30edbc22123be75479f99fb476613eaf38a8034c0e98bba24a344179", size = 23438145, upload-time = "2026-03-06T21:21:26.866Z" }, + { url = "https://files.pythonhosted.org/packages/27/8a/cad762b3e9bfb961b68b2ae43a258a92b522918958954b50b09dcb14bb4e/uv-0.10.9-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:24b1ce6d626e06c4582946b6af07b08a032fcccd81fe54c3db3ed2d1c63a97dc", size = 22326765, upload-time = "2026-03-06T21:21:14.283Z" }, + { url = "https://files.pythonhosted.org/packages/a7/62/7e066f197f3eb8f8f71e25d703a29c89849c9c047240c1223e29bc0a37e4/uv-0.10.9-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fa3401780273d96a2960dbeab58452ce1b387ad8c5da25be6221c0188519e21d", size = 23215175, upload-time = "2026-03-06T21:21:29.673Z" }, + { url = "https://files.pythonhosted.org/packages/7e/06/51db93b5edb8b0202c0ec6caf3f24384f5abdfc180b6376a3710223fd56f/uv-0.10.9-py3-none-musllinux_1_1_i686.whl", hash = "sha256:8f94a31832d2b4c565312ea17a71b8dd2f971e5aa570c5b796a27b2c9fcdb163", size = 22784507, upload-time = "2026-03-06T21:21:20.676Z" }, + { url = "https://files.pythonhosted.org/packages/96/34/1db511d9259c1f32e5e094133546e5723e183a9ba2c64f7ca6156badddee/uv-0.10.9-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:842c39c19d9072f1ad53c71bb4ecd1c9caa311d5de9d19e09a636274a6c95e2e", size = 23660703, upload-time = "2026-03-06T21:21:06.667Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a0/58388abb252c7a37bc67422fce3a6b87404ea3fac44ca20132a4ba502235/uv-0.10.9-py3-none-win32.whl", hash = "sha256:ed44047c602449916ba18a8596715ef7edbbd00859f3db9eac010dc62a0edd30", size = 21524142, upload-time = "2026-03-06T21:21:18.246Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e9/adf7a12136573937d12ac189569e2e90e7fad18b458192083df6986f3013/uv-0.10.9-py3-none-win_amd64.whl", hash = "sha256:af79552276d8bd622048ab2d67ec22120a6af64d83963c46b1482218c27b571f", size = 24103389, upload-time = "2026-03-06T21:20:56.495Z" }, + { url = "https://files.pythonhosted.org/packages/5e/49/4971affd9c62d26b3ff4a84dc6432275be72d9615d95f7bb9e027beeeed8/uv-0.10.9-py3-none-win_arm64.whl", hash = "sha256:47e18a0521d76293d4f60d129f520b18bddf1976b4a47b50f0fcb04fb6a9d40f", size = 22454171, upload-time = "2026-03-06T21:21:24.596Z" }, ] [[package]] name = "virtualenv" -version = "21.1.0" +version = "21.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, @@ -2105,9 +2105,9 @@ dependencies = [ { name = "python-discovery" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/c9/18d4b36606d6091844daa3bd93cf7dc78e6f5da21d9f21d06c221104b684/virtualenv-21.1.0.tar.gz", hash = "sha256:1990a0188c8f16b6b9cf65c9183049007375b26aad415514d377ccacf1e4fb44", size = 5840471, upload-time = "2026-02-27T08:49:29.702Z" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/92/58199fe10049f9703c2666e809c4f686c54ef0a68b0f6afccf518c0b1eb9/virtualenv-21.2.0.tar.gz", hash = "sha256:1720dc3a62ef5b443092e3f499228599045d7fea4c79199770499df8becf9098", size = 5840618, upload-time = "2026-03-09T17:24:38.013Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/55/896b06bf93a49bec0f4ae2a6f1ed12bd05c8860744ac3a70eda041064e4d/virtualenv-21.1.0-py3-none-any.whl", hash = "sha256:164f5e14c5587d170cf98e60378eb91ea35bf037be313811905d3a24ea33cc07", size = 5825072, upload-time = "2026-02-27T08:49:27.516Z" }, + { url = "https://files.pythonhosted.org/packages/c6/59/7d02447a55b2e55755011a647479041bc92a82e143f96a8195cb33bd0a1c/virtualenv-21.2.0-py3-none-any.whl", hash = "sha256:1bd755b504931164a5a496d217c014d098426cddc79363ad66ac78125f9d908f", size = 5825084, upload-time = "2026-03-09T17:24:35.378Z" }, ] [[package]] diff --git a/go-sdk/pkg/api/client.go b/go-sdk/pkg/api/client.go index f8abbf99cbc18..fd7b77fd3954c 100644 --- a/go-sdk/pkg/api/client.go +++ b/go-sdk/pkg/api/client.go @@ -61,7 +61,7 @@ func (c *Client) WithBearerToken(token string) (ClientInterface, error) { // We don't use SetAuthToken/SetAuthScheme, as that produces a (valid, but annoying) warning about using Auth // over HTTP: "Using sensitive credentials in HTTP mode is not secure." It's a time-limited-token though, so we - // can reasonably ignore that here and setting the header directly by-passes that + // can reasonably ignore that here and setting the header directly bypasses that rc.SetHeader("Authorization", fmt.Sprintf("Bearer %s", token)) opts := []ClientOption{ diff --git a/pyproject.toml b/pyproject.toml index 84a7f84f5b955..08b0195a86234 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -530,7 +530,7 @@ packages = [] "apache-airflow-providers-amazon[s3fs]", ] "uv" = [ - "uv>=0.10.8", + "uv>=0.10.9", ] diff --git a/scripts/tools/setup_breeze b/scripts/tools/setup_breeze index 7f2d54ccea7db..17bdc220fcebf 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.10.8" +UV_VERSION="0.10.9" function manual_instructions() { echo From d7ecffacad6a690add8985c9eede2b356c7e1d57 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 22:03:29 +0100 Subject: [PATCH 38/50] [v3-1-test] Make example_xcom resistant to escaping issues. (#63200) (#63268) (cherry picked from commit 900e5e222f8ed842918134572fd6a1c3c176cf0b) Co-authored-by: Jarek Potiuk --- .../src/airflow/example_dags/example_xcom.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/airflow-core/src/airflow/example_dags/example_xcom.py b/airflow-core/src/airflow/example_dags/example_xcom.py index 8b8bc5bebd770..8843537964239 100644 --- a/airflow-core/src/airflow/example_dags/example_xcom.py +++ b/airflow-core/src/airflow/example_dags/example_xcom.py @@ -78,12 +78,22 @@ def pull_value_from_bash_push(ti=None): 'echo "value_by_return"', ) + # This example shows a safe way of passing XCom values to a BashOperator via environment variables. + # The values are templated into the bash_command and then set as environment variables for the + # command to use. This is a recommended pattern for passing XCom values to BashOperator, as it avoids + # issues with quoting and escaping that can arise when trying to directly template XCom values + # into. bash_pull = BashOperator( task_id="bash_pull", bash_command='echo "bash pull demo" && ' - f'echo "The xcom pushed manually is {XComArg(bash_push, key="manually_pushed_value")}" && ' - f'echo "The returned_value xcom is {XComArg(bash_push)}" && ' + "echo \"The xcom pushed manually is '$MANUALLY_PUSHED_VALUE'\" && " + "echo \"The returned_value xcom is '$RETURNED_VALUE'\" && " 'echo "finished"', + env={ + "MANUALLY_PUSHED_VALUE": str(XComArg(bash_push, key="manually_pushed_value")), + "RETURNED_VALUE": str(XComArg(bash_push)), + }, + append_env=True, do_xcom_push=False, ) From a59a4800193343dea9ff18afa1d082759cbc4d1e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 22:18:47 +0100 Subject: [PATCH 39/50] =?UTF-8?q?[v3-1-test]=20fix=20Inconsistent=20XCom?= =?UTF-8?q?=20Return=20Type=20in=20Mapped=20Task=20Groups=20with=20Dynamic?= =?UTF-8?q?=20=E2=80=A6=20(#59104)=20(#63293)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix Inconsistent XCom Return Type in Mapped Task Groups with Dynamic Task Mapping * add unit test for xcom_pull * remove asc func (cherry picked from commit df2e2b831b4a9f2c13c109fa609579d20fffac39) Co-authored-by: Henry Chen --- .../src/airflow/models/taskinstance.py | 10 ++- .../tests/unit/models/test_taskinstance.py | 65 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/airflow-core/src/airflow/models/taskinstance.py b/airflow-core/src/airflow/models/taskinstance.py index 7d58046d03ac2..95a4430f9acbf 100644 --- a/airflow-core/src/airflow/models/taskinstance.py +++ b/airflow-core/src/airflow/models/taskinstance.py @@ -1847,6 +1847,7 @@ def xcom_pull( ) -> Any: """:meta private:""" # noqa: D400 # This is only kept for compatibility in tests for now while AIP-72 is in progress. + if dag_id is None: dag_id = self.dag_id if run_id is None: @@ -1878,12 +1879,15 @@ def xcom_pull( ).first() if first is None: # No matching XCom at all. return default + if map_indexes is not None or first.map_index < 0: return XComModel.deserialize_value(first) - # raise RuntimeError("Nothing should hit this anymore") - - # TODO: TaskSDK: We should remove this, but many tests still currently call `ti.run()`. See #45549 + return LazyXComSelectSequence.from_select( + query.with_only_columns(XComModel.value).order_by(None), + order_by=[XComModel.map_index.expression], + session=session, + ) # At this point either task_ids or map_indexes is explicitly multi-value. # Order return values to match task_ids and map_indexes ordering. diff --git a/airflow-core/tests/unit/models/test_taskinstance.py b/airflow-core/tests/unit/models/test_taskinstance.py index f3ffcedf21893..615c40ac91864 100644 --- a/airflow-core/tests/unit/models/test_taskinstance.py +++ b/airflow-core/tests/unit/models/test_taskinstance.py @@ -3029,6 +3029,71 @@ def cmds(): out_lines = [line.strip() for line in f] assert out_lines == ["hello FOO", "goodbye FOO", "hello BAR", "goodbye BAR"] + def test_xcom_pull_unmapped_task(self, dag_maker, session): + """ + Test that xcom_pull from unmapped task returns single deserialized value. + + For unmapped tasks with map_index < 0, xcom_pull should return the single value, + not a LazyXComSelectSequence. + """ + + with dag_maker(dag_id="test_xcom_unmapped", session=session): + upstream = PythonOperator( + task_id="unmapped_task", + python_callable=lambda: {"key": "value"}, + ) + downstream = PythonOperator( + task_id="downstream", + python_callable=lambda: None, + ) + upstream >> downstream + + dag_run = dag_maker.create_dagrun(logical_date=timezone.utcnow()) + + # Run upstream task to push xcom + dag_maker.run_ti("unmapped_task", dag_run=dag_run, session=session) + + # Get downstream task instance + ti_downstream = dag_run.get_task_instance("downstream", session=session) + ti_downstream.task = dag_maker.dag.task_dict["downstream"] + + # Pull xcom - should return single dict value, not LazyXComSelectSequence + result = ti_downstream.xcom_pull(task_ids="unmapped_task", session=session) + assert isinstance(result, dict), f"Expected dict for unmapped task, got {type(result)}" + assert result == {"key": "value"} + + def test_xcom_pull_returns_lazy_sequence_for_mapped_xcom(self, dag_maker, session): + """ + Test that xcom_pull returns LazyXComSelectSequence when XComs are mapped (map_index >= 0) + and map_indexes is not specified. + """ + from airflow.models.xcom import LazyXComSelectSequence + + with dag_maker(dag_id="test_xcom_mapped_values", session=session): + + @task + def push_values(val): + return val + + upstream = push_values.expand(val=[2, 4]) + downstream = PythonOperator( + task_id="downstream", + python_callable=lambda: None, + ) + upstream >> downstream + + dag_run = dag_maker.create_dagrun(logical_date=timezone.utcnow()) + dag_maker.run_ti(upstream.operator.task_id, map_index=0, dag_run=dag_run, session=session) + dag_maker.run_ti(upstream.operator.task_id, map_index=1, dag_run=dag_run, session=session) + + ti_downstream = dag_run.get_task_instance("downstream", session=session) + ti_downstream.task = dag_maker.dag.task_dict["downstream"] + + result = ti_downstream.xcom_pull(task_ids=upstream.operator.task_id, session=session) + assert isinstance(result, LazyXComSelectSequence), ( + f"Expected LazyXComSelectSequence for mapped XComs, got {type(result)}" + ) + def _get_lazy_xcom_access_expected_sql_lines() -> list[str]: backend = os.environ.get("BACKEND") From 5fd3fa5a79013223ba2349ece780185ed13920a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:26:42 +0100 Subject: [PATCH 40/50] [v3-1-test] Fix breeze worktree issue (#62905) (#63304) * Fix Breeze commands failing in git worktrees * Refine worktree fix: address review feedback (YAML formatting and path safety) * Fix unit tests: use valid paths for git worktree detection tests (cherry picked from commit bdb9a7e042b9951160f654da37cc7c40be18bfb0) Co-authored-by: Subham --- .../src/airflow_breeze/params/shell_params.py | 22 ++++ .../utils/docker_command_utils.py | 36 +++--- .../src/airflow_breeze/utils/path_utils.py | 26 +++++ dev/breeze/tests/test_git_worktree.py | 106 ++++++++++++++++++ 4 files changed, 176 insertions(+), 14 deletions(-) create mode 100644 dev/breeze/tests/test_git_worktree.py diff --git a/dev/breeze/src/airflow_breeze/params/shell_params.py b/dev/breeze/src/airflow_breeze/params/shell_params.py index d38880b1ecabe..5565806efee75 100644 --- a/dev/breeze/src/airflow_breeze/params/shell_params.py +++ b/dev/breeze/src/airflow_breeze/params/shell_params.py @@ -103,6 +103,7 @@ SCRIPTS_CI_DOCKER_COMPOSE_PROVIDERS_AND_TESTS_SOURCES_PATH, SCRIPTS_CI_DOCKER_COMPOSE_REMOVE_SOURCES_PATH, SCRIPTS_CI_DOCKER_COMPOSE_TESTS_SOURCES_PATH, + get_main_git_dir_for_worktree, ) from airflow_breeze.utils.run_utils import commit_sha, run_command from airflow_breeze.utils.shared_options import get_forced_answer, get_verbose @@ -385,6 +386,7 @@ def compose_file(self) -> str: compose_file_list.append(SCRIPTS_CI_DOCKER_COMPOSE_BASE_PATH) self.add_docker_in_docker(compose_file_list) + self.add_git_worktree_mount(compose_file_list) compose_file_list.extend(backend_files) compose_file_list.append(SCRIPTS_CI_DOCKER_COMPOSE_FILES_PATH) if os.environ.get("CI", "false") == "true": @@ -530,6 +532,26 @@ def add_docker_in_docker(self, compose_file_list: list[Path]): # the /var/run/docker.sock is available. See https://github.com/docker/for-mac/issues/6545 compose_file_list.append(SCRIPTS_CI_DOCKER_COMPOSE_DOCKER_SOCKET_PATH) + def add_git_worktree_mount(self, compose_file_list: list[Path]): + main_git_directory = get_main_git_dir_for_worktree() + if main_git_directory: + get_console().print( + f"[info]Detected git worktree. Mounting main git directory: {main_git_directory}[/]" + ) + generated_compose_file = SCRIPTS_CI_DOCKER_COMPOSE_PATH / "_generated_git_worktree_mount.yml" + generated_compose_file.write_text( + f"""--- +services: + airflow: + volumes: + - type: bind + source: "{main_git_directory}" + target: "{main_git_directory}" + read_only: true +""" + ) + compose_file_list.append(generated_compose_file) + @cached_property def rootless_docker(self) -> bool: return is_docker_rootless() diff --git a/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py b/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py index 3e717569ddb45..e5a49a94dc3ac 100644 --- a/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py +++ b/dev/breeze/src/airflow_breeze/utils/docker_command_utils.py @@ -37,6 +37,7 @@ SCRIPTS_DOCKER_PATH, cleanup_python_generated_files, create_mypy_volume_if_needed, + get_main_git_dir_for_worktree, ) from airflow_breeze.utils.shared_options import get_verbose from airflow_breeze.utils.visuals import ASCIIART, ASCIIART_STYLE, CHEATSHEET, CHEATSHEET_STYLE @@ -659,21 +660,28 @@ def fix_ownership_using_docker(quiet: bool = True): "run", "-v", f"{AIRFLOW_ROOT_PATH}:/opt/airflow/", - "-e", - f"HOST_OS={get_host_os()}", - "-e", - f"HOST_USER_ID={get_host_user_id()}", - "-e", - f"HOST_GROUP_ID={get_host_group_id()}", - "-e", - f"VERBOSE={str(get_verbose()).lower()}", - "-e", - f"DOCKER_IS_ROOTLESS={is_docker_rootless()}", - "--rm", - "-t", - OWNERSHIP_CLEANUP_DOCKER_TAG, - "/opt/airflow/scripts/in_container/run_fix_ownership.py", ] + main_git_directory = get_main_git_dir_for_worktree() + if main_git_directory: + cmd.extend(["-v", f"{main_git_directory}:{main_git_directory}:ro"]) + cmd.extend( + [ + "-e", + f"HOST_OS={get_host_os()}", + "-e", + f"HOST_USER_ID={get_host_user_id()}", + "-e", + f"HOST_GROUP_ID={get_host_group_id()}", + "-e", + f"VERBOSE={str(get_verbose()).lower()}", + "-e", + f"DOCKER_IS_ROOTLESS={is_docker_rootless()}", + "--rm", + "-t", + OWNERSHIP_CLEANUP_DOCKER_TAG, + "/opt/airflow/scripts/in_container/run_fix_ownership.py", + ] + ) run_command(cmd, text=True, check=False, quiet=quiet) diff --git a/dev/breeze/src/airflow_breeze/utils/path_utils.py b/dev/breeze/src/airflow_breeze/utils/path_utils.py index 6ee4863a093d2..b7081dbae351c 100644 --- a/dev/breeze/src/airflow_breeze/utils/path_utils.py +++ b/dev/breeze/src/airflow_breeze/utils/path_utils.py @@ -422,3 +422,29 @@ def cleanup_python_generated_files(): get_console().print("You can also remove those files manually using sudo.") if get_verbose(): get_console().print("[info]Cleaned") + + +def get_main_git_dir_for_worktree() -> Path | None: + """ + Detect if we are in a git worktree and return the main repository's .git directory. + + Git worktrees store a ``.git`` *file* (not a directory) containing a ``gitdir:`` reference + pointing to ``/.git/worktrees/``. This helper resolves that reference + (handling both absolute and relative paths) and returns the main ``.git`` directory + (i.e. the grandparent of the ``gitdir`` path). + + :return: Absolute path to the main repository's ``.git`` directory, or ``None`` + if the current checkout is not a worktree. + """ + git_path = AIRFLOW_ROOT_PATH / ".git" + if git_path.is_file(): + git_content = git_path.read_text().strip() + if git_content.startswith("gitdir:"): + gitdir = Path(git_content.removeprefix("gitdir:").strip()) + if not gitdir.is_absolute(): + gitdir = (AIRFLOW_ROOT_PATH / gitdir).resolve() + # gitdir points to /.git/worktrees/ + # .parent.parent gives us /.git + main_git_dir = gitdir.parent.parent + return main_git_dir if main_git_dir.is_dir() else None + return None diff --git a/dev/breeze/tests/test_git_worktree.py b/dev/breeze/tests/test_git_worktree.py new file mode 100644 index 0000000000000..a0c9d439bd259 --- /dev/null +++ b/dev/breeze/tests/test_git_worktree.py @@ -0,0 +1,106 @@ +# 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 + +from pathlib import Path +from unittest import mock + +import pytest + +from airflow_breeze.utils.path_utils import get_main_git_dir_for_worktree + + +class TestGetMainGitDirForWorktree: + """Tests for get_main_git_dir_for_worktree detection.""" + + def test_returns_none_when_dot_git_is_directory(self, tmp_path): + """Standard clone: .git is a directory, not a worktree.""" + git_dir = tmp_path / ".git" + git_dir.mkdir() + with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path): + assert get_main_git_dir_for_worktree() is None + + def test_returns_none_when_dot_git_missing(self, tmp_path): + """No .git at all — not a git repo.""" + with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path): + assert get_main_git_dir_for_worktree() is None + + def test_returns_none_when_dot_git_file_without_gitdir_prefix(self, tmp_path): + """.git file exists but does not start with 'gitdir: '.""" + git_file = tmp_path / ".git" + git_file.write_text("something unexpected\n") + with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path): + assert get_main_git_dir_for_worktree() is None + + def test_absolute_gitdir_path(self, tmp_path): + """Worktree with an absolute gitdir path resolves to the main .git directory.""" + # Simulate: /main-repo/.git/worktrees/my-worktree + main_repo = tmp_path / "main-repo" + main_git = main_repo / ".git" + worktree_gitdir = main_git / "worktrees" / "my-worktree" + worktree_gitdir.mkdir(parents=True) + + worktree_dir = tmp_path / "my-worktree" + worktree_dir.mkdir() + (worktree_dir / ".git").write_text(f"gitdir: {worktree_gitdir}\n") + + with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", worktree_dir): + result = get_main_git_dir_for_worktree() + assert result is not None + assert result == main_git + + def test_relative_gitdir_path(self, tmp_path): + """Worktree with a relative gitdir path is resolved correctly.""" + # Simulate: main-repo/.git/worktrees/my-worktree + main_repo = tmp_path / "main-repo" + main_git = main_repo / ".git" + worktree_gitdir = main_git / "worktrees" / "my-worktree" + worktree_gitdir.mkdir(parents=True) + + worktree_dir = tmp_path / "my-worktree" + worktree_dir.mkdir() + # Write a relative path from worktree_dir to worktree_gitdir + relative_gitdir = Path("../main-repo/.git/worktrees/my-worktree") + (worktree_dir / ".git").write_text(f"gitdir: {relative_gitdir}\n") + + with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", worktree_dir): + result = get_main_git_dir_for_worktree() + assert result is not None + assert result.resolve() == main_git.resolve() + + @pytest.mark.parametrize( + "gitdir_content", + [ + "gitdir: {path}/worktrees/wt\n", + "gitdir: {path}/worktrees/wt", + "gitdir: {path}/worktrees/wt \n", + ], + ids=["trailing-newline", "no-trailing-newline", "extra-whitespace"], + ) + def test_strips_whitespace_from_gitdir(self, tmp_path, gitdir_content): + """Whitespace and trailing newlines are stripped from the gitdir content.""" + main_repo = tmp_path / "main-repo" + main_git = main_repo / ".git" + (main_git / "worktrees" / "wt").mkdir(parents=True) + + content = gitdir_content.format(path=main_git) + (tmp_path / ".git").write_text(content) + + with mock.patch("airflow_breeze.utils.path_utils.AIRFLOW_ROOT_PATH", tmp_path): + result = get_main_git_dir_for_worktree() + assert result is not None + assert result == main_git From a605c2ccc87a0be9a6563ba07954f425fccdd23a Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Tue, 10 Mar 2026 23:31:40 +0100 Subject: [PATCH 41/50] [v3-1-test] Improve translation completeness checker (required keys, coverage, unused) (#62983) (#63307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improve translation completeness checker: required keys, coverage, unused - Required keys: EN base + plural forms for locale when EN has {{count}} - Merge Extra and Unused into single Unused (keys not required) - Table: Required (base EN), Required (plural), Total required, Translated, Missing, Coverage (translated/total), TODOs, Unused - Coverage uses only real translations (exclude TODO placeholders) - Rename --remove-extra to --remove-unused; remove_unused_translations() - Update docs, SKILL, README, and help SVG * Add translation:pt-BR section to boring-cyborg config * Revert "Add translation:pt-BR section to boring-cyborg config" This reverts commit dda93a9ef391741157ce150d2bf2d1256da198d6. * Apply ruff format to ui_commands.py * Update breeze docs: regenerate check-translation-completeness output * Update ui_commands.py * fix(breeze): translation checker row style (red for missing keys) Fix unreachable red branch in style logic: use red for missing keys, yellow for todos/unused, bold green when all clear. Also remove unused missing_counts param and rename extra_keys to unused_keys. --------- (cherry picked from commit 69257f04ee0d62e6e3a25996fb24d033143cc7df) Co-authored-by: André Ahlert Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/airflow/ui/public/i18n/README.md | 6 +- dev/breeze/doc/10_ui_tasks.rst | 6 +- ...tput_ui_check-translation-completeness.svg | 6 +- ...tput_ui_check-translation-completeness.txt | 2 +- .../airflow_breeze/commands/ui_commands.py | 246 ++++++++++-------- .../commands/ui_commands_config.py | 2 +- dev/breeze/tests/test_ui_commands.py | 77 +++++- 7 files changed, 218 insertions(+), 127 deletions(-) diff --git a/airflow-core/src/airflow/ui/public/i18n/README.md b/airflow-core/src/airflow/ui/public/i18n/README.md index e219db4e8302e..a58230a42eab1 100644 --- a/airflow-core/src/airflow/ui/public/i18n/README.md +++ b/airflow-core/src/airflow/ui/public/i18n/README.md @@ -332,16 +332,16 @@ Adding missing translations (with `TODO: translate` prefix): breeze ui check-translation-completeness --language --add-missing ``` -You can also remove extra translations from the language of your choice: +You can also remove unused translations from the language of your choice: ```bash -breeze ui check-translation-completeness --language --remove-extra +breeze ui check-translation-completeness --language --remove-unused ``` Or from all languages: ```bash -breeze ui check-translation-completeness --remove-extra +breeze ui check-translation-completeness --remove-unused ``` The script is also added as a prek hook (manual) so that it can be run from within `prek` and CI: diff --git a/dev/breeze/doc/10_ui_tasks.rst b/dev/breeze/doc/10_ui_tasks.rst index 0af6f739b2419..c1f7c04c3047c 100644 --- a/dev/breeze/doc/10_ui_tasks.rst +++ b/dev/breeze/doc/10_ui_tasks.rst @@ -62,11 +62,11 @@ Example usage: # Add missing translations with TODO markers breeze ui check-translation-completeness --add-missing - # Remove extra translations not present in English - breeze ui check-translation-completeness --remove-extra + # Remove unused translations (keys not required) + breeze ui check-translation-completeness --remove-unused # Fix translations for a specific language - breeze ui check-translation-completeness --language de --add-missing --remove-extra + breeze ui check-translation-completeness --language de --add-missing --remove-unused ----- diff --git a/dev/breeze/doc/images/output_ui_check-translation-completeness.svg b/dev/breeze/doc/images/output_ui_check-translation-completeness.svg index c05a8d5f6ce0f..26aff21705c42 100644 --- a/dev/breeze/doc/images/output_ui_check-translation-completeness.svg +++ b/dev/breeze/doc/images/output_ui_check-translation-completeness.svg @@ -105,9 +105,9 @@ Check completeness of UI translations. ╭─ Translation options â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•® -│--language-lShow summary for a single language (e.g. en, de, pl, etc.)(TEXT)│ -│--add-missingAdd missing translations for all languages except English, prefixed with 'TODO: translate:'.│ -│--remove-extraRemove extra translations that are present in the language but missing in English.│ +│--language-lShow summary for a single language (e.g. en, de, pl, etc.)(TEXT)│ +│--add-missingAdd missing translations for all languages except English, prefixed with 'TODO: translate:'.│ +│--remove-unusedRemove unused translations (keys present in the language but not required).│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Common options â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â•® │--verbose-vPrint verbose information about performed steps.│ diff --git a/dev/breeze/doc/images/output_ui_check-translation-completeness.txt b/dev/breeze/doc/images/output_ui_check-translation-completeness.txt index 1c09634e8b5a9..ce06792e62e1e 100644 --- a/dev/breeze/doc/images/output_ui_check-translation-completeness.txt +++ b/dev/breeze/doc/images/output_ui_check-translation-completeness.txt @@ -1 +1 @@ -9cb14c5898ad3622ce8112dcca284dea +a59814821bc3477be5f4451ce6e61290 diff --git a/dev/breeze/src/airflow_breeze/commands/ui_commands.py b/dev/breeze/src/airflow_breeze/commands/ui_commands.py index 6faf576a484ae..44a7a4b41981c 100644 --- a/dev/breeze/src/airflow_breeze/commands/ui_commands.py +++ b/dev/breeze/src/airflow_breeze/commands/ui_commands.py @@ -96,15 +96,15 @@ def char_key(c: str) -> tuple: class LocaleSummary(NamedTuple): """ - Summary of missing and extra translation keys for a file, per locale. + Summary of missing and unused translation keys for a file, per locale. Attributes: - missing_keys: A dictionary mapping locale codes to lists of missing translation keys. - extra_keys: A dictionary mapping locale codes to lists of extra translation keys. + missing_keys: Required keys that the locale does not have. + unused_keys: Keys present in the locale that are not required (never used at runtime). """ missing_keys: dict[str, list[str]] - extra_keys: dict[str, list[str]] + unused_keys: dict[str, list[str]] class LocaleFiles(NamedTuple): @@ -140,9 +140,17 @@ def get_plural_base(key: str, suffixes: list[str]) -> str | None: return None -def expand_plural_keys(keys: set[str], lang: str) -> set[str]: +COUNT_PLACEHOLDER = "{{count}}" + + +def expand_plural_keys(keys: set[str], lang: str, en_key_to_value: dict[str, str] | None = None) -> set[str]: """ - For a set of keys, expand all plural bases to include all required suffixes for the language. + For a set of keys, expand plural bases to include required suffixes for the language. + + When en_key_to_value is provided, only expand a base to all plural forms when at least + one of the English values for that base contains {{count}}. Keys without {{count}} + (e.g. fixed "1 Error") are not expanded, so locales are not required to have + unused forms like error_other when the source only has error_one. """ console = get_console() suffixes = PLURAL_SUFFIXES.get(lang) @@ -160,6 +168,11 @@ def expand_plural_keys(keys: set[str], lang: str) -> set[str]: base_to_suffixes.setdefault(base, set()).add(key[len(base) :]) expanded = set(keys) for base in base_to_suffixes.keys(): + if en_key_to_value is not None: + en_keys_for_base = [k for k in keys if get_plural_base(k, suffixes) == base] + any_has_count = any(COUNT_PLACEHOLDER in en_key_to_value.get(k, "") for k in en_keys_for_base) + if not any_has_count: + continue for suffix in suffixes: expanded.add(base + suffix) return expanded @@ -190,6 +203,18 @@ def flatten_keys(d: dict, prefix: str = "") -> list[str]: return keys +def flatten_keys_to_values(d: dict, prefix: str = "") -> dict[str, str]: + """Build a flat key -> value map for leaf string values (for i18n JSON).""" + result: dict[str, str] = {} + for k, v in d.items(): + full_key = f"{prefix}.{k}" if prefix else k + if isinstance(v, dict): + result.update(flatten_keys_to_values(v, full_key)) + elif isinstance(v, str): + result[full_key] = v + return result + + def compare_keys( locale_files: list[LocaleFiles], ) -> tuple[dict[str, LocaleSummary], dict[str, dict[str, int]]]: @@ -197,7 +222,7 @@ def compare_keys( Compare all non-English locales with English locale only. Returns a tuple: - - summary dict: filename -> LocaleSummary(missing, extra) + - summary dict: filename -> LocaleSummary(missing_keys, unused_keys) - missing_counts dict: filename -> {locale: count_of_missing_keys} """ all_files: set[str] = set() @@ -219,25 +244,32 @@ def compare_keys( key_sets.append(LocaleKeySet(locale=lf.locale, keys=keys)) keys_by_locale = {ks.locale: ks.keys for ks in key_sets} en_keys = keys_by_locale.get("en", set()) or set() - # Expand English keys for all required plural forms in each language - expanded_en_keys = {lang: expand_plural_keys(en_keys, lang) for lang in keys_by_locale.keys()} + en_key_to_value: dict[str, str] = {} + en_path = LOCALES_DIR / "en" / filename + if en_path.exists(): + try: + en_data = load_json(en_path) + en_key_to_value = flatten_keys_to_values(en_data) + except Exception as e: + get_console().print(f"Error loading en values from {en_path}: {e}") + # Required = EN keys plus, for bases with {{count}} in EN, all plural forms for the locale missing_keys: dict[str, list[str]] = {} - extra_keys: dict[str, list[str]] = {} + unused_keys: dict[str, list[str]] = {} missing_counts[filename] = {} for ks in key_sets: if ks.locale == "en": continue - required_keys = expanded_en_keys.get(ks.locale, en_keys) + required_keys = expand_plural_keys(en_keys, ks.locale, en_key_to_value) if ks.keys is None: missing_keys[ks.locale] = list(required_keys) - extra_keys[ks.locale] = [] + unused_keys[ks.locale] = [] missing_counts[filename][ks.locale] = len(required_keys) else: missing = list(required_keys - ks.keys) missing_keys[ks.locale] = missing - extra_keys[ks.locale] = list(ks.keys - required_keys) + unused_keys[ks.locale] = sorted(ks.keys - required_keys) missing_counts[filename][ks.locale] = len(missing) - summary[filename] = LocaleSummary(missing_keys=missing_keys, extra_keys=extra_keys) + summary[filename] = LocaleSummary(missing_keys=missing_keys, unused_keys=unused_keys) return summary, missing_counts @@ -294,15 +326,15 @@ def print_language_summary(locale_files: list[LocaleFiles], summary: dict[str, L for lf in sorted(locale_files): locale = lf.locale file_missing: dict[str, list[str]] = {} - file_extra: dict[str, list[str]] = {} + file_unused: dict[str, list[str]] = {} for filename, diff in sorted(summary.items()): missing_keys = diff.missing_keys.get(locale, []) - extra_keys = diff.extra_keys.get(locale, []) + unused_keys = diff.unused_keys.get(locale, []) if missing_keys: file_missing[filename] = missing_keys - if extra_keys: - file_extra[filename] = extra_keys - if file_missing or file_extra: + if unused_keys: + file_unused[filename] = unused_keys + if file_missing or file_unused: if locale == "en": continue console.print(Panel(f"[bold yellow]{locale}[/bold yellow]", style="blue")) @@ -313,34 +345,38 @@ def print_language_summary(locale_files: list[LocaleFiles], summary: dict[str, L console.print(f" [magenta]{filename}[/magenta]:") for k in keys: console.print(f" [yellow]{k}[/yellow]") - if file_extra: - found_difference = True - console.print("[red] Extra keys (need to be removed/updated):[/red]") - for filename, keys in file_extra.items(): + if file_unused: + console.print("[yellow] Unused keys (not required, can be removed):[/yellow]") + for filename, keys in file_unused.items(): console.print(f" [magenta]{filename}[/magenta]:") for k in keys: - console.print(f" [yellow]{k}[/yellow]") + console.print(f" [dim]{k}[/dim]") return found_difference +def is_todo_value(s: str) -> bool: + """Return True if the string is a TODO placeholder (e.g. 'TODO: translate: ...').""" + return isinstance(s, str) and s.strip().startswith("TODO: translate") + + def count_todos(obj) -> int: """Count TODO: translate entries in a dict or list.""" if isinstance(obj, dict): return sum(count_todos(v) for v in obj.values()) if isinstance(obj, list): return sum(count_todos(v) for v in obj) - if isinstance(obj, str) and obj.strip().startswith("TODO: translate"): + if is_todo_value(obj): return 1 return 0 -def print_translation_progress(locale_files, missing_counts, summary): +def print_translation_progress(locale_files, summary): console = get_console() from rich.table import Table tables = defaultdict(lambda: Table(show_lines=True)) all_files = set() - coverage_per_language = {} # Collect total coverage per language + coverage_per_language = {} for lf in locale_files: all_files.update(lf.files) @@ -353,91 +389,94 @@ def print_translation_progress(locale_files, missing_counts, summary): table = tables[lang] table.title = f"Translation Progress: {lang}" table.add_column("File", style="bold cyan") - table.add_column("Missing", style="red") - table.add_column("Extra", style="yellow") - table.add_column("TODOs", style="magenta") + table.add_column("Required (base EN)", style="dim") + table.add_column("Required (plural)", style="dim") + table.add_column("Total required", style="bold") table.add_column("Translated", style="green") - table.add_column("Total", style="bold") + table.add_column("Missing", style="red") table.add_column("Coverage", style="bold") - table.add_column("Completed", style="bold") + table.add_column("TODOs", style="magenta") + table.add_column("Unused", style="yellow") + total_required_base = 0 + total_required_plural = 0 + total_required = 0 + total_translated = 0 total_missing = 0 - total_extra = 0 total_todos = 0 - total_translated = 0 - total_total = 0 + total_unused = 0 for filename in sorted(all_files): - file_path = Path(LOCALES_DIR / lang / filename) - # Always get total from English version en_path = Path(LOCALES_DIR / "en" / filename) - if en_path.exists(): - with open(en_path) as f: - en_data = json.load(f) - file_total = sum(1 for _ in flatten_keys(en_data)) - else: - file_total = 0 + file_path = Path(LOCALES_DIR / lang / filename) + diff = summary.get(filename, LocaleSummary({}, {})) + if not en_path.exists(): + continue + with open(en_path) as f: + en_data = json.load(f) + en_keys = set(flatten_keys(en_data)) + en_key_to_value = flatten_keys_to_values(en_data) + required_keys = expand_plural_keys(en_keys, lang, en_key_to_value) + required_base_en = len(en_keys) + required_plural = len(required_keys) - required_base_en + total_req = len(required_keys) + file_missing = len(diff.missing_keys.get(lang, [])) + file_unused = len(diff.unused_keys.get(lang, [])) if file_path.exists(): with open(file_path) as f: - data = json.load(f) - file_missing = missing_counts.get(filename, {}).get(lang, 0) - file_extra = len(summary.get(filename, LocaleSummary({}, {})).extra_keys.get(lang, [])) - - file_todos = count_todos(data) + lang_data = json.load(f) + lang_key_to_value = flatten_keys_to_values(lang_data) + file_translated = sum( + 1 + for k in required_keys + if k in lang_key_to_value and not is_todo_value(lang_key_to_value[k]) + ) + file_todos = sum( + 1 for k in required_keys if k in lang_key_to_value and is_todo_value(lang_key_to_value[k]) + ) if file_todos > 0: has_todos = True - file_translated = file_total - file_missing - # Coverage: translated / total - file_coverage_percent = 100 * file_translated / file_total if file_total else 100 - # Complete percent: (translated - todos) / translated - file_actual_translated = file_translated - file_todos - complete_percent = 100 * file_actual_translated / file_translated if file_translated else 100 - style = ( - "bold green" - if file_missing == 0 and file_extra == 0 and file_todos == 0 - else ( - "yellow" if file_missing < file_total or file_extra > 0 or file_todos > 0 else "red" - ) - ) else: - file_missing = file_total - file_extra = len(summary.get(filename, LocaleSummary({}, {})).extra_keys.get(lang, [])) - file_todos = 0 file_translated = 0 - file_coverage_percent = 0 - complete_percent = 0 + file_todos = 0 + file_coverage = 100 * file_translated / total_req if total_req else 100.0 + if file_missing > 0: style = "red" + elif file_todos > 0 or file_unused > 0: + style = "yellow" + else: + style = "bold green" table.add_row( f"[bold reverse]{filename}[/bold reverse]", + str(required_base_en), + str(required_plural), + str(total_req), + str(file_translated), str(file_missing), - str(file_extra), + f"{file_coverage:.1f}%", str(file_todos), - str(file_translated), - str(file_total), - f"{file_coverage_percent:.1f}%", - f"{complete_percent:.1f}%", + str(file_unused), style=style, ) + total_required_base += required_base_en + total_required_plural += required_plural + total_required += total_req + total_translated += file_translated total_missing += file_missing - total_extra += file_extra total_todos += file_todos - total_translated += file_translated - total_total += file_total - - # Calculate totals for this language - total_coverage_percent = 100 * total_translated / total_total if total_total else 100 - total_actual_translated = total_translated - total_todos - total_complete_percent = 100 * total_actual_translated / total_translated if total_translated else 100 + total_unused += file_unused - coverage_per_language[lang] = total_coverage_percent + total_coverage = 100 * total_translated / total_required if total_required else 100.0 + coverage_per_language[lang] = total_coverage table.add_row( "All files", + str(total_required_base), + str(total_required_plural), + str(total_required), + str(total_translated), str(total_missing), - str(total_extra), + f"{total_coverage:.1f}%", str(total_todos), - str(total_translated), - str(total_total), - f"{total_coverage_percent:.1f}%", - f"{total_complete_percent:.1f}%", - style="red" if total_complete_percent < 100 else "bold green", + str(total_unused), + style="red" if total_missing > 0 or total_todos > 0 or total_unused > 0 else "bold green", ) for _lang, table in tables.items(): @@ -510,16 +549,16 @@ def sort_dict_keys(obj): console.print(f"[green]Added missing translations to {lang_path}[/green]") -def remove_extra_translations(language: str, summary: dict[str, LocaleSummary]): +def remove_unused_translations(language: str, summary: dict[str, LocaleSummary]): """ - Remove extra translations for the selected language. + Remove unused translations for the selected language. - Removes keys that are present in the language file but missing in the English file. + Removes keys that are present in the language file but are not required. """ console = get_console() for filename, diff in summary.items(): - extra_keys = set(diff.extra_keys.get(language, [])) - if not extra_keys: + unused_keys = set(diff.unused_keys.get(language, [])) + if not unused_keys: continue lang_path = LOCALES_DIR / language / filename try: @@ -528,12 +567,12 @@ def remove_extra_translations(language: str, summary: dict[str, LocaleSummary]): console.print(f"[yellow]Failed to load {language} file {lang_path}: {e}[/yellow]") continue - # Helper to recursively remove extra keys + # Helper to recursively remove unused keys def remove_keys(dst, prefix=""): keys_to_remove = [] for k, v in list(dst.items()): full_key = f"{prefix}.{k}" if prefix else k - if full_key in extra_keys: + if full_key in unused_keys: keys_to_remove.append(k) elif isinstance(v, dict): remove_keys(v, full_key) @@ -554,7 +593,7 @@ def sort_dict_keys(obj): with open(lang_path, "w", encoding="utf-8") as f: json.dump(lang_data, f, ensure_ascii=False, indent=2) f.write("\n") # Ensure newline at the end of the file - console.print(f"[green]Removed {len(extra_keys)} extra translations from {lang_path}[/green]") + console.print(f"[green]Removed {len(unused_keys)} unused translations from {lang_path}[/green]") @click.group(cls=BreezeGroup, name="ui", help="Tools for UI development and maintenance") @@ -579,15 +618,15 @@ def ui_group(): help="Add missing translations for all languages except English, prefixed with 'TODO: translate:'.", ) @click.option( - "--remove-extra", + "--remove-unused", is_flag=True, default=False, - help="Remove extra translations that are present in the language but missing in English.", + help="Remove unused translations (keys present in the language but not required).", ) @option_verbose @option_dry_run def check_translation_completeness( - language: str | None = None, add_missing: bool = False, remove_extra: bool = False + language: str | None = None, add_missing: bool = False, remove_unused: bool = False ): locale_files = get_locale_files() console = get_console() @@ -606,13 +645,13 @@ def check_translation_completeness( for filename, diff in summary.items(): filtered_summary[filename] = LocaleSummary( missing_keys={lf.locale: diff.missing_keys.get(lf.locale, [])}, - extra_keys={lf.locale: diff.extra_keys.get(lf.locale, [])}, + unused_keys={lf.locale: diff.unused_keys.get(lf.locale, [])}, ) add_missing_translations(lf.locale, filtered_summary) # After adding, re-run the summary for all languages summary, missing_counts = compare_keys(get_locale_files()) - if remove_extra and language != "en": - # Loop through all languages except 'en' and remove extra translations + if remove_unused and language != "en": + # Loop through all languages except 'en' and remove unused translations if language: language_files = [lf for lf in locale_files if lf.locale == language] else: @@ -622,9 +661,9 @@ def check_translation_completeness( for filename, diff in summary.items(): filtered_summary[filename] = LocaleSummary( missing_keys={lf.locale: diff.missing_keys.get(lf.locale, [])}, - extra_keys={lf.locale: diff.extra_keys.get(lf.locale, [])}, + unused_keys={lf.locale: diff.unused_keys.get(lf.locale, [])}, ) - remove_extra_translations(lf.locale, filtered_summary) + remove_unused_translations(lf.locale, filtered_summary) # After removing, re-run the summary for all languages summary, missing_counts = compare_keys(get_locale_files()) if language: @@ -640,7 +679,7 @@ def check_translation_completeness( for filename, diff in summary.items(): filtered_summary[filename] = LocaleSummary( missing_keys={language: diff.missing_keys.get(language, [])}, - extra_keys={language: diff.extra_keys.get(language, [])}, + unused_keys={language: diff.unused_keys.get(language, [])}, ) lang_diff = print_language_summary( [lf for lf in locale_files if lf.locale == language], filtered_summary @@ -651,7 +690,6 @@ def check_translation_completeness( found_difference = found_difference or lang_diff has_todos, coverage_per_language = print_translation_progress( [lf for lf in locale_files if language is None or lf.locale == language], - missing_counts, summary, ) if not found_difference and not has_todos: diff --git a/dev/breeze/src/airflow_breeze/commands/ui_commands_config.py b/dev/breeze/src/airflow_breeze/commands/ui_commands_config.py index ea5b19a6808da..066005d3abf29 100644 --- a/dev/breeze/src/airflow_breeze/commands/ui_commands_config.py +++ b/dev/breeze/src/airflow_breeze/commands/ui_commands_config.py @@ -30,7 +30,7 @@ "options": [ "--language", "--add-missing", - "--remove-extra", + "--remove-unused", ], }, ], diff --git a/dev/breeze/tests/test_ui_commands.py b/dev/breeze/tests/test_ui_commands.py index 843d985ed0281..8f7b844be796a 100644 --- a/dev/breeze/tests/test_ui_commands.py +++ b/dev/breeze/tests/test_ui_commands.py @@ -61,6 +61,25 @@ def test_expand_plural_keys_polish(self): assert "message_many" in expanded assert "message_other" in expanded + def test_expand_plural_keys_only_expands_when_en_has_count_placeholder(self): + # When en has error_one without {{count}}, we must not require error_other + keys = {"error_one"} + en_key_to_value = {"error_one": "1 Error"} + expanded = expand_plural_keys(keys, "pt", en_key_to_value) + assert "error_one" in expanded + assert "error_other" not in expanded + + def test_expand_plural_keys_expands_when_en_has_count_placeholder(self): + # Polish has 4 plural forms (_one, _few, _many, _other). Input has only _one and _other; + # expansion must add _few and _many so the test verifies the expansion logic ran. + keys = {"warning_one", "warning_other"} + en_key_to_value = {"warning_one": "1 Warning", "warning_other": "{{count}} Warnings"} + expanded = expand_plural_keys(keys, "pl", en_key_to_value) + assert "warning_one" in expanded + assert "warning_other" in expanded + assert "warning_few" in expanded + assert "warning_many" in expanded + class TestFlattenKeys: def test_flatten_simple_dict(self): @@ -112,7 +131,7 @@ def test_compare_keys_identical(self, tmp_path): assert "test.json" in summary assert summary["test.json"].missing_keys.get("de", []) == [] - assert summary["test.json"].extra_keys.get("de", []) == [] + assert summary["test.json"].unused_keys.get("de", []) == [] finally: ui_commands.LOCALES_DIR = original_locales_dir @@ -171,16 +190,50 @@ def test_compare_keys_with_extra(self, tmp_path): summary, missing_counts = compare_keys(locale_files) assert "test.json" in summary - assert "extra" in summary["test.json"].extra_keys.get("de", []) + assert "extra" in summary["test.json"].unused_keys.get("de", []) + finally: + ui_commands.LOCALES_DIR = original_locales_dir + + def test_compare_keys_optional_plural_unused_when_no_count(self, tmp_path): + """Plural variant of EN base with no {{count}} in EN is reported as unused.""" + en_dir = tmp_path / "en" + en_dir.mkdir() + de_dir = tmp_path / "de" + de_dir.mkdir() + + # EN has only error_one (no {{count}}), so error_other is never used at runtime + en_data = {"dagWarnings": {"error_one": "1 Error"}} + de_data = {"dagWarnings": {"error_one": "1 Fehler", "error_other": "{{count}} Fehler"}} + + (en_dir / "test.json").write_text(json.dumps(en_data)) + (de_dir / "test.json").write_text(json.dumps(de_data)) + + import airflow_breeze.commands.ui_commands as ui_commands + + original_locales_dir = ui_commands.LOCALES_DIR + ui_commands.LOCALES_DIR = tmp_path + + try: + locale_files = [ + LocaleFiles(locale="en", files=["test.json"]), + LocaleFiles(locale="de", files=["test.json"]), + ] + summary, _ = compare_keys(locale_files) + + # EN base has no {{count}}, so error_other is not required and is unused + assert "dagWarnings.error_other" in summary["test.json"].unused_keys.get("de", []) finally: ui_commands.LOCALES_DIR = original_locales_dir class TestLocaleSummary: def test_locale_summary_creation(self): - summary = LocaleSummary(missing_keys={"de": ["key1", "key2"]}, extra_keys={"de": ["key3"]}) + summary = LocaleSummary( + missing_keys={"de": ["key1", "key2"]}, + unused_keys={"de": ["key3"]}, + ) assert summary.missing_keys == {"de": ["key1", "key2"]} - assert summary.extra_keys == {"de": ["key3"]} + assert summary.unused_keys == {"de": ["key3"]} class TestLocaleFiles: @@ -255,7 +308,7 @@ def test_add_missing_translations(self, tmp_path): try: summary = LocaleSummary( missing_keys={"de": ["farewell"]}, - extra_keys={"de": []}, + unused_keys={"de": []}, ) add_missing_translations("de", {"test.json": summary}) @@ -267,9 +320,9 @@ def test_add_missing_translations(self, tmp_path): ui_commands.LOCALES_DIR = original_locales_dir -class TestRemoveExtraTranslations: - def test_remove_extra_translations(self, tmp_path): - from airflow_breeze.commands.ui_commands import remove_extra_translations +class TestRemoveUnusedTranslations: + def test_remove_unused_translations(self, tmp_path): + from airflow_breeze.commands.ui_commands import remove_unused_translations de_dir = tmp_path / "de" de_dir.mkdir() @@ -285,11 +338,11 @@ def test_remove_extra_translations(self, tmp_path): try: summary = LocaleSummary( missing_keys={"de": []}, - extra_keys={"de": ["extra"]}, + unused_keys={"de": ["extra"]}, ) - remove_extra_translations("de", {"test.json": summary}) + remove_unused_translations("de", {"test.json": summary}) - # Check that the extra key was removed + # Check that the unused key was removed de_data_updated = json.loads((de_dir / "test.json").read_text()) assert "extra" not in de_data_updated assert "greeting" in de_data_updated @@ -330,7 +383,7 @@ def test_natural_sort_matches_eslint(self, tmp_path): try: summary = LocaleSummary( missing_keys={"de": list(en_data.keys())}, - extra_keys={"de": []}, + unused_keys={"de": []}, ) add_missing_translations("de", {"test.json": summary}) From f7c88912831d665595f6ea13e1c1d2427d3ffd24 Mon Sep 17 00:00:00 2001 From: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com> Date: Wed, 11 Mar 2026 04:08:00 +0530 Subject: [PATCH 42/50] Add BaseXcom to airflow.sdk (#63116) (#63299) (cherry picked from commit 5b2d2fc3b4615987571e319f71ca30d51adfb98e) Co-authored-by: Jarek Potiuk --- task-sdk/src/airflow/sdk/__init__.py | 3 +++ task-sdk/src/airflow/sdk/__init__.pyi | 2 ++ 2 files changed, 5 insertions(+) diff --git a/task-sdk/src/airflow/sdk/__init__.py b/task-sdk/src/airflow/sdk/__init__.py index 2eaa5ccd2a2e4..6386ec4f07d7d 100644 --- a/task-sdk/src/airflow/sdk/__init__.py +++ b/task-sdk/src/airflow/sdk/__init__.py @@ -30,6 +30,7 @@ "BaseOperator", "BaseOperatorLink", "BaseSensorOperator", + "BaseXCom", "Connection", "Context", "DAG", @@ -70,6 +71,7 @@ from airflow.sdk.bases.operator import BaseOperator, chain, chain_linear, cross_downstream from airflow.sdk.bases.operatorlink import BaseOperatorLink from airflow.sdk.bases.sensor import BaseSensorOperator, PokeReturnValue + from airflow.sdk.bases.xcom import BaseXCom from airflow.sdk.definitions.asset import Asset, AssetAlias, AssetAll, AssetAny, AssetWatcher from airflow.sdk.definitions.asset.decorators import asset from airflow.sdk.definitions.asset.metadata import Metadata @@ -97,6 +99,7 @@ "BaseOperator": ".bases.operator", "BaseOperatorLink": ".bases.operatorlink", "BaseSensorOperator": ".bases.sensor", + "BaseXCom": ".bases.xcom", "Connection": ".definitions.connection", "Context": ".definitions.context", "DAG": ".definitions.dag", diff --git a/task-sdk/src/airflow/sdk/__init__.pyi b/task-sdk/src/airflow/sdk/__init__.pyi index bf7f63b209a6d..e36664594b425 100644 --- a/task-sdk/src/airflow/sdk/__init__.pyi +++ b/task-sdk/src/airflow/sdk/__init__.pyi @@ -34,6 +34,7 @@ from airflow.sdk.bases.sensor import ( BaseSensorOperator as BaseSensorOperator, PokeReturnValue as PokeReturnValue, ) +from airflow.sdk.bases.xcom import BaseXCom as BaseXCom from airflow.sdk.definitions.asset import ( Asset as Asset, AssetAlias as AssetAlias, @@ -73,6 +74,7 @@ __all__ = [ "BaseOperator", "BaseOperatorLink", "BaseSensorOperator", + "BaseXCom", "Connection", "Context", "DAG", From a82a0342312173a1de6c74faea8603b3375f49d0 Mon Sep 17 00:00:00 2001 From: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com> Date: Wed, 11 Mar 2026 04:10:46 +0530 Subject: [PATCH 43/50] Filter on dag_id when querying task_instance (#62751) (#63291) (cherry picked from commit 196553468f158d39a76ae204cc11785ec05779e9) Co-authored-by: Jeff Stein --- airflow-core/src/airflow/models/serialized_dag.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/airflow-core/src/airflow/models/serialized_dag.py b/airflow-core/src/airflow/models/serialized_dag.py index e714361df9d8f..401809c5087a7 100644 --- a/airflow-core/src/airflow/models/serialized_dag.py +++ b/airflow-core/src/airflow/models/serialized_dag.py @@ -432,7 +432,15 @@ def write_dag( has_task_instances: bool = False if dag_version: has_task_instances = bool( - session.scalar(select(exists().where(TaskInstance.dag_version_id == dag_version.id))) + session.scalar( + select( + exists().where( + # Using dag_id filter to speed up query via the composite index. + TaskInstance.dag_id == dag.dag_id, + TaskInstance.dag_version_id == dag_version.id, + ) + ) + ) ) if dag_version and not has_task_instances: From 8e30d8d90bc7d257efcd984366b4e650c54844a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 00:28:56 +0100 Subject: [PATCH 44/50] [v3-1-test] Update the UV command for upgrading tools in the Contributing docs (#61756) (#63313) * update uv command in contributing doc * add uv command in introduction and remove from prek related commands (cherry picked from commit 7c45e6860e863f2dcccb87396612442945059573) Co-authored-by: Pratiksha <128999446+Prab-27@users.noreply.github.com> --- contributing-docs/03_contributors_quick_start.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contributing-docs/03_contributors_quick_start.rst b/contributing-docs/03_contributors_quick_start.rst index b331b1dc610aa..b61b1989a8b9b 100644 --- a/contributing-docs/03_contributors_quick_start.rst +++ b/contributing-docs/03_contributors_quick_start.rst @@ -261,6 +261,14 @@ To avoid burden on our CI infrastructure and to save time, prek hooks can be run Installing prek is best done with ``uv`` (recommended) or ``pipx``. +You can also update the tools installed with UV, including ``prek``. + + Run the following command to upgrade all UV-managed tools: + + .. code-block:: bash + + uv tool upgrade --all + 1. Installing required packages on Debian / Ubuntu, install via @@ -285,6 +293,7 @@ on macOS, install via uv tool install prek + or with pipx: .. code-block:: bash @@ -361,6 +370,7 @@ It will run prek hooks automatically before committing and stops the commit on f cd ~/Projects/airflow prek uninstall + - For more information on this visit |08_static_code_checks.rst| .. |08_static_code_checks.rst| raw:: html From 56c28a5b32320d387467d711da19e358c9e22733 Mon Sep 17 00:00:00 2001 From: Rahul Vats <43964496+vatsrahul1001@users.noreply.github.com> Date: Wed, 11 Mar 2026 11:57:15 +0530 Subject: [PATCH 45/50] fix: Exclude JWT token from workload repr to prevent log exposure (#62964) (#63328) (cherry picked from commit b196cf3d1c5ed20667f39742cd4f8151b18123c9) Co-authored-by: Pineapple <224004177+SibtainOcn@users.noreply.github.com> --- airflow-core/newsfragments/62964.bugfix.rst | 1 + .../src/airflow/executors/workloads.py | 2 +- .../tests/unit/executors/test_workloads.py | 53 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 airflow-core/newsfragments/62964.bugfix.rst create mode 100644 airflow-core/tests/unit/executors/test_workloads.py diff --git a/airflow-core/newsfragments/62964.bugfix.rst b/airflow-core/newsfragments/62964.bugfix.rst new file mode 100644 index 0000000000000..048ba18893be4 --- /dev/null +++ b/airflow-core/newsfragments/62964.bugfix.rst @@ -0,0 +1 @@ +Prevent JWT tokens from appearing in task logs by excluding the token field from workload object representations. diff --git a/airflow-core/src/airflow/executors/workloads.py b/airflow-core/src/airflow/executors/workloads.py index 43a4aab1dbc47..bafb429dcc10c 100644 --- a/airflow-core/src/airflow/executors/workloads.py +++ b/airflow-core/src/airflow/executors/workloads.py @@ -40,7 +40,7 @@ class BaseWorkload(BaseModel): - token: str + token: str = Field(repr=False) """The identity token for this workload""" diff --git a/airflow-core/tests/unit/executors/test_workloads.py b/airflow-core/tests/unit/executors/test_workloads.py new file mode 100644 index 0000000000000..507204d41dc27 --- /dev/null +++ b/airflow-core/tests/unit/executors/test_workloads.py @@ -0,0 +1,53 @@ +# 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 + +from pathlib import PurePosixPath +from uuid import uuid4 + +from airflow.executors.workloads import BundleInfo, ExecuteTask, TaskInstance + + +def test_token_excluded_from_workload_repr(): + """Ensure JWT tokens do not leak into log output via repr().""" + fake_token = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.secret_payload.signature" + ti = TaskInstance( + id=uuid4(), + dag_version_id=uuid4(), + task_id="test_task", + dag_id="test_dag", + run_id="test_run", + try_number=1, + map_index=-1, + pool_slots=1, + queue="default", + priority_weight=1, + ) + workload = ExecuteTask( + ti=ti, + dag_rel_path=PurePosixPath("test_dag.py"), + token=fake_token, + bundle_info=BundleInfo(name="dags-folder", version=None), + log_path="test.log", + ) + + workload_repr = repr(workload) + + # Token MUST NOT appear in repr (prevents leaking into logs) + assert fake_token not in workload_repr, f"JWT token leaked into repr! Found token in: {workload_repr}" + # But token should still be accessible as an attribute + assert workload.token == fake_token From d4cfab8d98d2c326a40bd134fb75438d19683bac Mon Sep 17 00:00:00 2001 From: Pierre Jeambrun Date: Wed, 11 Mar 2026 12:42:05 +0100 Subject: [PATCH 46/50] Filter backfills list by readable DAGs (#63003) (#63275) (cherry picked from commit 211b96ce63cd8884e4db912e9c36e46e6e48852d) Co-authored-by: Henry Chen --- .../core_api/routes/ui/backfills.py | 5 ++-- .../airflow/api_fastapi/core_api/security.py | 10 +++++++ .../core_api/routes/ui/test_backfills.py | 26 ++++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/backfills.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/backfills.py index 9d1630689f76e..753c5427253f0 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/backfills.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/ui/backfills.py @@ -36,7 +36,7 @@ from airflow.api_fastapi.core_api.openapi.exceptions import ( create_openapi_http_exception_doc, ) -from airflow.api_fastapi.core_api.security import requires_access_backfill +from airflow.api_fastapi.core_api.security import ReadableBackfillsFilterDep, requires_access_backfill from airflow.models.backfill import Backfill backfills_router = AirflowRouter(tags=["Backfill"], prefix="/backfills") @@ -56,6 +56,7 @@ def list_backfills_ui( SortParam, Depends(SortParam(["id"], Backfill).dynamic_depends()), ], + readable_backfills_filter: ReadableBackfillsFilterDep, session: SessionDep, dag_id: Annotated[FilterParam[str | None], Depends(filter_param_factory(Backfill.dag_id, str | None))], active: Annotated[ @@ -65,7 +66,7 @@ def list_backfills_ui( ) -> BackfillCollectionResponse: select_stmt, total_entries = paginated_select( statement=select(Backfill).options(joinedload(Backfill.dag_model)), - filters=[dag_id, active], + filters=[dag_id, active, readable_backfills_filter], order_by=order_by, offset=offset, limit=limit, 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 4215baaa7712f..26b0e5bae61f7 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/security.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/security.py @@ -219,6 +219,13 @@ def to_orm(self, select: Select) -> Select: return select.where(DagVersion.dag_id.in_(self.value or set())) +class PermittedBackfillFilter(PermittedDagFilter): + """A parameter that filters the permitted backfills for the user.""" + + def to_orm(self, select: Select) -> Select: + return select.where(Backfill.dag_id.in_(self.value or set())) + + def permitted_dag_filter_factory( method: ResourceMethod, filter_class=PermittedDagFilter ) -> Callable[[Request, BaseUser], PermittedDagFilter]: @@ -264,6 +271,9 @@ def depends_permitted_dags_filter( ReadableDagVersionsFilterDep = Annotated[ PermittedDagVersionFilter, Depends(permitted_dag_filter_factory("GET", PermittedDagVersionFilter)) ] +ReadableBackfillsFilterDep = Annotated[ + PermittedBackfillFilter, Depends(permitted_dag_filter_factory("GET", PermittedBackfillFilter)) +] def requires_access_backfill( diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py index f7574936428f0..b397b06c9e2eb 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_backfills.py @@ -153,7 +153,7 @@ def test_should_response_200( expected_response = [] for backfill in response_params: expected_response.append(backfill_responses[backfill]) - with assert_queries_count(2 if test_params.get("dag_id") is None else 3): + with assert_queries_count(3 if test_params.get("dag_id") is None else 4): response = test_client.get("/backfills", params=test_params) assert response.status_code == 200 assert response.json() == { @@ -168,3 +168,27 @@ def test_should_response_401(self, unauthenticated_test_client): def test_should_response_403(self, unauthorized_test_client): response = unauthorized_test_client.get("/backfills", params={}) assert response.status_code == 403 + + @mock.patch("airflow.api_fastapi.auth.managers.base_auth_manager.BaseAuthManager.get_authorized_dag_ids") + def test_should_only_return_authorized_dag_backfills( + self, mock_get_authorized_dag_ids, test_client, session, testing_dag_bundle + ): + dags = self._create_dag_models() + from_date = timezone.utcnow() + to_date = timezone.utcnow() + backfills = [ + Backfill(dag_id=dags[0].dag_id, from_date=from_date, to_date=to_date), + Backfill(dag_id=dags[1].dag_id, from_date=from_date, to_date=to_date), + Backfill(dag_id=dags[2].dag_id, from_date=from_date, to_date=to_date), + ] + session.add_all(backfills) + session.commit() + + mock_get_authorized_dag_ids.return_value = {"TEST_DAG_2", "TEST_DAG_3"} + response = test_client.get("/backfills") + + mock_get_authorized_dag_ids.assert_called_once_with(user=mock.ANY, method="GET") + assert response.status_code == 200 + body = response.json() + assert body["total_entries"] == 2 + assert {b["dag_id"] for b in body["backfills"]} == {"TEST_DAG_2", "TEST_DAG_3"} From e1f2b153b650c28d4bee001436cc78fb2b94c07c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 14:24:02 +0100 Subject: [PATCH 47/50] [v3-1-test] fix(UI): show 403 error when unauthorized user reparses DAG (#61560) (#63339) * fix(UI): show permission error when unauthorized user tries to reparse DAG When a Viewer or Author without edit permission tries to reparse a DAG, the API returns 403 but the UI shows a generic "Dag parsing request failed" message. This checks the error status and shows an appropriate "Access Denied" toast instead. Closes #61459 * Generalize 403 permission toast handling in UI Move the forbidden toast copy to common translations and route DAG reparse mutation errors through a shared error toaster helper so 403 responses consistently show a reusable access-denied message. Made-with: Cursor * Small adjustments --------- (cherry picked from commit f01c69a15ab1a5d32d0917a793d438857c6b200b) Co-authored-by: Liam Co-authored-by: Cursor Co-authored-by: pierrejeambrun --- .../ui/public/i18n/locales/en/common.json | 4 ++ .../src/components/ui/createErrorToaster.ts | 40 +++++++++++++++++++ .../airflow/ui/src/queries/useDagParsing.ts | 15 +++---- 3 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 airflow-core/src/airflow/ui/src/components/ui/createErrorToaster.ts 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 0a59f20347358..e55c81ee5b009 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 @@ -288,6 +288,10 @@ "title": "Delete {{resourceName}} Request Submitted" } }, + "forbidden": { + "description": "You do not have permission to perform this action.", + "title": "Access Denied" + }, "import": { "error": "Import {{resourceName}} Request Failed", "success": { diff --git a/airflow-core/src/airflow/ui/src/components/ui/createErrorToaster.ts b/airflow-core/src/airflow/ui/src/components/ui/createErrorToaster.ts new file mode 100644 index 0000000000000..c59cabbf3b675 --- /dev/null +++ b/airflow-core/src/airflow/ui/src/components/ui/createErrorToaster.ts @@ -0,0 +1,40 @@ +/*! + * 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 type { TFunction } from "i18next"; + +import type { ExpandedApiError } from "src/components/ErrorAlert"; +import { toaster } from "src/components/ui"; + +type ErrorToastMessage = { + readonly description: string; + readonly title: string; +}; + +export const createErrorToaster = + (translate: TFunction, fallbackMessage: ErrorToastMessage) => (error: unknown) => { + const isForbidden = (error as ExpandedApiError).status === 403; + + toaster.create({ + description: isForbidden + ? translate("toaster.forbidden.description", { ns: "common" }) + : fallbackMessage.description, + title: isForbidden ? translate("toaster.forbidden.title", { ns: "common" }) : fallbackMessage.title, + type: "error", + }); + }; diff --git a/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts b/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts index 914799dfc5499..2fc8c43c0e394 100644 --- a/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts +++ b/airflow-core/src/airflow/ui/src/queries/useDagParsing.ts @@ -25,18 +25,15 @@ import { UseDagSourceServiceGetDagSourceKeyFn, } from "openapi/queries"; import { toaster } from "src/components/ui"; +import { createErrorToaster } from "src/components/ui/createErrorToaster"; export const useDagParsing = ({ dagId }: { readonly dagId: string }) => { const queryClient = useQueryClient(); - const { t: translate } = useTranslation("dag"); - - const onError = () => { - toaster.create({ - description: translate("parse.toaster.error.description"), - title: translate("parse.toaster.error.title"), - type: "error", - }); - }; + const { t: translate } = useTranslation(["dag", "common"]); + const onError = createErrorToaster(translate, { + description: translate("parse.toaster.error.description"), + title: translate("parse.toaster.error.title"), + }); const onSuccess = async () => { await queryClient.invalidateQueries({ From 4ec9f797e56e6fb2297297937bc7836b138275de Mon Sep 17 00:00:00 2001 From: Pierre Jeambrun Date: Wed, 11 Mar 2026 19:24:02 +0100 Subject: [PATCH 48/50] Add additional permission check in asset materialization (#63338) (#63363) --- .../core_api/routes/public/assets.py | 13 +++++++++++ .../core_api/routes/public/test_assets.py | 22 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py index b1bafae7766f8..714b77c65b97d 100644 --- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py +++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/assets.py @@ -25,6 +25,8 @@ from sqlalchemy.orm import joinedload, subqueryload from airflow._shared.timezones import timezone +from airflow.api_fastapi.app import get_auth_manager +from airflow.api_fastapi.auth.managers.models.resource_details import DagAccessEntity, DagDetails from airflow.api_fastapi.common.dagbag import DagBagDep, get_latest_version_of_dag from airflow.api_fastapi.common.db.common import SessionDep, paginated_select from airflow.api_fastapi.common.parameters import ( @@ -372,6 +374,17 @@ def materialize_asset( f"More than one DAG materializes asset with ID: {asset_id}", ) + if not get_auth_manager().is_authorized_dag( + method="POST", + access_entity=DagAccessEntity.RUN, + details=DagDetails(id=dag_id), + user=user, + ): + raise HTTPException( + status.HTTP_403_FORBIDDEN, + f"User is not authorized to trigger a run for DAG: {dag_id} that materializes this asset", + ) + dag = get_latest_version_of_dag(dag_bag, dag_id, session) return dag.create_dagrun( run_id=dag.timetable.generate_run_id( diff --git a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_assets.py b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_assets.py index 625b5abc9d708..451dbf22efda6 100644 --- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_assets.py +++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_assets.py @@ -24,6 +24,7 @@ import time_machine from airflow._shared.timezones import timezone +from airflow.api_fastapi.auth.managers.models.resource_details import DagAccessEntity, DagDetails from airflow.models import DagModel from airflow.models.asset import ( AssetActive, @@ -1261,6 +1262,27 @@ def test_should_respond_404_on_multiple_dags(self, test_client): assert response.status_code == 404 assert response.json()["detail"] == "No DAG materializes asset with ID: 3" + @pytest.mark.usefixtures("configure_git_connection_for_dag_bundle") + def test_should_respond_403_when_user_cannot_trigger_dag(self, test_client): + with mock.patch( + "airflow.api_fastapi.core_api.routes.public.assets.get_auth_manager", + autospec=True, + ) as mock_get_auth_manager: + mock_get_auth_manager.return_value.is_authorized_dag.return_value = False + + response = test_client.post("/assets/1/materialize") + + assert response.status_code == 403 + assert response.json()["detail"] == ( + f"User is not authorized to trigger a run for DAG: {self.DAG_ASSET1_ID} that materializes this asset" + ) + mock_get_auth_manager.return_value.is_authorized_dag.assert_called_once_with( + method="POST", + access_entity=DagAccessEntity.RUN, + details=DagDetails(id=self.DAG_ASSET1_ID), + user=mock.ANY, + ) + class TestGetAssetQueuedEvents(TestQueuedEventEndpoint): @pytest.mark.usefixtures("time_freezer") From 6839135af734fd1775b43f42518b5bf1494a442c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 14:50:55 -0400 Subject: [PATCH 49/50] [v3-1-test] fix(ui): Improve DurationChart labels and disable animation during auto-refresh (#62835) (#63366) * fix(ui): improve DurationChart labels and disable animation during auto-refresh - Shorten x-axis tick labels based on the time span of displayed entries: show "HH:mm:ss" when all runs are within 24 hours, or "MMM DD HH:mm" for longer ranges. Full datetime remains in tooltips. - Use formatDate with the user's selected timezone for correct label rendering across all timezone configurations. - Disable chart animation during auto-refresh to reduce visual noise when data updates automatically. Closes: #54786 * fix(ui): apply formatting fixes for ts-compile-lint-ui CI hook Import ordering and line-length adjustments applied by eslint/prettier. --------- (cherry picked from commit 98f129f0cd43838c87dbe30d0f49a8c2b57513a8) Co-authored-by: Antonio Mello Co-authored-by: Claude Opus 4.6 --- .../ui/src/components/DurationChart.tsx | 26 ++++++++++++++++++- .../ui/src/pages/Dag/Overview/Overview.tsx | 10 ++++++- 2 files changed, 34 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 186ebb5f6f19e..8008307fabf40 100644 --- a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx +++ b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx @@ -35,8 +35,9 @@ import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import type { TaskInstanceResponse, GridRunsResponse } from "openapi/requests/types.gen"; +import { useTimezone } from "src/context/timezone"; import { getComputedCSSVariableValue } from "src/theme"; -import { DEFAULT_DATETIME_FORMAT, renderDuration } from "src/utils/datetimeUtils"; +import { DEFAULT_DATETIME_FORMAT, formatDate, renderDuration } from "src/utils/datetimeUtils"; import { buildTaskInstanceUrl } from "src/utils/links"; ChartJS.register( @@ -69,15 +70,35 @@ const getDuration = (start: string, end: string | null) => { return dayjs.duration(endDate.diff(startDate)).asSeconds(); }; +const getTickLabelFormat = (entries: Array): string => { + if (entries.length < 2) { + return "HH:mm:ss"; + } + + const first = dayjs(entries[0]?.run_after); + const last = dayjs(entries[entries.length - 1]?.run_after); + + if (!first.isValid() || !last.isValid()) { + return "MMM DD"; + } + + const diffInDays = Math.abs(last.diff(first, "day")); + + return diffInDays < 1 ? "HH:mm:ss" : "MMM DD HH:mm"; +}; + export const DurationChart = ({ entries, + isAutoRefreshing = false, kind, }: { readonly entries: Array | undefined; + readonly isAutoRefreshing?: boolean; readonly kind: "Dag Run" | "Task Instance"; }) => { const { t: translate } = useTranslation(["components", "common"]); const navigate = useNavigate(); + const { selectedTimezone } = useTimezone(); const [queuedColorToken] = useToken("colors", ["queued.solid"]); // Get states and create color tokens for them @@ -175,6 +196,7 @@ export const DurationChart = ({ }} datasetIdKey="id" options={{ + animation: isAutoRefreshing ? false : undefined, onClick: (_event, elements) => { const [element] = elements; @@ -239,6 +261,8 @@ export const DurationChart = ({ x: { stacked: true, ticks: { + callback: (_value, index) => + formatDate(entries[index]?.run_after, selectedTimezone, getTickLabelFormat(entries)), maxTicksLimit: 3, }, title: { align: "end", display: true, text: translate("common:dagRun.runAfter") }, diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx index 8cebcc4ba0b8e..ba07cae494bcc 100644 --- a/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx +++ b/airflow-core/src/airflow/ui/src/pages/Dag/Overview/Overview.tsx @@ -35,6 +35,7 @@ import TimeRangeSelector from "src/components/TimeRangeSelector"; import { TrendCountButton } from "src/components/TrendCountButton"; import { SearchParamsKeys } from "src/constants/searchParams"; import { useGridRuns } from "src/queries/useGridRuns.ts"; +import { isStatePending, useAutoRefresh } from "src/utils"; const FailedLogs = lazy(() => import("./FailedLogs")); @@ -67,6 +68,9 @@ export const Overview = () => { state: ["failed"], }); const { data: gridRuns, isLoading: isLoadingRuns } = useGridRuns({ limit }); + const refetchInterval = useAutoRefresh({ dagId }); + const isAutoRefreshing = + Boolean(refetchInterval) && (gridRuns ?? []).some((run) => isStatePending(run.state)); const { data: assetEventsData, isLoading: isLoadingAssetEvents } = useAssetServiceGetAssetEvents({ limit, orderBy: [assetSortBy], @@ -124,7 +128,11 @@ export const Overview = () => { {isLoadingRuns ? ( ) : ( - + )} {assetEventsData && assetEventsData.total_entries > 0 ? ( From 8de45a90060ff161fe52fac87eb4a3dec35e8f08 Mon Sep 17 00:00:00 2001 From: Pablo Ugarte <99680272+Wastelander777@users.noreply.github.com> Date: Wed, 11 Mar 2026 20:38:39 +0100 Subject: [PATCH 50/50] [v3-1-test] feat(docker): add minute-level log retention to clean-logs script (#61855) * feat(docker): add minute-level log retention support to clean-logs.sh * feat(docker): import coauthored changes * update inlined scripts in Dockerfile * comments fixed (cherry picked from commit de01a6ba55d026432b27b46aa11b5ecfb0caf107) Co-authored-by: Pablo Ugarte <99680272+Wastelander777@users.noreply.github.com> --- Dockerfile | 9 ++++--- .../dag-processor-deployment.yaml | 4 ++++ .../scheduler/scheduler-deployment.yaml | 4 ++++ .../triggerer/triggerer-deployment.yaml | 4 ++++ .../templates/workers/worker-deployment.yaml | 4 ++++ chart/values.schema.json | 7 +++++- chart/values.yaml | 24 +++++++++++++++++++ scripts/docker/clean-logs.sh | 9 ++++--- 8 files changed, 58 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index f56301017e2eb..4fc4ef3588294 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1671,7 +1671,8 @@ COPY <<"EOF" /clean-logs.sh set -euo pipefail readonly DIRECTORY="${AIRFLOW_HOME:-/usr/local/airflow}" -readonly RETENTION="${AIRFLOW__LOG_RETENTION_DAYS:-15}" +readonly RETENTION_DAYS="${AIRFLOW__LOG_RETENTION_DAYS:-15}" +readonly RETENTION_MINUTES="${AIRFLOW__LOG_RETENTION_MINUTES:-0}" readonly FREQUENCY="${AIRFLOW__LOG_CLEANUP_FREQUENCY_MINUTES:-15}" readonly MAX_PERCENT="${AIRFLOW__LOG_MAX_SIZE_PERCENT:-0}" @@ -1696,10 +1697,12 @@ fi retention_days="${RETENTION}" while true; do - echo "Trimming airflow logs to ${retention_days} days." + total_retention_minutes=$(( (RETENTION_DAYS * 1440) + RETENTION_MINUTES )) + echo "Trimming airflow logs older than ${total_retention_minutes} minutes." + find "${DIRECTORY}"/logs \ -type d -name 'lost+found' -prune -o \ - -type f -mtime +"${retention_days}" -name '*.log' -print0 | \ + -type f -mmin +"${total_retention_minutes}" -name '*.log' -print0 | \ xargs -0 rm -f || true if [[ "$MAX_SIZE_BYTES" -gt 0 && "$retention_days" -ge 0 ]]; then diff --git a/chart/templates/dag-processor/dag-processor-deployment.yaml b/chart/templates/dag-processor/dag-processor-deployment.yaml index 3f029eebf9fd9..b8aba7d2a5810 100644 --- a/chart/templates/dag-processor/dag-processor-deployment.yaml +++ b/chart/templates/dag-processor/dag-processor-deployment.yaml @@ -218,6 +218,10 @@ spec: - name: AIRFLOW__LOG_RETENTION_DAYS value: "{{ .Values.dagProcessor.logGroomerSidecar.retentionDays }}" {{- end }} + {{- if .Values.dagProcessor.logGroomerSidecar.retentionMinutes }} + - name: AIRFLOW__LOG_RETENTION_MINUTES + value: "{{ .Values.dagProcessor.logGroomerSidecar.retentionMinutes }}" + {{- end }} {{- if .Values.dagProcessor.logGroomerSidecar.frequencyMinutes }} - name: AIRFLOW__LOG_CLEANUP_FREQUENCY_MINUTES value: "{{ .Values.dagProcessor.logGroomerSidecar.frequencyMinutes }}" diff --git a/chart/templates/scheduler/scheduler-deployment.yaml b/chart/templates/scheduler/scheduler-deployment.yaml index bb3670cecbebe..45ed2e2f36ceb 100644 --- a/chart/templates/scheduler/scheduler-deployment.yaml +++ b/chart/templates/scheduler/scheduler-deployment.yaml @@ -277,6 +277,10 @@ spec: - name: AIRFLOW__LOG_RETENTION_DAYS value: "{{ .Values.scheduler.logGroomerSidecar.retentionDays }}" {{- end }} + {{- if .Values.scheduler.logGroomerSidecar.retentionMinutes }} + - name: AIRFLOW__LOG_RETENTION_MINUTES + value: "{{ .Values.scheduler.logGroomerSidecar.retentionMinutes }}" + {{- end }} {{- if .Values.scheduler.logGroomerSidecar.frequencyMinutes }} - name: AIRFLOW__LOG_CLEANUP_FREQUENCY_MINUTES value: "{{ .Values.scheduler.logGroomerSidecar.frequencyMinutes }}" diff --git a/chart/templates/triggerer/triggerer-deployment.yaml b/chart/templates/triggerer/triggerer-deployment.yaml index 9010becf118c3..8a594105faba6 100644 --- a/chart/templates/triggerer/triggerer-deployment.yaml +++ b/chart/templates/triggerer/triggerer-deployment.yaml @@ -248,6 +248,10 @@ spec: - name: AIRFLOW__LOG_RETENTION_DAYS value: "{{ .Values.triggerer.logGroomerSidecar.retentionDays }}" {{- end }} + {{- if .Values.triggerer.logGroomerSidecar.retentionMinutes }} + - name: AIRFLOW__LOG_RETENTION_MINUTES + value: "{{ .Values.triggerer.logGroomerSidecar.retentionMinutes }}" + {{- end }} {{- if .Values.triggerer.logGroomerSidecar.frequencyMinutes }} - name: AIRFLOW__LOG_CLEANUP_FREQUENCY_MINUTES value: "{{ .Values.triggerer.logGroomerSidecar.frequencyMinutes }}" diff --git a/chart/templates/workers/worker-deployment.yaml b/chart/templates/workers/worker-deployment.yaml index a0d794137925d..3d450159483ea 100644 --- a/chart/templates/workers/worker-deployment.yaml +++ b/chart/templates/workers/worker-deployment.yaml @@ -344,6 +344,10 @@ spec: - name: AIRFLOW__LOG_RETENTION_DAYS value: "{{ .Values.workers.logGroomerSidecar.retentionDays }}" {{- end }} + {{- if .Values.workers.logGroomerSidecar.retentionMinutes }} + - name: AIRFLOW__LOG_RETENTION_MINUTES + value: "{{ .Values.workers.logGroomerSidecar.retentionMinutes }}" + {{- end }} {{- if .Values.workers.logGroomerSidecar.frequencyMinutes }} - name: AIRFLOW__LOG_CLEANUP_FREQUENCY_MINUTES value: "{{ .Values.workers.logGroomerSidecar.frequencyMinutes }}" diff --git a/chart/values.schema.json b/chart/values.schema.json index fd832f9b8974d..304c07b7ca818 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -12563,10 +12563,15 @@ ] }, "retentionDays": { - "description": "Number of days to retain the logs when running the Airflow log groomer sidecar.", + "description": "Number of days to retain the logs when running the Airflow log groomer sidecar. Total retention time is retentionDays + retentionMinutes.", "type": "integer", "default": 15 }, + "retentionMinutes": { + "description": "Number of minutes to retain the logs when running the Airflow log groomer sidecar. Total retention time is retentionDays + retentionMinutes.", + "type": "integer", + "default": 0 + }, "frequencyMinutes": { "description": "Number of minutes between attempts to groom the Airflow logs in log groomer sidecar.", "type": "integer", diff --git a/chart/values.yaml b/chart/values.yaml index d4dde3fdf6941..57595632ca894 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -932,6 +932,12 @@ workers: # Number of days to retain logs retentionDays: 15 + # Number of minutes to retain logs. + # This can be used for finer granularity than days. + # Total retention is retentionDays + retentionMinutes. + retentionMinutes: 0 + + # Frequency to attempt to groom logs (in minutes) frequencyMinutes: 15 @@ -1181,6 +1187,12 @@ scheduler: args: ["bash", "/clean-logs"] # Number of days to retain logs retentionDays: 15 + + # Number of minutes to retain logs. + # This can be used for finer granularity than days. + # Total retention is retentionDays + retentionMinutes. + retentionMinutes: 0 + # frequency to attempt to groom logs, in minutes frequencyMinutes: 15 # Max size of logs in bytes. 0 = disabled @@ -1969,6 +1981,12 @@ triggerer: args: ["bash", "/clean-logs"] # Number of days to retain logs retentionDays: 15 + + # Number of minutes to retain logs. + # This can be used for finer granularity than days. + # Total retention is retentionDays + retentionMinutes. + retentionMinutes: 0 + # frequency to attempt to groom logs, in minutes frequencyMinutes: 15 # Max size of logs in bytes. 0 = disabled @@ -2161,6 +2179,12 @@ dagProcessor: args: ["bash", "/clean-logs"] # Number of days to retain logs retentionDays: 15 + + # Number of minutes to retain logs. + # This can be used for finer granularity than days. + # Total retention is retentionDays + retentionMinutes. + retentionMinutes: 0 + # frequency to attempt to groom logs, in minutes frequencyMinutes: 15 # Max size of logs in bytes. 0 = disabled diff --git a/scripts/docker/clean-logs.sh b/scripts/docker/clean-logs.sh index 1537036269538..7253424f461dd 100755 --- a/scripts/docker/clean-logs.sh +++ b/scripts/docker/clean-logs.sh @@ -20,7 +20,8 @@ set -euo pipefail readonly DIRECTORY="${AIRFLOW_HOME:-/usr/local/airflow}" -readonly RETENTION="${AIRFLOW__LOG_RETENTION_DAYS:-15}" +readonly RETENTION_DAYS="${AIRFLOW__LOG_RETENTION_DAYS:-15}" +readonly RETENTION_MINUTES="${AIRFLOW__LOG_RETENTION_MINUTES:-0}" readonly FREQUENCY="${AIRFLOW__LOG_CLEANUP_FREQUENCY_MINUTES:-15}" readonly MAX_PERCENT="${AIRFLOW__LOG_MAX_SIZE_PERCENT:-0}" @@ -45,10 +46,12 @@ fi retention_days="${RETENTION}" while true; do - echo "Trimming airflow logs to ${retention_days} days." + total_retention_minutes=$(( (RETENTION_DAYS * 1440) + RETENTION_MINUTES )) + echo "Trimming airflow logs older than ${total_retention_minutes} minutes." + find "${DIRECTORY}"/logs \ -type d -name 'lost+found' -prune -o \ - -type f -mtime +"${retention_days}" -name '*.log' -print0 | \ + -type f -mmin +"${total_retention_minutes}" -name '*.log' -print0 | \ xargs -0 rm -f || true if [[ "$MAX_SIZE_BYTES" -gt 0 && "$retention_days" -ge 0 ]]; then