Skip to content
Merged
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
10 changes: 10 additions & 0 deletions .changes/pr-pipeline/perf-main-whole-suite-batching-9548bbe5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
bump: patch
---

### Changed

- pr-merge starts at most one full run of main per 30 minutes, of main's tip, covering every merge since the last. dispatch-full-run and post-merge-dispatch read the newest pr-require-checks.yml dispatches on main first (`Read main's full-run cover`): within the cap they start nothing, and post-merge-dispatch starts one on its next scheduled run for a tip no full run covers, whoever merged, while the lane is live (kill switch and report-only off). A read of the cover refused for a rate limit stops the job red and sends nothing more (`.github/workflows/pr-merge.yml`).
- dispatch-full-run ends once it dispatches, where it held a runner up to 39 minutes polling the run; its timeout drops from 45 to 10 minutes. post-merge-dispatch now sends a red full run to post-merge-demotion-alert.yml on its next scheduled run while the lane is live (kill switch and report-only off), up to 15 minutes after the run ends, once per run (`pr-merge-alerted-<id>`, counted only when its own run on main uploaded it, by `babysit_postmerge.py --lane-alerted`), and skips a run that never started.
- pr-require-checks.yml's dispatches on main (attempt 1) share one concurrency group with no `queue` key and `cancel-in-progress` false: one runs, one waits, and a newer one replaces the waiting one. A re-run and every other run keep their own group and cancel.
- post-merge-demotion-alert.yml files nothing for a cancelled full run with no job, one the concurrency group replaced before it started.
11 changes: 11 additions & 0 deletions .changes/source-control/perf-main-whole-suite-batching-3c4daaf0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
bump: patch
---

### Fixed

- The post-merge check (`babysit_postmerge.py`) skips a full run cancelled with no job on attempt 1, one pr-require-checks.yml's main-dispatch concurrency group replaced before it started: it no longer holds a merge as attribution-pending, asks for its re-run, or serves as the baseline of a later red run. A run cancelled after its jobs started still reads red.

### Added

- `babysit_postmerge.py --lane-alerted RUN_ID --branch <branch>` exits 0 when pr-merge.yml's post-merge-dispatch on the branch already sent that full run to post-merge-demotion-alert.yml, 4 when not, 3 when unreadable; 4 is a code no crash produces, and pr-merge.yml sends only on it. It counts the `pr-merge-alerted-<id>` record only from a sender the dispatch and re-run records' rule accepts (`_lane_sender`), so a same-name artifact from any other run is no record.
440 changes: 436 additions & 4 deletions .github/scripts/pr-merge/merge-job.test.mjs

Large diffs are not rendered by default.

379 changes: 230 additions & 149 deletions .github/scripts/pr-merge/workflow.test.mjs

Large diffs are not rendered by default.

24 changes: 17 additions & 7 deletions .github/workflows/post-merge-demotion-alert.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ name: post-merge-demotion-alert
# second intake dispatch. The record keeps needs-human, and closing a fix issue
# changes nothing on it.
#
# A full run pr-merge.yml starts after each merge uses GITHUB_TOKEN, so its
# completion raises no workflow_run event. pr-merge's dispatch-full-run job
# sends a red one here through workflow_dispatch with its run id and head SHA
# instead; the first step reads that run and refuses anything but a red
# A full run pr-merge.yml starts for main's merges uses GITHUB_TOKEN, so its
# completion raises no workflow_run event. pr-merge's post-merge-dispatch job
# sends a red one here on its next scheduled run, through workflow_dispatch
# with its run id and head SHA, instead; the first step reads that run and refuses anything but a red
# pr-require-checks run on this repository's main that github-actions[bot]
# dispatched, at that head SHA. Red is
# any conclusion in babysit_postmerge.py's FAILED_CONCLUSIONS. A red run
Expand Down Expand Up @@ -76,7 +76,7 @@ on:
workflows: [pr-require-checks, post-merge-detect-silent-revert]
types: [completed]
branches: [main]
# pr-merge.yml's dispatch-full-run job, with GITHUB_TOKEN, or a listed
# pr-merge.yml's post-merge-dispatch job, with GITHUB_TOKEN, or a listed
# human (trusted-actors.json on main) names a red full run that raised no
# workflow_run event. Both inputs are checked before use, and the head SHA
# must be the run's own.
Expand Down Expand Up @@ -287,8 +287,11 @@ jobs:
exit 0
;;
esac
# Neither signal's runs are cancelled by concurrency, so a cancel
# comes from an actor with actions: write and counts as a failure.
# A cancel counts as a failure: pr-require-checks.yml cancels no
# running full run, so it came from an actor with actions: write or
# a time-budget overrun. A dispatch the main-dispatch concurrency
# group replaced before it started is cancelled too, with no job:
# that is no signal, and the check below files nothing for it.
# A re-run that passes is recorded on the record; it clears nothing.
# A dispatched run also files on action_required, as the Read step
# accepts every conclusion in babysit_postmerge.py's FAILED_CONCLUSIONS.
Expand Down Expand Up @@ -325,6 +328,13 @@ jobs:
echo "::error::run attempt '$RUN_ATTEMPT' is not a positive integer"
exit 1
fi
# A failed read is a run that started: it files as before.
if [[ "$RUN_CONCLUSION" == cancelled && "$signal" != canary ]] &&
jobs="$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID/attempts/$RUN_ATTEMPT/jobs?per_page=1" \
--jq '.total_count // (.jobs | length)')" && [[ "$jobs" == 0 ]]; then
echo "$RUN_WORKFLOW was cancelled before any job started (a newer dispatch replaced it): nothing to file"
exit 0
fi
newly=''
if [[ -z "$passed" && "$signal" != canary ]]; then
# Re-run the failed jobs once and wait here for that attempt: a
Expand Down
Loading
Loading