Merger
The merger clicks "merge" for you once fouine has approved a PR and CI is green — the last step of the review loop that otherwise sits waiting on a human.
It is off by default. Once a repo opts in, every non-draft PR on that repo merges itself — there's nothing to type, nothing to remember.
The five conditions
The merger checks all of the following, re-checked at the moment of merge, not just when a PR is armed:
- fouine's latest review on the armed head SHA is
APPROVED. Read straight from GitHub, not from fouine's own database — neverPENDING, never a stale comment/changes-requested state, and never a review left on a commit that was later superseded by a push. - No human review is
CHANGES_REQUESTED. A human's laterAPPROVEDclears their own earlierCHANGES_REQUESTED; fouine's approval never overrides one that's still standing. - Every check run and commit status on the head SHA has completed, and none concluded
failure,cancelled,timed_outoraction_required.neutralandskippedcount as passing. If GitHub reports required status checks for the branch, only those count; otherwise every check on the commit does. - The PR's head SHA still equals the SHA that was armed. A new push re-arms it against the new commit (see below); this is the belt-and-braces re-check right before merging.
- The PR is
mergeable— GitHub's own computed field, polled briefly if it's stillnull.
If any condition is false, the merger does nothing and waits for the next relevant event (a new review, a check finishing, a new commit status). It never retries on a timer.
Opting in
Two settings, global with a per-repo override — same pattern as the deny-test-commands toggle:
- Auto-merge — on/off. Off by default.
- Merge method —
merge,squash, orrebase. Defaults tosquash.
Both live in the dashboard's settings page and on each repo's detail page.
Arming: automatic
Once a repo is opted in, fouine arms every non-draft PR against its current head SHA the moment it's opened, pushed to, reopened, or marked ready for review. There's no command:
- Open a PR (or push to one) on an opted-in repo — it's armed immediately.
- The merger evaluates it whenever something relevant happens: fouine's review lands, a check finishes, a commit status reports.
- A new push re-arms it against the new commit — no disarm step, no comment, it just moves to the new SHA.
- Draft PRs are never armed. Marking a PR ready for review arms it.
- An arm left untouched for 7 days is dropped automatically.
The recap comment
Once merged, fouine posts one short comment on the PR: the merge method and commit SHA, a link to the approving review, how many findings it raised and how many pushes it took to clear them, how many checks passed and whether required or all checks applied, fixer commits if any, and fouine's total cost on that PR. A retried evaluation never posts a second recap: once the PR shows as merged, evaluation short-circuits before ever reaching the recap step.
What it never does
- Never merges a repo that hasn't opted into auto-merge. The setting is what turns this on at all.
- Never merges over a standing human
CHANGES_REQUESTED, even with fouine's approval. - Never merges a draft PR, an unmergeable PR, or a PR whose head has moved since it was armed.
- Never deletes the head branch. Use GitHub's own "automatically delete head branches" repo setting for that.
- Never uses GitHub's native auto-merge (GraphQL) or merge queues — those need branch protection with required checks, which many of the small repos this feature targets don't have.
