Keep sync PRs building across bot pushes
Three things kept the upstream sync PR (#589) from ever finishing a build: Scoped dispatches wiped the shared PR. A workflow_dispatch with `packages` regenerates only those packages from master, and pushing that to auto/sync-upstream replaced 38 pending updates with one. Scoped runs now push to their own auto/sync-{upstream,rebuilds}-<packages> branch and PR; scheduled runs keep the shared branch. build-approved stopped working after the first bot push. A GITHUB_TOKEN push creates pull_request runs held for approval but no pull_request_target run, so approve-pr.yml never saw it: its last run on the branch was the label itself (2026-09-25T19:26), and each of the next four syncs sat at action_required. The sync workflows now release the held runs for the commit they just pushed, from a separate job holding actions: write, and only for their own bot-authored, same-repo PR while build-approved is on it. Each approved push cancelled the in-flight build. Approving the 21:43 sync's build cancelled the label-triggered one still queued on strata and schist-bin. On auto/sync-* branches a new build now waits for the running one instead, then reuses its artifacts. The approval script no longer waits for a lone approved build to start before releasing tests, which a queued build would have turned into a timeout.
This commit is contained in:
1 parent
6df9953d8f
commit
4aca3bdbc7
8 files changed
+363
-9
No files matched your search
@@ -1,7 +1,11 @@
|
||||
const BUILD = '.github/workflows/build-pr.yml';
|
||||
const TESTS = '.github/workflows/test.yml';
|
||||
|
||||
// pullRequest/action/since default to the pull_request_target event. The
|
||||
// sync workflows pass them explicitly: GitHub creates no pull_request_target
|
||||
// run for a GITHUB_TOKEN push, so they release their own pushes' held runs.
|
||||
module.exports = async function approve({ github, context, core, vouchStatus,
|
||||
pullRequest = context.payload.pull_request, action = context.payload.action, since,
|
||||
sleep = ms => new Promise(resolve => setTimeout(resolve, ms)), attempts = 36 }) {
|
||||
// Missing/failed vouch lookups must not become approval. Denouncements
|
||||
// remain absolute, just as they are in the package build gate.
|
||||
@@ -9,8 +13,8 @@ module.exports = async function approve({ github, context, core, vouchStatus,
|
||||
throw new Error(`Cannot approve workflows: vouch status is ${vouchStatus || 'missing'}.`);
|
||||
}
|
||||
|
||||
const expected = context.payload.pull_request;
|
||||
const eventTime = Date.parse(expected.updated_at);
|
||||
const expected = pullRequest;
|
||||
const eventTime = Date.parse(since ?? expected.updated_at);
|
||||
if (!Number.isFinite(eventTime)) throw new Error('Missing PR event timestamp.');
|
||||
const approved = new Set();
|
||||
let precedingBuild;
|
||||
@@ -47,7 +51,7 @@ module.exports = async function approve({ github, context, core, vouchStatus,
|
||||
const newestBuild = runs.findLast(run => run.path === BUILD);
|
||||
if (!newestBuild || !(Date.parse(newestBuild.created_at) >= eventTime) ||
|
||||
!runs.some(run => run.path === TESTS &&
|
||||
(context.payload.action === 'labeled' || Date.parse(run.created_at) >= eventTime))) continue;
|
||||
(action === 'labeled' || Date.parse(run.created_at) >= eventTime))) continue;
|
||||
|
||||
if (precedingBuild) {
|
||||
const { data: run } = await github.rest.actions.getWorkflowRun({
|
||||
@@ -71,7 +75,13 @@ module.exports = async function approve({ github, context, core, vouchStatus,
|
||||
await github.rest.actions.approveWorkflowRun({ ...context.repo, run_id: run.id });
|
||||
approved.add(run.id);
|
||||
core.info(`Approved ${run.path} run ${run.id} for PR #${expected.number}.`);
|
||||
if (run.path === BUILD) precedingBuild = run.id;
|
||||
// Only a newer held build needs this one to take the concurrency slot
|
||||
// first. A lone build may sit pending behind an in-flight build of an
|
||||
// older commit (sync branches queue rather than cancel); waiting for it
|
||||
// to start would time out before the tests run was released.
|
||||
if (run.path === BUILD && pending.some(other => other.path === BUILD && other.id > run.id)) {
|
||||
precedingBuild = run.id;
|
||||
}
|
||||
if (pending.length === 1) return;
|
||||
}
|
||||
throw new Error('Timed out waiting for PR workflows. Remove and reapply build-approved to retry.');
|
||||
|
||||
Reference in new issue
Block a user