Gitea already does this. I do not think we should write the workflow.
Measured on this instance rather than read from docs.
The finding
merge_when_checks_succeed is a documented field on MergePullRequestOption
in this server's own swagger, and it works:
POST /repos/weblib/weblib-ci/pulls/6/merge
{"Do":"merge","merge_when_checks_succeed":true}
on a PR that was unapproved, targeting protected main. It did not
refuse for lack of approvals and it did not merge — it scheduled. Proved by
cancelling twice:
DELETE .../pulls/6/merge -> 204 No Content (something was scheduled)
DELETE .../pulls/6/merge -> 404 Not Found (nothing left to cancel)
So the whole feature is one extra field when I open a PR. Nothing to install,
nothing to maintain, and it is armed at the moment the PR is created rather
than discovered later by a poller.
Why I would not add the workflow
A workflow would have to live in five repos and be kept in step, and it
walks into three traps this project has already paid for:
scheduled workflows only run from the default branch, so a polling
version would be inert on development until promoted
the Actions token's permissions are not the same as mine — it cannot even
delete an issue label, measured; whether it can merge is another thing to
find out
it would race the native mechanism if both existed
Against that, the native path is a single JSON field.
What is not yet proven
That the scheduled merge fires on approval, rather than only on status
checks. The name says checks; Gitea evaluates full mergeability, which should
include approvals, but I have not seen it happen.
PR #6 is armed and waiting for exactly that. It is a real change — the
README describing what the reconciler now does — and it needs your approval
anyway. Approve it and one of two things happens:
it merges by itself → confirmed, and I will start passing the flag on every
PR and close this issue
it sits there → the flag waits on checks only, and this issue becomes worth
doing properly, at which point I would still put the logic in a script here
and call it from a thin per-repo workflow
Either way we learn it from one approval rather than from building something.
One thing I need you to disambiguate
PRs that got approved and check all boxes
Two readings, and they need different work:
CI checks pass — covered by the native flag, nothing more to do.
The markdown task list in the PR body is fully ticked (- [ ] → - [x]).
Not covered. The PR API exposes no task-list state at all — I listed every
field on the object to check — so this would mean fetching .body and
parsing it, and that genuinely needs a script.
I read you as meaning (1), which is why I tested that first. If you meant (2),
say so and I will build it — it is a reasonable thing to want, and it is the
only part of this issue that native auto-merge cannot do.
**Gitea already does this. I do not think we should write the workflow.**
Measured on this instance rather than read from docs.
## The finding
`merge_when_checks_succeed` is a documented field on `MergePullRequestOption`
in this server's own swagger, and it works:
```
POST /repos/weblib/weblib-ci/pulls/6/merge
{"Do":"merge","merge_when_checks_succeed":true}
```
on a PR that was **unapproved**, targeting **protected `main`**. It did not
refuse for lack of approvals and it did not merge — it *scheduled*. Proved by
cancelling twice:
```
DELETE .../pulls/6/merge -> 204 No Content (something was scheduled)
DELETE .../pulls/6/merge -> 404 Not Found (nothing left to cancel)
```
So the whole feature is one extra field when I open a PR. Nothing to install,
nothing to maintain, and it is armed at the moment the PR is created rather
than discovered later by a poller.
## Why I would not add the workflow
A workflow would have to live in **five** repos and be kept in step, and it
walks into three traps this project has already paid for:
- **scheduled workflows only run from the default branch**, so a polling
version would be inert on `development` until promoted
- the Actions token's permissions are not the same as mine — it **cannot even
delete an issue label**, measured; whether it can merge is another thing to
find out
- it would race the native mechanism if both existed
Against that, the native path is a single JSON field.
## What is *not* yet proven
That the scheduled merge fires on **approval**, rather than only on status
checks. The name says checks; Gitea evaluates full mergeability, which should
include approvals, but I have not seen it happen.
**PR #6 is armed and waiting for exactly that.** It is a real change — the
README describing what the reconciler now does — and it needs your approval
anyway. Approve it and one of two things happens:
- it merges by itself → confirmed, and I will start passing the flag on every
PR and close this issue
- it sits there → the flag waits on checks only, and this issue becomes worth
doing properly, at which point I would still put the logic in a script here
and call it from a thin per-repo workflow
Either way we learn it from one approval rather than from building something.
## One thing I need you to disambiguate
> PRs that got approved **and check all boxes**
Two readings, and they need different work:
1. **CI checks pass** — covered by the native flag, nothing more to do.
2. **The markdown task list in the PR body is fully ticked** (`- [ ]` → `- [x]`).
Not covered. The PR API exposes no task-list state at all — I listed every
field on the object to check — so this would mean fetching `.body` and
parsing it, and *that* genuinely needs a script.
I read you as meaning (1), which is why I tested that first. If you meant (2),
say so and I will build it — it is a reasonable thing to want, and it is the
only part of this issue that native auto-merge cannot do.
APPROVED by bit 16:42:25
merged 16:42:27 <- two seconds later
merged_by claude <- the user who *scheduled* it, not the approver
cancel probe 404 <- the scheduled merge was consumed
I never touched it after arming it. So merge_when_checks_succeed waits for
the PR to become mergeable — which includes required approvals — not merely
for CI. That is exactly what this issue asked for, and Gitea has had it all
along.
What I will do instead of building it
Pass the flag when opening every PR:
$TEA api -X POST repos/weblib/<repo>/pulls/<n>/merge \
-d '{"Do":"merge","merge_when_checks_succeed":true}'
For a PR into development that changes nothing in practice — I can merge those
myself after the cold re-read, and I would rather keep that read than have it
merge out from under me. For a PR into main, or anything in weblib-ci, it
closes a real gap: those need your approval, and until now the PR sat until I
next looked. Now your approval is the merge.
One caveat worth stating: an armed PR merges without a cold re-read from me
if you approve after I have moved on. For weblib-ci and promotions that is
fine, since your approval is the review. I will not arm a development PR for
that reason.
Still open — the half native auto-merge cannot do
PRs that got approved and check all boxes
If "boxes" meant the markdown task list in the PR body, that is not covered and
not exposed by the API at all. Say the word and I will build it; otherwise I
will close this as done by the native feature.
Recorded in docs/WORKFLOW.md.
## Confirmed: native auto-merge fires on **approval**. No workflow needed.
Your approval of #6 settled it:
```
APPROVED by bit 16:42:25
merged 16:42:27 <- two seconds later
merged_by claude <- the user who *scheduled* it, not the approver
cancel probe 404 <- the scheduled merge was consumed
```
I never touched it after arming it. So `merge_when_checks_succeed` waits for
the PR to become **mergeable** — which includes required approvals — not merely
for CI. That is exactly what this issue asked for, and Gitea has had it all
along.
## What I will do instead of building it
Pass the flag when opening every PR:
```bash
$TEA api -X POST repos/weblib/<repo>/pulls/<n>/merge \
-d '{"Do":"merge","merge_when_checks_succeed":true}'
```
For a PR into `development` that changes nothing in practice — I can merge those
myself after the cold re-read, and I would rather keep that read than have it
merge out from under me. **For a PR into `main`, or anything in weblib-ci, it
closes a real gap**: those need your approval, and until now the PR sat until I
next looked. Now your approval *is* the merge.
One caveat worth stating: an armed PR merges **without a cold re-read from me**
if you approve after I have moved on. For weblib-ci and promotions that is
fine, since your approval is the review. I will not arm a `development` PR for
that reason.
## Still open — the half native auto-merge cannot do
> PRs that got approved **and check all boxes**
If "boxes" meant the markdown task list in the PR body, that is not covered and
not exposed by the API at all. Say the word and I will build it; otherwise I
will close this as done by the native feature.
Recorded in `docs/WORKFLOW.md`.
Agreed and done — auto-merge is now the default for every PR.
I had said I would not arm development PRs, because there no approval is
required, so armed means "merges the moment CI goes green" with no review at
all — and the cold re-read is the only review those get. You have that in front
of you and said default it on, so it is on.
The fix turned out to be ordering, not an exception:
old: push -> wait for CI -> re-read -> merge
new: push -> re-read -> arm -> (CI green) -> it merges itself
The review still happens, on the same diff, before anything can merge — and it
is faster, because the old order meant coming back to a PR after CI finished,
which is the waiting you are trying to remove. So the rule is arm last:
after the re-read, after the final push.
One thing I have not verified and am treating as dangerous until I do:
whether pushing to an already-armed PR cancels the scheduled merge. A scheduled
merge attaches to the PR, not to a commit, so it may merge code nobody re-read.
Until measured, the rule is cancel → push → re-read → re-arm:
$TEA api -X DELETE repos/weblib/<repo>/pulls/<n>/merge # 204 = was armed, 404 = not
That DELETE doubles as the way to ask whether a PR is armed.
Recorded in docs/WORKFLOW.md, loop step 6 of docs/UNSUPERVISED.md, and the
subagent briefing in docs/DELEGATION.md — subagents open PRs but do not
arm them, since arming before the parent's re-read is exactly the failure this
ordering avoids.
Closing: no workflow needed, native auto-merge does it, and it is now the
default. If you did mean the markdown task-list checkboxes by "check all
boxes", reopen and say so — that part is genuinely not covered and would need
parsing the PR body.
Agreed and done — auto-merge is now the default for every PR.
I had said I would *not* arm `development` PRs, because there no approval is
required, so armed means "merges the moment CI goes green" with no review at
all — and the cold re-read is the only review those get. You have that in front
of you and said default it on, so it is on.
**The fix turned out to be ordering, not an exception:**
```
old: push -> wait for CI -> re-read -> merge
new: push -> re-read -> arm -> (CI green) -> it merges itself
```
The review still happens, on the same diff, before anything can merge — and it
is *faster*, because the old order meant coming back to a PR after CI finished,
which is the waiting you are trying to remove. So the rule is **arm last**:
after the re-read, after the final push.
One thing I have **not** verified and am treating as dangerous until I do:
whether pushing to an already-armed PR cancels the scheduled merge. A scheduled
merge attaches to the PR, not to a commit, so it may merge code nobody re-read.
Until measured, the rule is cancel → push → re-read → re-arm:
```bash
$TEA api -X DELETE repos/weblib/<repo>/pulls/<n>/merge # 204 = was armed, 404 = not
```
That `DELETE` doubles as the way to ask whether a PR is armed.
Recorded in `docs/WORKFLOW.md`, loop step 6 of `docs/UNSUPERVISED.md`, and the
subagent briefing in `docs/DELEGATION.md` — subagents open PRs but do **not**
arm them, since arming before the parent's re-read is exactly the failure this
ordering avoids.
Closing: no workflow needed, native auto-merge does it, and it is now the
default. If you did mean the markdown task-list checkboxes by "check all
boxes", reopen and say so — that part is genuinely not covered and would need
parsing the PR body.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Gitea already does this. I do not think we should write the workflow.
Measured on this instance rather than read from docs.
The finding
merge_when_checks_succeedis a documented field onMergePullRequestOptionin this server's own swagger, and it works:
on a PR that was unapproved, targeting protected
main. It did notrefuse for lack of approvals and it did not merge — it scheduled. Proved by
cancelling twice:
So the whole feature is one extra field when I open a PR. Nothing to install,
nothing to maintain, and it is armed at the moment the PR is created rather
than discovered later by a poller.
Why I would not add the workflow
A workflow would have to live in five repos and be kept in step, and it
walks into three traps this project has already paid for:
version would be inert on
developmentuntil promoteddelete an issue label, measured; whether it can merge is another thing to
find out
Against that, the native path is a single JSON field.
What is not yet proven
That the scheduled merge fires on approval, rather than only on status
checks. The name says checks; Gitea evaluates full mergeability, which should
include approvals, but I have not seen it happen.
PR #6 is armed and waiting for exactly that. It is a real change — the
README describing what the reconciler now does — and it needs your approval
anyway. Approve it and one of two things happens:
PR and close this issue
doing properly, at which point I would still put the logic in a script here
and call it from a thin per-repo workflow
Either way we learn it from one approval rather than from building something.
One thing I need you to disambiguate
Two readings, and they need different work:
- [ ]→- [x]).Not covered. The PR API exposes no task-list state at all — I listed every
field on the object to check — so this would mean fetching
.bodyandparsing it, and that genuinely needs a script.
I read you as meaning (1), which is why I tested that first. If you meant (2),
say so and I will build it — it is a reasonable thing to want, and it is the
only part of this issue that native auto-merge cannot do.
Confirmed: native auto-merge fires on approval. No workflow needed.
Your approval of #6 settled it:
I never touched it after arming it. So
merge_when_checks_succeedwaits forthe PR to become mergeable — which includes required approvals — not merely
for CI. That is exactly what this issue asked for, and Gitea has had it all
along.
What I will do instead of building it
Pass the flag when opening every PR:
For a PR into
developmentthat changes nothing in practice — I can merge thosemyself after the cold re-read, and I would rather keep that read than have it
merge out from under me. For a PR into
main, or anything in weblib-ci, itcloses a real gap: those need your approval, and until now the PR sat until I
next looked. Now your approval is the merge.
One caveat worth stating: an armed PR merges without a cold re-read from me
if you approve after I have moved on. For weblib-ci and promotions that is
fine, since your approval is the review. I will not arm a
developmentPR forthat reason.
Still open — the half native auto-merge cannot do
If "boxes" meant the markdown task list in the PR body, that is not covered and
not exposed by the API at all. Say the word and I will build it; otherwise I
will close this as done by the native feature.
Recorded in
docs/WORKFLOW.md.in that case, auto-merge should become the default option for PRs
Agreed and done — auto-merge is now the default for every PR.
I had said I would not arm
developmentPRs, because there no approval isrequired, so armed means "merges the moment CI goes green" with no review at
all — and the cold re-read is the only review those get. You have that in front
of you and said default it on, so it is on.
The fix turned out to be ordering, not an exception:
The review still happens, on the same diff, before anything can merge — and it
is faster, because the old order meant coming back to a PR after CI finished,
which is the waiting you are trying to remove. So the rule is arm last:
after the re-read, after the final push.
One thing I have not verified and am treating as dangerous until I do:
whether pushing to an already-armed PR cancels the scheduled merge. A scheduled
merge attaches to the PR, not to a commit, so it may merge code nobody re-read.
Until measured, the rule is cancel → push → re-read → re-arm:
That
DELETEdoubles as the way to ask whether a PR is armed.Recorded in
docs/WORKFLOW.md, loop step 6 ofdocs/UNSUPERVISED.md, and thesubagent briefing in
docs/DELEGATION.md— subagents open PRs but do notarm them, since arming before the parent's re-read is exactly the failure this
ordering avoids.
Closing: no workflow needed, native auto-merge does it, and it is now the
default. If you did mean the markdown task-list checkboxes by "check all
boxes", reopen and say so — that part is genuinely not covered and would need
parsing the PR body.