Skip to content

ci: green PRs merge and deploy themselves - #1

Merged
catomean merged 3 commits into
mainfrom
ci/auto-merge
Aug 5, 2026
Merged

ci: green PRs merge and deploy themselves#1
catomean merged 3 commits into
mainfrom
ci/auto-merge

Conversation

@catomean

@catomean catomean commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Why

Merging and deploying should not need a human. The owner does not review PRs, and
background-job agent sessions are hard-barred from merging — so "the agent ships it"
cannot be a per-session promise. It has to be repo automation.

Same setup already running on orangecat and fleetcrown, ported with both bugs
their first live runs exposed already fixed.

The chain

push branch → open PR → CI green → auto-merge squash-merges → re-arm (ci.yml) → deploy

Policy lives in scripts/ci/auto-merge-sweep.sh. A PR merges iff it is not a draft,
carries no hold label, has ≥1 check, every check finished green, and GitHub reports it
cleanly MERGEABLE.

How you hold work back

  • Draft PR — waits forever.
  • Labelhold, no-automerge, do-not-merge, wip.

Corollary: never open a non-draft PR you would not want deployed.

Adapted for this repo

  • Added workflow_dispatch to ci.yml — without it the re-arm below silently fails.
  • No deploy workflow in this repo, so the re-arm only restarts CI.

Two load-bearing design points

  1. One PR per sweep, only onto a green base. A PR's checks prove it against the base
    it branched from, not against the other queued PRs — batch-merging would put a
    combination on the base that nothing ever built.
  2. The re-arm. A push made with the default GITHUB_TOKEN does not trigger
    workflows. CI and deploy here both run on push, so without the explicit dispatch a
    merge would land and silently never build or ship. It is also what keeps the train
    moving: the green-base guard requires a CI run for the current tip, so with no run
    ever produced the next sweep would block forever.

Ported fixes (don't reintroduce)

  • Poll mergeability. GitHub computes it lazily and invalidates it whenever the base
    moves, so the fast path always sees UNKNOWN on its first look.
  • Re-run cancelled checks. cancel-in-progress means an unrelated push can kill a
    PR's build; nothing re-runs it and the PR strands forever. Genuine failures are left alone.

Bootstrap — this is the last hand-merge

GitHub only runs the default branch's copy of workflow_run/schedule workflows, so
this PR cannot merge itself. One manual merge, ever; after it lands nothing here is merged
by hand again.

🤖 Generated with Claude Code

@catomean
catomean merged commit 0071384 into main Aug 5, 2026
1 check passed
@catomean
catomean deleted the ci/auto-merge branch August 5, 2026 17:15
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