potiuk opened a new pull request, #70885: URL: https://github.com/apache/airflow/pull/70885
> **Stacked on [#70884](https://github.com/apache/airflow/pull/70884)** — both > touch `team_command.py`. Review that one first; this PR's own change is the > second commit. Team names are case sensitive — `data_eng` and `Data_Eng` are two distinct teams, both accepted by `^[a-zA-Z0-9_-]{3,50}$` — but the environment secrets backend upper-cases the team name when it builds the variable name: ```python os.environ.get(f"{CONN_ENV_PREFIX}_{team_name.upper()}___" + conn_id.upper()) ``` So both resolve `AIRFLOW_CONN__DATA_ENG___<ID>`. The two teams share one secrets namespace: each reads the other's Connections and Variables, and whichever provisions a variable last wins. Whether the two rows can coexist at all is decided by the **database's collation** on a `String` primary key rather than by Airflow, so the same configuration behaves differently across backends — on a case sensitive collation both persist and the namespaces merge; on a case insensitive one the second `teams create` fails on the primary key. ### Approach Reject the collision at creation, on **both** paths. - `teams create` refuses a name that upper-cases onto an existing team's name. - `teams sync` checks the incoming bundle names against each other as well as against the stored ones, because one bundle config can introduce both halves of a collision in the same run. The alternative — dropping the `upper()` fold so team identity stays case sensitive end to end — was rejected: environment variable names are conventionally upper-case, and it would silently change *which* variable an existing deployment resolves. Failing at the moment the name is chosen is the safer half of that trade, and it makes behaviour uniform across database collations. `upper()` rather than `casefold()` is deliberate: it is exactly what the backend applies, and team names are ASCII-only by the name pattern. ### Behaviour change `airflow teams create` and `airflow teams sync` now fail with an explanatory message when a name differs from an existing team's only by case. Deployments that already have such a pair are **not** migrated by this change — the collision already exists there and is reported by neither command. Names differing by more than case are unaffected. ### Test plan - [x] `test_team_command.py` — 23 cases pass - [x] `test_team_create_rejects_a_name_differing_only_in_case` — creating `data_eng` then `Data_Eng` fails, and no second row is written - [x] `test_team_create_allows_a_name_differing_by_more_than_case` — `data_eng` and `data_eng2` coexist - [x] `ruff check` / `ruff format` clean ##### Was generative AI tooling used to co-author this PR? - [X] Yes — Claude Opus 5 (1M context) Generated-by: Claude Opus 5 (1M context) following the guidelines at https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
