potiuk commented on code in PR #74889:
URL: https://github.com/apache/airflow/pull/74889#discussion_r4354004314


##########
dev/breeze/src/airflow_breeze/utils/selective_checks.py:
##########
@@ -2127,6 +2130,119 @@ def amd_runners(self) -> str:
     def arm_runners(self) -> str:
         return PUBLIC_ARM_RUNNERS
 
+    @cached_property
+    def runner_type(self) -> str:
+        """Runner labels for the jobs of a CI run on this run's platform.
+
+        The RunsOn label is a template the jobs fill in with their size class.
+        """
+        # RunsOn needs the run id in the label; without one (e.g. a local run) 
the jobs would never start.
+        run_id = self._github_context_dict.get("run_id")
+        if not run_id or not self._use_runs_on_runners():
+            return PUBLIC_ARM_RUNNERS if self._platform == CI_ARM_PLATFORM 
else PUBLIC_AMD_RUNNERS
+        template = (
+            RUNS_ON_ARM_RUNNER_TEMPLATE if self._platform == CI_ARM_PLATFORM 
else RUNS_ON_AMD_RUNNER_TEMPLATE
+        )
+        return json.dumps([template.format(run_id=run_id)])
+
+    def _use_runs_on_runners(self) -> bool:
+        """Whether this run should use the self-hosted RunsOn runners.
+
+        This only routes runs; it does not keep fork code off RunsOn. A 
``pull_request`` run uses
+        the PR's own workflow files and breeze, so a fork can request a RunsOn 
label directly -
+        that restriction has to be enforced by the RunsOn stack and the 
repository's Actions
+        settings, not here. Routed there: pushes, schedules and dispatches, 
and PRs from
+        apache/airflow branches except bots' (e.g. Dependabot's). A fork PR 
goes there while it
+        carries the ``use self-hosted runners`` label, a committer has 
approved its head commit and
+        no committer's request for changes is outstanding.
+        The repository variable ``USE_PUBLIC_RUNNERS=true`` moves every run 
back to public runners.
+        """
+        if self._github_repository != APACHE_AIRFLOW_GITHUB_REPOSITORY:
+            return False
+        if os.environ.get("USE_PUBLIC_RUNNERS", "").casefold() == "true":
+            return False
+        if USE_PUBLIC_RUNNERS_LABEL in self._pr_labels:
+            return False
+        if self._github_event in [GithubEvents.PUSH, GithubEvents.SCHEDULE, 
GithubEvents.WORKFLOW_DISPATCH]:
+            return True
+        if self._github_event != GithubEvents.PULL_REQUEST:
+            return False
+        if USE_SELF_HOSTED_RUNNERS_LABEL in self._pr_labels and 
self._is_self_hosted_label_approved():
+            return True
+        if NON_COMMITTER_BUILD_LABEL in self._pr_labels:
+            return False
+        pull_request = self._github_context_dict.get("event", 
{}).get("pull_request", {})
+        # The PR author, not github.actor: a committer rebasing a Dependabot 
PR becomes the actor.
+        # The branch too: anyone can open their own PR from a Dependabot 
branch.
+        if (pull_request.get("user") or {}).get("type") == "Bot" or (
+            pull_request.get("head", {}).get("ref", 
"").startswith("dependabot/")
+        ):
+            return False
+        # A PR from a deleted fork has no head repo.
+        head_repo = (pull_request.get("head", {}).get("repo") or 
{}).get("full_name")
+        return head_repo == APACHE_AIRFLOW_GITHUB_REPOSITORY
+
+    def _is_self_hosted_label_approved(self) -> bool:
+        """Whether the PR still has the label, a committer approved its head 
commit and no committer's veto stands.
+
+        A re-run reuses the labels of its original event, so a later removal 
only shows in the PR
+        itself. The label outlives the commit it was added for, so on its own 
it would vouch for
+        every later push. A request for changes stays in force across pushes, 
as on GitHub, until
+        that committer reviews again or it is dismissed. Any failure to tell 
counts as "no".
+        """
+        # Lazy: breeze keeps its top-level imports minimal 
(check-breeze-top-dependencies-limited).
+        import requests
+
+        pull_request = self._github_context_dict.get("event", 
{}).get("pull_request", {})
+        head_sha = pull_request.get("head", {}).get("sha")
+        if not head_sha:
+            return False
+        pull_request_url = (
+            
f"https://api.github.com/repos/{self._github_repository}/pulls/{pull_request.get('number')}"
+        )
+        headers = {"Accept": "application/vnd.github+json"}
+        if token := os.environ.get("GITHUB_TOKEN"):
+            headers["Authorization"] = f"Bearer {token}"
+        # Each reviewer's latest verdict, on the head commit and on any 
commit; a dismissed review is
+        # listed as DISMISSED in place, and comment-only reviews change 
nothing.
+        latest_on_head: dict[str, str] = {}
+        latest_overall: dict[str, str] = {}
+        try:
+            response = requests.get(pull_request_url, headers=headers, 
timeout=30)
+            response.raise_for_status()
+            if USE_SELF_HOSTED_RUNNERS_LABEL not in {label["name"] for label 
in response.json()["labels"]}:
+                console_print(
+                    f"[warning]Ignoring the {USE_SELF_HOSTED_RUNNERS_LABEL!r} 
label: the PR no longer has it"
+                )
+                return False
+            url: str | None = f"{pull_request_url}/reviews?per_page=100"
+            while url:
+                response = requests.get(url, headers=headers, timeout=30)
+                response.raise_for_status()
+                for review in response.json():
+                    if review.get("state") not in {"APPROVED", 
"CHANGES_REQUESTED", "DISMISSED"}:
+                        continue
+                    login = ((review.get("user") or {}).get("login") or 
"").casefold()
+                    latest_overall[login] = review["state"]
+                    if review.get("commit_id") == head_sha:
+                        latest_on_head[login] = review["state"]
+                url = response.links.get("next", {}).get("url")
+        # AttributeError / KeyError / TypeError: a 200 whose body is not the 
expected PR or list of reviews.
+        except (requests.RequestException, AttributeError, KeyError, 
TypeError) as e:

