You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by po...@apache.org on 2025/06/14 13:56:40 UTC
(airflow) branch v3-0-test updated: [v3-0-test] Optimize ui lint pre-commits (#51725) (#51729)
This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch v3-0-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-0-test by this push:
new 1b5d32ef633 [v3-0-test] Optimize ui lint pre-commits (#51725) (#51729)
1b5d32ef633 is described below
commit 1b5d32ef63311f9ef0cdf1435f3bcbd38745453d
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Sat Jun 14 15:56:33 2025 +0200
[v3-0-test] Optimize ui lint pre-commits (#51725) (#51729)
Running pre-commits for typescript compilation, linting formatting is
currently very slow. The pre-commit that is doing it took more than 2.5
minutes - always, independently which files changed. Also, no matter
whether UI or simple auth manager UI changed, both were compiled.
This is the first iteration of speeding up the pre-commit especially
for incremental changes.
The following changes were implemented:
* the scripts were split into ui and simple-auth-manager-ui
* timing information and verbose commands displayed so that
we can measure which commands take how much time
* the pre-commmit now passes all the files as input (and pre-commit
is serialized) - which means that some commands can only be run
on the subset of files that changed
* tsc step is modified to only run on a subset of .ts and .tsx files
that were changed (via dynamic extension of the project)
Overall when just few files change, the pre-commit should now complete
in less than 10-20 seconds
Still some optimisations are possible in the future.
(cherry picked from commit 52be0dd4c471101e1afe342b8ef8d716bde2525c)
---
.pre-commit-config.yaml | 73 +++++++++++++-----
contributing-docs/08_static_code_checks.rst | 4 +-
dev/breeze/doc/images/output_static-checks.svg | 86 +++++++++++-----------
dev/breeze/doc/images/output_static-checks.txt | 2 +-
dev/breeze/src/airflow_breeze/pre_commit_ids.py | 3 +-
.../src/airflow_breeze/utils/selective_checks.py | 3 +-
dev/breeze/tests/test_selective_checks.py | 21 ++++--
scripts/ci/pre_commit/common_precommit_utils.py | 54 ++++++++++++++
scripts/ci/pre_commit/compile_lint_ui.py | 51 -------------
.../ts_compile_lint_simple_auth_manager_ui.py | 61 +++++++++++++++
scripts/ci/pre_commit/ts_compile_lint_ui.py | 61 +++++++++++++++
11 files changed, 296 insertions(+), 123 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index e5c88598f17..fe166b32a39 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -19,6 +19,7 @@ default_stages: [pre-commit, pre-push]
default_language_version:
python: python3
node: 22.16.0
+ golang: 1.24.0
minimum_pre_commit_version: '3.2.0'
exclude: ^.*/.*_vendor/
repos:
@@ -301,6 +302,7 @@ repos:
^.*airflow\.template\.yaml$|
^.*init_git_sync\.template\.yaml$|
^chart/(?:templates|files)/.*\.yaml$|
+ ^helm-tests/tests/chart_utils/keda.sh_scaledobjects\.yaml$|
.*/v1.*\.yaml$|
^.*openapi.*\.yaml$|
^\.pre-commit-config\.yaml$|
@@ -328,7 +330,17 @@ repos:
The word(s) should be in lowercase." && exec codespell "$@"' --
language: python
types: [text]
- exclude: material-icons\.css$|^images/.*$|^RELEASE_NOTES\.txt$|^.*package-lock\.json$|^.*/kinglear\.txt$|^.*pnpm-lock\.yaml$|.*/dist/.*
+ exclude: >
+ (?x)
+ material-icons\.css$|
+ ^images/.*$|
+ ^RELEASE_NOTES\.txt$|
+ ^.*package-lock\.json$|
+ ^.*/kinglear\.txt$|
+ ^.*pnpm-lock\.yaml$|
+ .*/dist/.*|
+ ^airflow-core/src/airflow/ui/src/i18n/locales/de/|
+ ^airflow-core/src/airflow/ui/src/i18n/locales/pl/
args:
- --ignore-words=docs/spelling_wordlist.txt
- --skip=providers/.*/src/airflow/providers/*/*.rst,providers/*/docs/changelog.rst,docs/*/commits.rst,providers/*/docs/commits.rst,providers/*/*/docs/commits.rst,docs/apache-airflow/tutorial/pipeline_example.csv,*.min.js,*.lock,INTHEWILD.md,*.svg
@@ -390,7 +402,7 @@ repos:
types_or: [python, pyi]
args: [--fix]
require_serial: true
- additional_dependencies: ['ruff==0.11.2']
+ additional_dependencies: ['ruff==0.11.13']
exclude: ^airflow-core/tests/unit/dags/test_imports\.py$|^performance/tests/test_.*\.py$
- id: ruff-format
name: Run 'ruff format'
@@ -400,14 +412,14 @@ repos:
types_or: [python, pyi]
args: []
require_serial: true
- additional_dependencies: ['ruff==0.11.2']
+ additional_dependencies: ['ruff==0.11.13']
exclude: ^airflow-core/tests/unit/dags/test_imports\.py$
- id: replace-bad-characters
name: Replace bad characters
entry: ./scripts/ci/pre_commit/replace_bad_characters.py
language: python
types: [file, text]
- exclude: ^clients/gen/go\.sh$|^\.gitmodules$|.*/dist/.*
+ exclude: ^clients/gen/go\.sh$|^\.gitmodules$|.*/dist/.*|\.go$|/go\.(mod|sum)$
additional_dependencies: ['rich>=12.4.4']
- id: lint-dockerfile
name: Lint Dockerfile
@@ -606,7 +618,9 @@ repos:
pass_filenames: true
exclude: >
(?x)
+ ^airflow-core/src/airflow/ui/src/i18n/config\.ts$|
^airflow-core/src/airflow/ui/openapi-gen/|
+ ^airflow-core/src/airflow/ui/src/i18n/locales/de/README\.md$|
^airflow-core/src/airflow/cli/commands/local_commands/fastapi_api_command\.py$|
^airflow-core/src/airflow/config_templates/|
^airflow-core/src/airflow/models/baseoperator\.py$|
@@ -628,6 +642,7 @@ repos:
^providers/google/src/airflow/providers/google/cloud/operators/cloud_build\.py$|
^providers/google/src/airflow/providers/google/cloud/operators/dataproc\.py$|
^providers/google/src/airflow/providers/google/cloud/operators/mlengine\.py$|
+ ^providers/keycloak/src/airflow/providers/keycloak/auth_manager/cli/definition.py|
^providers/microsoft/azure/src/airflow/providers/microsoft/azure/hooks/cosmos\.py$|
^providers/microsoft/winrm/src/airflow/providers/microsoft/winrm/hooks/winrm\.py$|
^airflow-core/docs/.*commits\.rst$|
@@ -641,6 +656,7 @@ repos:
^airflow-core/src/airflow/utils/trigger_rule\.py$|
^chart/values.schema\.json$|
^helm-tests/tests/chart_utils/helm_template_generator\.py$|
+ ^helm-tests/tests/chart_utils/ingress-networking-v1beta1\.json$|
^dev/|
^devel-common/src/docs/README\.rst$|
^docs/apache-airflow-providers-amazon/secrets-backends/aws-ssm-parameter-store\.rst$|
@@ -856,7 +872,6 @@ repos:
- id: compile-fab-assets
name: Compile FAB provider assets
language: node
- 'types_or': [javascript, ts, tsx]
files: ^providers/fab/.*/www/
entry: ./scripts/ci/pre_commit/compile_fab_assets.py
pass_filenames: false
@@ -1231,6 +1246,40 @@ repos:
files: ^airflow-core/src/airflow/migrations/versions/.*\.py$
exclude:
airflow-core/src/airflow/migrations/versions/0028_3_0_0_drop_ab_user_id_foreign_key.py
+ - id: ts-compile-lint-ui
+ name: Compile / format / lint UI
+ description: TS types generation / ESLint / Prettier new UI files
+ language: node
+ files: |
+ (?x)
+ ^airflow-core/src/airflow/ui/.*\.(js|ts|tsx|yaml|css|json)|
+ ^airflow-core/src/airflow/api_fastapi/core_api/openapi/.*\.yaml$|
+ ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/openapi/v1.*\.yaml$
+ exclude: |
+ (?x)
+ ^airflow-core/src/airflow/ui/node-modules/.*|
+ ^airflow-core/src/airflow/ui/.pnpm-store
+ entry: ./scripts/ci/pre_commit/ts_compile_lint_ui.py
+ additional_dependencies: ['pnpm@9.7.1']
+ pass_filenames: true
+ require_serial: true
+ - id: ts-compile-lint-simple-auth-manager-ui
+ name: Compile / format / lint simple auth manager UI
+ description: TS types generation / ESLint / Prettier new UI files
+ language: node
+ files: |
+ (?x)
+ ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/.*\.(js|ts|tsx|yaml|css|json)|
+ ^airflow-core/src/airflow/api_fastapi/core_api/openapi/.*\.yaml$|
+ ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/openapi/v1.*\.yaml$
+ exclude: |
+ (?x)
+ ^airflow-core/src/airflow/api_fastapi/node-modules/.*|
+ ^airflow-core/src/airflow/api_fastapi/.pnpm-store
+ entry: ./scripts/ci/pre_commit/ts_compile_lint_simple_auth_manager_ui.py
+ additional_dependencies: ['pnpm@9.7.1']
+ pass_filenames: true
+ require_serial: true
## ADD MOST PRE-COMMITS ABOVE THAT LINE
# The below pre-commits are those requiring CI image to be built
- id: mypy-dev
@@ -1346,20 +1395,6 @@ repos:
files: ^airflow-core/src/airflow/api_fastapi/.*\.py$|^airflow-core/src/airflow/api_fastapi/auth/managers/simple/.*\.py$|^providers/fab/src/airflow/providers/fab/auth_manager/api_fastapi/.*\.py$
exclude: ^airflow-core/src/airflow/api_fastapi/execution_api/.*
additional_dependencies: ['rich>=12.4.4', 'openapi-spec-validator>=0.7.1']
- - id: ts-compile-format-lint-ui
- name: Compile / format / lint UI
- description: TS types generation / ESLint / Prettier new UI files
- language: node
- types_or: [javascript, ts, tsx, yaml, css, json]
- files: |
- (?x)
- ^airflow-core/src/airflow/ui/|
- ^airflow-core/src/airflow/api_fastapi/core_api/openapi/.*\.yaml$|
- ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/|
- ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/openapi/v1.*\.yaml$
- entry: ./scripts/ci/pre_commit/compile_lint_ui.py
- additional_dependencies: ['pnpm@9.7.1']
- pass_filenames: false
- id: check-provider-yaml-valid
name: Validate provider.yaml files
entry: ./scripts/ci/pre_commit/check_provider_yaml_files.py
diff --git a/contributing-docs/08_static_code_checks.rst b/contributing-docs/08_static_code_checks.rst
index 9e4a4fbd5a5..ab4ec43edec 100644
--- a/contributing-docs/08_static_code_checks.rst
+++ b/contributing-docs/08_static_code_checks.rst
@@ -352,7 +352,9 @@ require Breeze Docker image to be built locally.
+-----------------------------------------------------------+--------------------------------------------------------+---------+
| trailing-whitespace | Remove trailing whitespace at end of line | |
+-----------------------------------------------------------+--------------------------------------------------------+---------+
-| ts-compile-format-lint-ui | Compile / format / lint UI | * |
+| ts-compile-lint-simple-auth-manager-ui | Compile / format / lint simple auth manager UI | |
++-----------------------------------------------------------+--------------------------------------------------------+---------+
+| ts-compile-lint-ui | Compile / format / lint UI | |
+-----------------------------------------------------------+--------------------------------------------------------+---------+
| update-black-version | Update black versions everywhere (manual) | |
+-----------------------------------------------------------+--------------------------------------------------------+---------+
diff --git a/dev/breeze/doc/images/output_static-checks.svg b/dev/breeze/doc/images/output_static-checks.svg
index 4dd66c187ff..8ff92c29da3 100644
--- a/dev/breeze/doc/images/output_static-checks.svg
+++ b/dev/breeze/doc/images/output_static-checks.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 2172.7999999999997" xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 2197.2" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath id="breeze-static-checks-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="2121.7999999999997" />
+ <rect x="0" y="0" width="1463.0" height="2146.2" />
</clipPath>
<clipPath id="breeze-static-checks-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -303,9 +303,12 @@
<clipPath id="breeze-static-checks-line-85">
<rect x="0" y="2075.5" width="1464" height="24.65"/>
</clipPath>
+<clipPath id="breeze-static-checks-line-86">
+ <rect x="0" y="2099.9" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="2170.8" rx="8"/><text class="breeze-static-checks-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command: static-checks</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="2195.2" rx="8"/><text class="breeze-static-checks-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">Command: static-checks</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -364,44 +367,45 @@
</text><text class="breeze-static-checks-r5" x="0" y="1142.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-46)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1142.4" textLength="988.2" clip-path="url(#breeze-static-checks-line-46)">mypy-airflow-core | mypy-airflow-ctl | mypy-dev | mypy-devel-common |            </text><text class="breeze-static-checks-r5" x="1451.8" [...]
</text><text class="breeze-static-checks-r5" x="0" y="1166.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-47)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1166.8" textLength="988.2" clip-path="url(#breeze-static-checks-line-47)">mypy-providers | mypy-task-sdk | pretty-format-json | pylint | python-no-log-warn</text><text class="breeze-static-checks-r5" x="1451.8" y="1166.8" textLength="12.2" clip-path="url(#breeze-sta [...]
</text><text class="breeze-static-checks-r5" x="0" y="1191.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-48)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1191.2" textLength="988.2" clip-path="url(#breeze-static-checks-line-48)">| replace-bad-characters | rst-backticks | ruff | ruff-format | shellcheck |     </text><text class="breeze-static-checks-r5" x="1451.8" y="1191.2" textLengt [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1215.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-49)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1215.6" textLength="988.2" clip-path="url(#breeze-static-checks-line-49)">trailing-whitespace | ts-compile-format-lint-ui | update-black-version |         </text><text class="breeze-static-checks-r5" x="1451.8" y="1215.6" textLength="12 [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1240" textLength="12.2" clip-path="url(#breeze-static-checks-line-50)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1240" textLength="988.2" clip-path="url(#breeze-static-checks-line-50)">update-breeze-cmd-output | update-breeze-readme-config-hash |                    </text><text class="breeze-static-checks [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1264.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-51)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1264.4" textLength="988.2" clip-path="url(#breeze-static-checks-line-51)">update-chart-dependencies | update-er-diagram | update-in-the-wild-to-be-sorted |</text><text class="breeze-static-checks-r5" x="1451.8" y="1264.4" textLength="12.2" clip-path="url(#breeze-static-checks-line [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1288.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-52)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1288.8" textLength="988.2" clip-path="url(#breeze-static-checks-line-52)">update-inlined-dockerfile-scripts | update-installed-providers-to-be-sorted |    </text><text class="breeze-static-checks-r5" x="1451.8" y="1288.8" textLength="12.2" clip-path="url(#breeze-static-c [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1313.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-53)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1313.2" textLength="988.2" clip-path="url(#breeze-static-checks-line-53)">update-installers-and-pre-commit | update-local-yml-file |                       </text><text class="b [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1337.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-54)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1337.6" textLength="988.2" clip-path="url(#breeze-static-checks-line-54)">update-migration-references | update-providers-build-files |                     </text><text class="breeze-stat [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1362" textLength="12.2" clip-path="url(#breeze-static-checks-line-55)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1362" textLength="988.2" clip-path="url(#breeze-static-checks-line-55)">update-providers-dependencies | update-pyproject-toml |                          </text><te [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1386.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-56)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1386.4" textLength="988.2" clip-path="url(#breeze-static-checks-line-56)">update-reproducible-source-date-epoch | update-spelling-wordlist-to-be-sorted |  </text><text class="breeze-static-checks-r5" x="1451.8" y="1386.4" textLength="12.2" clip-path="url(#breeze-static-checks-line [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1410.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-57)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1410.8" textLength="988.2" clip-path="url(#breeze-static-checks-line-57)">update-supported-versions | update-vendored-in-k8s-json-schema | update-version |</text><text class="breeze-static-checks-r5" x="1451.8" y="1410.8" textLength="12.2" clip-path="url(#breeze-static-checks-line [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1435.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-58)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1435.2" textLength="988.2" clip-path="url(#breeze-static-checks-line-58)">validate-operators-init | yamllint | zizmor)                             [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1459.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-59)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1459.6" textLength="268.4" clip-path="url(#breeze-static-checks-line-59)">--show-diff-on-failure</text><text class="breeze-static-checks-r6" x="402.6" y="1459.6" textLength="24.4" clip-path="url(#breeze-static-checks-line-59)">-s</text><text class="breeze-static-checks-r1" x="451.4" y="1459.6" textLength=" [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1484" textLength="12.2" clip-path="url(#breeze-static-checks-line-60)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1484" textLength="292.8" clip-path="url(#breeze-static-checks-line-60)">--initialize-environment</text><text class="breeze-static-checks-r1" x="451.4" y="1484" textLength="549" clip-path="url(#breeze-static-checks-line-60)">Initialize environment before running checks.</text><text class=" [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1508.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-61)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1508.4" textLength="353.8" clip-path="url(#breeze-static-checks-line-61)">--max-initialization-attempts</text><text class="breeze-static-checks-r1" x="451.4" y="1508.4" textLength="854" clip-path="url(#breeze-static-checks-line-61)">Maximum number of attempts to initialize env [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1532.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-62)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1532.8" textLength="854" clip-path="url(#breeze-static-checks-line-62)">(INTEGER RANGE)                                    [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1557.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-63)">│</text><text class="breeze-static-checks-r5" x="451.4" y="1557.2" textLength="854" clip-path="url(#breeze-static-checks-line-63)">[default: 3; 1<=x<=10]                                 [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1581.6" textLength="1464" clip-path="url(#breeze-static-checks-line-64)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="1581.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-64)">
-</text><text class="breeze-static-checks-r5" x="0" y="1606" textLength="24.4" clip-path="url(#breeze-static-checks-line-65)">╭─</text><text class="breeze-static-checks-r5" x="24.4" y="1606" textLength="463.6" clip-path="url(#breeze-static-checks-line-65)"> Selecting files to run the checks on </text><text class="breeze-static-checks-r5" x="488" y="1606" textLength="951.6" clip-path="url(#breeze-static-checks-line-65)">────────────────────────────── [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1630.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-66)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1630.4" textLength="73.2" clip-path="url(#breeze-static-checks-line-66)">--file</text><text class="breeze-static-checks-r6" x="256.2" y="1630.4" textLength="24.4" clip-path="url(#breeze-static-checks-line-66)">-f</text><text class="breeze-static-checks-r1" x="305" y="1630.4" textLength="427" clip-path="url [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1654.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-67)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1654.8" textLength="134.2" clip-path="url(#breeze-static-checks-line-67)">--all-files</text><text class="breeze-static-checks-r6" x="256.2" y="1654.8" textLength="24.4" clip-path="url(#breeze-static-checks-line-67)">-a</text><text class="breeze-static-checks-r1" x="305" y="1654.8" textLength="292.8" clip-p [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1679.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-68)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1679.2" textLength="146.4" clip-path="url(#breeze-static-checks-line-68)">--commit-ref</text><text class="breeze-static-checks-r6" x="256.2" y="1679.2" textLength="24.4" clip-path="url(#breeze-static-checks-line-68)">-r</text><text class="breeze-static-checks-r1" x="305" y="1679.2" textLength="1134.6" clip [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1703.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-69)">│</text><text class="breeze-static-checks-r1" x="305" y="1703.6" textLength="183" clip-path="url(#breeze-static-checks-line-69)">exclusive with </text><text class="breeze-static-checks-r4" x="488" y="1703.6" textLength="158.6" clip-path="url(#breeze-static-checks-line-69)">--last-commit</text><text class="breeze-static-checks-r1" x="646.6" y="1703.6" te [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1728" textLength="12.2" clip-path="url(#breeze-static-checks-line-70)">│</text><text class="breeze-static-checks-r7" x="305" y="1728" textLength="1134.6" clip-path="url(#breeze-static-checks-line-70)">(TEXT)                                       [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1752.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-71)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1752.4" textLength="158.6" clip-path="url(#breeze-static-checks-line-71)">--last-commit</text><text class="breeze-static-checks-r6" x="256.2" y="1752.4" textLength="24.4" clip-path="url(#breeze-static-checks-line-71)">-c</text><text class="breeze-static-checks-r1" x="305" y="1752.4" textLength="793" clip-p [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1776.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-72)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1776.8" textLength="207.4" clip-path="url(#breeze-static-checks-line-72)">--only-my-changes</text><text class="breeze-static-checks-r6" x="256.2" y="1776.8" textLength="24.4" clip-path="url(#breeze-static-checks-line-72)">-m</text><text class="breeze-static-checks-r1" x="305" y="1776.8" textLength="1134.6" [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1801.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-73)">│</text><text class="breeze-static-checks-r1" x="305" y="1801.2" textLength="1134.6" clip-path="url(#breeze-static-checks-line-73)">branch and HEAD of your branch.                              [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1825.6" textLength="1464" clip-path="url(#breeze-static-checks-line-74)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="1825.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-74)">
-</text><text class="breeze-static-checks-r5" x="0" y="1850" textLength="24.4" clip-path="url(#breeze-static-checks-line-75)">╭─</text><text class="breeze-static-checks-r5" x="24.4" y="1850" textLength="463.6" clip-path="url(#breeze-static-checks-line-75)"> Building image before running checks </text><text class="breeze-static-checks-r5" x="488" y="1850" textLength="951.6" clip-path="url(#breeze-static-checks-line-75)">──────────────────────────────────────── [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1874.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-76)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1874.4" textLength="317.2" clip-path="url(#breeze-static-checks-line-76)">--skip-image-upgrade-check</text><text class="breeze-static-checks-r1" x="414.8" y="1874.4" textLength="536.8" clip-path="url(#breeze-static-checks-line-76)">Skip checking if the CI image is up  [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1898.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-77)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1898.8" textLength="158.6" clip-path="url(#breeze-static-checks-line-77)">--force-build</text><text class="breeze-static-checks-r1" x="414.8" y="1898.8" textLength="707.6" clip-path="url(#breeze-static-checks-line-77)">Force image build no matter if it is determined& [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1923.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-78)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1923.2" textLength="231.8" clip-path="url(#breeze-static-checks-line-78)">--github-repository</text><text class="breeze-static-checks-r6" x="366" y="1923.2" textLength="24.4" clip-path="url(#breeze-static-checks-line-78)">-g</text><text class="breeze-static-checks-r1" x="414.8" y="1923.2" textLength="585.6 [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1947.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-79)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1947.6" textLength="109.8" clip-path="url(#breeze-static-checks-line-79)">--builder</text><text class="breeze-static-checks-r1" x="414.8" y="1947.6" textLength="756.4" clip-path="url(#breeze-static-checks-line-79)">Buildx builder used to perform `docker buildx build`  [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1972" textLength="12.2" clip-path="url(#breeze-static-checks-line-80)">│</text><text class="breeze-static-checks-r5" x="414.8" y="1972" textLength="756.4" clip-path="url(#breeze-static-checks-line-80)">[default: autodetect]                                    [...]
-</text><text class="breeze-static-checks-r5" x="0" y="1996.4" textLength="1464" clip-path="url(#breeze-static-checks-line-81)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="1996.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-81)">
-</text><text class="breeze-static-checks-r5" x="0" y="2020.8" textLength="24.4" clip-path="url(#breeze-static-checks-line-82)">╭─</text><text class="breeze-static-checks-r5" x="24.4" y="2020.8" textLength="195.2" clip-path="url(#breeze-static-checks-line-82)"> Common options </text><text class="breeze-static-checks-r5" x="219.6" y="2020.8" textLength="1220" clip-path="url(#breeze-static-checks-line-82)">────────────────────────────────────────────────────────────────────── [...]
-</text><text class="breeze-static-checks-r5" x="0" y="2045.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-83)">│</text><text class="breeze-static-checks-r4" x="24.4" y="2045.2" textLength="109.8" clip-path="url(#breeze-static-checks-line-83)">--dry-run</text><text class="breeze-static-checks-r6" x="158.6" y="2045.2" textLength="24.4" clip-path="url(#breeze-static-checks-line-83)">-D</text><text class="breeze-static-checks-r1" x="207.4" y="2045.2" textLength="719.8" clip-p [...]
-</text><text class="breeze-static-checks-r5" x="0" y="2069.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-84)">│</text><text class="breeze-static-checks-r4" x="24.4" y="2069.6" textLength="109.8" clip-path="url(#breeze-static-checks-line-84)">--verbose</text><text class="breeze-static-checks-r6" x="158.6" y="2069.6" textLength="24.4" clip-path="url(#breeze-static-checks-line-84)">-v</text><text class="breeze-static-checks-r1" x="207.4" y="2069.6" textLength="585.6" clip-p [...]
-</text><text class="breeze-static-checks-r5" x="0" y="2094" textLength="12.2" clip-path="url(#breeze-static-checks-line-85)">│</text><text class="breeze-static-checks-r4" x="24.4" y="2094" textLength="73.2" clip-path="url(#breeze-static-checks-line-85)">--help</text><text class="breeze-static-checks-r6" x="158.6" y="2094" textLength="24.4" clip-path="url(#breeze-static-checks-line-85)">-h</text><text class="breeze-static-checks-r1" x="207.4" y="2094" textLength="329.4" clip-path="url(#br [...]
-</text><text class="breeze-static-checks-r5" x="0" y="2118.4" textLength="1464" clip-path="url(#breeze-static-checks-line-86)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="2118.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-86)">
+</text><text class="breeze-static-checks-r5" x="0" y="1215.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-49)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1215.6" textLength="988.2" clip-path="url(#breeze-static-checks-line-49)">trailing-whitespace | ts-compile-lint-simple-auth-manager-ui | ts-compile-lint-ui</text><text class="breeze-static-checks-r5" x="1451.8" y="1215.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-49)" [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1240" textLength="12.2" clip-path="url(#breeze-static-checks-line-50)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1240" textLength="988.2" clip-path="url(#breeze-static-checks-line-50)">| update-black-version | update-breeze-cmd-output |                            [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1264.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-51)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1264.4" textLength="988.2" clip-path="url(#breeze-static-checks-line-51)">update-breeze-readme-config-hash | update-chart-dependencies | update-er-diagram </text><text class="breeze-static-checks-r5" x="1451.8" y="1264.4" textLength="12.2" clip-path="url(#breeze-static-checks-line [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1288.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-52)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1288.8" textLength="988.2" clip-path="url(#breeze-static-checks-line-52)">| update-in-the-wild-to-be-sorted | update-inlined-dockerfile-scripts |          </text><text class="breeze-static-checks-r5" x="1451.8" y="1288.8" textLength="12 [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1313.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-53)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1313.2" textLength="988.2" clip-path="url(#breeze-static-checks-line-53)">update-installed-providers-to-be-sorted | update-installers-and-pre-commit |     </text><text class="breeze-static-checks-r5" x="1451.8" y="1313.2" textLength="12.2" clip-path="url(#breeze-sta [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1337.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-54)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1337.6" textLength="988.2" clip-path="url(#breeze-static-checks-line-54)">update-local-yml-file | update-migration-references |                           &# [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1362" textLength="12.2" clip-path="url(#breeze-static-checks-line-55)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1362" textLength="988.2" clip-path="url(#breeze-static-checks-line-55)">update-providers-build-files | update-providers-dependencies |                   </text><text class="breeze-static-checks-r5" [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1386.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-56)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1386.4" textLength="988.2" clip-path="url(#breeze-static-checks-line-56)">update-pyproject-toml | update-reproducible-source-date-epoch |                  </text><text class="breeze-static-checks-r5" x [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1410.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-57)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1410.8" textLength="988.2" clip-path="url(#breeze-static-checks-line-57)">update-spelling-wordlist-to-be-sorted | update-supported-versions |              </text><text class="breeze-static-checks-r5" x="1451.8" y="1410.8" [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1435.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-58)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1435.2" textLength="988.2" clip-path="url(#breeze-static-checks-line-58)">update-vendored-in-k8s-json-schema | update-version | validate-operators-init |  </text><text class="breeze-static-checks-r5" x="1451.8" y="1435.2" textLength="12.2" clip-path="url(#breeze-static-c [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1459.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-59)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1459.6" textLength="988.2" clip-path="url(#breeze-static-checks-line-59)">yamllint | zizmor)                                   [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1484" textLength="12.2" clip-path="url(#breeze-static-checks-line-60)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1484" textLength="268.4" clip-path="url(#breeze-static-checks-line-60)">--show-diff-on-failure</text><text class="breeze-static-checks-r6" x="402.6" y="1484" textLength="24.4" clip-path="url(#breeze-static-checks-line-60)">-s</text><text class="breeze-static-checks-r1" x="451.4" y="1484" textLength="524.6" c [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1508.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-61)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1508.4" textLength="292.8" clip-path="url(#breeze-static-checks-line-61)">--initialize-environment</text><text class="breeze-static-checks-r1" x="451.4" y="1508.4" textLength="549" clip-path="url(#breeze-static-checks-line-61)">Initialize environment before running checks.</text><text c [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1532.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-62)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1532.8" textLength="353.8" clip-path="url(#breeze-static-checks-line-62)">--max-initialization-attempts</text><text class="breeze-static-checks-r1" x="451.4" y="1532.8" textLength="854" clip-path="url(#breeze-static-checks-line-62)">Maximum number of attempts to initialize env [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1557.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-63)">│</text><text class="breeze-static-checks-r7" x="451.4" y="1557.2" textLength="854" clip-path="url(#breeze-static-checks-line-63)">(INTEGER RANGE)                                    [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1581.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-64)">│</text><text class="breeze-static-checks-r5" x="451.4" y="1581.6" textLength="854" clip-path="url(#breeze-static-checks-line-64)">[default: 3; 1<=x<=10]                                 [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1606" textLength="1464" clip-path="url(#breeze-static-checks-line-65)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="1606" textLength="12.2" clip-path="url(#breeze-static-checks-line-65)">
+</text><text class="breeze-static-checks-r5" x="0" y="1630.4" textLength="24.4" clip-path="url(#breeze-static-checks-line-66)">╭─</text><text class="breeze-static-checks-r5" x="24.4" y="1630.4" textLength="463.6" clip-path="url(#breeze-static-checks-line-66)"> Selecting files to run the checks on </text><text class="breeze-static-checks-r5" x="488" y="1630.4" textLength="951.6" clip-path="url(#breeze-static-checks-line-66)">──────────────────────── [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1654.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-67)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1654.8" textLength="73.2" clip-path="url(#breeze-static-checks-line-67)">--file</text><text class="breeze-static-checks-r6" x="256.2" y="1654.8" textLength="24.4" clip-path="url(#breeze-static-checks-line-67)">-f</text><text class="breeze-static-checks-r1" x="305" y="1654.8" textLength="427" clip-path="url [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1679.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-68)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1679.2" textLength="134.2" clip-path="url(#breeze-static-checks-line-68)">--all-files</text><text class="breeze-static-checks-r6" x="256.2" y="1679.2" textLength="24.4" clip-path="url(#breeze-static-checks-line-68)">-a</text><text class="breeze-static-checks-r1" x="305" y="1679.2" textLength="292.8" clip-p [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1703.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-69)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1703.6" textLength="146.4" clip-path="url(#breeze-static-checks-line-69)">--commit-ref</text><text class="breeze-static-checks-r6" x="256.2" y="1703.6" textLength="24.4" clip-path="url(#breeze-static-checks-line-69)">-r</text><text class="breeze-static-checks-r1" x="305" y="1703.6" textLength="1134.6" clip [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1728" textLength="12.2" clip-path="url(#breeze-static-checks-line-70)">│</text><text class="breeze-static-checks-r1" x="305" y="1728" textLength="183" clip-path="url(#breeze-static-checks-line-70)">exclusive with </text><text class="breeze-static-checks-r4" x="488" y="1728" textLength="158.6" clip-path="url(#breeze-static-checks-line-70)">--last-commit</text><text class="breeze-static-checks-r1" x="646.6" y="1728" textLength [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1752.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-71)">│</text><text class="breeze-static-checks-r7" x="305" y="1752.4" textLength="1134.6" clip-path="url(#breeze-static-checks-line-71)">(TEXT)                                       [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1776.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-72)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1776.8" textLength="158.6" clip-path="url(#breeze-static-checks-line-72)">--last-commit</text><text class="breeze-static-checks-r6" x="256.2" y="1776.8" textLength="24.4" clip-path="url(#breeze-static-checks-line-72)">-c</text><text class="breeze-static-checks-r1" x="305" y="1776.8" textLength="793" clip-p [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1801.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-73)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1801.2" textLength="207.4" clip-path="url(#breeze-static-checks-line-73)">--only-my-changes</text><text class="breeze-static-checks-r6" x="256.2" y="1801.2" textLength="24.4" clip-path="url(#breeze-static-checks-line-73)">-m</text><text class="breeze-static-checks-r1" x="305" y="1801.2" textLength="1134.6" [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1825.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-74)">│</text><text class="breeze-static-checks-r1" x="305" y="1825.6" textLength="1134.6" clip-path="url(#breeze-static-checks-line-74)">branch and HEAD of your branch.                              [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1850" textLength="1464" clip-path="url(#breeze-static-checks-line-75)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="1850" textLength="12.2" clip-path="url(#breeze-static-checks-line-75)">
+</text><text class="breeze-static-checks-r5" x="0" y="1874.4" textLength="24.4" clip-path="url(#breeze-static-checks-line-76)">╭─</text><text class="breeze-static-checks-r5" x="24.4" y="1874.4" textLength="463.6" clip-path="url(#breeze-static-checks-line-76)"> Building image before running checks </text><text class="breeze-static-checks-r5" x="488" y="1874.4" textLength="951.6" clip-path="url(#breeze-static-checks-line-76)">────────────────────────────────── [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1898.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-77)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1898.8" textLength="317.2" clip-path="url(#breeze-static-checks-line-77)">--skip-image-upgrade-check</text><text class="breeze-static-checks-r1" x="414.8" y="1898.8" textLength="536.8" clip-path="url(#breeze-static-checks-line-77)">Skip checking if the CI image is up  [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1923.2" textLength="12.2" clip-path="url(#breeze-static-checks-line-78)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1923.2" textLength="158.6" clip-path="url(#breeze-static-checks-line-78)">--force-build</text><text class="breeze-static-checks-r1" x="414.8" y="1923.2" textLength="707.6" clip-path="url(#breeze-static-checks-line-78)">Force image build no matter if it is determined& [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1947.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-79)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1947.6" textLength="231.8" clip-path="url(#breeze-static-checks-line-79)">--github-repository</text><text class="breeze-static-checks-r6" x="366" y="1947.6" textLength="24.4" clip-path="url(#breeze-static-checks-line-79)">-g</text><text class="breeze-static-checks-r1" x="414.8" y="1947.6" textLength="585.6 [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1972" textLength="12.2" clip-path="url(#breeze-static-checks-line-80)">│</text><text class="breeze-static-checks-r4" x="24.4" y="1972" textLength="109.8" clip-path="url(#breeze-static-checks-line-80)">--builder</text><text class="breeze-static-checks-r1" x="414.8" y="1972" textLength="756.4" clip-path="url(#breeze-static-checks-line-80)">Buildx builder used to perform `docker buildx build` comma [...]
+</text><text class="breeze-static-checks-r5" x="0" y="1996.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-81)">│</text><text class="breeze-static-checks-r5" x="414.8" y="1996.4" textLength="756.4" clip-path="url(#breeze-static-checks-line-81)">[default: autodetect]                                  &# [...]
+</text><text class="breeze-static-checks-r5" x="0" y="2020.8" textLength="1464" clip-path="url(#breeze-static-checks-line-82)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="2020.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-82)">
+</text><text class="breeze-static-checks-r5" x="0" y="2045.2" textLength="24.4" clip-path="url(#breeze-static-checks-line-83)">╭─</text><text class="breeze-static-checks-r5" x="24.4" y="2045.2" textLength="195.2" clip-path="url(#breeze-static-checks-line-83)"> Common options </text><text class="breeze-static-checks-r5" x="219.6" y="2045.2" textLength="1220" clip-path="url(#breeze-static-checks-line-83)">────────────────────────────────────────────────────────────────────── [...]
+</text><text class="breeze-static-checks-r5" x="0" y="2069.6" textLength="12.2" clip-path="url(#breeze-static-checks-line-84)">│</text><text class="breeze-static-checks-r4" x="24.4" y="2069.6" textLength="109.8" clip-path="url(#breeze-static-checks-line-84)">--dry-run</text><text class="breeze-static-checks-r6" x="158.6" y="2069.6" textLength="24.4" clip-path="url(#breeze-static-checks-line-84)">-D</text><text class="breeze-static-checks-r1" x="207.4" y="2069.6" textLength="719.8" clip-p [...]
+</text><text class="breeze-static-checks-r5" x="0" y="2094" textLength="12.2" clip-path="url(#breeze-static-checks-line-85)">│</text><text class="breeze-static-checks-r4" x="24.4" y="2094" textLength="109.8" clip-path="url(#breeze-static-checks-line-85)">--verbose</text><text class="breeze-static-checks-r6" x="158.6" y="2094" textLength="24.4" clip-path="url(#breeze-static-checks-line-85)">-v</text><text class="breeze-static-checks-r1" x="207.4" y="2094" textLength="585.6" clip-path="url [...]
+</text><text class="breeze-static-checks-r5" x="0" y="2118.4" textLength="12.2" clip-path="url(#breeze-static-checks-line-86)">│</text><text class="breeze-static-checks-r4" x="24.4" y="2118.4" textLength="73.2" clip-path="url(#breeze-static-checks-line-86)">--help</text><text class="breeze-static-checks-r6" x="158.6" y="2118.4" textLength="24.4" clip-path="url(#breeze-static-checks-line-86)">-h</text><text class="breeze-static-checks-r1" x="207.4" y="2118.4" textLength="329.4" clip-path= [...]
+</text><text class="breeze-static-checks-r5" x="0" y="2142.8" textLength="1464" clip-path="url(#breeze-static-checks-line-87)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text class="breeze-static-checks-r1" x="1464" y="2142.8" textLength="12.2" clip-path="url(#breeze-static-checks-line-87)">
</text>
</g>
</g>
diff --git a/dev/breeze/doc/images/output_static-checks.txt b/dev/breeze/doc/images/output_static-checks.txt
index 3f8a96af044..5d493551b20 100644
--- a/dev/breeze/doc/images/output_static-checks.txt
+++ b/dev/breeze/doc/images/output_static-checks.txt
@@ -1 +1 @@
-f90752bd76c0617a4f6e9eb1d208e4f5
+3d43a8428b5e0fefbfccaef5003fa5a6
diff --git a/dev/breeze/src/airflow_breeze/pre_commit_ids.py b/dev/breeze/src/airflow_breeze/pre_commit_ids.py
index acaa592acd5..7095d55b43f 100644
--- a/dev/breeze/src/airflow_breeze/pre_commit_ids.py
+++ b/dev/breeze/src/airflow_breeze/pre_commit_ids.py
@@ -129,7 +129,8 @@ PRE_COMMIT_LIST = [
"ruff-format",
"shellcheck",
"trailing-whitespace",
- "ts-compile-format-lint-ui",
+ "ts-compile-lint-simple-auth-manager-ui",
+ "ts-compile-lint-ui",
"update-black-version",
"update-breeze-cmd-output",
"update-breeze-readme-config-hash",
diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
index c622914fb91..1d53a730356 100644
--- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
+++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
@@ -1204,7 +1204,8 @@ class SelectiveChecks:
self._matching_files(FileGroupForCi.UI_FILES, CI_FILE_GROUP_MATCHES)
or self._matching_files(FileGroupForCi.API_CODEGEN_FILES, CI_FILE_GROUP_MATCHES)
):
- pre_commits_to_skip.add("ts-compile-format-lint-ui")
+ pre_commits_to_skip.add("ts-compile-lint-ui")
+ pre_commits_to_skip.add("ts-compile-lint-simple-auth-manager-ui")
if not self._matching_files(FileGroupForCi.ALL_PYTHON_FILES, CI_FILE_GROUP_MATCHES):
pre_commits_to_skip.add("flynt")
if not self._matching_files(
diff --git a/dev/breeze/tests/test_selective_checks.py b/dev/breeze/tests/test_selective_checks.py
index 956b151261e..84e7795c3be 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -112,7 +112,8 @@ ALL_MYPY_CHECKS_EXCEPT_PROVIDERS = str(
ALL_SKIPPED_COMMITS_ON_NO_CI_IMAGE = (
"check-provider-yaml-valid,flynt,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,"
- "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui"
+ "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,"
+ "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_BY_DEFAULT_ON_ALL_TESTS_NEEDED = (
@@ -121,7 +122,7 @@ ALL_SKIPPED_COMMITS_BY_DEFAULT_ON_ALL_TESTS_NEEDED = (
ALL_SKIPPED_COMMITS_IF_NO_UI = (
"identity,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common,"
- "mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui"
+ "mypy-providers,mypy-task-sdk,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_HELM_TESTS = (
"identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common,"
@@ -130,23 +131,26 @@ ALL_SKIPPED_COMMITS_IF_NO_HELM_TESTS = (
ALL_SKIPPED_COMMITS_IF_NO_UI_AND_HELM_TESTS = (
"identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common,"
- "mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui"
+ "mypy-providers,mypy-task-sdk,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS_AND_UI = (
"check-provider-yaml-valid,identity,mypy-airflow-core,mypy-airflow-ctl,"
- "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui"
+ "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,"
+ "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS = (
"check-provider-yaml-valid,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,"
- "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui"
+ "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,"
+ "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_PROVIDERS_UI_AND_HELM_TESTS = (
"check-provider-yaml-valid,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,"
- "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui"
+ "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,"
+ "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
ALL_SKIPPED_COMMITS_IF_NO_CODE_PROVIDERS_AND_HELM_TESTS = (
@@ -156,7 +160,8 @@ ALL_SKIPPED_COMMITS_IF_NO_CODE_PROVIDERS_AND_HELM_TESTS = (
ALL_SKIPPED_COMMITS_IF_NOT_IMPORTANT_FILES_CHANGED = (
"check-provider-yaml-valid,flynt,identity,lint-helm-chart,mypy-airflow-core,mypy-airflow-ctl,"
- "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui"
+ "mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,"
+ "ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui"
)
@@ -1219,7 +1224,7 @@ def assert_outputs_are_printed(expected_outputs: dict[str, str], stderr: str):
"run-tests": "true",
"run-amazon-tests": "false",
"docs-build": "true",
- "skip-pre-commits": "check-provider-yaml-valid,flynt,identity,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui",
+ "skip-pre-commits": "check-provider-yaml-valid,flynt,identity,mypy-airflow-core,mypy-airflow-ctl,mypy-dev,mypy-devel-common,mypy-providers,mypy-task-sdk,ts-compile-lint-simple-auth-manager-ui,ts-compile-lint-ui",
"upgrade-to-newer-dependencies": "false",
"core-test-types-list-as-strings-in-json": None,
"providers-test-types-list-as-strings-in-json": None,
diff --git a/scripts/ci/pre_commit/common_precommit_utils.py b/scripts/ci/pre_commit/common_precommit_utils.py
index cb775fb9bb9..e0b965ad0f0 100644
--- a/scripts/ci/pre_commit/common_precommit_utils.py
+++ b/scripts/ci/pre_commit/common_precommit_utils.py
@@ -24,7 +24,11 @@ import shutil
import subprocess
import sys
import textwrap
+import time
+from collections.abc import Generator
+from contextlib import contextmanager
from pathlib import Path
+from tempfile import NamedTemporaryFile, _TemporaryFileWrapper
AIRFLOW_ROOT_PATH = Path(__file__).parents[3].resolve()
AIRFLOW_CORE_ROOT_PATH = AIRFLOW_ROOT_PATH / "airflow-core"
@@ -47,6 +51,56 @@ except ImportError:
console = None # type: ignore[assignment]
+@contextmanager
+def temporary_tsc_project(
+ tsconfig_path: Path, files: list[str]
+) -> Generator[_TemporaryFileWrapper, None, None]:
+ """
+ Create a temporary tsconfig.json file that extends the main tsconfig.json file.
+ This is needed to run TypeScript compiler with specific files included only
+ """
+ if not tsconfig_path.exists():
+ raise RuntimeError(f"Cannot find {tsconfig_path}")
+ temp_tsconfig_path = NamedTemporaryFile(mode="wt", suffix=".json", dir=tsconfig_path.parent, delete=True)
+ files_joined = ", ".join([f'"{file}"' for file in files])
+ content = f'{{"extends": "./{tsconfig_path.name}", "include": [{files_joined}]}}'
+ if console:
+ console.print(f"[magenta]Creating temporary tsconfig.json at {temp_tsconfig_path.name}[/]")
+ console.print(content)
+ else:
+ print(f"Creating temporary tsconfig.json at {temp_tsconfig_path.name}", file=sys.stderr)
+ print(content, file=sys.stderr)
+ temp_tsconfig_path.write(content)
+ temp_tsconfig_path.flush()
+ yield temp_tsconfig_path
+
+
+def run_command(*args, **kwargs) -> None:
+ """
+ Run command with given arguments and return the result.
+ """
+ cmd = " ".join([shlex.quote(arg) for arg in args[0]])
+ cwd = kwargs.get("cwd", os.getcwd())
+ text = f"Running command: `{cmd}` in directory: `{cwd}`"
+ if console:
+ console.print(f"[magenta]{text}[/]")
+ else:
+ print("#" * min(len(text), 200), file=sys.stderr)
+ print(text, file=sys.stderr)
+ print("#" * min(len(text), 200), file=sys.stderr)
+ time_start = time.time()
+ subprocess.check_call(*args, **kwargs)
+ time_end = time.time()
+ if console:
+ console.print(f"[green]After {text}[/]")
+ console.print(f"[green]Command finished in {time_end - time_start:.2f} seconds[/]")
+ else:
+ print("#" * min(len(text), 200), file=sys.stderr)
+ print(f"After {text}")
+ print(f"Command finished in {time_end - time_start:.2f} seconds", file=sys.stderr)
+ print("#" * min(len(text), 200), file=sys.stderr)
+
+
def read_airflow_version() -> str:
ast_obj = ast.parse((AIRFLOW_CORE_SOURCES_PATH / "airflow" / "__init__.py").read_text())
for node in ast_obj.body:
diff --git a/scripts/ci/pre_commit/compile_lint_ui.py b/scripts/ci/pre_commit/compile_lint_ui.py
deleted file mode 100755
index 297ed8be3d7..00000000000
--- a/scripts/ci/pre_commit/compile_lint_ui.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python3
-# 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
-
-import subprocess
-import sys
-from pathlib import Path
-
-sys.path.insert(0, str(Path(__file__).parent.resolve())) # make sure common_precommit_utils is imported
-from common_precommit_utils import AIRFLOW_CORE_SOURCES_PATH
-
-if __name__ not in ("__main__", "__mp_main__"):
- raise SystemExit(
- "This file is intended to be executed as an executable program. You cannot use it as a module."
- f"To run this script, run the ./{__file__} command"
- )
-
-if __name__ == "__main__":
- dir = AIRFLOW_CORE_SOURCES_PATH / "airflow" / "ui"
- subprocess.check_call(["pnpm", "config", "set", "store-dir", ".pnpm-store"], cwd=dir)
- subprocess.check_call(
- ["pnpm", "install", "--frozen-lockfile", "--config.confirmModulesPurge=false"], cwd=dir
- )
- subprocess.check_call(["pnpm", "codegen"], cwd=dir)
- subprocess.check_call(["pnpm", "format"], cwd=dir)
- subprocess.check_call(["pnpm", "lint:fix"], cwd=dir)
-
- dir = AIRFLOW_CORE_SOURCES_PATH / "airflow" / "api_fastapi" / "auth" / "managers" / "simple" / "ui"
- subprocess.check_call(["pnpm", "config", "set", "store-dir", ".pnpm-store"], cwd=dir)
-
- subprocess.check_call(
- ["pnpm", "install", "--frozen-lockfile", "--config.confirmModulesPurge=false"], cwd=dir
- )
- subprocess.check_call(["pnpm", "codegen"], cwd=dir)
- subprocess.check_call(["pnpm", "format"], cwd=dir)
- subprocess.check_call(["pnpm", "lint:fix"], cwd=dir)
diff --git a/scripts/ci/pre_commit/ts_compile_lint_simple_auth_manager_ui.py b/scripts/ci/pre_commit/ts_compile_lint_simple_auth_manager_ui.py
new file mode 100755
index 00000000000..3c9b5a74122
--- /dev/null
+++ b/scripts/ci/pre_commit/ts_compile_lint_simple_auth_manager_ui.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+# 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
+
+import sys
+from pathlib import Path
+
+sys.path.insert(0, str(Path(__file__).parent.resolve())) # make sure common_precommit_utils is imported
+from common_precommit_utils import (
+ AIRFLOW_CORE_SOURCES_PATH,
+ AIRFLOW_ROOT_PATH,
+ run_command,
+ temporary_tsc_project,
+)
+
+if __name__ not in ("__main__", "__mp_main__"):
+ raise SystemExit(
+ "This file is intended to be executed as an executable program. You cannot use it as a module."
+ f"To run this script, run the ./{__file__} command"
+ )
+
+if __name__ == "__main__":
+ original_files = sys.argv[1:]
+ print("Original files:", original_files)
+ dir = AIRFLOW_CORE_SOURCES_PATH / "airflow" / "api_fastapi" / "auth" / "managers" / "simple" / "ui"
+ relative_dir = Path(dir).relative_to(AIRFLOW_ROOT_PATH)
+ files = [
+ file[len(relative_dir.as_posix()) + 1 :]
+ for file in original_files
+ if Path(file).is_relative_to(relative_dir)
+ ]
+ all_non_yaml_files = [file for file in files if not file.endswith(".yaml")]
+ print("All non-YAML files:", all_non_yaml_files)
+ all_ts_files = [file for file in files if file.endswith(".ts") or file.endswith(".tsx")]
+ print("All TypeScript files:", all_ts_files)
+
+ run_command(["pnpm", "config", "set", "store-dir", ".pnpm-store"], cwd=dir)
+ run_command(["pnpm", "install", "--frozen-lockfile", "--config.confirmModulesPurge=false"], cwd=dir)
+ if any("/openapi/" in file for file in original_files):
+ run_command(["pnpm", "codegen"], cwd=dir)
+ if all_non_yaml_files:
+ run_command(["pnpm", "prettier", "--write", *all_non_yaml_files], cwd=dir)
+ run_command(["pnpm", "eslint", "--fix", *all_non_yaml_files], cwd=dir)
+ if all_ts_files:
+ with temporary_tsc_project(dir / "tsconfig.app.json", all_ts_files) as tsc_project:
+ run_command(["pnpm", "tsc", "--p", tsc_project.name], cwd=dir)
diff --git a/scripts/ci/pre_commit/ts_compile_lint_ui.py b/scripts/ci/pre_commit/ts_compile_lint_ui.py
new file mode 100755
index 00000000000..4693ae2107c
--- /dev/null
+++ b/scripts/ci/pre_commit/ts_compile_lint_ui.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+# 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
+
+import sys
+from pathlib import Path
+
+sys.path.insert(0, str(Path(__file__).parent.resolve())) # make sure common_precommit_utils is imported
+from common_precommit_utils import (
+ AIRFLOW_CORE_SOURCES_PATH,
+ AIRFLOW_ROOT_PATH,
+ run_command,
+ temporary_tsc_project,
+)
+
+if __name__ not in ("__main__", "__mp_main__"):
+ raise SystemExit(
+ "This file is intended to be executed as an executable program. You cannot use it as a module."
+ f"To run this script, run the ./{__file__} command"
+ )
+
+if __name__ == "__main__":
+ original_files = sys.argv[1:]
+ print("Original files:", original_files)
+ dir = AIRFLOW_CORE_SOURCES_PATH / "airflow" / "ui"
+ relative_dir = Path(dir).relative_to(AIRFLOW_ROOT_PATH)
+ files = [
+ file[len(relative_dir.as_posix()) + 1 :]
+ for file in original_files
+ if Path(file).is_relative_to(relative_dir)
+ ]
+ all_non_yaml_files = [file for file in files if not file.endswith(".yaml")]
+ print("All non-YAML files:", all_non_yaml_files)
+ all_ts_files = [file for file in files if file.endswith(".ts") or file.endswith(".tsx")]
+ print("All TypeScript files:", all_ts_files)
+
+ run_command(["pnpm", "config", "set", "store-dir", ".pnpm-store"], cwd=dir)
+ run_command(["pnpm", "install", "--frozen-lockfile", "--config.confirmModulesPurge=false"], cwd=dir)
+ if any("/openapi/" in file for file in original_files):
+ run_command(["pnpm", "codegen"], cwd=dir)
+ if all_non_yaml_files:
+ run_command(["pnpm", "prettier", "--write", *all_non_yaml_files], cwd=dir)
+ run_command(["pnpm", "eslint", "--fix", *all_non_yaml_files], cwd=dir)
+ if all_ts_files:
+ with temporary_tsc_project(dir / "tsconfig.app.json", all_ts_files) as tsc_project:
+ run_command(["pnpm", "tsc", "--p", tsc_project.name], cwd=dir)