Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ name: Tests
on:
push:
branches: [main]
# Pull requests into any base branch: a stacked pull request targets
# another pull request's branch and needs the same jobs.
pull_request:
branches: [main]

# Cancel outdated PR runs; give each main push its own independent group.
concurrency:
Expand Down
1 change: 1 addition & 0 deletions changelog.d/1321-ci-pull-requests-into-any-base.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The Tests workflow (`.github/workflows/test.yml`) now runs for pull requests into any base branch, not only `main` (microcosm#1321). A stacked pull request, whose base is another pull request's branch, previously got no CI at all. Pushes still run it only for `main`, and the jobs, the country selection, the concurrency group and the secrets are unchanged.
8 changes: 7 additions & 1 deletion docs/agent-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ or `uv sync --all-packages --all-extras`. To keep both countries set up, point

PR CI (`.github/workflows/test.yml`) has `lint`, `engine-free`, `engine-us`,
`engine-uk`, `integration-uk`, and `wheels` jobs, plus the
`select-countries` orchestration job.
`select-countries` orchestration job. It runs for pull requests into any base
branch, so a stacked pull request, whose base is another pull request's
branch, gets the same jobs; pushes run it only for `main`. That costs runner
time: every push to a pull request's branch, whatever its base, runs the full
workflow on the organization's shared runners, with the jobs and country
selection a pull request into `main` would get. Merging one change up a stack
of N pull requests therefore starts N full runs.
`tools/ci_test_plan.py` is the only authority for test-directory ownership, CI
job assignment, country ownership, US timing-report categories, and
changed-path country selection. Its `TEST_GROUPS` registry defines every valid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from __future__ import annotations

from typing import Any

import yaml

from test_support.paths import paths_for
Expand Down Expand Up @@ -71,6 +73,30 @@ def test_integration_job_is_uk_selected_and_read_only() -> None:
assert "run: bash tools/run_integration_tests.sh" in integration


def _workflow_triggers() -> dict[str, Any]:
workflow = yaml.safe_load(_TEST_WORKFLOW.read_text(encoding="utf-8"))
# PyYAML follows YAML 1.1, which reads the bare key ``on`` as boolean true.
return workflow[True]


def test_pull_requests_into_any_base_branch_run_the_tests_workflow() -> None:
"""A stacked pull request targets another pull request's branch, not main,
and must get the same jobs.

GitHub matches ``branches`` and ``branches-ignore`` entries as glob
patterns, so checking particular branch names against them proves nothing
about other bases. The trigger must have no base-branch filter at all.
"""
pull_request_trigger = _workflow_triggers()["pull_request"] or {}

base_branch_filters = {"branches", "branches-ignore"} & pull_request_trigger.keys()
assert sorted(base_branch_filters) == []


def test_only_pushes_to_main_run_the_tests_workflow() -> None:
assert _workflow_triggers()["push"] == {"branches": ["main"]}


def test_every_workflow_job_caps_its_runtime() -> None:
"""A hung job must not hold an org-shared runner for GitHub's 6-hour default."""
jobs = yaml.safe_load(_TEST_WORKFLOW.read_text(encoding="utf-8"))["jobs"]
Expand Down
Loading