Review Comment:
   Good: with `KeyError` added, a 200 that is not a PR object (e.g. 
`{"message": "Not Found"}`) counts as "no" instead of raising.



##########
dev/breeze/src/airflow_breeze/utils/selective_checks.py:
##########
@@ -2127,6 +2130,119 @@ def amd_runners(self) -> str:
     def arm_runners(self) -> str:
         return PUBLIC_ARM_RUNNERS
 
+    @cached_property
+    def runner_type(self) -> str:
+        """Runner labels for the jobs of a CI run on this run's platform.
+
+        The RunsOn label is a template the jobs fill in with their size class.
+        """
+        # RunsOn needs the run id in the label; without one (e.g. a local run) 
the jobs would never start.
+        run_id = self._github_context_dict.get("run_id")
+        if not run_id or not self._use_runs_on_runners():
+            return PUBLIC_ARM_RUNNERS if self._platform == CI_ARM_PLATFORM 
else PUBLIC_AMD_RUNNERS
+        template = (
+            RUNS_ON_ARM_RUNNER_TEMPLATE if self._platform == CI_ARM_PLATFORM 
else RUNS_ON_AMD_RUNNER_TEMPLATE
+        )
+        return json.dumps([template.format(run_id=run_id)])
+
+    def _use_runs_on_runners(self) -> bool:
+        """Whether this run should use the self-hosted RunsOn runners.
+
+        This only routes runs; it does not keep fork code off RunsOn. A 
``pull_request`` run uses
+        the PR's own workflow files and breeze, so a fork can request a RunsOn 
label directly -
+        that restriction has to be enforced by the RunsOn stack and the 
repository's Actions
+        settings, not here. Routed there: pushes, schedules and dispatches, 
and PRs from
+        apache/airflow branches except bots' (e.g. Dependabot's). A fork PR 
goes there while it
+        carries the ``use self-hosted runners`` label, a committer has 
approved its head commit and
+        no committer's request for changes is outstanding.
+        The repository variable ``USE_PUBLIC_RUNNERS=true`` moves every run 
back to public runners.
+        """
+        if self._github_repository != APACHE_AIRFLOW_GITHUB_REPOSITORY:
+            return False
+        if os.environ.get("USE_PUBLIC_RUNNERS", "").casefold() == "true":
+            return False
+        if USE_PUBLIC_RUNNERS_LABEL in self._pr_labels:
+            return False
+        if self._github_event in [GithubEvents.PUSH, GithubEvents.SCHEDULE, 
GithubEvents.WORKFLOW_DISPATCH]:
+            return True
+        if self._github_event != GithubEvents.PULL_REQUEST:
+            return False
+        if USE_SELF_HOSTED_RUNNERS_LABEL in self._pr_labels and 
self._is_self_hosted_label_approved():
+            return True
+        if NON_COMMITTER_BUILD_LABEL in self._pr_labels:
+            return False
+        pull_request = self._github_context_dict.get("event", 
{}).get("pull_request", {})
+        # The PR author, not github.actor: a committer rebasing a Dependabot 
PR becomes the actor.
+        # The branch too: anyone can open their own PR from a Dependabot 
branch.
+        if (pull_request.get("user") or {}).get("type") == "Bot" or (
+            pull_request.get("head", {}).get("ref", 
"").startswith("dependabot/")
+        ):
+            return False
+        # A PR from a deleted fork has no head repo.
+        head_repo = (pull_request.get("head", {}).get("repo") or 
{}).get("full_name")
+        return head_repo == APACHE_AIRFLOW_GITHUB_REPOSITORY
+
+    def _is_self_hosted_label_approved(self) -> bool:
+        """Whether the PR still has the label, a committer approved its head 
commit and no committer's veto stands.
+
+        A re-run reuses the labels of its original event, so a later removal 
only shows in the PR
+        itself. The label outlives the commit it was added for, so on its own 
it would vouch for
+        every later push. A request for changes stays in force across pushes, 
as on GitHub, until
+        that committer reviews again or it is dismissed. Any failure to tell 
counts as "no".
+        """
+        # Lazy: breeze keeps its top-level imports minimal 
(check-breeze-top-dependencies-limited).
+        import requests
+
+        pull_request = self._github_context_dict.get("event", 
{}).get("pull_request", {})
+        head_sha = pull_request.get("head", {}).get("sha")
+        if not head_sha:
+            return False
+        pull_request_url = (
+            
f"https://api.github.com/repos/{self._github_repository}/pulls/{pull_request.get('number')}"
+        )
+        headers = {"Accept": "application/vnd.github+json"}
+        if token := os.environ.get("GITHUB_TOKEN"):
+            headers["Authorization"] = f"Bearer {token}"
+        # Each reviewer's latest verdict, on the head commit and on any 
commit; a dismissed review is
+        # listed as DISMISSED in place, and comment-only reviews change 
nothing.
+        latest_on_head: dict[str, str] = {}
+        latest_overall: dict[str, str] = {}
+        try:
+            response = requests.get(pull_request_url, headers=headers, 
timeout=30)
+            response.raise_for_status()
+            if USE_SELF_HOSTED_RUNNERS_LABEL not in {label["name"] for label 
in response.json()["labels"]}:

