ci: nightly failover and janitor exemptions cover delivery runs only
Summary
dep-fleet's ruling (#27521) says: never cancel a started nightly, DEV or promote build. It protects delivery runs, meaning runs that publish, sign, roll back or file things. It never meant that a pull request's test run of a post-publish check can't fail over. Three exemptions read it by workflow path or name instead, so the pull request runs of nightly-next-canary.yml and nightly-next-launch-smoke.yml (both trigger on pull_request for edits to themselves) were covered too:
owned_pool_rescue.never_fails_over()exempted every path inNEVER_FAILOVER_PATHSand any file name containing "nightly", so the open-head failover never moved a pull request run of the canary or launch smoke off a dead label.queue_janitor.PROTECTED_WORKFLOWmatched "nightly" in the run name or path, so the sweep left every canary and smoke run alone, pull request runs included.queue_janitor.reserves_pool()(#28364) matched delivery workflows by path only, so queued pull request jobs of the canary and smoke counted asreserved_queued. The 14:16Z snapshot showedreserved_queued: 8onglaeda-side-std-xcode-26.6.
One shared predicate fixes all three: delivery_workflows.delivers(path, event, *names). It is true for a delivery workflow's run (is_delivery_run(), unchanged) from any event except a pull request's (pull_request, pull_request_target, merge_group). An unread event still counts as a delivery event, so a run whose event we can't read keeps its protection.
- Rescue:
Targetnow records the run's event.never_fails_over(path, event)is true only for a delivery run: a run of aNEVER_FAILOVER_PATHSworkflow or any delivery workflow, from an event that can deliver. Runs ofnightly.yml, DEV daily,release.yml, sign, train, rollback, verdict and feed-watch keep their exemption. Most of those never have a pull request run anyway, and the failover already skips non-PR targets. - Janitor:
protected_reason()drops the "nightly" match only for a pull request run of a delivery workflow. Release, publish, notarization, TestFlight and App Store names still protect it.orphan_protected_reason()andreserves_pool()usedelivers().
Nothing changes for scheduled, dispatched or pushed runs, nightly-branch runs included: they stay protected and reserved. A started nightly delivery build is still never cancelled.
The diff is small and touches never_fails_over() and the Target constructors only. #28249 (feat-cmux-next) does not touch those lines.
Testing
Red on base (0368f4e1, tests only on top of 7ca718f7), green on head:
python3 tests/test_delivery_workflows_cancel.py,DeliveryRunTests. Base: 32 errors (deliversmissing). Head: OK (29 tests).python3 tests/test_ci_owned_pool_rescue.py, three tests. A pull request run of the canary or smoke is not excluded. A PR run of the canary or smoke on a dead label is cancelled and re-run. Every delivery run (schedule, dispatch, push, workflow_run, unread event) is still excluded. Base: 2 failures ('cancel' not found in ['pull', 'run']) and 2 errors. Head: OK (403 tests).python3 tests/test_ci_queue_janitor.py,DeliveryRunScopeTests. A PR run of the canary or smoke is unprotected, classifiedstale-prwhen its PR is closed, kept at its open head, and reserves 0. Scheduled, main and nightly-next dispatch runs and a nightly-next push ofnightly.ymlstay protected and reserve 1. Base: 2 failures ('release/nightly/TestFlight/App Store workflow' is not None). Head: OK (253 tests).
Observed / Not run
- Observed: the three files above, plus every other
tests/*.pythat importsqueue_janitor,owned_pool_rescueordelivery_workflows(health report, owned pool sources, late placement, pool pickers, starved labels, nightly delivery concurrency, nightly-next feed watch and cancelled tip, run_e2e, app-host product reuse), all pass on head. - Not run: a live sweep. The janitor and rescue run from main's copy on their next schedule.
Changelog
none
Agent session: agent session
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Limits the nightly failover exemption and janitor protection to delivery runs, so a pull request's test run of the nightly canary or launch smoke workflow is treated like any ordinary PR run.
Adds delivery_workflows.delivers(), true for a delivery workflow's run from any event except a pull request's (pull_request, pull_request_target, merge_group). An unread event still counts as a delivery one, so protection stays when the event can't be read. The rescue's never_fails_over(), the janitor's protected_reason()/orphan_protected_reason(), and reserves_pool() all use it.
- Before, exemptions matched "nightly" by workflow path or name, covering PR runs of
nightly-next-canary.ymlandnightly-next-launch-smoke.yml; those runs publish, sign, roll back and file nothing, so dep-fleet's ruling (#27521) never protected them. - Scheduled, dispatched, pushed and unread-event delivery runs stay protected and reserved; started nightly builds remain uncancelled.
Summary by CodeRabbit
- Bug Fixes
- Pull request, pull request target, and merge-group runs of delivery workflows are now handled as test runs rather than delivery runs. These runs can follow the usual stale pull request and failover behavior.
- Scheduled, manually started, pushed, and workflow-triggered delivery runs retain their protection and queue reservations.
- Delivery-run handling now accounts for the triggering event and run details, avoiding incorrect protection based only on a workflow’s name.