From 2cdabadcb89e87b0e618c4e46909348daa1734ec Mon Sep 17 00:00:00 2001 From: Richard Pierre Date: Sat, 5 Sep 2026 22:25:15 -0400 Subject: [PATCH] fix(ci): sweep must retry, mergeStateStatus is computed lazily The sweep added in #151 was a no-op. It used a single query per PR to avoid burning runner minutes, but GitHub computes mergeStateStatus lazily: the first query for a PR it has not looked at recently returns UNKNOWN and only then starts the computation. Every cold PR therefore read UNKNOWN and was skipped. The first live sweep confirmed it, skipping all 7 open PRs with 'mergeStateStatus=UNKNOWN, leaving for the next sweep'. Warms every candidate in one parallel pass, then reads the settled values, and retries on UNKNOWN rather than giving up after one attempt. --- .github/workflows/automerge.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 01c7d2c..f2c3ca6 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -118,11 +118,20 @@ jobs: pr.mergeStateStatus === 'CLEAN' || (pr.mergeStateStatus === 'UNSTABLE' && pr.mergeable === 'MERGEABLE'); + // mergeStateStatus is computed LAZILY. The first query for a PR GitHub + // has not looked at recently returns UNKNOWN and only then kicks off the + // computation. On a sweep that means every cold PR reads UNKNOWN and gets + // skipped: the first live sweep was a no-op across all 7 open PRs for + // exactly this reason. Warm them all first, then read the settled values. + if (isSweep) { + await Promise.all(numbers.map(n => + github.graphql(Q, {o: owner, r: repo, n}).catch(() => null))); + await sleep(5000); + } + for (const n of numbers) { - // mergeStateStatus is computed async; retry briefly on UNKNOWN. - // One pass is enough on the sweep: the next one is 15 minutes away, - // so waiting here would only burn runner minutes. - const attempts = isSweep ? 1 : 6; + // Still retry: the warm-up is best-effort, not a guarantee. + const attempts = 6; let data; for (let i = 0; i < attempts; i++) { data = await github.graphql(Q, {o: owner, r: repo, n});