Review Comment:
   This fixes the re-run regression from the last round: a re-run still carries 
`use self-hosted runners` in the event payload, and this check against the PR's 
current labels now sends it back to public runners once a committer has removed 
the label.



##########
dev/breeze/tests/test_selective_checks.py:
##########
@@ -4752,3 +4754,412 @@ def 
test_providers_with_test_side_effects_are_shared_process_providers():
     for provider in PROVIDERS_WITH_PROCESS_GLOBAL_TEST_SIDE_EFFECTS:
         assert provider in get_available_distributions()
         assert provider not in LONG_RUNNING_TEST_PROVIDERS
+
+
+RUNS_ON_AMD = 
'["runs-on=42/family=m7a+m7i+m6a+m6i/image=ubuntu22-full-x64/volume=150gb/cpu={0}/ram={1}"]'
+RUNS_ON_ARM = 
'["runs-on=42/family=m8g+m7g+m6g/image=ubuntu22-full-arm64/volume=150gb/cpu={0}/ram={1}"]'
+
+
+HEAD_SHA = "a" * 40
+
+
[email protected](autouse=True)
+def _no_use_public_runners_variable(monkeypatch):
+    monkeypatch.delenv("USE_PUBLIC_RUNNERS", raising=False)
+
+
+def _pull_request_context(head_repo: str | None, author_type: str = "User") -> 
dict[str, Any]:
+    head = {"repo": {"full_name": head_repo} if head_repo else None, "sha": 
HEAD_SHA}
+    return {
+        "run_id": 42,
+        "event": {"pull_request": {"number": 7, "head": head, "user": {"type": 
author_type}}},
+    }
+
+
[email protected](
+    ("github_event", "github_repository", "github_context_dict", "pr_labels", 
"platform", "expected"),
+    [
+        pytest.param(
+            GithubEvents.PUSH,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_AMD_PLATFORM,
+            RUNS_ON_AMD,
+            id="canary push uses RunsOn",
+        ),
+        pytest.param(
+            GithubEvents.SCHEDULE,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_ARM_PLATFORM,
+            RUNS_ON_ARM,
+            id="scheduled ARM canary uses ARM RunsOn",
+        ),
+        pytest.param(
+            GithubEvents.WORKFLOW_DISPATCH,
+            "apache/airflow",
+            {"run_id": 42},
+            (),
+            CI_AMD_PLATFORM,
+            RUNS_ON_AMD,
+            id="workflow_dispatch uses RunsOn",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("apache/airflow", author_type="Bot"),
+            (),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="bot PR from an apache/airflow branch uses public runners",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            {
+                "run_id": 42,
+                "event": {
+                    "pull_request": {
+                        "head": {"ref": "dependabot/uv/foo", "repo": 
{"full_name": "apache/airflow"}},
+                        "user": {"type": "User"},
+                    }
+                },
+            },
+            (),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="user PR from a Dependabot branch uses public runners",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("apache/airflow", author_type="Bot"),
+            ("use self-hosted runners", "non committer build"),
+            CI_AMD_PLATFORM,
+            RUNS_ON_AMD,
+            id="committer's self-hosted label wins over bot author and non 
committer build",
+        ),
+        pytest.param(
+            GithubEvents.PUSH,
+            "apache/airflow",
+            {},
+            (),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="push without a run id stays on public runners",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("someone/airflow"),
+            ("use self-hosted runners", "use public runners"),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="public runners label wins over the self-hosted label",
+        ),
+        pytest.param(
+            GithubEvents.PUSH,
+            "someone/airflow",
+            {"run_id": 42},
+            (),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="push in a fork repository stays on public runners",
+        ),
+        pytest.param(
+            GithubEvents.SCHEDULE,
+            "someone/airflow",
+            {"run_id": 42},
+            (),
+            CI_ARM_PLATFORM,
+            '["ubuntu-22.04-arm"]',
+            id="schedule in a fork repository stays on public ARM runners",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("apache/airflow"),
+            (),
+            CI_AMD_PLATFORM,
+            RUNS_ON_AMD,
+            id="PR from an apache/airflow branch uses RunsOn",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("someone/airflow"),
+            (),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="PR from a fork uses public runners",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context(None),
+            (),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="PR from a deleted fork uses public runners",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("someone/airflow"),
+            ("use self-hosted runners",),
+            CI_AMD_PLATFORM,
+            RUNS_ON_AMD,
+            id="PR from a fork with the self-hosted label uses RunsOn",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("someone/airflow"),
+            ("canary", "full tests needed"),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="canary label does not route a fork PR to RunsOn",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("apache/airflow"),
+            ("use public runners",),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="public runners label opts an apache/airflow PR out",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST,
+            "apache/airflow",
+            _pull_request_context("apache/airflow"),
+            ("non committer build",),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="non committer build label treats an apache/airflow PR as a 
fork PR",
+        ),
+        pytest.param(
+            GithubEvents.PULL_REQUEST_TARGET,
+            "apache/airflow",
+            _pull_request_context("someone/airflow"),
+            (),
+            CI_AMD_PLATFORM,
+            '["ubuntu-22.04"]',
+            id="pull_request_target uses public runners",
+        ),
+    ],
+)
[email protected](SelectiveChecks, "_is_self_hosted_label_approved", 
autospec=True, return_value=True)
+def test_runner_type(
+    _mock_is_self_hosted_label_approved,
+    github_event: GithubEvents,
+    github_repository: str,
+    github_context_dict: dict[str, Any],
+    pr_labels: tuple[str, ...],
+    platform: str,
+    expected: str,
+):
+    selective_checks = SelectiveChecks(
+        github_event=github_event,
+        github_repository=github_repository,
+        github_context_dict=github_context_dict,
+        pr_labels=pr_labels,
+        platform=platform,
+    )
+    assert selective_checks.runner_type == expected
+
+
[email protected](
+    ("value", "expected"),
+    [
+        pytest.param("true", '["ubuntu-22.04"]', id="true moves a push to 
public runners"),
+        pytest.param("True", '["ubuntu-22.04"]', id="case does not matter"),
+        pytest.param("false", RUNS_ON_AMD, id="false keeps RunsOn"),
+        pytest.param("", RUNS_ON_AMD, id="an unset variable keeps RunsOn"),
+    ],
+)
+def test_use_public_runners_variable(monkeypatch, value: str, expected: str):
+    monkeypatch.setenv("USE_PUBLIC_RUNNERS", value)
+    selective_checks = SelectiveChecks(
+        github_event=GithubEvents.PUSH, github_repository="apache/airflow", 
github_context_dict={"run_id": 42}
+    )
+    assert selective_checks.runner_type == expected
+
+
[email protected](SelectiveChecks, "_is_self_hosted_label_approved", 
autospec=True, return_value=True)
+def test_use_public_runners_variable_beats_the_self_hosted_label(
+    _mock_is_self_hosted_label_approved, monkeypatch
+):
+    monkeypatch.setenv("USE_PUBLIC_RUNNERS", "true")
+    selective_checks = SelectiveChecks(
+        github_event=GithubEvents.PULL_REQUEST,
+        github_repository="apache/airflow",
+        github_context_dict=_pull_request_context("apache/airflow"),
+        pr_labels=("use self-hosted runners",),
+    )
+    assert selective_checks.runner_type == '["ubuntu-22.04"]'
+
+
+def _review(login: str, state: str, commit_id: str = HEAD_SHA) -> dict[str, 
Any]:
+    return {"user": {"login": login}, "state": state, "commit_id": commit_id}
+
+
[email protected](
+    ("pages", "expected"),
+    [
+        pytest.param([[_review(COMMITTERS[0], "APPROVED")]], True, 
id="approved by a committer"),
+        pytest.param(
+            [[_review(COMMITTERS[0].swapcase(), "APPROVED")]],
+            True,
+            id="approved by a committer whose login differs in case",
+        ),
+        pytest.param([[_review("a-triager", "APPROVED")]], False, id="approved 
by a non-committer"),
+        pytest.param(
+            [[_review(COMMITTERS[0], "APPROVED", commit_id="b" * 40)]],
+            False,
+            id="approved an earlier commit only",
+        ),
+        pytest.param(
+            [[_review(COMMITTERS[0], "APPROVED"), _review(COMMITTERS[0], 
"CHANGES_REQUESTED")]],
+            False,
+            id="changes requested after approving",
+        ),
+        pytest.param(
+            [[_review(COMMITTERS[0], "CHANGES_REQUESTED"), 
_review(COMMITTERS[0], "APPROVED")]],
+            True,
+            id="approved after requesting changes",
+        ),
+        pytest.param(
+            [[_review(COMMITTERS[0], "APPROVED"), _review(COMMITTERS[0], 
"DISMISSED")]],
+            False,
+            id="approval dismissed",
+        ),
+        pytest.param(
+            [[_review(COMMITTERS[0], "APPROVED"), _review(COMMITTERS[0], 
"COMMENTED")]],
+            True,
+            id="a later comment keeps the approval",
+        ),
+        pytest.param(
+            [[_review("a-triager", "APPROVED")], [_review(COMMITTERS[0], 
"APPROVED")]],
+            True,
+            id="approved on a later page",
+        ),
+        pytest.param(
+            [[_review(COMMITTERS[0], "APPROVED"), _review(COMMITTERS[1], 
"CHANGES_REQUESTED")]],
+            False,
+            id="another committer's request for changes vetoes an approval",
+        ),
+        pytest.param(
+            [[_review(COMMITTERS[0], "APPROVED"), _review("a-triager", 
"CHANGES_REQUESTED")]],
+            True,
+            id="a non-committer's request for changes does not veto",
+        ),
+        pytest.param(
+            [
+                [
+                    _review(COMMITTERS[1], "CHANGES_REQUESTED", commit_id="b" 
* 40),
+                    _review(COMMITTERS[0], "APPROVED"),
+                ]
+            ],
+            False,
+            id="a committer's request for changes on an earlier commit still 
vetoes",
+        ),
+        pytest.param(
+            [
+                [
+                    _review(COMMITTERS[1], "CHANGES_REQUESTED", commit_id="b" 
* 40),
+                    _review(COMMITTERS[1], "APPROVED", commit_id="b" * 40),
+                    _review(COMMITTERS[0], "APPROVED"),
+                ]
+            ],
+            True,
+            id="a request for changes withdrawn by its committer's later 
approval does not veto",
+        ),
+        pytest.param([[]], False, id="no review"),
+        pytest.param([{"message": "Not Found"}], False, id="error object 
instead of reviews"),
+    ],
+)
+@patch("requests.get", autospec=True)
+def test_is_self_hosted_label_approved(mock_get, pages: list[list[dict[str, 
Any]]], expected: bool):
+    pull_request = Mock(spec=requests.Response)
+    pull_request.json.return_value = {"labels": [{"name": "use self-hosted 
runners"}]}
+    responses = [pull_request]
+    for index, page in enumerate(pages):
+        response = Mock(spec=requests.Response)
+        response.json.return_value = page
+        response.links = {"next": {"url": f"page-{index + 1}"}} if index + 1 < 
len(pages) else {}
+        responses.append(response)
+    mock_get.side_effect = responses
+    selective_checks = SelectiveChecks(
+        github_context_dict=_pull_request_context("someone/airflow"),
+        pr_labels=("use self-hosted runners",),
+    )
+    assert selective_checks._is_self_hosted_label_approved() is expected
+    assert [call.args[0] for call in mock_get.call_args_list[:2]] == [
+        "https://api.github.com/repos/apache/airflow/pulls/7";,
+        
"https://api.github.com/repos/apache/airflow/pulls/7/reviews?per_page=100";,
+    ]
+
+
[email protected](
+    "pull_request_body",
+    [
+        pytest.param({"labels": [{"name": "full tests needed"}]}, id="label 
removed since the event"),
+        pytest.param({"message": "Not Found"}, id="error object instead of the 
PR"),
+    ],
+)
+@patch("requests.get", autospec=True)
+def test_is_self_hosted_label_approved_needs_the_current_label(mock_get, 
pull_request_body: dict[str, Any]):

Review Comment:
   Nice that `assert_called_once()` also pins that the reviews are not fetched 
once the label check has failed.



##########
dev/breeze/doc/ci/04_selective_checks.md:
##########
@@ -666,32 +667,87 @@ GitHub Actions to pass the list of parameters to a 
command to execute
 | upgrade-to-newer-dependencies                           | Whether the image 
build should attempt to upgrade all dependencies (true/false or commit hash)    
      | false                                    |      |
 
 
-## Committer vs. Non-committer PRs
-
-There is a difference in how the CI jobs are run for committer and 
non-committer PRs from forks.
-The main reason is security; we do not want to run untrusted code on our 
infrastructure for self-hosted runners.
-
-Currently there is no difference because we are not using `self-hosted` 
runners (until we implement `Action
-Runner Controller` but most of the jobs, committer builds will use 
"Self-hosted" runners by default,
-while non-committer builds will use "Public" runners. For committers, this can 
be overridden by setting the
-`use public runners` label in the PR.
+## Self-hosted (RunsOn) vs. public runners
+
+The `Tests (AMD)` / `Tests (ARM)` jobs run either on GitHub-hosted ("public") 
runners or on self-hosted
+[RunsOn](https://runs-on.com) EC2 runners in the Airflow AWS account. 
Selective checks route runs of
+code from `apache/airflow` itself there; this is a routing preference, not 
what keeps fork code off
+RunsOn (see below). The `runner-type` output is decided as follows, first 
match wins:
+
+1. Runs in any repository other than `apache/airflow` (forks running their own 
CI) use public runners.
+2. Any run uses public runners while the repository variable 
`USE_PUBLIC_RUNNERS` is `true`: the
+   switch for moving `main` off RunsOn without a PR, e.g. when the stack is 
unavailable.
+3. PRs with the `use public runners` label use public runners.
+4. Any `push`, `schedule` or `workflow_dispatch` in `apache/airflow` (canary 
runs and the release
+   branch pushes, all triggered by people with write access) uses RunsOn.
+5. Other events than `pull_request` use public runners.
+6. PRs with the `use self-hosted runners` label use RunsOn, if a committer's 
(`COMMITTERS` in
+   `global_constants.py`) latest review of the PR's head commit is an approval 
and no committer's
+   request for changes stands. The label outlives the commit it was added for, 
so on its own it would
+   vouch for every later push: a new push sends the PR back to public runners 
until the head commit is
+   approved again, and so does a dismissed approval if no other committer's 
approval of the head commit
+   remains. A committer's request for changes keeps the PR on public runners 
across pushes, as it blocks
+   a merge on GitHub, until that committer reviews again or the review is 
dismissed. The label must
+   also still be on the PR: a re-run reuses the labels of its original event, 
so they are checked

Review Comment:
   Matches the code. (The PR description's *Which runs go where* paragraph 
could get the same clause; see the review body.)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to