This is an automated email from the ASF dual-hosted git repository.
vatsrahul1001 pushed a commit to branch v3-4-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/v3-4-test by this push:
new ea342be8ed8 [v3-4-test] Wait for a maintainer when a fork PR changes
any CI-defining file (#75718) (#75733)
ea342be8ed8 is described below
commit ea342be8ed89789b5e51ecb8972441d8c3b3851c
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Oct 27 10:22:51 2026 +0000
[v3-4-test] Wait for a maintainer when a fork PR changes any CI-defining
file (#75718) (#75733)
The project-CI rule of the workflow run auto-approval checked a shorter
list of CI-defining paths than the fork CI reconciler. A PR changing a
.pre-commit-config.yaml, which decides the static checks CI runs, had its
runs approved without a maintainer's look. Changes to Dockerfile*,
scripts/docker/ and scripts/in_container/ were held back only because
selective checks currently run the full set of tests for them. Both
rules now read the reconciler's list, so a path added there applies to
both.
(cherry picked from commit c79293ea4b998370e034284c159931e4edc40bdf)
Co-authored-by: Shahar Epstein <[email protected]>
---
contributing-docs/05_pull_requests.rst | 10 ++++++----
dev/breeze/doc/ci/05_workflows.md | 14 +++++++-------
.../src/airflow_breeze/utils/workflow_run_approval.py | 14 ++++----------
dev/breeze/tests/test_workflow_run_approval.py | 17 +++++++++++++++++
4 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/contributing-docs/05_pull_requests.rst
b/contributing-docs/05_pull_requests.rst
index 593180aba6f..405c55da48a 100644
--- a/contributing-docs/05_pull_requests.rst
+++ b/contributing-docs/05_pull_requests.rst
@@ -252,8 +252,10 @@ and approves them automatically when all of these hold:
* The PR targets ``main``. PRs to release branches, such as ``v3-4-test``,
always wait for a
maintainer.
-* The PR does not change anything under ``.github/``, ``dev/breeze/`` or
``scripts/ci/``. Those
- files define the CI workflows and choose the runners they use.
+* The PR does not change files that define CI: anything under ``.github/``,
``dev/breeze/``,
+ ``scripts/ci/``, ``scripts/docker/`` or ``scripts/in_container/``, a
top-level ``Dockerfile*``,
+ or a ``.pre-commit-config.yaml`` in any directory. Those files define the CI
workflows, what
+ their jobs run and the runners they use.
* The change does not need the full set of tests, does not change dependencies
(``pyproject.toml``,
lock files, ``package.json``, ``go.mod``, Gradle build files) and does not
add a new provider.
* The CI jobs your change selects are estimated to take at most 310
job-minutes, about a quarter of
@@ -269,8 +271,8 @@ and approves them automatically when all of these hold:
If your PR's CI runs in your fork (it carries the ``fork ci required`` label),
the CI run in
``apache/airflow`` only checks that, so none of the rules above apply. Its
runs are approved
automatically unless the PR changes files that define CI: anything under
``.github/``,
-``dev/breeze/``, ``scripts/ci/``, ``scripts/docker/`` or
``scripts/in_container/``, a ``Dockerfile``
-or ``.pre-commit-config.yaml``. Then the runs wait for a maintainer and a
comment on the PR explains
+``dev/breeze/``, ``scripts/ci/``, ``scripts/docker/`` or
``scripts/in_container/``, a top-level
+``Dockerfile*``, or a ``.pre-commit-config.yaml`` in any directory. Then the
runs wait for a maintainer and a comment on the PR explains
why. CI in your fork runs either way.
Each new push is checked again, because approval applies to one commit. Only
runs started in the
diff --git a/dev/breeze/doc/ci/05_workflows.md
b/dev/breeze/doc/ci/05_workflows.md
index 264bf7378e6..9352647116d 100644
--- a/dev/breeze/doc/ci/05_workflows.md
+++ b/dev/breeze/doc/ci/05_workflows.md
@@ -107,8 +107,10 @@ them, for the contributors the repository's approval
setting covers. The
- the PR targets `main`; PRs to release branches (`v3-4-test`,
`airflow-ctl/v0-1-test`, ...) run those
branches' own workflows and always wait for a maintainer
-- the PR changes nothing under `.github/`, `dev/breeze/` or `scripts/ci/`,
which define the workflows
- and choose the runners
+- the PR changes no file the fork CI reconciler counts as CI-defining
(`.github/`, `dev/breeze/`,
+ `scripts/ci/`, `scripts/docker/`, `scripts/in_container/`, a top-level
`Dockerfile*`, a
+ `.pre-commit-config.yaml` in any directory),
+ which define the workflows, what their jobs run and the runners they use
- the PR changes no dependency manifest or lock file (`pyproject.toml`,
`uv.lock`, `package.json`,
`pnpm-lock.yaml`, `go.mod`, Gradle build files, ...) and adds no new
provider (selective checks
run from `main`'s tree and do not know it)
@@ -121,11 +123,9 @@ them, for the contributors the repository's approval
setting covers. The
A PR to `main` whose CI runs in the contributor's fork (AIP-120: the `Fork CI
gate` job would skip
project CI for it) is decided by one rule instead, because its `Tests (AMD)`
run only executes the
-gate: its runs are approved whatever its size, cost or dependency changes,
unless it changes a file
-the fork CI reconciler counts as CI-defining (`.github/`, `dev/breeze/`,
`scripts/ci/`,
-`scripts/docker/`, `scripts/in_container/`, `Dockerfile*`,
`.pre-commit-config.yaml`). Such a PR gets
-the `need workflow approval` label and one comment telling the author that the
CI change needs a
-maintainer; see
+gate: its runs are approved whatever its size, cost or dependency changes,
unless it changes one of
+those CI-defining files. Such a PR gets the `need workflow approval` label and
one comment telling
+the author that the CI change needs a maintainer; see
[Approving gated
runs](08_fork_ci_for_external_contributors.md#approving-gated-runs).
Only runs created in the last 24 hours (`--max-run-age-hours`) are considered,
so the workflow never
diff --git a/dev/breeze/src/airflow_breeze/utils/workflow_run_approval.py
b/dev/breeze/src/airflow_breeze/utils/workflow_run_approval.py
index 5b0289d2e19..9592fef64cc 100644
--- a/dev/breeze/src/airflow_breeze/utils/workflow_run_approval.py
+++ b/dev/breeze/src/airflow_breeze/utils/workflow_run_approval.py
@@ -78,11 +78,6 @@ AUTO_APPROVABLE_BASE_BRANCH = "main"
MAX_ERROR_TEXT_LENGTH = 200
-# Changes here can change which runner a job uses (``runs-on:``,
``runner-type`` computed by
-# selective checks, the scripts build-info runs) or what the workflows do, so
they always need a
-# maintainer's look.
-CI_DEFINITION_PATH_PREFIXES = (".github/", "dev/breeze/", "scripts/ci/")
-
# Dependency manifests and lock files. Selective checks only switch to
dependency-upgrade mode for
# pyproject.toml, but a changed lock file or JS / Go / Java manifest also
changes what CI installs.
DEPENDENCY_FILE_PATTERN = re.compile(
@@ -156,10 +151,6 @@ def count_source_lines(changed_files: list[ChangedFile])
-> int:
return sum(file.changed_lines for file in changed_files if not
NON_SOURCE_FILE_PATTERN.search(file.path))
-def find_ci_definition_files(files: list[str]) -> list[str]:
- return [file for file in files if
file.startswith(CI_DEFINITION_PATH_PREFIXES)]
-
-
def find_dependency_files(files: list[str]) -> list[str]:
return [file for file in files if DEPENDENCY_FILE_PATTERN.search(file)]
@@ -248,7 +239,10 @@ def decide_approval(
estimate=estimate,
)
paths = [file.path for file in changed_files]
- ci_files = find_ci_definition_files(paths)
+ # CI definition files can change which runner a job uses (``runs-on:``,
``runner-type``
+ # computed by selective checks, the scripts build-info runs) or what the
jobs run, so they
+ # always need a maintainer's look.
+ ci_files = find_fork_ci_definition_files(paths)
if ci_files:
return ApprovalDecision(
approve=False,
diff --git a/dev/breeze/tests/test_workflow_run_approval.py
b/dev/breeze/tests/test_workflow_run_approval.py
index 6286cda6c39..2b46aa19802 100644
--- a/dev/breeze/tests/test_workflow_run_approval.py
+++ b/dev/breeze/tests/test_workflow_run_approval.py
@@ -133,6 +133,23 @@ def mock_estimate():
"CI definition files",
id="selective-checks-change",
),
+ *(
+ pytest.param(
+ [ChangedFile(path, 1)],
+ _selective_checks(),
+ 100,
+ False,
+ f"CI definition files: {path}",
+ id=f"fork-ci-defining-{path}",
+ )
+ for path in (
+ ".pre-commit-config.yaml",
+ "airflow-core/.pre-commit-config.yaml",
+ "Dockerfile.ci",
+ "scripts/docker/entrypoint_ci.sh",
+ "scripts/in_container/run_ci_tests.sh",
+ )
+ ),
pytest.param(
CORE_CHANGE,
_selective_checks(full_tests_needed=True),