Skip to content

fix(ci): add a scheduled sweep so merge-queue PRs cannot strand - #151

Merged
cmarko89 merged 2 commits into
mainfrom
fix-automerge-sweep-20260906
Sep 6, 2026
Merged

cmarko89 merged 2 commits into
mainfrom
fix-automerge-sweep-20260906

Conversation

@cmarko89

@cmarko89 cmarko89 commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Problem

automerge.yml fires on check_suite: completed, reads mergeStateStatus, and only enqueues when the PR is already mergeable. At that moment GitHub has usually not recomputed mergeStateStatus, so the PR reads BLOCKED and the job logs waiting for a later check_suite event and exits.

If that was the last check_suite event, nothing ever retries. The PR then goes CLEAN and sits open indefinitely.

Pin PR #148 stranded exactly this way for four days. Because build-and-deploy.yml only classifies mode=webhook for a chore: pin muninn -> head commit, the Portainer redeploy never fired and the host kept serving the previous image, with no alert anywhere. Reproduced live on #150: checks went CLEAN, no further automerge run fired, queue stayed empty until it was enqueued by hand.

Muninn is the only Emkraan repo with a merge-queue ruleset, so it is the only repo where this explicit enqueue call is load-bearing.

Fix

  1. Retry in-run while the PR is BLOCKED and its check rollup is still PENDING. Terminal states (failing checks, conflicts) break out immediately rather than burning twelve attempts.
  2. A 15-minute scheduled sweep over all open PRs that enqueues any that are mergeable and unqueued. This is the convergence guarantee: independent of event delivery, so a dropped or badly-timed event can no longer strand a PR.

Sweep runs a single pass per PR (the next sweep is 15 minutes away); event runs wait, since they are racing GitHub's own recomputation.

Concurrency group now falls back to run_id so sweeps do not collapse into one group.

The event-driven path alone is not sufficient on a merge-queue repo. When a
check_suite completes GitHub has often not recomputed mergeStateStatus, so the
PR still reads BLOCKED; the workflow logged 'waiting for a later check_suite
event' and exited. When that was the last such event nothing ever retried and
the PR sat open while reading CLEAN. Pin PR #148 stranded for four days, which
silently froze the deploy chain: build-and-deploy only classifies mode=webhook
for a pin commit, so the redeploy never ran and the host kept the old image.

Adds two defences: retry in-run while BLOCKED with checks still PENDING, and a
15-minute scheduled sweep that enqueues any open mergeable unqueued PR.
Rebases muninn's automerge.yml onto the homelab-stacks canonical version and
adds the sweep on top.

Two pre-existing standard violations are fixed by the rebase:
  - github-actions-monorepo-standard.md requires automerge.yml to mint the
    deploy-bot App token and pass it to the step calling enqueuePullRequest.
    Muninn ran the mutation under the default GITHUB_TOKEN.
  - The UNSTABLE self-check handling from homelab-stacks #406 was missing, so
    a fast-CI PR could strand on this job's own in-progress automerge check.

The new part is the scheduled sweep. The event path alone cannot guarantee
convergence on a merge-queue repo: when a check_suite completes GitHub has
often not recomputed mergeStateStatus, the PR reads BLOCKED, and if that was
the last event nothing retried. Pin PR #148 stranded four days that way and
silently froze the deploy chain.
@cmarko89
cmarko89 added this pull request to the merge queue Sep 6, 2026
Merged via the queue into main with commit e94fa55 Sep 6, 2026
3 checks passed
@cmarko89
cmarko89 deleted the fix-automerge-sweep-20260906 branch September 6, 2026 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant