* Auto-approve cheap CI runs of external contributors' PRs GitHub holds the workflow runs of fork PRs until a maintainer approves them. With self-hosted runners (AIP-118) the approval gate becomes part of the trust model, so it should cover all external contributors, but approving every push by hand does not scale and makes contributors wait. Runs whose change cannot touch the CI definition and whose CI is cheap are safe to start without a maintainer. Expensive or large changes, and anything that changes how CI or runners are chosen, still get a human look first, which also keeps the load on the shared public runners down. The CI-minutes estimate lets maintainers see what a run will cost before approving it. Generated-by: Claude Opus 5 * Add inline script metadata to the CI-minutes calibration script The script uses only the standard library, so with a PEP 723 block it runs with plain `uv run dev/calibrate_ci_minutes_estimates.py` instead of syncing the whole Breeze environment. Document that invocation in the script and in .github/AGENTS.md. * Keep one PR's API or git error from aborting the approval tick Each PR is now processed in its own try block. A requests.RequestException or subprocess.CalledProcessError for one PR no longer stops the remaining PRs or skips the job summary. The failed PR is recorded with failed=True and shown as "failed" in the summary, keeping its CI-time estimate when one was computed and giving a short, single-line form of the error as the reason. The workflow also tries to add the 'need workflow approval' label to it, so it is not lost once its runs leave the query window. Nothing is approved on failure. approve_workflow_runs exits 1 after writing the summary when any PR failed, so a persistent failure turns the scheduled run red instead of passing silently. * Approve the runs of fork CI pull requests unless they change CI A pull request whose CI runs in the contributor's fork (AIP-120) still gets pull_request runs in apache/airflow, and GitHub holds them until a maintainer approves them. Those runs only execute the fork CI gate, so judging them by the cost and size of project CI left cheap gate-only runs waiting for a maintainer for no benefit, and a gated run that never ran could not be cleaned up by the reconciler. What still needs a maintainer is a change to the files that define CI, since it could remove the gate or add a workflow that does run. Using the reconciler's own list keeps the two decisions consistent, and the author is told why their runs wait instead of only seeing a label. Generated-by: Claude Opus 5 * Keep CI-minutes estimates true to the runs they approve A run selects its tests from the labels the PR had when it started, so approving it on the current labels could start a full-tests run whose label was removed while it waited. Calibrating from self-hosted and all-versions runs, and leaving out the jobs that need no CI image, made the estimate describe runs other than those it is used to approve. Generated-by: Claude Opus 5 --------- Co-authored-by: Shahar Epstein <60007259+shahar1@users.noreply.github.com>
2.2 KiB
Table of Contents generated with DocToc
The .github folder — Agent Instructions
Keep the CI-minutes estimates in sync with the workflows
breeze ci approve-workflow-runs (run by workflows/auto-approve-workflow-runs.yml) decides whether
to approve an external contributor's CI runs from an estimate of the job-minutes they take. The
numbers live in dev/breeze/src/airflow_breeze/utils/ci_minutes_estimate.py and are medians
measured on recent Tests (AMD) PR runs on public runners.
After you change the CI workflows in a way that adds, removes, splits or resizes jobs (new test groups, a changed matrix, new composite workflows, a move between runner types), refresh the estimates once the change has run on enough PRs, and in any case about once a month:
- Run
uv run dev/calibrate_ci_minutes_estimates.py --since <date>from the repository root with an authenticatedghCLI. Pick a date that covers at least a week of runs after the workflow change. - Copy the medians and fits it prints into the constants of
ci_minutes_estimate.py, and update the "Last calibrated" line next to them. - When you add a new job group to the workflows, add a matching group to both
ci_minutes_estimate.py(with the selective-check output that turns it on) and theJOB_GROUPSpatterns of the calibration script. Unmatched jobs fall into the base group. - Run
uv run --project dev/breeze pytest dev/breeze/tests/test_ci_minutes_estimate.py dev/breeze/tests/test_workflow_run_approval.py -xvs.
The estimates cover public runners only. Self-hosted (RunsOn) runners need their own set once there is enough data from them.