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]

Reply via email to