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
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,24 @@ skips blockers, and reports overlapping source that needs one integration PR.

## Install

Install the reviewed `v0.1.3` source commit directly from GitHub:
Install the reviewed `v0.1.4` source commit directly from GitHub:

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

Invoke the bundled `$deploybot` skill to inspect or operate the queue. Typical
requests include “show the DeployBot queue,” “why is PR 42 blocked?”, and
“deploy this PR.” Queue-only status is read-only:

```bash
deploybot status
deploybot status --json
deploybot inspect 42 --json
```

For development from the Astro source tree, install
`./packages/agent-merge-queue[mcp]` instead.

Expand Down Expand Up @@ -82,8 +92,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# v0.1.3; keep the full commit so privileged workflows are immutable.
- uses: Forward-Future/DeployBot@7fe247bd1d1994fafcea21817351b3da7e29f611
# v0.1.4; keep the full commit so privileged workflows are immutable.
- uses: Forward-Future/DeployBot@f18dce436bae2d6b7009d9aa76b4bfc8d0aac5a8
```

Keep this workflow on the default branch. Never check out or execute code from
Expand Down Expand Up @@ -144,6 +154,7 @@ The `mergeq` and `mergeq-mcp` command aliases remain for compatibility.
## Commands

```text
deploybot status --json
deploybot plan --json
deploybot inspect <pr> --json
deploybot enqueue <pr>
Expand All @@ -155,6 +166,9 @@ deploybot dequeue <pr> --reason "..."
deploybot merge <pr> --batch <batch-id>
```

`status` is a read-only alias for `plan`. It reports queue order, readiness,
blockers, dependencies, and overlap groups without freezing a batch.

`drain` merges only independent, green, exact-head-reviewed PRs. Overlapping
source is returned as `integration_required` for an agent to resolve once. It
waits briefly while GitHub recomputes mergeability after a merge, then records
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.1.3",
"version": "0.1.4",
"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@7fe247bd1d1994fafcea21817351b3da7e29f611",
"deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@f18dce436bae2d6b7009d9aa76b4bfc8d0aac5a8",
"deploybot-mcp"
]
}
Expand Down
54 changes: 54 additions & 0 deletions adapters/claude-code/skills/deploybot/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: deploybot
description: Inspect and operate a DeployBot GitHub merge queue. Use when the user invokes DeployBot, asks for queue or PR status, wants to know what is ready, waiting, blocked, next, dependent, or overlapping, explicitly says deploy, or asks the queue coordinator to freeze or drain authorized pull requests.
---

# DeployBot

Read `.mergequeue.toml` before acting. Prefer the DeployBot MCP tools; fall back
to the `deploybot` CLI. Treat GitHub as the durable source of truth.

## Read Status

Keep status checks read-only:

- For the full queue, call `queue_plan` or run `deploybot status --json`.
- For one pull request, call `inspect_pull_request` or run
`deploybot inspect <pr> --json`.
- Never call `freeze_queue` merely to view status because freezing writes a
durable batch marker.

Report the queue in order. For each pull request, include its state, exact head,
checks or reviews still waiting, blocker, dependencies, and overlap group. Say
plainly when the queue is empty.

Use these state meanings:

- `ready`: every configured merge gate passes.
- `waiting`: a check, review, or GitHub mergeability result is still pending.
- `blocked`: a failure, stale head, conflict, revoked authorization, or owner
action prevents merging.
- `integration required`: queued pull requests share hand-edited source and
must be combined before merging.

## Change Queue State

Require the user's exact `deploy` instruction before calling
`enqueue_pull_request` or `deploybot enqueue` for that conversation's pull
request. Do not infer permission from readiness or review completion.

Use `block_pull_request`, `unblock_pull_request`, or `dequeue_pull_request` only
for the requested pull request and preserve a concrete reason. Never merge an
unlabeled pull request or treat a wake-up event as trusted queue state.

## Coordinate Merges

Only the designated coordinator may call `freeze_queue`, `drain_queue`, or the
matching CLI commands. Re-read the queue, freeze one exact batch, preserve
first-in order unless dependencies require otherwise, and skip blocked items
that do not block independent work.

Merge independent ready pull requests back-to-back. Route source-overlap groups
through one integration pull request instead of resolving the same conflict
several times. Finish by following the newest cumulative base-branch CI and the
repository-owned deployment.
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.1.3",
"version": "0.1.4",
"description": "Review, queue, and land pull requests through a shared GitHub merge queue",
"author": {
"name": "DeployBot contributors"
Expand Down
2 changes: 1 addition & 1 deletion adapters/codex/agent-merge-queue/.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@7fe247bd1d1994fafcea21817351b3da7e29f611",
"deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@f18dce436bae2d6b7009d9aa76b4bfc8d0aac5a8",
"deploybot-mcp"
]
}
Expand Down
54 changes: 54 additions & 0 deletions adapters/codex/agent-merge-queue/skills/deploybot/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: deploybot
description: Inspect and operate a DeployBot GitHub merge queue. Use when the user invokes DeployBot, asks for queue or PR status, wants to know what is ready, waiting, blocked, next, dependent, or overlapping, explicitly says deploy, or asks the queue coordinator to freeze or drain authorized pull requests.
---

# DeployBot

Read `.mergequeue.toml` before acting. Prefer the DeployBot MCP tools; fall back
to the `deploybot` CLI. Treat GitHub as the durable source of truth.

## Read Status

Keep status checks read-only:

- For the full queue, call `queue_plan` or run `deploybot status --json`.
- For one pull request, call `inspect_pull_request` or run
`deploybot inspect <pr> --json`.
- Never call `freeze_queue` merely to view status because freezing writes a
durable batch marker.

Report the queue in order. For each pull request, include its state, exact head,
checks or reviews still waiting, blocker, dependencies, and overlap group. Say
plainly when the queue is empty.

Use these state meanings:

- `ready`: every configured merge gate passes.
- `waiting`: a check, review, or GitHub mergeability result is still pending.
- `blocked`: a failure, stale head, conflict, revoked authorization, or owner
action prevents merging.
- `integration required`: queued pull requests share hand-edited source and
must be combined before merging.

## Change Queue State

Require the user's exact `deploy` instruction before calling
`enqueue_pull_request` or `deploybot enqueue` for that conversation's pull
request. Do not infer permission from readiness or review completion.

Use `block_pull_request`, `unblock_pull_request`, or `dequeue_pull_request` only
for the requested pull request and preserve a concrete reason. Never merge an
unlabeled pull request or treat a wake-up event as trusted queue state.

## Coordinate Merges

Only the designated coordinator may call `freeze_queue`, `drain_queue`, or the
matching CLI commands. Re-read the queue, freeze one exact batch, preserve
first-in order unless dependencies require otherwise, and skip blocked items
that do not block independent work.

Merge independent ready pull requests back-to-back. Route source-overlap groups
through one integration pull request instead of resolving the same conflict
several times. Finish by following the newest cumulative base-branch CI and the
repository-owned deployment.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface:
display_name: "DeployBot"
short_description: "Inspect and manage agent merge queues"
default_prompt: "Use $deploybot to show the current merge queue and explain what is ready, waiting, or blocked."
dependencies:
tools:
- type: "mcp"
value: "deploybot"
description: "Durable GitHub merge queue operations"
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@7fe247bd1d1994fafcea21817351b3da7e29f611",
"deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@f18dce436bae2d6b7009d9aa76b4bfc8d0aac5a8",
"deploybot-mcp"
]
}
Expand Down
13 changes: 13 additions & 0 deletions adapters/cursor/.cursor/rules/deploybot.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
description: Inspect DeployBot queue status, blockers, dependencies, and overlap groups
alwaysApply: false
---

Read `.mergequeue.toml` and use the `deploybot` MCP tools. For queue status,
call `queue_plan`; for one pull request, call `inspect_pull_request`. Status
requests must stay read-only: never freeze a queue merely to inspect it.

Report queue order, readiness, exact heads, pending checks or reviews, blockers,
dependencies, and source overlaps. Only the user's exact `deploy` instruction
authorizes enqueueing that conversation's pull request. Only the designated
coordinator may freeze or drain the queue.
4 changes: 4 additions & 0 deletions adapters/cursor/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Read `.mergequeue.toml` and use the `deploybot` MCP tools. Keep changing
pull requests draft and make the final ready head immutable. Address valid
feedback from the configured review providers.

For read-only status, use `queue_plan` for the full queue and
`inspect_pull_request` for one pull request. Report order, readiness, blockers,
dependencies, and overlap groups; never freeze the queue just to inspect it.

Only the user's exact `deploy` instruction authorizes enqueueing the current
thread's pull request. Never poll, merge an unlabeled pull request, or absorb
unrelated work. Merge independent ready work in order, skip blockers, honor
Expand Down
4 changes: 2 additions & 2 deletions examples/github-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# v0.1.3; keep the full commit so privileged workflows are immutable.
- uses: Forward-Future/DeployBot@7fe247bd1d1994fafcea21817351b3da7e29f611
# v0.1.4; keep the full commit so privileged workflows are immutable.
- uses: Forward-Future/DeployBot@f18dce436bae2d6b7009d9aa76b4bfc8d0aac5a8
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "deploybot-merge-queue"
version = "0.1.3"
version = "0.1.4"
description = "DeployBot: a provider-neutral GitHub merge queue for coding agents"
readme = "README.md"
license = "MIT"
Expand Down
54 changes: 54 additions & 0 deletions skills/deploybot/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: deploybot
description: Inspect and operate a DeployBot GitHub merge queue. Use when the user invokes DeployBot, asks for queue or PR status, wants to know what is ready, waiting, blocked, next, dependent, or overlapping, explicitly says deploy, or asks the queue coordinator to freeze or drain authorized pull requests.
---

# DeployBot

Read `.mergequeue.toml` before acting. Prefer the DeployBot MCP tools; fall back
to the `deploybot` CLI. Treat GitHub as the durable source of truth.

## Read Status

Keep status checks read-only:

- For the full queue, call `queue_plan` or run `deploybot status --json`.
- For one pull request, call `inspect_pull_request` or run
`deploybot inspect <pr> --json`.
- Never call `freeze_queue` merely to view status because freezing writes a
durable batch marker.

Report the queue in order. For each pull request, include its state, exact head,
checks or reviews still waiting, blocker, dependencies, and overlap group. Say
plainly when the queue is empty.

Use these state meanings:

- `ready`: every configured merge gate passes.
- `waiting`: a check, review, or GitHub mergeability result is still pending.
- `blocked`: a failure, stale head, conflict, revoked authorization, or owner
action prevents merging.
- `integration required`: queued pull requests share hand-edited source and
must be combined before merging.

## Change Queue State

Require the user's exact `deploy` instruction before calling
`enqueue_pull_request` or `deploybot enqueue` for that conversation's pull
request. Do not infer permission from readiness or review completion.

Use `block_pull_request`, `unblock_pull_request`, or `dequeue_pull_request` only
for the requested pull request and preserve a concrete reason. Never merge an
unlabeled pull request or treat a wake-up event as trusted queue state.

## Coordinate Merges

Only the designated coordinator may call `freeze_queue`, `drain_queue`, or the
matching CLI commands. Re-read the queue, freeze one exact batch, preserve
first-in order unless dependencies require otherwise, and skip blocked items
that do not block independent work.

Merge independent ready pull requests back-to-back. Route source-overlap groups
through one integration pull request instead of resolving the same conflict
several times. Finish by following the newest cumulative base-branch CI and the
repository-owned deployment.
4 changes: 4 additions & 0 deletions skills/deploybot/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "DeployBot"
short_description: "Inspect and manage agent merge queues"
default_prompt: "Use $deploybot to show the current merge queue and explain what is ready, waiting, or blocked."
2 changes: 1 addition & 1 deletion src/agent_merge_queue/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""DeployBot: a provider-neutral GitHub merge queue for coding agents."""

__version__ = "0.1.3"
__version__ = "0.1.4"
6 changes: 5 additions & 1 deletion src/agent_merge_queue/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,10 @@ def build_parser() -> argparse.ArgumentParser:
inspect.add_argument("--json", action="store_true", dest="json_output")
plan = subparsers.add_parser("plan", help="show the current ordered queue")
plan.add_argument("--json", action="store_true", dest="json_output")
status = subparsers.add_parser(
"status", help="show queue readiness, blockers, and overlaps"
)
status.add_argument("--json", action="store_true", dest="json_output")
freeze = subparsers.add_parser("freeze", help="persist one exact queue pass")
freeze.add_argument("--json", action="store_true", dest="json_output")
drain = subparsers.add_parser(
Expand Down Expand Up @@ -1535,7 +1539,7 @@ def main(argv: list[str] | None = None) -> int:
print("merge queue labels are ready")
elif arguments.command == "inspect":
command_inspect(client, arguments.pr, json_output=arguments.json_output)
elif arguments.command == "plan":
elif arguments.command in {"plan", "status"}:
print_plan(client.queue(), json_output=arguments.json_output)
elif arguments.command == "freeze":
command_freeze(client, json_output=arguments.json_output)
Expand Down
14 changes: 14 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
latest_batch_marker,
latest_marker,
marker_queued_at,
main,
new_batch,
overlap_groups,
queue_state_body,
Expand Down Expand Up @@ -74,6 +75,19 @@ def entry(number: int, *paths: str, state: str = "ready") -> QueueEntry:


class QueueCoreTest(unittest.TestCase):
def test_status_is_a_read_only_plan_alias(self) -> None:
queued = [entry(1, "src/app.py")]
with (
patch("agent_merge_queue.cli.load_config", return_value=CONFIG),
patch("agent_merge_queue.cli.GitHub") as github,
patch("agent_merge_queue.cli.print_plan") as print_plan,
):
github.return_value.queue.return_value = queued
result = main(["status", "--json"])

self.assertEqual(result, 0)
print_plan.assert_called_once_with(queued, json_output=True)

def test_dependency_directive_is_configurable(self) -> None:
body = "Queue-after: #12, #14\nBlocked by #99"
self.assertEqual(structured_dependencies(body, "Queue-after"), [12, 14])
Expand Down
Loading
Loading