Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .mergequeue.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ registry_title = "DeployBot delivery registry"
thread_active_hours = 72
ci_workflows = ["CI"]
deploy_workflows = ["Deploy"]
batch_settle_seconds = 0
repair_hold_minutes = 60
hold_merges_while_releasing = true
repair_branch_prefix = "deploybot/repair"
Expand All @@ -52,10 +53,10 @@ merge_to_live_target_minutes = 10
auto_promote = true
intent_scope = "head" # safest: a trusted source agent refreshes replacement heads
pause_on_failure = true
# verified (default, safest) holds new merges until the cumulative release is
# live. ci-passed admits the next batch as soon as exact-main CI passes and lets
# deploy and health checks keep following, trading blast radius for throughput.
release_admission = "verified"
# merged (default) admits independent ready work immediately after the previous
# merge. ci-passed waits for exact-main CI; verified waits until production is
# live. Every mode pauses future merges when a later release failure is observed.
release_admission = "merged"
# Receives best-effort events, including retryable thread-deployed messages.
# webhook_url_env = "DEPLOYBOT_WEBHOOK_URL"

Expand Down
36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ integration PRs, follows `main` through production, and pauses after failures.

## Install

Install the reviewed `v0.2.24` source commit directly from GitHub:
Install the reviewed `v0.2.25` source commit directly from GitHub:

```bash
python3 -m pip install \
'deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@73004ea7c9dcb81e7f1281c0687aea0897d1571d'
'deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@12c6c03aa76a553fa4068279baa29e90a30bbeb1'
deploybot init
```

Expand Down Expand Up @@ -90,12 +90,15 @@ completions, and completed external check suites. Keep its `workflows` list
aligned with `pipeline.ci_workflows`. A five-minute scheduled reconciliation
rereads all durable state in case GitHub concurrency coalesces the last pending
event in a burst. The privileged worker never checks out or executes
pull-request code. The Action follows releases by default so the same serialized
worker can dispatch deployment when GitHub suppresses the `workflow_run` event
for token-dispatched CI. Pin the Action to the full reviewed release commit:
pull-request code. The Action advances releases to the configured admission
gate. In the default `merged` mode it returns after each healthy observation,
leaving completion to later release events and keeping the serialized merge
worker free. It can still dispatch deployment when GitHub suppresses the
`workflow_run` event for token-dispatched CI. Pin the Action to the full reviewed
release commit:

```yaml
- uses: Forward-Future/DeployBot@73004ea7c9dcb81e7f1281c0687aea0897d1571d
- uses: Forward-Future/DeployBot@12c6c03aa76a553fa4068279baa29e90a30bbeb1
```

The Action uses GitHub's built-in workflow token. GitHub intentionally does not
Expand Down Expand Up @@ -141,6 +144,13 @@ workflow name, base branch, head SHA, event, status, and conclusion to match the
expected successful exact-main CI run. The deployment must still pull the
current base branch and stop if it no longer equals `ci_sha`.

The deployment workflow must also acquire the repository's shared deployment
lock, fetch the base branch again after acquiring it, and coalesce superseded
requests onto that newest integrated SHA. It must never deploy an older SHA after
a newer one, and it keeps the lock through production health verification. These
release rules are unchanged by `release_admission = "merged"`; only merge
admission becomes asynchronous.

The workflow bot and each person allowed to request deployment must be
explicitly listed:

Expand Down Expand Up @@ -172,11 +182,11 @@ work, and creates integration PRs when configured. New batches contain at most
`integration.max_batch_size` entries; later FIFO work remains in the next batch.
A larger indivisible source-overlap or dependency closure is the sole exception:
it ships alone, never mixed with unrelated work.
After any merge, admission stays closed until the cumulative exact-main release
is verified live, preventing newer merges from starving an older deployment.
Set `pipeline.release_admission = "ci-passed"` to reopen admission as soon as
exact-main CI is green—deploy and health checks keep following in the
background—when higher merge throughput is worth a larger failure blast radius.
By default, `pipeline.release_admission = "merged"`: after one healthy merge,
DeployBot immediately admits the next independent ready PR or batch. Exact-main
CI, deployment, and health checks keep tracking asynchronously, and a later real
failure pauses future merges. Use `ci-passed` to wait for exact-main CI before
admitting more work, or `verified` to wait until the cumulative revision is live.
Draft status and incomplete
checks or reviews remain waiting states; they do not create a repair latch. A
conflict, failed gate, unresolved review, manual block, or stale authorized head
Expand Down Expand Up @@ -269,7 +279,7 @@ ending the PR-opening-thread response.
[pipeline]
ci_workflows = ["CI"]
deploy_workflows = ["Deploy"]
batch_settle_seconds = 15
batch_settle_seconds = 0
ci_failure_grace_seconds = 90
promotion_workers = 4
hold_merges_while_releasing = true
Expand All @@ -279,7 +289,7 @@ merge_to_live_target_minutes = 10
auto_promote = true
intent_scope = "head"
pause_on_failure = true
release_admission = "verified" # or "ci-passed" for higher merge throughput
release_admission = "merged" # or "ci-passed" / "verified" for stricter admission

