You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by ka...@apache.org on 2025/08/26 21:57:48 UTC
(airflow) branch v3-0-test updated (f92400e9f6e -> fc2239b75f2)
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a change to branch v3-0-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
discard f92400e9f6e [v3-0-test] docs: add docs for custom alert messages (#50273) (#54955)
omit da69f554d5f [v3-0-test] Fix typo in documentation building doc (#54944) (#54946)
omit 579e18cb4be Update release notes for 3.0.6rc2
add e965c2e676d Update release notes for 3.0.6rc2
new 2e0d8a69510 [v3-0-test] Fix typo in documentation building doc (#54944) (#54946)
new 1ea36e8ac63 [v3-0-test] docs: add docs for custom alert messages (#50273) (#54955)
new fc2239b75f2 Fix XCom deletion failure for mapped task instances (#54954)
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (f92400e9f6e)
\
N -- N -- N refs/heads/v3-0-test (fc2239b75f2)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
task-sdk/src/airflow/sdk/bases/xcom.py | 1 +
.../src/airflow/sdk/execution_time/task_runner.py | 1 +
task-sdk/tests/task_sdk/bases/test_xcom.py | 72 ++++++++++++++++++++++
.../task_sdk/execution_time/test_task_runner.py | 65 +++++++++++++++++++
4 files changed, 139 insertions(+)
create mode 100644 task-sdk/tests/task_sdk/bases/test_xcom.py
(airflow) 01/03: [v3-0-test] Fix typo in documentation building doc (#54944) (#54946)
Posted by ka...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch v3-0-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 2e0d8a695109eabc6d84c9e4a40db066a61da11b
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Tue Aug 26 16:18:48 2025 +0200
[v3-0-test] Fix typo in documentation building doc (#54944) (#54946)
(cherry picked from commit 23f7a4d90653d313be99482f4ea69839baaf50af)
Co-authored-by: Mathieu Montgomery <10...@users.noreply.github.com>
---
contributing-docs/11_documentation_building.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/contributing-docs/11_documentation_building.rst b/contributing-docs/11_documentation_building.rst
index 836e61c50fb..81bc151f9f6 100644
--- a/contributing-docs/11_documentation_building.rst
+++ b/contributing-docs/11_documentation_building.rst
@@ -117,8 +117,8 @@ Building the documentation
In Airflow 3 the documentation is placed closely to where source code is placed (in most distribution
packages it is in the ``doc`` subfolder of a distribution you want to build the documentation for.
-Some distributions do not have ``docs``subfolder - when they are ``doc-only``. The ``build-doc`` script
-is installed automatically from ``devel-common` distribution and available to run using ``uv run``
+Some distributions do not have ``docs`` subfolder - when they are ``doc-only``. The ``build-doc`` script
+is installed automatically from ``devel-common`` distribution and available to run using ``uv run``
command (or directly ``build-docs`` inside the ``breeze`` container). This script will automatically
detect which distribution you are in and build the documentation for it.
(airflow) 03/03: Fix XCom deletion failure for mapped task instances (#54954)
Posted by ka...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch v3-0-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
commit fc2239b75f22bd7376ab56c5b4ed7f3a391b8237
Author: Kaxil Naik <ka...@apache.org>
AuthorDate: Tue Aug 26 22:55:47 2025 +0100
Fix XCom deletion failure for mapped task instances (#54954)
XCom deletion was not working properly for mapped task instances due to
missing map_index parameter in deletion requests. This caused XCom data
to persist incorrectly when attempting to clear XComs from specific
mapped task executions.
Fixed in both `BaseXCom.delete()` and task_runner XCom clearing logic.
(cherry picked from commit c44bff4d45da96989ada6f340c2370aa14040fc7)
---
task-sdk/src/airflow/sdk/bases/xcom.py | 1 +
.../src/airflow/sdk/execution_time/task_runner.py | 1 +
task-sdk/tests/task_sdk/bases/test_xcom.py | 72 ++++++++++++++++++++++
.../task_sdk/execution_time/test_task_runner.py | 65 +++++++++++++++++++
4 files changed, 139 insertions(+)
diff --git a/task-sdk/src/airflow/sdk/bases/xcom.py b/task-sdk/src/airflow/sdk/bases/xcom.py
index 7c982a050dd..e35912d39f1 100644
--- a/task-sdk/src/airflow/sdk/bases/xcom.py
+++ b/task-sdk/src/airflow/sdk/bases/xcom.py
@@ -374,5 +374,6 @@ class BaseXCom:
dag_id=dag_id,
task_id=task_id,
run_id=run_id,
+ map_index=map_index,
),
)
diff --git a/task-sdk/src/airflow/sdk/execution_time/task_runner.py b/task-sdk/src/airflow/sdk/execution_time/task_runner.py
index e366136f699..968d83e794e 100644
--- a/task-sdk/src/airflow/sdk/execution_time/task_runner.py
+++ b/task-sdk/src/airflow/sdk/execution_time/task_runner.py
@@ -906,6 +906,7 @@ def run(
dag_id=ti.dag_id,
task_id=ti.task_id,
run_id=ti.run_id,
+ map_index=ti.map_index,
)
with set_current_context(context):
diff --git a/task-sdk/tests/task_sdk/bases/test_xcom.py b/task-sdk/tests/task_sdk/bases/test_xcom.py
new file mode 100644
index 00000000000..5bc2fb85b25
--- /dev/null
+++ b/task-sdk/tests/task_sdk/bases/test_xcom.py
@@ -0,0 +1,72 @@
+# 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 unittest import mock
+
+import pytest
+
+from airflow.sdk.bases.xcom import BaseXCom
+from airflow.sdk.execution_time.comms import DeleteXCom, XComResult
+
+
+class TestBaseXCom:
+ @pytest.mark.parametrize(
+ "map_index",
+ [
+ pytest.param(None, id="map_index_none"),
+ pytest.param(-1, id="map_index_negative_one"),
+ pytest.param(0, id="map_index_zero"),
+ pytest.param(5, id="map_index_positive"),
+ ],
+ )
+ def test_delete_includes_map_index_in_delete_xcom_message(self, map_index, mock_supervisor_comms):
+ """Test that BaseXCom.delete properly passes map_index to the DeleteXCom message."""
+ with mock.patch.object(
+ BaseXCom, "_get_xcom_db_ref", return_value=XComResult(key="test_key", value="test_value")
+ ) as mock_get_ref:
+ with mock.patch.object(BaseXCom, "purge") as mock_purge:
+ BaseXCom.delete(
+ key="test_key",
+ task_id="test_task",
+ dag_id="test_dag",
+ run_id="test_run",
+ map_index=map_index,
+ )
+
+ mock_get_ref.assert_called_once_with(
+ key="test_key",
+ dag_id="test_dag",
+ task_id="test_task",
+ run_id="test_run",
+ map_index=map_index,
+ )
+
+ # Verify purge was called
+ mock_purge.assert_called_once()
+
+ # Verify DeleteXCom message was sent with map_index
+ mock_supervisor_comms.send.assert_called_once()
+ sent_message = mock_supervisor_comms.send.call_args[0][0]
+
+ assert isinstance(sent_message, DeleteXCom)
+ assert sent_message.key == "test_key"
+ assert sent_message.dag_id == "test_dag"
+ assert sent_message.task_id == "test_task"
+ assert sent_message.run_id == "test_run"
+ assert sent_message.map_index == map_index
diff --git a/task-sdk/tests/task_sdk/execution_time/test_task_runner.py b/task-sdk/tests/task_sdk/execution_time/test_task_runner.py
index 48550de9fc6..0b7f157ee52 100644
--- a/task-sdk/tests/task_sdk/execution_time/test_task_runner.py
+++ b/task-sdk/tests/task_sdk/execution_time/test_task_runner.py
@@ -54,6 +54,7 @@ from airflow.sdk.api.datamodels._generated import (
DagRunState,
TaskInstance,
TaskInstanceState,
+ TIRunContext,
)
from airflow.sdk.bases.xcom import BaseXCom
from airflow.sdk.definitions._internal.types import SET_DURING_EXECUTION
@@ -1908,6 +1909,70 @@ class TestRuntimeTaskInstance:
assert dr.run_id == "prev_success_run"
assert dr.state == "success"
+ @pytest.mark.parametrize(
+ "map_index",
+ [
+ pytest.param(-1, id="map_index_negative_one"),
+ pytest.param(0, id="map_index_zero"),
+ pytest.param(5, id="map_index_positive"),
+ ],
+ )
+ def test_xcom_clearing_includes_map_index(self, create_runtime_ti, mock_supervisor_comms, map_index):
+ """Test that XCom clearing during task execution properly passes map_index."""
+
+ task = BaseOperator(task_id="test_task")
+ runtime_ti = create_runtime_ti(task=task, map_index=map_index)
+
+ # Mock the ti_context_from_server to include xcom_keys_to_clear
+ runtime_ti._ti_context_from_server = TIRunContext(
+ dag_run=runtime_ti._ti_context_from_server.dag_run,
+ task_reschedule_count=0,
+ max_tries=1,
+ should_retry=False,
+ xcom_keys_to_clear=["key1", "key2", "key3"],
+ )
+
+ with mock.patch.object(XCom, "delete") as mock_delete:
+ run(runtime_ti, context=runtime_ti.get_template_context(), log=mock.MagicMock())
+
+ # Verify that XCom.delete was called for each key with the correct map_index
+ expected_calls = [
+ mock.call(
+ key="key1",
+ dag_id=runtime_ti.dag_id,
+ task_id=runtime_ti.task_id,
+ run_id=runtime_ti.run_id,
+ map_index=map_index,
+ ),
+ mock.call(
+ key="key2",
+ dag_id=runtime_ti.dag_id,
+ task_id=runtime_ti.task_id,
+ run_id=runtime_ti.run_id,
+ map_index=map_index,
+ ),
+ mock.call(
+ key="key3",
+ dag_id=runtime_ti.dag_id,
+ task_id=runtime_ti.task_id,
+ run_id=runtime_ti.run_id,
+ map_index=map_index,
+ ),
+ ]
+ mock_delete.assert_has_calls(expected_calls)
+
+ def test_xcom_clearing_without_keys_to_clear(self, create_runtime_ti, mock_supervisor_comms):
+ """Test that no XCom clearing occurs when xcom_keys_to_clear is empty."""
+ task = BaseOperator(task_id="test_task")
+ runtime_ti = create_runtime_ti(task=task)
+
+ assert runtime_ti._ti_context_from_server.xcom_keys_to_clear is None
+
+ with mock.patch.object(XCom, "delete") as mock_delete:
+ run(runtime_ti, context=runtime_ti.get_template_context(), log=mock.MagicMock())
+
+ mock_delete.assert_not_called()
+
class TestXComAfterTaskExecution:
@pytest.mark.parametrize(
(airflow) 02/03: [v3-0-test] docs: add docs for custom alert messages (#50273) (#54955)
Posted by ka...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kaxilnaik pushed a commit to branch v3-0-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
commit 1ea36e8ac635c55aff6576c54a05bf5a1b80134c
Author: github-actions[bot] <41...@users.noreply.github.com>
AuthorDate: Tue Aug 26 22:31:00 2025 +0200
[v3-0-test] docs: add docs for custom alert messages (#50273) (#54955)
(cherry picked from commit 8583fbaa3d02ee27dd1f6870eb3e3b879bc87ac4)
Co-authored-by: Zhen-Lun (Kevin) Hong <ke...@yahoo.com.tw>
---
airflow-core/docs/howto/customize-ui.rst | 37 +++++++++++++++++++++
.../docs/img/ui-alert-message-markdown.png | Bin 0 -> 45266 bytes
airflow-core/docs/img/ui-alert-message.png | Bin 48753 -> 42025 bytes
3 files changed, 37 insertions(+)
diff --git a/airflow-core/docs/howto/customize-ui.rst b/airflow-core/docs/howto/customize-ui.rst
index 2378fe39747..85947c87e0d 100644
--- a/airflow-core/docs/howto/customize-ui.rst
+++ b/airflow-core/docs/howto/customize-ui.rst
@@ -64,3 +64,40 @@ After
.. note::
From version 2.3.0 you can include markup in ``instance_name`` variable for further customization. To enable, set ``instance_name_has_markup`` under the ``[webserver]`` section inside ``airflow.cfg`` to ``True``.
+
+
+Add custom alert messages on the dashboard
+------------------------------------------
+
+Extra alert messages can be shown on the UI dashboard. This can be useful for warning about setup issues
+or announcing changes to end users. The following example shows how to add alert messages:
+
+1. Add the following contents to ``airflow_local_settings.py`` file under ``$AIRFLOW_HOME/config``.
+ Each alert message should specify a severity level (``info``, ``warning``, ``error``) using ``category``.
+
+ .. code-block:: python
+
+ from airflow.api_fastapi.common.types import UIAlert
+
+ DASHBOARD_UIALERTS = [
+ UIAlert(text="Welcome to Airflow.", category="info"),
+ UIAlert(text="Airflow server downtime scheduled for tomorrow at 10:00 AM.", category="warning"),
+ UIAlert(text="Critical error detected!", category="error"),
+ ]
+
+ See :ref:`Configuring local settings <set-config:configuring-local-settings>` for details on how to
+ configure local settings.
+
+2. Restart Airflow Webserver, and you should now see:
+
+.. image:: ../img/ui-alert-message.png
+
+Alert messages also support Markdown. In the following example, we show an alert message of heading 2 with a link included.
+
+ .. code-block:: python
+
+ DASHBOARD_UIALERTS = [
+ UIAlert(text="## Visit [airflow.apache.org](https://airflow.apache.org)", category="info"),
+ ]
+
+.. image:: ../img/ui-alert-message-markdown.png
diff --git a/airflow-core/docs/img/ui-alert-message-markdown.png b/airflow-core/docs/img/ui-alert-message-markdown.png
new file mode 100755
index 00000000000..39b7843cad7
Binary files /dev/null and b/airflow-core/docs/img/ui-alert-message-markdown.png differ
diff --git a/airflow-core/docs/img/ui-alert-message.png b/airflow-core/docs/img/ui-alert-message.png
index 5f436f9a0ae..2e419b8de8c 100644
Binary files a/airflow-core/docs/img/ui-alert-message.png and b/airflow-core/docs/img/ui-alert-message.png differ