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

vincbeck pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new fa00af4d044 Update multi-team docs to match the teams CLI and name 
rules (#72045)
fa00af4d044 is described below

commit fa00af4d0444315c6b4cc925191b0db90841e1b1
Author: PoAn Yang <[email protected]>
AuthorDate: Tue Aug 25 21:54:29 2026 +0900

    Update multi-team docs to match the teams CLI and name rules (#72045)
---
 airflow-core/docs/core-concepts/multi-team.rst     | 50 +++++++++++++++++++---
 airflow-core/src/airflow/cli/cli_config.py         |  3 +-
 .../always/test_secrets_environment_variables.py   |  4 +-
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/airflow-core/docs/core-concepts/multi-team.rst 
b/airflow-core/docs/core-concepts/multi-team.rst
index 6d6c8493e73..da1ca415a0e 100644
--- a/airflow-core/docs/core-concepts/multi-team.rst
+++ b/airflow-core/docs/core-concepts/multi-team.rst
@@ -54,7 +54,8 @@ A **Team** is a logical grouping that represents a group of 
users within your or
 
 Teams within the Airflow database have a very simple structure, only 
containing one field:
 
-- **name**: A unique identifier for the team (3-50 characters, alphanumeric 
with hyphens and underscores)
+- **name**: A unique identifier for the team (3-50 characters, lower case 
letters, digits, hyphens and
+  underscores, with no two consecutive underscores)
 
 Teams are associated with Dag bundles through a separate association table, 
which links team names to Dag bundle names.
 
@@ -118,8 +119,10 @@ implement two methods:
   used primarily to check whether a user belongs to a team.
 - ``_get_teams``: Returns the set of teams defined in the auth manager.
 
-During initialization, Airflow validates that all teams defined in the auth 
manager are also present in the
-Airflow metadata database. If any team is missing, Airflow will raise an error.
+During initialization, Airflow compares the teams defined in the auth manager 
with the teams in the Airflow
+metadata database. A mismatch in either direction -- a team the auth manager 
defines that the database does
+not have, or a team the database has that the auth manager does not define -- 
emits a ``UserWarning``.
+Startup is not blocked, so watch the startup log for these warnings.
 
 If the auth manager you are using does not implement these methods, Airflow 
will raise a
 ``NotImplementedError`` at runtime.
@@ -161,7 +164,8 @@ Creating a Team
 
     airflow teams create <team_name>
 
-Team names must be 3-50 characters long and contain only alphanumeric 
characters, hyphens, and underscores.
+Team names must be 3-50 characters long and contain only lower case letters, 
digits, hyphens and underscores.
+Two consecutive underscores are not allowed.
 
 Listing Teams
 ^^^^^^^^^^^^^
@@ -189,6 +193,38 @@ Or to skip the confirmation prompt:
 
     A team cannot be deleted if it has associated resources (Dag bundles, 
Variables, Connections, or Pools). You must remove these associations first.
 
+.. _multi-team-teams-sync:
+
+Syncing Teams from the Dag Bundle Config
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.3.0
+
+.. code-block:: bash
+
+    airflow teams sync
+
+Creates a team for every ``team_name`` in the :ref:`Dag bundle config 
<multi-team-dag-bundles>` that the
+database does not have yet, so the bundle config can be the one place teams 
are declared instead of running
+``airflow teams create`` once per team. It also creates the default pool of 
any configured team that is
+missing one, including teams that already existed.
+
+.. _multi-team-teams-verify:
+
+Verifying the Configuration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.4.0
+
+.. code-block:: bash
+
+    airflow teams verify
+
+Checks the multi-team configuration against the database and reports any of 
these problems:
+
+- a team that has no default pool
+- a team referenced by a Dag bundle but missing from the database
+
 Configuring Team Resources
 --------------------------
 
@@ -516,6 +552,8 @@ name followed by an equals sign:
     broker_url = redis://team-b-redis:6379/0
     result_backend = db+postgresql+psycopg://team-b-db/celery_results
 
+.. _multi-team-dag-bundles:
+
 Dag Bundle to Team Association
 ------------------------------
 
@@ -552,7 +590,9 @@ In this example:
 
 .. note::
 
-    The team specified in ``team_name`` must exist in the database before 
syncing the Dag bundles. Create teams first using ``airflow teams create``.
+    The team specified in ``team_name`` must exist in the database before 
syncing the Dag bundles. Create the
+    teams first with ``airflow teams create``, or let ``airflow teams sync`` 
create them from this config
+    (see :ref:`multi-team-teams-sync`).
 
 How Scheduling Works
 --------------------
diff --git a/airflow-core/src/airflow/cli/cli_config.py 
b/airflow-core/src/airflow/cli/cli_config.py
index 1a83af7a272..06c8819136b 100644
--- a/airflow-core/src/airflow/cli/cli_config.py
+++ b/airflow-core/src/airflow/cli/cli_config.py
@@ -1657,7 +1657,8 @@ TEAMS_COMMANDS = (
         name="create",
         help="Create a team",
         description=(
-            "Create a team. Team names must be 3-50 characters long and 
contain only alphanumeric characters, hyphens, and underscores.\n"
+            "Create a team. Team names must be 3-50 characters long and 
contain only lower case letters, "
+            "digits, hyphens and underscores, with no two consecutive 
underscores.\n"
         ),
         
func=lazy_load_command("airflow.cli.commands.team_command.team_create"),
         args=(ARG_TEAM_NAME, ARG_VERBOSE),
diff --git 
a/airflow-core/tests/unit/always/test_secrets_environment_variables.py 
b/airflow-core/tests/unit/always/test_secrets_environment_variables.py
index 200b545bf03..692827a3ab9 100644
--- a/airflow-core/tests/unit/always/test_secrets_environment_variables.py
+++ b/airflow-core/tests/unit/always/test_secrets_environment_variables.py
@@ -28,8 +28,8 @@ from airflow.secrets.environment_variables import (
 
 from tests_common.test_utils.config import conf_vars
 
-# A team specific secret is stored as ``<PREFIX>_<TEAM_NAME>___<SECRET_ID>``. 
Team names may contain
-# underscores (they are validated against ``^[a-zA-Z0-9_-]{3,50}$``), so both 
shapes are exercised.
+# A team specific secret is stored as ``<PREFIX>_<TEAM_NAME>___<SECRET_ID>``. 
Team names may contain a
+# single underscore (they are validated against ``TEAM_NAME_PATTERN``), so 
both shapes are exercised.
 TEAM_NAMES = ["team_a", "teama"]
 OTHER_TEAM_NAME = "team_b"
 SECRET_ID = "dbconn"

Reply via email to