[[pipeline.verifications]]
name = "Login"
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ inputs:
required: false
default: .mergequeue.toml
follow:
description: Follow cumulative main through CI and deployment
description: Advance cumulative main to the configured release-admission gate
required: false
default: "true"
dispatch_ci:
Expand Down
2 changes: 1 addition & 1 deletion adapters/claude-code/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "deploybot",
"version": "0.2.24",
"version": "0.2.25",
"description": "DeployBot: a provider-neutral GitHub merge queue for coding agents",
"author": {
"name": "DeployBot contributors"
Expand Down
2 changes: 1 addition & 1 deletion adapters/claude-code/.mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"command": "uvx",
"args": [
"--from",
"deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@73004ea7c9dcb81e7f1281c0687aea0897d1571d",
"deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@12c6c03aa76a553fa4068279baa29e90a30bbeb1",
"deploybot-mcp"
]
}
Expand Down
13 changes: 8 additions & 5 deletions adapters/claude-code/skills/deploybot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ Merge independent ready pull requests back-to-back. Route source-overlap groups
through `create_integration_pull_request`; when policy mode is `all`, validate
the entire frozen batch through that cumulative PR. Never invent a conflict
resolution. Return the repair packet to its source thread, then call `resume`
after its new exact head passes. Finish with `follow_release`, following newer
cumulative base heads until CI, deployment, and configured health checks verify.
after its new exact head passes. Keep release tracking event-driven: in
`release_admission = "merged"` mode, admit independent ready work immediately
after a healthy merge while later events continue CI, deployment, and health
tracking. Scheduled reconciliation is a fallback, not the normal promotion path.

Genuine repair blocks may hold overlapping ready work for the configured bounded
repair window, but they remain merge-ineligible until the trusted source agent
Expand Down Expand Up @@ -123,9 +125,10 @@ named thread already owns that failed SHA; wait for that repair and never create
a competing PR. The owner is encoded in the atomic branch ref, so a registry
write failure is recovered by calling the same tool again.

New batches are FIFO-bounded by `integration.max_batch_size`, and a merged batch
closes admission until its cumulative main revision is verified live. Do not
override either boundary for later work. Never execute merged PR code inside
New batches are FIFO-bounded by `integration.max_batch_size`. Honor the configured
release-admission gate: `merged` permits the next independent batch immediately,
while `ci-passed` and `verified` impose stricter release fences. A later observed
release failure pauses future merges in every mode. Never execute merged PR code inside
the privileged coordinator; generated-artifact conflicts go to the elected
repair owner for a normal reviewed rebuild. When PR-authored checks are
required, use a GitHub App installation token, list its bot login in
Expand Down
9 changes: 5 additions & 4 deletions adapters/claude-code/skills/manage-merge-queue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ poll or merge an unlabeled PR.
Use `pipeline_status` and `react_to_delivery_event` for bursts. Skip blockers,
honor dependencies, route overlap or cumulative validation through
`create_integration_pull_request`, return repair packets to the source thread,
and use `resume_pull_request` after fresh review. Finish with `follow_release`;
a failed CI or deployment pauses the pipeline until verified recovery.
and use `resume_pull_request` after fresh review. In `release_admission =
"merged"` mode, admit independent ready work immediately after merge while
later events track CI and deployment; a later failure pauses the pipeline.

A genuine repair remains merge-ineligible, but DeployBot may temporarily hold
overlapping ready work for the configured bounded repair window so concurrent
merges do not repeatedly invalidate the replacement head.

Before creating an exact-main recovery, call `claim_release_repair`; only the
returned `owned` thread may use the deterministic repair branch. Respect the
maximum batch size and keep new merges closed while an earlier release is
unfinished.
maximum batch size and the selected `merged`, `ci-passed`, or `verified`
release-admission fence.

