# Auto-merge

Auto-merge requests that wait on a blocked pull request and land when its base's protection is met.

Auto-merge lets a blocked pull request wait for its base's protection to be met, then merges it. Turn auto-merge on for a blocked pull request and meet its requirements to watch it land:

```bash
H='Authorization: Bearer ghp_anything'
R="$RYSTIC_URL/repos/tb-owner/tb-repo"
curl -s "$RYSTIC_URL/_rystic/inspect" | jq '{state_repository: {"tb-owner/tb-repo": (.state_repository["tb-owner/tb-repo"] | .allow_auto_merge = true)}}' > "$PWD/allow-auto-merge.json"
curl -s -X POST "$RYSTIC_URL/_rystic/seed" -d @"$PWD/allow-auto-merge.json" -o /dev/null -w '%{http_code}\n'
# -> 204
curl -s -X PUT "$R/branches/tb-base-branch/protection" -H "$H" -d '{"required_status_checks":{"strict":false,"contexts":["unit"]},"enforce_admins":false,"required_pull_request_reviews":{"required_approving_review_count":1},"restrictions":null}' -o /dev/null -w '%{http_code}\n'
# -> 200
curl -s -X POST "$RYSTIC_URL/graphql" -H "$H" -d '{"query":"mutation { enablePullRequestAutoMerge(input: {pullRequestId: \"tb-pr-41-node-id\", mergeMethod: SQUASH}) { pullRequest { number autoMergeRequest { mergeMethod enabledBy { login } } } } }"}' | jq -c '.data.enablePullRequestAutoMerge.pullRequest.autoMergeRequest'
# -> {"enabledBy":{"login":"tb-owner"},"mergeMethod":"SQUASH"}
curl -s "$R/pulls/41" -H "$H" | jq -c '{state, merged, auto_merge: (.auto_merge | {merge_method, enabled_by: .enabled_by.login})}'
# -> {"state":"open","merged":false,"auto_merge":{"merge_method":"squash","enabled_by":"tb-owner"}}
curl -s -X POST "$R/statuses/517a4bbdfb525691b11db3e28f466eb3d7598d19" -H "$H" -d '{"state":"success","context":"unit"}' -o /dev/null -w '%{http_code}\n'
# -> 201
curl -s -X POST "$R/pulls/41/reviews" -H "$H" -H 'X-Rystic-Actor: tb-reviewer-login' -d '{"event":"APPROVE"}' | jq -c '{state}'
# -> {"state":"APPROVED"}
curl -s "$R/pulls/41" -H "$H" | jq -c '{state, merged, merged_by: .merged_by.login}'
# -> {"state":"closed","merged":true,"merged_by":"tb-owner"}
curl -s "$R/issues/41/events" -H "$H" | jq -c '[.[].event]'
# -> ["auto_merge_enabled","merged","closed"]
```

"Unconfirmed" marks behavior not yet checked against GitHub. Into a base that holds a merge queue, auto-merge joins the queue instead: see [Merge queues](https://www.rystic.ai/docs/simulators/github-pulls/features/merge-queue.md).

### Enabling auto-merge

`gh pr merge --auto` on a blocked pull request sends `enablePullRequestAutoMerge`. The simulator records the request as the pull request's `auto_merge`, which GraphQL reads as `autoMergeRequest`. Enabling it logs `auto_merge_enabled` and sends the `pull_request` `auto_merge_enabled` webhook.

The repository must allow auto-merge (`allow_auto_merge`) unless the base holds a merge queue. Every authored scenario seeds it off. Off a queue base, a pull request reading anything but `blocked`, `behind` or `unknown` is refused `Pull request is in <mergeable_state> status`. A draft is refused `Pull request is in draft status`.

Enabling auto-merge with a merge method the repository or a ruleset doesn't allow is accepted (unconfirmed). Off a merge queue, such a request never lands while the method stays disallowed.

### When auto-merge lands

The simulator lands an auto-merge request on the enabler's behalf as soon as the base's protection is met. It checks again after each status, check run, protection or ruleset write, and after submitting or dismissing a review. It also checks after creating a review comment through `POST .../pulls/{n}/comments` or deleting one. A push, an update-branch, a reopen or a base change makes it check too. It merges through the merge route with the recorded method:

- The pull request reads `merged`, with the enabler as `merged_by`.
- Its log gains `merged` and `closed`.
- The `pull_request` `closed` webhook goes out.
- `auto_merge` stays on the merged record.

After a push to the head, a request the new head's results meet lands after the push's own `synchronize`.

A request stays on a pull request that closes (unconfirmed). A reopen that finds the base's protection met lands it after the `reopened` event.

### Disabling auto-merge

`gh pr merge --disable-auto` sends `disablePullRequestAutoMerge`, which clears the request, logs `auto_merge_disabled` and sends `auto_merge_disabled`. With no request standing it changes nothing. On a closed pull request it is refused `Can't disable auto-merge for this pull request.`.

---

Source: https://www.rystic.ai/docs/simulators/github-pulls/features/auto-merge · Markdown: https://www.rystic.ai/docs/simulators/github-pulls/features/auto-merge.md
