| # 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. |
| --- |
| default_stages: [pre-commit, pre-push] |
| default_install_hook_types: [pre-commit, commit-msg] |
| minimum_prek_version: '0.3.4' |
| default_language_version: |
| python: python3 |
| node: 22.19.0 |
| golang: 1.25.0 |
| exclude: ^.*/.*_vendor/ |
| repos: |
| - repo: meta |
| hooks: |
| - id: identity |
| name: Print checked files |
| description: Print input to the static check hooks for troubleshooting |
| - id: check-hooks-apply |
| name: Check if all hooks apply to the repository |
| - repo: https://github.com/thlorenz/doctoc.git |
| rev: 59dcae910a6ad4bbe8711275b854e3cd5c30f08b # frozen: v2.5.0 |
| hooks: |
| - id: doctoc |
| name: Add TOC for Markdown and RST files |
| files: |
| (?x) |
| ^README\.md$| |
| ^UPDATING.*\.md$| |
| ^chart/UPDATING.*\.md$| |
| ^dev/.*\.md$| |
| ^dev/.*\.rst$| |
| ^docs/README\.md$| |
| ^\.github/.*\.md$| |
| ^airflow-core/tests/system/README\.md$ |
| exclude: |
| (?x) |
| .github/PULL_REQUEST_TEMPLATE\.md$| |
| .github/instructions/| |
| .github/skills/ |
| args: |
| - "--maxlevel" |
| - "2" |
| - repo: https://github.com/Lucas-C/pre-commit-hooks |
| rev: ad1b27d73581aa16cca06fc4a0761fc563ffe8e8 # frozen: v1.5.6 |
| hooks: |
| - id: insert-license |
| name: Add license for all SQL files |
| files: \.sql$ |
| exclude: | |
| (?x) |
| ^\.github/| |
| ^java-sdk/gradlew$| |
| ^java-sdk/gradlew\.bat$| |
| ^java-sdk/gradle/| |
| ^scripts/ci/license-templates/ |
| args: |
| - --comment-style |
| - "/*||*/" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| - id: insert-license |
| name: Add license for all RST files |
| args: |
| - --comment-style |
| - "||" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.rst |
| - --fuzzy-match-generates-todo |
| files: \.rst$ |
| exclude: |
| (?x) |
| ^\.github/.*$| |
| newsfragments/.*\.rst$| |
| ^scripts/ci/license-templates/ |
| - id: insert-license |
| name: Add license for CSS/JS/JSX/PUML/TS/TSX |
| files: \.(css|jsx?|puml|tsx?)$ |
| exclude: ^\.github/.*$|ui/openapi-gen/|www/openapi-gen/|.*/dist/.* |
| args: |
| - --comment-style |
| - "/*!| *| */" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| - id: insert-license |
| name: Add license for all Shell files |
| exclude: ^\.github/.*$|^dev/breeze/autocomplete/.*$ |
| files: \.bash$|\.sh$ |
| args: |
| - --comment-style |
| - "|#|" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| - id: insert-license |
| name: Add license for all toml files |
| exclude: ^\.github/.*$|^dev/breeze/autocomplete/.*$ |
| files: \.toml$ |
| args: |
| - --comment-style |
| - "|#|" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| - id: insert-license |
| name: Add license for all Python files |
| exclude: ^\.github/.*$|^.*/_vendor/.*$|^airflow-ctl/.*/.*generated\.py$ |
| files: \.py$|\.pyi$ |
| args: |
| - --comment-style |
| - "|#|" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| - id: insert-license |
| name: Add license for all XML files |
| exclude: ^\.github/.*$ |
| files: \.xml$ |
| args: |
| - --comment-style |
| - "<!--||-->" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| - id: insert-license |
| name: Add license for all YAML files except Helm templates |
| exclude: > |
| (?x) |
| ^\.github/.*$| |
| ^chart/templates/.*| |
| .*reproducible_build\.yaml$| |
| ^.*/v2.*\.yaml$| |
| ^.*/openapi/_private_ui.*\.yaml$| |
| ^.*/pnpm-lock\.yaml$| |
| .*-generated\.yaml$ |
| types: [yaml] |
| files: \.ya?ml$ |
| args: |
| - --comment-style |
| - "|#|" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| - id: insert-license |
| name: Add license for all Markdown files |
| files: \.md$ |
| args: |
| - --comment-style |
| - "<!--|| -->" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| exclude: |
| (?x) |
| ^\.github/.*\.md$| |
| ^\.claude/| |
| ^\.agents/| |
| ^(?:.*/)?AGENTS\.md$| |
| ^(?:.*/)?CLAUDE\.md$| |
| ^(?:.*/)?SKILL\.md$| |
| ^scripts/ci/license-templates/ |
| - id: insert-license |
| name: Add short license for agentic Markdown files |
| args: |
| - --comment-style |
| - "||" |
| - --license-filepath |
| - scripts/ci/license-templates/SHORT_LICENSE.md |
| - --detect-license-in-X-top-lines |
| - '30' |
| - --fuzzy-match-generates-todo |
| files: |
| (?x) |
| ^\.github/.*\.md$| |
| ^\.claude/| |
| ^\.agents/| |
| ^(?:.*/)?AGENTS\.md$| |
| ^(?:.*/)?CLAUDE\.md$| |
| ^(?:.*/)?SKILL\.md$ |
| exclude: |
| (?x) |
| ^scripts/ci/license-templates/ |
| - id: insert-license |
| name: Add license for all other files |
| args: |
| - --comment-style |
| - "|#|" |
| - --license-filepath |
| - scripts/ci/license-templates/LICENSE.txt |
| - --fuzzy-match-generates-todo |
| files: | |
| (?x) |
| \.cfg$| |
| \.conf$| |
| \.ini$| |
| \.ldif$| |
| \.properties$| |
| \.service$| |
| \.tf$| |
| Dockerfile.*$ |
| exclude: |
| (?x) |
| ^\.github/.*$| |
| ^scripts/ci/license-templates/ |
| - repo: local |
| hooks: |
| - id: check-min-python-version |
| name: Check minimum Python version |
| entry: ./scripts/ci/prek/check_min_python_version.py |
| language: python |
| require_serial: true |
| - id: update-notice-year |
| name: Update NOTICE files to current year (manual) |
| entry: ./scripts/ci/prek/update_notice_year.py |
| stages: ['manual'] |
| language: python |
| pass_filenames: false |
| require_serial: true |
| - id: check-notice-files |
| name: Check NOTICE files for current year and ASF references |
| entry: ./scripts/ci/prek/check_notice_files.py |
| language: python |
| files: ^.*NOTICE$ |
| - id: check-version-consistency |
| name: Check version consistency |
| entry: ./scripts/ci/prek/check_version_consistency.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/__init__\.py$| |
| ^airflow-core/pyproject\.toml$| |
| ^task-sdk/src/airflow/sdk/__init__\.py$| |
| ^pyproject\.toml$ |
| pass_filenames: false |
| require_serial: true |
| - id: check-ci-workflows-in-sync |
| name: Check ci-arm.yml and ci-amd.yml stay in sync |
| entry: ./scripts/ci/prek/check_ci_workflows_in_sync.py |
| language: python |
| files: ^\.github/workflows/ci-(arm|amd)\.yml$ |
| pass_filenames: false |
| require_serial: true |
| - id: check-java-sdk-version-in-sync |
| name: Check Java SDK JDK version is consistent across build files |
| entry: ./scripts/ci/prek/check_java_sdk_version_in_sync.py |
| language: python |
| files: > |
| (?x) |
| ^\.github/workflows/ci-(arm|amd)\.yml$| |
| ^\.github/workflows/codeql-analysis\.yml$| |
| ^java-sdk/buildSrc/src/main/kotlin/airflow-jvm-conventions\.gradle\.kts$| |
| ^scripts/docker/install_os_dependencies\.sh$| |
| ^Dockerfile$| |
| ^Dockerfile\.ci$ |
| pass_filenames: false |
| require_serial: true |
| - id: sync-java-sdk-supervisor-schema |
| name: Sync Java SDK supervisor schema with configured version |
| description: "Refresh the Supervisor Schema when Java SDK's bundled schema.json is not at the configured version" |
| entry: ./scripts/ci/prek/sync_java_sdk_supervisor_schema.py |
| language: python |
| pass_filenames: false |
| files: > |
| (?x) |
| ^java-sdk/gradle\.properties$| |
| ^java-sdk/sdk/schema/schema\.json$ |
| - id: regenerate-java-sdk-verification-metadata |
| name: Regenerate the Java SDK dependency verification metadata |
| description: "Drop trusted checksums that no Java SDK build task resolves any more" |
| entry: ./scripts/ci/prek/regenerate_java_sdk_verification_metadata.py |
| language: python |
| pass_filenames: false |
| # example/ and scala_spark_example/ are separate builds this metadata does |
| # not cover, so their build files are excluded. |
| files: > |
| (?x) |
| ^java-sdk/build\.gradle\.kts$| |
| ^java-sdk/buildSrc/.*$| |
| ^java-sdk/gradle\.properties$| |
| ^java-sdk/gradle/libs\.versions\.toml$| |
| ^java-sdk/gradle/verification-metadata\.xml$| |
| ^java-sdk/gradle/wrapper/gradle-wrapper\.properties$| |
| ^java-sdk/settings\.gradle\.kts$| |
| ^scripts/ci/prek/regenerate_java_sdk_verification_metadata\.py$| |
| ^java-sdk/(?!example/|scala_spark_example/)[^/]+/(?:build\.gradle\.kts|gradle\.properties)$ |
| - id: update-java-sdk-readme-matrix |
| name: Update the Java SDK compatibility matrix in java-sdk/README.md and Dokka module doc |
| entry: ./scripts/ci/prek/update_java_sdk_readme_matrix.py |
| language: python |
| files: > |
| (?x) |
| ^java-sdk/capabilities\.yaml$| |
| ^java-sdk/gradle\.properties$| |
| ^java-sdk/README\.md$| |
| ^java-sdk/sdk/module\.md$| |
| ^scripts/ci/prek/lang_sdk_compat_matrix\.py$| |
| ^scripts/ci/prek/update_java_sdk_readme_matrix\.py$ |
| additional_dependencies: ['PyYAML>=6.0', 'rich>=13.6.0'] |
| pass_filenames: false |
| require_serial: true |
| - id: update-ts-sdk-readme-matrix |
| name: Update the TypeScript SDK compatibility matrix in ts-sdk/README.md |
| entry: ./scripts/ci/prek/update_ts_sdk_readme_matrix.py |
| language: python |
| files: > |
| (?x) |
| ^ts-sdk/capabilities\.yaml$| |
| ^ts-sdk/src/generated/supervisor\.ts$| |
| ^ts-sdk/README\.md$| |
| ^scripts/ci/prek/lang_sdk_compat_matrix\.py$| |
| ^scripts/ci/prek/update_ts_sdk_readme_matrix\.py$ |
| additional_dependencies: ['PyYAML>=6.0', 'rich>=13.6.0'] |
| pass_filenames: false |
| require_serial: true |
| - id: sync-ts-sdk-dag-schema |
| name: Sync TypeScript SDK Dag serialization schema with airflow-core |
| description: "Copy airflow-core's serialization schema when TS SDK's vendored dag-schema.json drifts" |
| entry: ./ts-sdk/scripts/ci/prek/sync_dag_schema.py |
| language: python |
| pass_filenames: false |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/serialization/schema\.json$| |
| ^ts-sdk/schema/dag-schema\.json$ |
| - id: sync-java-sdk-dag-schema |
| name: Sync Java SDK Dag serialization schema with airflow-core |
| description: "Copy airflow-core's serialization schema when Java SDK's vendored dag-schema.json drifts" |
| entry: ./java-sdk/gradlew -p ./java-sdk :sdk:syncDagSchema -PfailOnDagSchemaDrift |
| language: system |
| pass_filenames: false |
| # Runs on every commit: a stale vendored copy is exactly the drift that broke a |
| # vendored Go copy unnoticed (see sync-go-sdk-schemas below), so this fails |
| # loudly instead of silently falling behind. -PfailOnDagSchemaDrift is what makes |
| # it fail here; generateDagDsl's own dependency on this same task never passes it, |
| # so an ordinary in-repo build keeps refreshing the copy without breaking on a |
| # schema someone is mid-edit on. The task refreshes the file and fails when it |
| # had to, so `git add` the refreshed copy and recommit. |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/serialization/schema\.json$| |
| ^java-sdk/sdk/schema/dag-schema\.json$ |
| - id: sync-go-sdk-schemas |
| name: Sync Go SDK vendored schemas with the distributions that own them |
| description: "Copy airflow-core's Dag schema and task-sdk's supervisor schema when go-sdk's vendored copies drift" |
| entry: ./scripts/ci/prek/sync_go_sdk_schemas.py |
| language: python |
| pass_filenames: false |
| # Runs on every commit: it used to be manual, "a go-sdk maintainer's deliberate |
| # step," so a Python-only schema change could ship with the vendored Go copy |
| # silently left behind — no hook caught it, because this one was never invoked |
| # and check-go-sdk-generated-drift below only watched the Go side. This refreshes |
| # the copy and fails when it had to, so `git add` the refreshed file(s) and |
| # recommit; check-go-sdk-generated-drift then catches the generated code that |
| # needs regenerating from the refreshed copy. |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/serialization/schema\.json$| |
| ^task-sdk/src/airflow/sdk/execution_time/schema/schema\.json$| |
| ^go-sdk/schema/.*\.json$| |
| ^scripts/ci/prek/sync_go_sdk_schemas\.py$ |
| - id: check-go-sdk-generated-drift |
| name: Check Go SDK generated files against the schemas they generate from |
| description: "Regenerate the Dag specs and the coordinator-protocol models, and fail when a committed file differs" |
| entry: ./scripts/ci/prek/check_go_sdk_generated_drift.py |
| # golang so prek provisions the toolchain the generators need, the way the |
| # other checks that shell out to `go` in go-sdk get theirs. |
| language: golang |
| # Also triggered by the Python schemas themselves, not just the vendored copies: |
| # sync-go-sdk-schemas (which runs first, see hook order above) refreshes the |
| # vendored copy in the same commit a Python schema changes, and this regenerates |
| # from whatever that copy now holds, so the two together catch both a stale copy |
| # and generated code that copy was never regenerated from. |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/serialization/schema\.json$| |
| ^task-sdk/src/airflow/sdk/execution_time/schema/schema\.json$| |
| ^go-sdk/schema/.*\.json$| |
| ^go-sdk/airflow/spec\.gen\.go$| |
| ^go-sdk/airflow/spec\.go$| |
| ^go-sdk/internal/genspec/.*\.go$| |
| ^go-sdk/internal/genlicense/.*\.go$| |
| ^go-sdk/pkg/execution/genmodels/.*\.go$| |
| ^scripts/ci/prek/check_go_sdk_generated_drift\.py$ |
| pass_filenames: false |
| require_serial: true |
| # check-ts-sdk-serialization-conformance in ts-sdk/ covers the SDK's own files; this runs the same |
| # check when the shared harness or Airflow's serializer changes, which that project cannot see. |
| - id: check-ts-sdk-serialization-conformance-shared |
| name: Check the TS SDK serializes Dags the way Airflow does, after a shared change |
| description: "Serialize the shared test Dags with the TS SDK and with Airflow, and compare the two" |
| entry: ./ts-sdk/scripts/ci/prek/check_serialization_conformance.py |
| language: node |
| additional_dependencies: ['pnpm@10.28.1'] |
| pass_filenames: false |
| require_serial: true |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/serialization/serialized_objects\.py$| |
| ^airflow-core/src/airflow/serialization/schema\.json$| |
| ^scripts/ci/lang_sdk_serialization/.*$ |
| - id: check-go-version-in-sync |
| name: Check Go toolchain version is consistent across build files |
| entry: ./scripts/ci/prek/check_go_version_in_sync.py |
| language: python |
| files: > |
| (?x) |
| ^go-sdk/go\.mod$| |
| ^kubernetes-tests/lang_sdk/go_example/go\.mod$| |
| ^\.github/workflows/ci-(arm|amd)\.yml$| |
| ^airflow-e2e-tests/tests/airflow_e2e_tests/constants\.py$| |
| ^dev/breeze/src/airflow_breeze/commands/kubernetes_commands\.py$| |
| ^go-sdk/\.pre-commit-config\.yaml$| |
| ^\.pre-commit-config\.yaml$ |
| pass_filenames: false |
| require_serial: true |
| - id: update-go-sdk-readme-matrix |
| name: Update the Go SDK compatibility matrix in go-sdk/README.md |
| entry: ./scripts/ci/prek/update_go_sdk_readme_matrix.py |
| language: python |
| files: > |
| (?x) |
| ^go-sdk/capabilities\.yaml$| |
| ^go-sdk/pkg/execution/messages\.go$| |
| ^go-sdk/README\.md$| |
| ^scripts/ci/prek/lang_sdk_compat_matrix\.py$| |
| ^scripts/ci/prek/update_go_sdk_readme_matrix\.py$ |
| additional_dependencies: ['PyYAML>=6.0', 'rich>=13.6.0'] |
| pass_filenames: false |
| require_serial: true |
| - id: check-go-example-mod-tidy |
| name: Check lang-SDK Go example module is tidy against the Go SDK |
| entry: ./scripts/ci/prek/check_go_example_mod_tidy.py |
| # golang so prek provisions the toolchain the check needs: static checks run on a |
| # runner whose preinstalled toolchains are wiped to free disk space, and the SDK's |
| # own `go mod tidy` hook gets its Go the same way. |
| language: golang |
| # The example module keeps its own copy of the SDK's indirect requirements |
| # (it resolves the SDK through a `replace`), so a dependency moving in |
| # go-sdk/go.mod leaves it stale. Watching both modules' manifests is enough: |
| # any new requirement in the SDK necessarily lands in go-sdk/go.mod first. |
| files: > |
| (?x) |
| ^go-sdk/go\.(mod|sum)$| |
| ^kubernetes-tests/lang_sdk/go_example/go\.(mod|sum)$ |
| pass_filenames: false |
| require_serial: true |
| - id: check-partition-mapper-defaults-in-sync |
| name: Check partition-mapper core/SDK sync (FanOutMapper table + SegmentWindow/FixedKeyMapper) |
| entry: ./scripts/ci/prek/check_partition_mapper_defaults_in_sync.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/partition_mappers/temporal\.py$| |
| ^airflow-core/src/airflow/partition_mappers/window\.py$| |
| ^airflow-core/src/airflow/partition_mappers/fixed_key\.py$| |
| ^task-sdk/src/airflow/sdk/definitions/partition_mappers/temporal\.py$| |
| ^task-sdk/src/airflow/sdk/definitions/partition_mappers/window\.py$| |
| ^task-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key\.py$ |
| pass_filenames: false |
| require_serial: true |
| - id: check-window-in-sync |
| name: Check Window definitions stay in sync (core/SDK) |
| entry: ./scripts/ci/prek/check_window_in_sync.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/partition_mappers/window\.py$| |
| ^task-sdk/src/airflow/sdk/definitions/partition_mappers/window\.py$ |
| pass_filenames: false |
| require_serial: true |
| - id: sync-uv-min-version-markers |
| name: Sync `# sync-uv-min-version` markers with [tool.uv] required-version |
| entry: ./scripts/ci/prek/sync_uv_min_version_markers.py |
| language: python |
| # Hook reads pyproject.toml itself; the file list selects places that may carry |
| # the `# sync-uv-min-version` marker. Any new test/file using the marker should |
| # be added here. |
| files: > |
| (?x) |
| ^pyproject\.toml$| |
| ^dev/breeze/src/airflow_breeze/utils/check_release_files\.py$| |
| ^dev/breeze/tests/test_environment_check\.py$ |
| require_serial: true |
| - id: check-distribution-gitignore |
| name: Check distribution .gitignore files have *.iml |
| entry: ./scripts/ci/prek/check_distribution_gitignore.py |
| language: python |
| files: > |
| (?x) |
| ^.*/\.gitignore$| |
| ^\.gitignore$| |
| ^.*/pyproject\.toml$| |
| ^pyproject\.toml$ |
| pass_filenames: false |
| require_serial: true |
| - id: upgrade-important-versions |
| name: Upgrade important versions (manual) |
| entry: ./scripts/ci/prek/upgrade_important_versions.py |
| stages: ['manual'] |
| language: python |
| files: > |
| (?x) |
| ^\.pre-commit-config\.yaml$| |
| ^\.github/\.pre-commit-config\.yaml$| |
| ^scripts/ci/prek/upgrade_important_versions\.py$ |
| pass_filenames: false |
| require_serial: true |
| - id: upgrade-dependency-floors |
| name: Upgrade curated dependency floors (manual) |
| entry: ./scripts/ci/prek/upgrade_dependency_floors.py |
| stages: ['manual'] |
| language: python |
| files: > |
| (?x) |
| ^pyproject\.toml$| |
| ^scripts/ci/prek/upgrade_dependency_floors\.py$ |
| pass_filenames: false |
| require_serial: true |
| additional_dependencies: ['packaging>=25', 'requests>=2.31.0', 'rich>=13.6.0', 'tomli>=2.0.1'] |
| - repo: https://github.com/adamchainz/blacken-docs |
| rev: fda77690955e9b63c6687d8806bafd56a526e45f # frozen: 1.20.0 |
| hooks: |
| - id: blacken-docs |
| name: Run black on docs |
| args: |
| - --line-length=110 |
| - --target-version=py310 |
| - --target-version=py311 |
| - --target-version=py312 |
| - --target-version=py313 |
| alias: blacken-docs |
| additional_dependencies: |
| - 'black==26.1.0' |
| exclude: > |
| (?x) |
| ^\.agents/skills/aip-user-stories |
| - repo: https://github.com/pre-commit/pre-commit-hooks |
| rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 |
| hooks: |
| - id: check-merge-conflict |
| name: Check that merge conflicts are not being committed |
| - id: debug-statements |
| name: Detect accidentally committed debug statements |
| - id: check-builtin-literals |
| name: Require literal syntax when initializing builtins |
| - id: detect-private-key |
| name: Detect if private key is added to the repository |
| exclude: ^providers/ssh/docs/connections/ssh\.rst$ |
| - id: end-of-file-fixer |
| name: Make sure that there is an empty line at the end |
| exclude: > |
| (?x) |
| ^airflow-core/docs/img/.*\.dot| |
| ^airflow-core/docs/img/.*\.sha256| |
| .*/dist/.*| |
| LICENSES-ui\.txt$| |
| .*/openapi-gen/.* |
| - id: mixed-line-ending |
| name: Detect if mixed line ending is used (\r vs. \r\n) |
| - id: check-executables-have-shebangs |
| name: Check that executables have shebang |
| - id: check-xml |
| name: Check XML files with xmllint |
| exclude: > |
| (?x) |
| ^scripts/ci/docker-compose/gremlin/. |
| - id: trailing-whitespace |
| name: Remove trailing whitespace at end of line |
| exclude: > |
| (?x) |
| ^airflow-core/docs/img/.*\.dot$| |
| ^dev/breeze/doc/images/output.*$| |
| ^.*/openapi-gen/.*$| |
| ^airflow-ctl/docs/images/.*\.svg$ |
| - repo: https://github.com/pre-commit/pygrep-hooks |
| rev: 3a6eb0fadf60b3cccfd80bad9dbb6fae7e47b316 # frozen: v1.10.0 |
| hooks: |
| - id: rst-backticks |
| name: Check if RST files use double backticks for code |
| - id: python-no-log-warn |
| name: Check if there are no deprecate log warn |
| - repo: https://github.com/adrienverge/yamllint |
| rev: cba56bcde1fdd01c1deb3f945e69764c291a6530 # frozen: v1.38.0 |
| hooks: |
| - id: yamllint |
| name: Check YAML files with yamllint |
| entry: yamllint -c yamllint-config.yml --strict |
| types: [yaml] |
| exclude: > |
| (?x) |
| ^.*airflow\.template\.yaml$| |
| ^.*init_git_sync\.template\.yaml$| |
| ^chart/(?:templates|files)/.*\.yaml$| |
| ^chart/tests/chart_utils/keda.sh_scaledobjects\.yaml$| |
| ^chart/tests/chart_utils/gateway.networking.k8s.io_httproutes\.yaml$| |
| .*/v1.*\.yaml$| |
| ^.*openapi.*\.yaml$| |
| ^\.pre-commit-config\.yaml$| |
| ^.*reproducible_build\.yaml$| |
| ^.*pnpm-lock\.yaml$| |
| ^.*-generated\.yaml$ |
| - repo: https://github.com/ikamensh/flynt |
| rev: 97be693bf18bc2f050667dd282d243e2824b81e2 # frozen: 1.0.6 |
| hooks: |
| - id: flynt |
| name: Run flynt string format converter for Python |
| args: |
| # If flynt detects too long text it ignores it. So we set a very large limit to make it easy |
| # to split the text by hand. Too long lines are detected by flake8 (below), |
| # so the user is informed to take action. |
| - --line-length |
| - '99999' |
| - repo: https://github.com/codespell-project/codespell |
| rev: 57b21406f092110c18776e39b0bda50d37c945c8 # frozen: v2.4.3 |
| hooks: |
| - id: codespell |
| name: Run codespell |
| description: Run codespell to check for common misspellings in files |
| entry: bash -c 'echo "If you think that this failure is an error, consider adding the word(s) |
| to the codespell dictionary at docs/spelling_wordlist.txt. |
| The word(s) should be in lowercase." && exec codespell "$@"' -- |
| language: python |
| types: [text] |
| exclude: > |
| (?x) |
| material-icons\.css$| |
| ^images/.*$| |
| ^RELEASE_NOTES\.txt$| |
| ^.*package-lock\.json$| |
| ^.*/kinglear\.txt$| |
| ^.*pnpm-lock\.yaml$| |
| ^java-sdk/gradle/verification-metadata\.xml$| |
| .*/dist/.*| |
| ^airflow-core/src/airflow/ui/public/i18n/locales/(?!en/).+/| |
| ^\.agents/skills/airflow-translations/| |
| ^scripts/docker/keys/.*\.asc$ |
| 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 |
| - --exclude-file=.codespellignorelines |
| - repo: https://github.com/woodruffw/zizmor-pre-commit |
| rev: fa412071e4f5d44d44f9e365f4676f9df92456a2 # frozen: v1.30.1 |
| hooks: |
| - id: zizmor |
| name: Run zizmor to check for github workflow syntax errors |
| types: [yaml] |
| files: ^\.github/workflows/.*$|^\.github/actions/.*$ |
| require_serial: true |
| entry: zizmor |
| - repo: https://github.com/lycheeverse/lychee |
| rev: 2c1fb3ad1373b1eb5148176bb6dcd4773f2a564d # frozen: nightly |
| hooks: |
| # Use the upstream `lychee-docker` variant rather than the script-based |
| # `lychee` hook because the prebuilt lychee binaries that the script |
| # downloads are linked against newer glibc than ubuntu-22.04 runners |
| # ship with (`GLIBC_2.38` / `GLIBC_2.39` not found at runtime). The |
| # docker variant runs the official `lycheeverse/lychee` image, which |
| # bundles its own libc and is portable across runners. |
| - id: lychee-docker |
| name: Check internal Markdown links with lychee (offline mode) |
| description: >- |
| Validate intra-repo links in Markdown files (relative paths, anchors, |
| and fragments) without making any HTTP requests. Auto-generated client |
| docs are excluded because they are regenerated from OpenAPI specs. |
| types: [markdown] |
| args: |
| - --offline |
| - --no-progress |
| - --root-dir |
| - . |
| - --include-fragments |
| exclude: | |
| (?x) |
| ^clients/python/| |
| ^.*/openapi-gen/| |
| ^.*/node_modules/| |
| ^\.build/| |
| ^generated/| |
| ^\.apache-magpie-overrides/ |
| - repo: local |
| # Note that this is the 2nd "local" repo group in the .pre-commit-config.yaml file. This is because |
| # we try to minimize the number of passes that must happen to apply some of the changes |
| # done by prek-hooks. Some of the prek hooks not only check for errors but also fix them. This means |
| # that output from an earlier prek hook becomes input to another prek hook. Splitting the local |
| # scripts of our and adding some other non-local prek hook in-between allows us to handle such |
| # changes quickly - especially when we want the early modifications from the first local group |
| # to be applied before the non-local prek hooks are run |
| hooks: |
| - id: check-shared-distributions-structure |
| name: Check shared distributions structure |
| entry: ./scripts/ci/prek/check_shared_distributions_structure.py |
| language: python |
| pass_filenames: false |
| files: > |
| (?x) |
| ^shared/.*$| |
| ^.*/pyproject\.toml$| |
| ^.*/_shared/.*$| |
| ^airflow-core/.*\.py$| |
| ^task-sdk/.*\.py$ |
| - id: check-shared-distributions-usage |
| name: Check shared distributions usage |
| entry: ./scripts/ci/prek/check_shared_distributions_usage.py |
| language: python |
| pass_filenames: false |
| files: ^shared/.*$|^.*/pyproject.toml$|^.*/_shared/.*$ |
| - id: check-airflow-imports-in-shared |
| name: Check for core/sdk imports in shared libraries |
| entry: ./scripts/ci/prek/check_airflow_imports_in_shared.py |
| language: python |
| pass_filenames: true |
| files: ^shared/.*/src/.*\.py$ |
| exclude: | |
| (?x) |
| ^shared/listeners/src/airflow_shared/listeners/spec/taskinstance\.py$| |
| ^shared/logging/src/airflow_shared/logging/remote\.py$| |
| ^shared/observability/src/airflow_shared/observability/metrics/stats\.py$| |
| ^shared/secrets_backend/src/airflow_shared/secrets_backend/base\.py$ |
| - id: check-test-only-imports-in-src |
| name: Check for test-only imports in production source |
| entry: ./scripts/ci/prek/check_test_only_imports_in_src.py |
| language: python |
| pass_filenames: true |
| files: > |
| (?x) |
| ^airflow-core/src/.*\.py$| |
| ^airflow-ctl/src/.*\.py$| |
| ^providers/.*/src/.*\.py$| |
| ^task-sdk/src/.*\.py$| |
| ^shared/.*/src/.*\.py$ |
| - id: check-secrets-search-path-sync |
| name: Check sync between sdk and core |
| entry: ./scripts/ci/prek/check_secrets_search_path_sync.py |
| language: python |
| pass_filenames: false |
| files: ^airflow-core/src/airflow/secrets/base_secrets\.py$|^task-sdk/src/airflow/sdk/execution_time/secrets/__init__\.py$ |
| - id: check-registry-types-json-sync |
| name: Check registry types.json in sync with types.py |
| entry: ./scripts/ci/prek/check_registry_types_json_sync.py |
| language: python |
| pass_filenames: false |
| files: ^dev/registry/registry_tools/types\.py$|^registry/src/_data/types\.json$ |
| - id: ruff |
| name: Run 'ruff' for extremely fast Python linting |
| description: "Run 'ruff' for extremely fast Python linting" |
| entry: ruff check --force-exclude |
| language: python |
| types_or: [python, pyi] |
| args: [--fix] |
| require_serial: true |
| additional_dependencies: ['ruff==0.16.8'] |
| exclude: ^airflow-core/tests/unit/dags/test_imports\.py$|^performance/tests/test_.*\.py$ |
| - id: ruff-format |
| name: Run 'ruff format' |
| description: "Run 'ruff format' for extremely fast Python formatting" |
| entry: ./scripts/ci/prek/ruff_format.py |
| language: python |
| types_or: [python, pyi] |
| args: [] |
| require_serial: true |
| exclude: ^airflow-core/tests/unit/dags/test_imports\.py$ |
| - id: replace-bad-characters |
| name: Replace bad characters |
| entry: ./scripts/ci/prek/replace_bad_characters.py |
| language: python |
| types: [file, text] |
| exclude: > |
| (?x) |
| ^clients/gen/go\.sh$| |
| ^\.gitmodules$| |
| ^airflow-core/src/airflow/ui/openapi-gen/| |
| ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/openapi-gen/| |
| ^providers/edge3/src/airflow/providers/edge3/plugins/www/openapi-gen/| |
| .*/dist/.*| |
| \.go$| |
| /go\.(mod|sum)$ |
| - id: lint-dockerfile |
| name: Lint Dockerfile |
| language: python |
| entry: ./scripts/ci/prek/lint_dockerfile.py |
| files: Dockerfile.*$ |
| pass_filenames: true |
| require_serial: true |
| - id: check-airflow-bug-report-template |
| name: Sort airflow-bug-report provider list |
| language: python |
| files: ^\.github/ISSUE_TEMPLATE/1-airflow_bug_report\.yml$ |
| require_serial: true |
| entry: ./scripts/ci/prek/check_airflow_bug_report_template.py |
| - id: update-local-yml-file |
| name: Update mounts in the local yml file |
| entry: ./scripts/ci/prek/local_yml_mounts.py |
| language: python |
| files: ^dev/breeze/src/airflow_breeze/utils/docker_command_utils\.py$|^scripts/ci/docker_compose/local\.yml$ |
| pass_filenames: false |
| - id: check-extras-order |
| name: Check order of extras in Dockerfile |
| entry: ./scripts/ci/prek/check_order_dockerfile_extras.py |
| language: python |
| files: ^Dockerfile$ |
| pass_filenames: false |
| - id: generate-airflow-diagrams |
| name: Generate airflow diagrams |
| entry: ./scripts/ci/prek/generate_airflow_diagrams.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/docs/.*/diagram_[^/]*\.py$| |
| ^contributing-docs/images/diagram_[^/]*\.py$| |
| ^docs/images/.*\.py$| |
| ^airflow-ctl/docs/images/diagrams/.*\.py$ |
| pass_filenames: true |
| - id: prevent-deprecated-sqlalchemy-usage |
| name: Prevent deprecated sqlalchemy usage |
| entry: ./scripts/ci/prek/prevent_deprecated_sqlalchemy_usage.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/.*\.py$| |
| ^airflow-ctl.*\.py$| |
| ^airflow-ctl-tests.*\.py| |
| ^dev/.*\.py$| |
| ^devel-common/.*\.py| |
| ^providers/.*\.py$| |
| ^task-sdk.*\.py$| |
| ^task-sdk-integration-tests.*\.py |
| pass_filenames: true |
| - id: update-supported-versions |
| name: Updates supported versions in documentation |
| entry: ./scripts/ci/prek/supported_versions.py |
| language: python |
| files: ^airflow-core/docs/installation/supported-versions\.rst$|^scripts/ci/prek/supported_versions\.py$|^README\.md$ |
| pass_filenames: false |
| - id: generate-api-permissions-doc |
| name: Generate REST API permission reference documentation |
| entry: ./scripts/ci/prek/extract_permissions.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/api_fastapi/core_api/routes/public/.*\.py$| |
| ^airflow-core/src/airflow/api_fastapi/core_api/security\.py$| |
| ^scripts/ci/prek/extract_permissions\.py$| |
| ^airflow-core/docs/security/api_permissions_ref\.rst$ |
| pass_filenames: false |
| - id: generate-fab-permissions-doc |
| name: Generate FAB auth manager REST API permission table |
| entry: ./scripts/ci/prek/fab_permissions_doc.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/api_fastapi/core_api/routes/public/.*\.py$| |
| ^airflow-core/src/airflow/api_fastapi/core_api/security\.py$| |
| ^providers/fab/src/airflow/providers/fab/auth_manager/fab_auth_manager\.py$| |
| ^providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override\.py$| |
| ^providers/fab/src/airflow/providers/fab/www/security/permissions\.py$| |
| ^scripts/ci/prek/extract_permissions\.py$| |
| ^scripts/ci/prek/fab_permissions_doc\.py$| |
| ^providers/fab/docs/auth-manager/access-control\.rst$ |
| pass_filenames: false |
| - id: update-tested-versions |
| name: Update tested Python/DB/Kubernetes versions in docs |
| entry: ./scripts/ci/prek/update_tested_versions.py |
| language: python |
| files: ^airflow-core/docs/installation/prerequisites\.rst$|^README\.md$|^dev/breeze/src/airflow_breeze/global_constants\.py$|^scripts/ci/prek/update_tested_versions\.py$|^scripts/ci/prek/common_prek_utils\.py$ |
| pass_filenames: false |
| - id: check-revision-heads-map |
| name: Check that the REVISION_HEADS_MAP is up-to-date |
| language: python |
| entry: ./scripts/ci/prek/check_revision_heads_map.py |
| pass_filenames: false |
| files: > |
| (?x) |
| ^scripts/ci/prek/version_heads_map\.py$| |
| ^airflow-core/src/airflow/migrations/versions/.*$| |
| ^airflow-core/src/airflow/migrations/versions| |
| ^airflow-core/src/airflow/utils/db\.py$ |
| - id: update-version |
| name: Update versions in docs |
| entry: ./scripts/ci/prek/update_versions.py |
| language: python |
| files: ^docs|^airflow-core/src/airflow/__init__\.py$|.*/pyproject\.toml$ |
| pass_filenames: false |
| - id: check-pydevd-left-in-code |
| language: pygrep |
| name: Check for pydevd debug statements accidentally left |
| entry: "pydevd.*settrace\\(" |
| pass_filenames: true |
| files: \.py$ |
| - id: check-safe-filter-usage-in-html |
| language: pygrep |
| name: Don't use safe in templates |
| description: the Safe filter is error-prone, use Markup() in code instead |
| entry: "\\|\\s*safe" |
| files: \.html$ |
| pass_filenames: true |
| - id: check-urlparse-usage-in-code |
| language: pygrep |
| name: Don't use urlparse in code |
| description: urlparse is not recommended, use urlsplit() in code instead |
| entry: "^\\s*from urllib\\.parse import ((\\|, )(urlparse\\|urlunparse))+$" |
| pass_filenames: true |
| files: \.py$ |
| - id: check-for-inclusive-language |
| language: pygrep |
| name: Check for language that we do not accept as community |
| description: Please use more appropriate words for community documentation. |
| entry: > |
| (?ix) |
| (black|white)[_-]?list| |
| \bshe\b| |
| \bhe\b| |
| \bher\b| |
| \bhis\b| |
| \bmaster\b| |
| \bslave\b| |
| \bsanity\b| |
| \bdummy\b |
| pass_filenames: true |
| exclude: > |
| (?x) |
| ^README\.md$| |
| ^pyproject\.toml$| |
| ^generated/PYPI_README\.md$| |
| ^airflow-core/src/airflow/ui/public/i18n/README\.md$| |
| ^airflow-core/docs/.*commits\.rst$| |
| ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/ui/pnpm-lock\.yaml$| |
| ^airflow-core/src/airflow/api_fastapi/gunicorn_config\.py$| |
| ^airflow-core/src/airflow/cli/commands/api_server_command\.py$| |
| ^airflow-core/src/airflow/api_fastapi/gunicorn_monitor\.py$| |
| ^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$| |
| ^airflow-core/src/airflow/operators/__init__\.py$| |
| ^airflow-core/src/airflow/serialization/serialized_objects\.py$| |
| ^airflow-core/src/airflow/ui/openapi-gen/| |
| ^airflow-core/src/airflow/ui/pnpm-lock\.yaml$| |
| ^providers/common/ai/src/airflow/providers/common/ai/plugins/www/pnpm-lock\.yaml$| |
| ^airflow-core/src/airflow/ui/public/i18n/locales/de/README\.md$| |
| ^airflow-core/src/airflow/ui/src/i18n/config\.ts$| |
| ^airflow-core/src/airflow/ui/src/i18n/dayjsLocale\.ts$| |
| ^\.agents/skills/airflow-translations/| |
| ^airflow-core/src/airflow/utils/db\.py$| |
| ^airflow-core/src/airflow/utils/trigger_rule\.py$| |
| ^airflow-core/tests/| |
| ^java-sdk/gradlew$| |
| ^java-sdk/gradlew\.bat$| |
| ^java-sdk/gradle| |
| ^java-sdk/scala_spark_example/src/main/scala/org/apache/airflow/example/ScalaSparkExample\.scala$| |
| ^task-sdk/tests/| |
| ^.*changelog\.(rst|txt)$| |
| ^.*CHANGELOG\.(rst|txt)$| |
| ^chart/values.schema\.json$| |
| ^.*commits\.(rst|txt)$| |
| ^.*/conf_constants\.py$| |
| ^.*/conf\.py$| |
| ^contributing-docs/03_contributors_quick_start\.rst$| |
| ^dev/| |
| ^devel-common/src/docs/README\.rst$| |
| ^devel-common/src/sphinx_exts/removemarktransform\.py| |
| ^devel-common/src/tests_common/test_utils/db\.py| |
| .*/dist/.*| |
| ^docs/apache-airflow-providers-amazon/secrets-backends/aws-ssm-parameter-store\.rst$| |
| git| |
| ^chart/tests/chart_utils/helm_template_generator\.py$| |
| package-lock\.json$| |
| ^.*\.(png|gif|jp[e]?g|svg|tgz|lock|woff2?)$| |
| ^\.pre-commit-config\.yaml$| |
| ^.*/provider_conf\.py$| |
| ^providers/\.pre-commit-config\.yaml$| |
| ^providers/amazon/src/airflow/providers/amazon/aws/hooks/emr\.py$| |
| ^providers/amazon/src/airflow/providers/amazon/aws/operators/emr\.py$| |
| ^providers/.*/get_provider_info\.py$| |
| ^providers/.*/provider\.yaml$| |
| ^providers/apache/cassandra/src/airflow/providers/apache/cassandra/hooks/cassandra\.py$| |
| ^providers/apache/hdfs/docs/connections\.rst$| |
| ^providers/apache/hive/src/airflow/providers/apache/hive/operators/hive_stats\.py$| |
| ^providers/apache/hive/src/airflow/providers/apache/hive/transfers/vertica_to_hive\.py$| |
| ^providers/apache/kafka/docs/connections/kafka\.rst$| |
| ^providers/apache/spark/docs/decorators/pyspark\.rst$| |
| ^providers/apache/spark/docs/connections/spark-submit.rst$| |
| ^providers/apache/spark/docs/operators\.rst$| |
| ^providers/apache/spark/src/airflow/providers/apache/spark/decorators/| |
| ^providers/apache/spark/src/airflow/providers/apache/spark/hooks/| |
| ^providers/apache/spark/src/airflow/providers/apache/spark/operators/| |
| ^providers/cncf/kubernetes/docs/operators\.rst$| |
| ^providers/common/sql/tests/provider_tests/common/sql/operators/test_sql_execute\.py$| |
| ^providers/edge3/src/airflow/providers/edge3/plugins/www/pnpm-lock.yaml$| |
| ^providers/exasol/src/airflow/providers/exasol/hooks/exasol\.py$| |
| ^providers/fab/docs/auth-manager/webserver-authentication\.rst$| |
| ^providers/fab/src/airflow/providers/fab/auth_manager/security_manager/| |
| ^providers/fab/src/airflow/providers/fab/www/static/| |
| ^providers/fab/src/airflow/providers/fab/www/templates/| |
| ^providers/google/docs/operators/cloud/kubernetes_engine\.rst$| |
| ^providers/google/src/airflow/providers/google/cloud/hooks/bigquery\.py$| |
| ^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/cli/definition.py| |
| ^providers/microsoft/azure/docs/connections/azure_cosmos\.rst$| |
| ^providers/microsoft/azure/src/airflow/providers/microsoft/azure/hooks/cosmos\.py$| |
| ^providers/microsoft/winrm/src/airflow/providers/microsoft/winrm/hooks/winrm\.py$| |
| ^providers/microsoft/winrm/src/airflow/providers/microsoft/winrm/operators/winrm\.py$| |
| ^providers/opsgenie/src/airflow/providers/opsgenie/hooks/opsgenie\.py$| |
| ^providers/redis/src/airflow/providers/redis/provider\.yaml$| |
| ^providers/.*/tests/| |
| .rat-excludes| |
| ^.*RELEASE_NOTES\.rst$| |
| ^scripts/ci/docker-compose/integration-keycloak\.yml$| |
| ^scripts/ci/docker-compose/keycloak/keycloak-entrypoint\.sh$| |
| ^scripts/ci/prek/upgrade_important_versions.py$| |
| ^scripts/ci/prek/download_k8s_schemas\.py$| |
| ^scripts/ci/prek/vendor_k8s_json_schema\.py$ |
| - id: check-template-context-variable-in-sync |
| name: Sync template context variable refs |
| language: python |
| entry: ./scripts/ci/prek/check_template_context_variable_in_sync.py |
| files: |
| (?x) |
| ^airflow-core/src/airflow/models/taskinstance\.py$| |
| ^task-sdk/src/airflow/sdk/definitions/context\.py$| |
| ^airflow-core/docs/templates-ref\.rst$ |
| - id: check-base-operator-usage |
| language: pygrep |
| name: Check BaseOperator core imports |
| description: Make sure BaseOperator is imported from airflow.models.baseoperator in core |
| entry: "from airflow\\.models import.* BaseOperator\\b" |
| files: \.py$ |
| pass_filenames: true |
| exclude: > |
| (?x) |
| ^airflow-core/src/airflow/decorators/.*$| |
| ^airflow-core/src/airflow/hooks/.*$| |
| ^airflow-core/src/airflow/operators/.*$| |
| ^providers/.*$ |
| - id: check-base-operator-usage |
| language: pygrep |
| name: Check BaseOperatorLink core imports |
| description: Make sure BaseOperatorLink is not imported from airflow.models in core |
| entry: "^\\s*from airflow\\.models\\.baseoperatorlink import BaseOperatorLink\\b" |
| files: \.py$ |
| pass_filenames: true |
| exclude: > |
| (?x) |
| ^airflow-core/src/airflow/decorators/.*$| |
| ^airflow-core/src/airflow/hooks/.*$| |
| ^airflow-core/src/airflow/operators/.*$| |
| ^providers/.*/src/airflow/providers/.*$| |
| ^providers/.*/src/airflow/providers/standard/sensors/.*$ |
| - id: check-core-deprecation-classes |
| language: pygrep |
| name: Verify usage of Airflow deprecation classes in core |
| entry: category=DeprecationWarning|category=PendingDeprecationWarning |
| files: \.py$ |
| exclude: > |
| (?x) |
| ^airflow-core/src/airflow/configuration\.py$| |
| ^airflow-core/tests/.*$| |
| ^providers/.*/src/airflow/providers/| |
| ^scripts/in_container/verify_providers\.py$| |
| ^providers/.*/tests/.*$| |
| ^scripts/tests/.*$| |
| ^devel-common/ |
| pass_filenames: true |
| - id: check-provide-create-sessions-imports |
| language: pygrep |
| name: Check session util imports |
| description: NEW_SESSION, provide_session, and create_session should be imported from airflow.utils.session to avoid import cycles. |
| entry: "from airflow\\.utils\\.db import.* (NEW_SESSION|provide_session|create_session)" |
| files: \.py$ |
| pass_filenames: true |
| - id: check-incorrect-use-of-LoggingMixin |
| language: pygrep |
| name: Make sure LoggingMixin is not used alone |
| entry: "LoggingMixin\\(\\)" |
| files: \.py$ |
| pass_filenames: true |
| - id: check-start-date-not-used-in-defaults |
| language: pygrep |
| name: start_date not in default_args |
| entry: "default_args\\s*=\\s*{\\s*(\"|')start_date(\"|')|(\"|')start_date(\"|'):" |
| files: \.*example_dags.*\.py$ |
| pass_filenames: true |
| - id: check-example-dag-tags |
| name: Check example DAGs carry the "example" tag |
| entry: ./scripts/ci/prek/check_example_dag_tags.py |
| language: python |
| files: ^.*/example_dags/.*\.py$ |
| pass_filenames: true |
| - id: check-apache-license-rat |
| name: Check if licenses are OK for Apache |
| entry: ./scripts/ci/prek/check_license.py |
| language: python |
| files: ^LICENSE$ |
| pass_filenames: false |
| - id: check-metrics-synced-with-registry |
| name: Check that metrics in the codebase are in sync with the metrics registry YAML file. |
| entry: ./scripts/ci/prek/check_metrics_synced_with_the_registry.py |
| language: python |
| files: \.py$|^shared/observability/src/airflow_shared/observability/metrics/metrics_template\.yaml$ |
| exclude: ^(tests/|.*/tests/|airflow-core/src/airflow/observability/stats\.py$|task-sdk/src/airflow/sdk/observability/stats\.py$) |
| pass_filenames: true |
| require_serial: true |
| additional_dependencies: ["PyYAML>=6.0", "rich>=13.6.0"] |
| - id: check-boring-cyborg-configuration |
| name: Checks for Boring Cyborg configuration consistency |
| language: python |
| entry: ./scripts/ci/prek/boring_cyborg.py |
| pass_filenames: false |
| require_serial: true |
| - id: update-in-the-wild-to-be-sorted |
| name: Sort INTHEWILD.md alphabetically |
| entry: ./scripts/ci/prek/sort_in_the_wild.py |
| language: python |
| files: ^\.pre-commit-config\.yaml$|^INTHEWILD\.md$ |
| pass_filenames: false |
| require_serial: true |
| - id: update-installed-providers-to-be-sorted |
| name: Sort and uniquify installed_providers.txt |
| entry: ./scripts/ci/prek/sort_installed_providers.py |
| language: python |
| files: ^\.pre-commit-config\.yaml$|^.*_installed_providers\.txt$ |
| pass_filenames: false |
| require_serial: true |
| - id: update-spelling-wordlist-to-be-sorted |
| name: Sort spelling_wordlist.txt |
| entry: ./scripts/ci/prek/sort_spelling_wordlist.py |
| language: python |
| files: ^\.pre-commit-config\.yaml$|^docs/spelling_wordlist\.txt$ |
| require_serial: true |
| pass_filenames: false |
| - id: shellcheck |
| name: Check Shell scripts syntax correctness |
| language: docker_image |
| entry: koalaman/shellcheck:v0.8.0 -x -a |
| files: \.(bash|sh)$|^hooks/build$|^hooks/push$ |
| exclude: ^dev/breeze/autocomplete/.*$ |
| - id: check-integrations-list-consistent |
| name: Sync integrations list with docs |
| entry: ./scripts/ci/prek/check_integrations_list.py |
| language: python |
| files: ^scripts/ci/docker-compose/integration-.*\.yml$|^contributing-docs/testing/integration_tests\.rst$ |
| require_serial: true |
| pass_filenames: false |
| - id: sync-translation-namespaces |
| name: Sync translation namespace file list |
| entry: ./scripts/ci/prek/sync_translation_namespaces.py |
| language: python |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/ui/public/i18n/locales/en/.*\.json$| |
| ^\.agents/skills/airflow-translations/SKILL\.md$ |
| pass_filenames: false |
| - id: generate-agent-skills |
| name: Sync AGENTS.md commands from contributing docs |
| entry: ./scripts/ci/prek/generate_agent_skills.py |
| language: python |
| files: > |
| (?x) |
| ^contributing-docs/.*\.rst$| |
| ^AGENTS\.md$| |
| ^scripts/ci/prek/generate_agent_skills\.py$ |
| pass_filenames: false |
| additional_dependencies: ['pyyaml', 'rich>=13.6.0'] |
| - id: check-documented-commands |
| name: Check documented breeze and prek commands exist |
| entry: ./scripts/ci/prek/check_documented_commands.py |
| language: python |
| files: > |
| (?x) |
| ^AGENTS\.md$| |
| ^contributing-docs/.*\.rst$| |
| ^dev/breeze/src/airflow_breeze/commands/| |
| ^(?:.*/)?\.pre-commit-config\.yaml$| |
| ^scripts/ci/prek/check_documented_commands\.py$ |
| pass_filenames: false |
| require_serial: true |
| additional_dependencies: ['pyyaml', 'rich>=13.6.0'] |
| # The three skill-eval hooks below are skipped by id in .github/actions/install-prek/action.yml |
| # (their node environments are ~3.5 GB and never run in CI). Renaming one silently re-enables |
| # its installation there, so update the action alongside any id change. |
| - id: run-skill-eval |
| name: Run skill-eval against AGENTS.md and cases |
| entry: ./dev/skill-evals/eval.py |
| language: node |
| language_version: '22.22.0' |
| additional_dependencies: ['promptfoo@0.121.17', '@anthropic-ai/claude-agent-sdk@0.3.185'] |
| stages: ['manual'] |
| files: > |
| (?x) |
| ^AGENTS\.md$| |
| ^dev/skill-evals/ |
| pass_filenames: false |
| require_serial: true |
| verbose: true |
| - id: run-skill-eval-codex |
| name: Run skill-eval against AGENTS.md and cases (Codex runtime) |
| # Kept separate from run-skill-eval so only contributors who actually run |
| # the Codex arm build an env carrying the Codex CLI binary. promptfoo |
| # bundles its own @openai/codex-sdk, but that build ships a binary whose |
| # Developer ID certificate Apple has revoked — macOS kills it on exec — |
| # so a notarized version has to be installed explicitly. |
| entry: env AGENT_RUNTIME=codex ./dev/skill-evals/eval.py |
| language: node |
| language_version: '22.22.0' |
| additional_dependencies: |
| - 'promptfoo@0.121.17' |
| - '@openai/codex-sdk@0.144.6' |
| stages: ['manual'] |
| files: > |
| (?x) |
| ^AGENTS\.md$| |
| ^dev/skill-evals/ |
| pass_filenames: false |
| require_serial: true |
| verbose: true |
| - id: view-skill-eval |
| name: View skill-eval results in browser (manual) |
| entry: env PROMPTFOO_CONFIG_DIR=.build/promptfoo promptfoo view |
| language: node |
| language_version: '22.22.0' |
| additional_dependencies: ['promptfoo@0.121.17', '@anthropic-ai/claude-agent-sdk@0.3.185'] |
| stages: ['manual'] |
| files: > |
| (?x) |
| ^AGENTS\.md$| |
| ^dev/skill-evals/ |
| pass_filenames: false |
| require_serial: true |
| - id: check-eval-hash |
| name: Verify skill-eval ran on current AGENTS.md and cases |
| entry: ./scripts/ci/prek/check_eval_hash.py |
| language: python |
| files: > |
| (?x) |
| ^AGENTS\.md$| |
| ^dev/skill-evals/cases/| |
| ^dev/skill-evals/last-eval-hash\.txt$ |
| pass_filenames: false |
| - id: update-pyproject-toml |
| name: Update Airflow's meta-package pyproject.toml |
| language: python |
| entry: ./scripts/ci/prek/update_airflow_pyproject_toml.py |
| files: > |
| (?x) |
| ^.*/pyproject\.toml$| |
| ^scripts/ci/prek/update_airflow_pyproject_toml\.py$| |
| ^providers/.*/pyproject\.toml$| |
| ^providers/.*/provider\.yaml$ |
| pass_filenames: false |
| require_serial: true |
| - id: check-excluded-provider-markers |
| name: Check excluded-provider python_version and platform markers in pyproject.toml |
| language: python |
| entry: ./scripts/ci/prek/check_excluded_provider_markers.py |
| files: > |
| (?x) |
| ^pyproject\.toml$| |
| ^providers/.*/provider\.yaml$ |
| pass_filenames: false |
| require_serial: true |
| additional_dependencies: ['packaging>=25', 'pyyaml', 'tomli>=2.0.1', 'rich>=13.6.0'] |
| - id: check-provider-config-fallback-defaults |
| name: Check provider_config_fallback_defaults.cfg is in sync with provider.yaml files |
| language: python |
| entry: ./scripts/ci/prek/check_provider_config_fallback_defaults.py |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/config_templates/provider_config_fallback_defaults\.cfg$| |
| ^providers/.*/provider\.yaml$| |
| ^scripts/ci/prek/check_provider_config_fallback_defaults\.py$ |
| pass_filenames: false |
| require_serial: true |
| additional_dependencies: ['pyyaml', 'rich>=13.6.0'] |
| - id: check-dependency-lower-bounds |
| name: Check that dependencies in pyproject.toml have lower bounds |
| language: python |
| entry: ./scripts/ci/prek/check_dependency_lower_bounds.py |
| files: (^|/)pyproject\.toml$ |
| require_serial: true |
| additional_dependencies: ['packaging>=25', 'tomli>=2.0.1', 'rich>=13.6.0'] |
| - id: update-reproducible-source-date-epoch |
| name: Update Source Date Epoch for reproducible builds |
| language: python |
| entry: ./scripts/ci/prek/update_source_date_epoch.py |
| files: ^RELEASE_NOTES\.rst$|^chart/RELEASE_NOTES\.rst$ |
| require_serial: true |
| - id: check-breeze-top-dependencies-limited |
| name: Check top-level breeze deps |
| description: Breeze should have small number of top-level dependencies |
| language: python |
| entry: ./scripts/tools/check_if_limited_dependencies.py |
| files: ^dev/breeze/.*$ |
| pass_filenames: false |
| require_serial: true |
| - id: check-system-tests-present |
| name: Check if system tests have required segments of code |
| entry: ./scripts/ci/prek/check_system_tests.py |
| language: python |
| files: ^.*/tests/system/.*/example_[^/]*\.py$ |
| pass_filenames: true |
| - id: generate-pypi-readme |
| name: Generate PyPI README |
| entry: ./scripts/ci/prek/generate_pypi_readme.py |
| language: python |
| files: ^README\.md$ |
| pass_filenames: false |
| - id: sync-provider-readme |
| name: Sync provider README.rst Requirements table with pyproject.toml |
| description: | |
| Provider README.rst files are regenerated from pyproject.toml at distribution-build |
| time. Between releases, dependency bumps in pyproject.toml do not propagate to the |
| committed README, leading to drift. This hook re-renders the Requirements table from |
| the current pyproject.toml whenever the latter changes. |
| entry: ./scripts/ci/prek/sync_provider_readme.py |
| language: python |
| files: ^providers/.*/pyproject\.toml$ |
| pass_filenames: true |
| - id: lint-markdown |
| name: Run markdownlint |
| description: Checks the style of Markdown files. |
| entry: markdownlint |
| language: node |
| types: [markdown] |
| files: \.(md|mdown|markdown)$ |
| exclude: | |
| (?x) |
| ^\.apache-magpie-overrides/ |
| additional_dependencies: ['markdownlint-cli@0.38.0'] |
| - id: lint-json-schema |
| name: Lint JSON Schema files |
| entry: ./scripts/ci/prek/lint_json_schema.py |
| args: |
| - --spec-file |
| - scripts/ci/prek/draft7_schema.json |
| language: python |
| pass_filenames: true |
| files: .*\.schema\.json$ |
| require_serial: true |
| - id: lint-json-schema |
| name: Lint NodePort Service |
| entry: ./scripts/ci/prek/lint_json_schema.py |
| args: |
| - --spec-url |
| - https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.20.2-standalone/service-v1.json |
| language: python |
| pass_filenames: true |
| files: ^scripts/ci/kubernetes/nodeport\.yaml$ |
| require_serial: true |
| - id: lint-json-schema |
| name: Lint Docker compose files |
| entry: ./scripts/ci/prek/lint_json_schema.py |
| args: |
| - --spec-url |
| - https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json |
| language: python |
| pass_filenames: true |
| files: ^scripts/ci/docker-compose/.+\.ya?ml$|docker-compose\.ya?ml$ |
| exclude: > |
| (?x) |
| ^scripts/ci/docker-compose/grafana/.| |
| ^scripts/ci/docker-compose/gremlin/.| |
| ^scripts/ci/docker-compose/.+-config\.ya?ml$ |
| require_serial: true |
| - id: check-persist-credentials-disabled-in-github-workflows |
| name: Check persistent creds in workflow files |
| description: Check that workflow files have persist-credentials disabled |
| entry: ./scripts/ci/prek/checkout_no_credentials.py |
| language: python |
| pass_filenames: true |
| files: ^\.github/workflows/.*\.yml$ |
| - id: check-docstring-param-types |
| name: Check that docstrings do not specify param types |
| entry: ./scripts/ci/prek/docstring_param_type.py |
| language: python |
| pass_filenames: true |
| files: \.py$ |
| - id: check-zip-file-is-not-committed |
| name: Check no zip files are committed |
| description: Zip files are not allowed in the repository |
| language: fail |
| entry: | |
| Zip files are not allowed in the repository as they are hard to |
| track and have security implications. Please remove the zip file from the repository. |
| files: \.zip$ |
| - id: update-inlined-dockerfile-scripts |
| name: Inline Dockerfile and Dockerfile.ci scripts |
| entry: ./scripts/ci/prek/inline_scripts_in_docker.py |
| language: python |
| pass_filenames: false |
| files: ^Dockerfile$|^Dockerfile\.ci$|^scripts/docker/.*$ |
| require_serial: true |
| - id: update-docker-gpg-keys |
| name: Update Docker build GPG keys (manual) |
| entry: ./scripts/ci/prek/update_docker_gpg_keys.py |
| stages: ['manual'] |
| language: python |
| pass_filenames: false |
| files: ^scripts/docker/keys/.*$|^scripts/ci/prek/update_docker_gpg_keys\.py$ |
| require_serial: true |
| - id: check-changelog-has-no-duplicates |
| name: Check changelogs for duplicate entries |
| language: python |
| files: changelog\.(rst|txt)$ |
| entry: ./scripts/ci/prek/changelog_duplicates.py |
| pass_filenames: true |
| - id: check-no-conventional-commit-message |
| name: Check commit message is not Conventional Commits style |
| description: "Reject feat:/fix:/chore: style commit subjects - Airflow uses plain prose" |
| language: python |
| entry: ./scripts/ci/prek/check_no_conventional_commit_message.py |
| stages: [commit-msg] |
| always_run: true |
| pass_filenames: true |
| - id: check-changelog-format |
| name: Check changelog format |
| language: python |
| files: changelog\.(rst|txt)$ |
| entry: ./scripts/ci/prek/check_changelog_format.py |
| pass_filenames: true |
| - id: check-newsfragments-are-valid |
| name: Check newsfragments are valid |
| language: python |
| files: newsfragments/.*\.rst$ |
| entry: ./scripts/ci/prek/newsfragments.py |
| pass_filenames: true |
| # We sometimes won't have newsfragments in the repo, so always run it so `check-hooks-apply` passes |
| # This is fast, so not too much downside |
| always_run: true |
| - id: update-breeze-cmd-output |
| name: Update breeze docs |
| description: Update output of breeze commands in Breeze documentation |
| entry: ./scripts/ci/prek/breeze_cmd_line.py |
| language: python |
| files: > |
| (?x) |
| ^dev/breeze/.*$| |
| ^\.pre-commit-config\.yaml$| |
| ^scripts/ci/prek/breeze_cmd_line\.py$$ |
| require_serial: true |
| pass_filenames: false |
| - id: check-example-dags-urls |
| name: Check that example dags url include provider versions |
| entry: ./scripts/ci/prek/update_example_dags_paths.py |
| language: python |
| pass_filenames: true |
| files: |
| (?x) |
| ^airflow-core/docs/.*example-dags\.rst$| |
| ^airflow-core/docs/.*index\.rst$| |
| ^docs/.*index\.rst$ |
| always_run: true |
| - id: check-lazy-logging |
| name: Check that all logging methods are lazy |
| entry: ./scripts/ci/prek/check_lazy_logging.py |
| language: python |
| pass_filenames: true |
| files: \.py$ |
| - id: check-no-new-airflow-exceptions |
| name: Check that no new raise AirflowException usages are added |
| entry: ./scripts/ci/prek/check_new_airflow_exception_usage.py |
| language: python |
| pass_filenames: true |
| files: ^(airflow-core|airflow-ctl|task-sdk|providers|shared)/.*\.py$ |
| - id: check-no-new-provide-session-positional |
| name: Check that no new @provide_session functions declare `session` positionally |
| entry: ./scripts/ci/prek/check_provide_session_kwargs.py |
| language: python |
| pass_filenames: true |
| files: ^(airflow-core|providers)/.*\.py$|^scripts/ci/prek/known_provide_session_positional\.txt$|^scripts/ci/prek/check_provide_session_kwargs\.py$ |
| - id: check-no-new-airflow-core-utils-modules |
| name: Check that no new modules are added under airflow-core/src/airflow/utils |
| entry: ./scripts/ci/prek/check_no_new_airflow_core_utils_modules.py |
| language: python |
| pass_filenames: false |
| files: ^airflow-core/src/airflow/utils/[^/]+$|^scripts/ci/prek/known_airflow_core_utils_modules\.txt$|^scripts/ci/prek/check_no_new_airflow_core_utils_modules\.py$ |
| - id: check-mapped-column-nullable-annotations |
| name: Check that nullable mapped_column attributes are annotated Mapped[X | None] |
| entry: ./scripts/ci/prek/check_mapped_column_nullable_annotations.py |
| language: python |
| pass_filenames: true |
| files: > |
| (?x) |
| ^airflow-core/src/airflow/(models|jobs)/.*\.py$| |
| ^providers/edge3/src/airflow/providers/edge3/models/.*\.py$| |
| ^providers/fab/src/airflow/providers/fab/auth_manager/models/.*\.py$| |
| ^scripts/ci/prek/check_mapped_column_nullable_annotations\.py$ |
| - id: bandit |
| name: bandit |
| description: "Bandit is a tool for finding common security issues in Python code" |
| entry: bandit |
| language: python |
| language_version: python3 |
| types: [python] |
| additional_dependencies: ['bandit==1.7.6'] |
| require_serial: true |
| files: ^airflow-core/src/airflow/.* # TODO Expand this to more than just airflow-core |
| exclude: |
| airflow/example_dags/.* |
| args: |
| - "--skip" |
| - "B101,B301,B324,B403,B404,B603" |
| - "--severity-level" |
| - "high" # TODO: remove this line when we fix all the issues |
| - id: check-k8s-schemas-published |
| name: Check K8s schemas are published on airflow.apache.org |
| entry: ./scripts/ci/prek/check_k8s_schemas_published.py |
| language: python |
| pass_filenames: false |
| files: ^dev/breeze/src/airflow_breeze/global_constants\.py$ |
| require_serial: true |
| # This is a fast regular hook that runs when any pyproject.toml changes. |
| # It runs locally with `--frozen` so the lock is only verified against pyproject.toml, |
| # never silently rewritten during a commit. If a pyproject.toml change makes the lock |
| # stale, the hook fails and the contributor must run `uv lock` explicitly and commit |
| # the refreshed uv.lock — which keeps lock updates intentional and reviewable. |
| - id: update-uv-lock |
| name: Update uv.lock |
| entry: uv lock --frozen |
| language: system |
| files: > |
| (?x) |
| (^|/)pyproject\.toml$| |
| ^uv\.lock$ |
| pass_filenames: false |
| require_serial: true |
| - id: mypy-devel-common |
| name: Run mypy for devel-common |
| language: python |
| entry: ./scripts/ci/prek/run_mypy_full_dist_local_venv_or_breeze_in_ci.py devel-common |
| pass_filenames: false |
| files: ^.*\.py$ |
| require_serial: true |
| - id: check-shared-mypy-hooks |
| name: Every shared/<dist> has a mypy-shared-<dist> prek hook |
| language: python |
| entry: ./scripts/ci/prek/check_shared_mypy_hooks.py |
| pass_filenames: false |
| files: ^shared/.*|^scripts/ci/prek/check_shared_mypy_hooks\.py$ |
| require_serial: true |
| - id: check-migration-patterns |
| name: Check migration files for anti-patterns and style (MIG001-MIG004) |
| entry: ./scripts/ci/prek/check_migration_patterns.py |
| language: python |
| pass_filenames: true |
| files: ^airflow-core/src/airflow/migrations/versions/.*\.py$ |
| additional_dependencies: [rich>=13.6.0] |
| require_serial: true |
| ## ADD MOST PREK HOOK ABOVE THAT LINE |
| # The below prek hooks are those requiring CI image to be built |
| ## ONLY ADD PREK HOOKS HERE THAT REQUIRE CI IMAGE |
| - id: check-template-fields-valid |
| name: Check templated fields mapped in operators/sensors |
| language: python |
| entry: ./scripts/ci/prek/check_template_fields.py |
| files: ^(providers/[^/]+|airflow-core)/src/airflow/(.*/)?(sensors|operators)/.*\.py$ |
| require_serial: true |
| - id: check-execution-api-versions |
| name: Check execution API datamodel changes have corresponding version updates |
| entry: ./scripts/ci/prek/check_execution_api_versions.py |
| language: python |
| pass_filenames: true |
| files: ^airflow-core/src/airflow/api_fastapi/execution_api/(datamodels|versions)/.*\.py$ |
| require_serial: true |
| - id: generate-supervisor-schemas-snapshot |
| name: Regenerate supervisor schema snapshot |
| entry: ./scripts/ci/prek/generate_supervisor_schemas_snapshot.py |
| language: python |
| pass_filenames: false |
| files: ^(task-sdk/src/airflow/sdk/execution_time/(comms\.py|schema/.*\.py)|airflow-core/src/airflow/dag_processing/processor\.py)$ |
| require_serial: true |
| - id: check-supervisor-schemas-versions |
| name: Check supervisor schema changes have corresponding version updates |
| entry: ./scripts/ci/prek/check_supervisor_schemas_versions.py |
| language: python |
| pass_filenames: true |
| files: ^(task-sdk/src/airflow/sdk/execution_time/(comms\.py|schema/.*\.py)|airflow-core/src/airflow/dag_processing/processor\.py)$ |
| require_serial: true |
| - id: generate-tasksdk-datamodels |
| name: Generate Datamodels for TaskSDK client |
| language: python |
| entry: uv run -p 3.12 --no-progress --active --group codegen --package apache-airflow-task-sdk --directory task-sdk -s dev/generate_task_sdk_models.py |
| pass_filenames: false |
| files: ^airflow-core/src/airflow/api_fastapi/execution_api/.*\.py$ |
| require_serial: true |
| - id: generate-airflowctl-datamodels |
| name: Generate Datamodels for AirflowCTL |
| language: python |
| entry: > |
| bash -c ' |
| uv run -p 3.12 --no-dev --no-progress --active --group codegen --package apache-airflow-ctl --directory airflow-ctl/ datamodel-codegen && |
| uv run -p 3.12 --no-dev --no-progress --active --group codegen --package apache-airflow-ctl --directory airflow-ctl/ datamodel-codegen --input="../airflow-core/src/airflow/api_fastapi/auth/managers/simple/openapi/v2-simple-auth-manager-generated.yaml" --output="src/airflowctl/api/datamodels/auth_generated.py"' |
| pass_filenames: false |
| files: |
| (?x) |
| ^airflow-core/src/airflow/api_fastapi/core_api/datamodels/.*\.py$| |
| ^airflow-core/src/airflow/api_fastapi/auth/managers/simple/(datamodels|routes|services|openapi)/.*\.py$ |
| require_serial: true |
| - id: check-contextmanager-class-decorators |
| name: Check for problematic context manager class decorators |
| entry: ./scripts/ci/prek/check_contextmanager_class_decorators.py |
| language: python |
| files: .*test.*\.py$ |
| pass_filenames: true |
| - id: ktlint |
| name: Run ktlint format |
| description: "Use ktlint (via Gradle) to format Kotlin and Java files" |
| entry: ./java-sdk/gradlew -p ./java-sdk ktlintFormat |
| language: system |
| pass_filenames: false |
| files: ^java-sdk/.*$ |
| - id: spotless |
| name: Run spotless apply |
| description: "Use spotless (via Gradle) to format Java files" |
| entry: ./java-sdk/gradlew -p ./java-sdk spotlessApply |
| language: system |
| pass_filenames: false |
| files: ^java-sdk/.*\.java$ |