Immediately before asking the user to `unpause` or take another repair action,
call `pipeline_status` again. Never show a stale pause prompt when durable state
Expand Down
2 changes: 1 addition & 1 deletion adapters/codex/agent-merge-queue/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "deploybot",
"version": "0.2.24",
"version": "0.2.25",
"description": "Coordinate exact-head pull requests through verified deployment and thread notification",
"author": {
"name": "DeployBot contributors"
Expand Down
14 changes: 8 additions & 6 deletions adapters/codex/agent-merge-queue/skills/deploybot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ Merge independent ready pull requests back-to-back. Route source-overlap groups
through `deploybot integrate`; when policy mode is `all`, validate the entire
frozen batch through that cumulative PR. Never invent a conflict resolution.
Return the repair packet to its source thread, then run `deploybot resume` after
its new exact head passes. Finish with `deploybot follow --json`, following
newer cumulative base heads until CI, deployment, and configured health checks
verify.
its new exact head passes. Keep release tracking event-driven: in
`release_admission = "merged"` mode, admit independent ready work immediately
after a healthy merge while later events continue CI, deployment, and health
tracking. Scheduled reconciliation is a fallback, not the normal promotion path.

Genuine repair blocks may hold overlapping ready work for the configured bounded
repair window, but they remain merge-ineligible until the trusted source agent
Expand Down Expand Up @@ -118,9 +119,10 @@ named thread already owns that failed SHA; wait for that repair and never create
a competing PR. The owner is encoded in the atomic branch ref, so a registry
write failure is recovered by calling the same tool again.

New batches are FIFO-bounded by `integration.max_batch_size`, and a merged batch
closes admission until its cumulative main revision is verified live. Do not
override either boundary for later work. Never execute merged PR code inside
New batches are FIFO-bounded by `integration.max_batch_size`. Honor the configured
release-admission gate: `merged` permits the next independent batch immediately,
while `ci-passed` and `verified` impose stricter release fences. A later observed
release failure pauses future merges in every mode. Never execute merged PR code inside
the privileged coordinator; generated-artifact conflicts go to the elected
repair owner for a normal reviewed rebuild. When PR-authored checks are
required, use a GitHub App installation token, list its bot login in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@ Run `deploybot status --json` before a burst and `deploybot react` to coordinate
it. Merge independent ready PRs back-to-back, skip blocked work, honor explicit
dependencies, and use `deploybot integrate` for overlaps or a cumulative batch
gate. Return repair packets to their source thread and run `deploybot resume`
after fresh review. Finish with `deploybot follow --json`; a failed CI or
deployment pauses the pipeline until verified recovery.
after fresh review. In `release_admission = "merged"` mode, admit independent
ready work immediately after merge while later events track CI and deployment;
a later failure pauses the pipeline.

A genuine repair remains merge-ineligible, but DeployBot may temporarily hold
overlapping ready work for the configured bounded repair window so concurrent
merges do not repeatedly invalidate the replacement head.

Before creating an exact-main recovery, run `deploybot claim-release-repair`;
only the returned `owned` thread may use the deterministic repair branch. Respect the
maximum batch size and keep new merges closed while an earlier release is
unfinished.
maximum batch size and the selected `merged`, `ci-passed`, or `verified`
release-admission fence.

Immediately before asking the user to `unpause` or take another repair action,
run `deploybot status --json` again. Never show a stale pause prompt when
Expand Down
2 changes: 1 addition & 1 deletion adapters/cursor/.cursor/mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"command": "uvx",
"args": [
"--from",
"deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@73004ea7c9dcb81e7f1281c0687aea0897d1571d",
"deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@12c6c03aa76a553fa4068279baa29e90a30bbeb1",
"deploybot-mcp"
]
}
Expand Down
4 changes: 4 additions & 0 deletions adapters/cursor/.cursor/rules/deploybot.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ the stable Cursor thread ID, never prompts or transcripts. Refresh intent only
after replacement-head review. Only the coordinator may react, integrate,
drain, follow, pause, or resume repaired work.

Honor `pipeline.release_admission`. In `merged` mode, admit the next independent
ready PR immediately after a healthy merge while release events continue CI,
deployment, and health tracking. A later failure pauses future merges normally.

Immediately before asking the user to unpause or take repair action, call
`pipeline_status` again and suppress the request if durable state is already
running or the release advanced. The original deploy instruction authorizes the
Expand Down
4 changes: 3 additions & 1 deletion adapters/cursor/.cursor/rules/manage-merge-queue.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ wakes GitHub and promotes only after fresh exact-head gates; never poll or merge
an unlabeled PR. Use `pipeline_status` and `react_to_delivery_event`, skip
blockers, honor dependencies, route overlaps or cumulative validation through
one integration PR, return repair packets to their source thread, atomically
resume after fresh review, and follow cumulative `main` through deployment.
resume after fresh review, and follow cumulative `main` through deployment. In
`release_admission = "merged"` mode, admit independent ready work immediately
after merge while later events continue release tracking.
4 changes: 3 additions & 1 deletion adapters/cursor/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ branch is itself a merge and is forbidden outside DeployBot.
Never poll, merge an unlabeled PR, or absorb unrelated work. Let the event worker
promote fresh exact heads, use one integration PR for overlaps or cumulative
validation, return repair packets to the source thread, atomically resume after
fresh review, and follow cumulative `main` through verified deployment.
fresh review, and follow cumulative `main` through verified deployment. When
`release_admission = "merged"`, admit independent ready work immediately after
merge while release events continue asynchronously; later failures still pause.

For each verified `thread_notifications` entry, post its message back to the
native PR-opening thread and only then call `acknowledge_thread_deployment`. Leave
Expand Down
6 changes: 3 additions & 3 deletions docs/reference.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# DeployBot reference

This reference describes the CLI, MCP server, policy file, and GitHub Action in
DeployBot v0.2.24. GitHub labels and authenticated comments are the durable state;
DeployBot v0.2.25. GitHub labels and authenticated comments are the durable state;
the CLI and MCP tools are two interfaces to the same operations.

## CLI
Expand Down Expand Up @@ -166,15 +166,15 @@ Provider fields are:
| `thread_active_hours` | Positive integer; default 72. Notification obligations and pending messages use their own non-expiring outbox. |
| `ci_workflows` | Workflow names followed as exact-main CI. Default: `["CI"]`. |
| `deploy_workflows` | Deployment workflow names. Default: `["Deploy"]`. |
| `batch_settle_seconds` | Non-negative window for coalescing near-ready deploy requests before freezing a batch. Default: 15. |
| `batch_settle_seconds` | Non-negative window for coalescing near-ready deploy requests before freezing a batch. Default: 0, so event-driven ready work freezes immediately; scheduled reconciliation is only a fallback. |
| `ci_failure_grace_seconds` | Non-negative window for an exact-main CI retry to replace a failed attempt before the release fails. Default: 90. |
| `promotion_workers` | Positive maximum number of deploy requests promoted concurrently. Default: 4. |
| `repair_hold_minutes` | Positive maximum time that a genuine repair may hold overlapping ready work without becoming merge-eligible. Default: 60. |
| repair handoff refresh | When `main` changes during a conflict repair, DeployBot emits a new `repair-required` handoff with the new base SHA for each affected source owner while preserving the original bounded hold start. |
| integration repair packet | Includes `source_pull_requests` and the complete `source_heads` map so the elected owner can verify every frozen source before resuming the cumulative PR. |
| suppressed integration PR run | Integration `pull_request` runs, including `action_required` zero-job placeholders, are not exact CI evidence. DeployBot uses its own exact-branch `workflow_dispatch` run, whose real failures still fail closed. |
| `hold_merges_while_releasing` | Default `true`; after a merge, admit no newer batch until the release reaches the `release_admission` gate. |
| `release_admission` | How far an in-flight release must progress before the next batch is admitted; allowed: `verified` (default, safest) waits for the cumulative exact-main revision to be live, `ci-passed` reopens admission once exact-main CI is green while deploy and health checks keep following in the background. `ci-passed` trades a larger failure blast radius for throughput, and verification and notifications for a release may be emitted by a later reaction rather than the merging one. |
| `release_admission` | How far an in-flight release must progress before the next independent batch is admitted. `merged` (default) reopens admission immediately after merge while CI, deployment, and health tracking continue asynchronously. `ci-passed` waits for exact-main CI; `verified` waits until the cumulative revision is live. A later observed CI, deployment, or health failure pauses future merges in every mode. |
| `repair_branch_prefix` | Deterministic release-repair lease branch prefix; default `"deploybot/repair"`. |
| `ready_to_merge_target_minutes` | Positive request-to-ready and queued-to-merge timing target; default 15. |
| `merge_to_live_target_minutes` | Positive timing target; default 10. |
Expand Down
Loading