diff --git a/README.md b/README.md index 2b92e2a..8a27ecd 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ integration PRs, follows `main` through production, and pauses after failures. ## Install -Install the reviewed `v0.2.0` source commit directly from GitHub: +Install the reviewed `v0.2.1` source commit directly from GitHub: ```bash python3 -m pip install \ - 'deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@2e884f65f182f6a9ddc4c4785288045bdf98f188' + 'deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@6ed5569ffbcbb4dea1dece6f889726b67d9411f2' deploybot init ``` @@ -86,7 +86,7 @@ aligned with `pipeline.ci_workflows`. The privileged worker never checks out or executes pull-request code. Pin the Action to the full reviewed release commit: ```yaml -- uses: Forward-Future/DeployBot@2e884f65f182f6a9ddc4c4785288045bdf98f188 +- uses: Forward-Future/DeployBot@6ed5569ffbcbb4dea1dece6f889726b67d9411f2 ``` The workflow bot and each person allowed to request deployment must be diff --git a/adapters/claude-code/.claude-plugin/plugin.json b/adapters/claude-code/.claude-plugin/plugin.json index 6cbeac2..c002716 100644 --- a/adapters/claude-code/.claude-plugin/plugin.json +++ b/adapters/claude-code/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "deploybot", - "version": "0.2.0", + "version": "0.2.1", "description": "DeployBot: a provider-neutral GitHub merge queue for coding agents", "author": { "name": "DeployBot contributors" diff --git a/adapters/claude-code/.mcp.json b/adapters/claude-code/.mcp.json index 0de772c..160d419 100644 --- a/adapters/claude-code/.mcp.json +++ b/adapters/claude-code/.mcp.json @@ -4,7 +4,7 @@ "command": "uvx", "args": [ "--from", - "deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@2e884f65f182f6a9ddc4c4785288045bdf98f188", + "deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@6ed5569ffbcbb4dea1dece6f889726b67d9411f2", "deploybot-mcp" ] } diff --git a/adapters/codex/agent-merge-queue/.codex-plugin/plugin.json b/adapters/codex/agent-merge-queue/.codex-plugin/plugin.json index 8cfbebf..d059ced 100644 --- a/adapters/codex/agent-merge-queue/.codex-plugin/plugin.json +++ b/adapters/codex/agent-merge-queue/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "deploybot", - "version": "0.2.0", + "version": "0.2.1", "description": "Review, queue, and land pull requests through a shared GitHub merge queue", "author": { "name": "DeployBot contributors" diff --git a/adapters/codex/agent-merge-queue/.mcp.json b/adapters/codex/agent-merge-queue/.mcp.json index 0de772c..160d419 100644 --- a/adapters/codex/agent-merge-queue/.mcp.json +++ b/adapters/codex/agent-merge-queue/.mcp.json @@ -4,7 +4,7 @@ "command": "uvx", "args": [ "--from", - "deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@2e884f65f182f6a9ddc4c4785288045bdf98f188", + "deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@6ed5569ffbcbb4dea1dece6f889726b67d9411f2", "deploybot-mcp" ] } diff --git a/adapters/cursor/.cursor/mcp.json b/adapters/cursor/.cursor/mcp.json index 0de772c..160d419 100644 --- a/adapters/cursor/.cursor/mcp.json +++ b/adapters/cursor/.cursor/mcp.json @@ -4,7 +4,7 @@ "command": "uvx", "args": [ "--from", - "deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@2e884f65f182f6a9ddc4c4785288045bdf98f188", + "deploybot-merge-queue[mcp] @ git+https://github.com/Forward-Future/DeployBot.git@6ed5569ffbcbb4dea1dece6f889726b67d9411f2", "deploybot-mcp" ] } diff --git a/examples/github-workflow.yml b/examples/github-workflow.yml index fe9b7ad..0ed7a1b 100644 --- a/examples/github-workflow.yml +++ b/examples/github-workflow.yml @@ -37,5 +37,5 @@ jobs: with: ref: ${{ github.event.repository.default_branch }} persist-credentials: false - # v0.2.0 implementation; keep the full commit for privileged workflows. - - uses: Forward-Future/DeployBot@2e884f65f182f6a9ddc4c4785288045bdf98f188 + # v0.2.1 implementation; keep the full commit for privileged workflows. + - uses: Forward-Future/DeployBot@6ed5569ffbcbb4dea1dece6f889726b67d9411f2 diff --git a/pyproject.toml b/pyproject.toml index ffd52d1..8d02f23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "deploybot-merge-queue" -version = "0.2.0" +version = "0.2.1" description = "DeployBot: a provider-neutral GitHub merge queue for coding agents" readme = "README.md" license = "MIT" diff --git a/src/agent_merge_queue/__init__.py b/src/agent_merge_queue/__init__.py index 7997dca..d271b3d 100644 --- a/src/agent_merge_queue/__init__.py +++ b/src/agent_merge_queue/__init__.py @@ -1,3 +1,3 @@ """DeployBot: a provider-neutral GitHub merge queue for coding agents.""" -__version__ = "0.2.0" +__version__ = "0.2.1" diff --git a/src/agent_merge_queue/doctor.py b/src/agent_merge_queue/doctor.py index bb74625..4b2e314 100644 --- a/src/agent_merge_queue/doctor.py +++ b/src/agent_merge_queue/doctor.py @@ -58,18 +58,20 @@ def diagnose( ] rows.append(row("tooling", "ok", "GitHub CLI is installed")) - code, auth = _gh("auth", "status", cwd=root) + code, _ = _gh("auth", "status", cwd=root) authenticated = code == 0 + auth_detail = "GitHub authentication is not active" + if authenticated: + auth_detail = "GitHub authentication is active" + user_code, user, _ = _json("api", "user", cwd=root) + login = str((user or {}).get("login") or "") if user_code == 0 else "" + if login: + auth_detail += f" for {login}" rows.append( row( "authentication", "ok" if authenticated else "fail", - auth - or ( - "GitHub authentication is active" - if authenticated - else "Not authenticated" - ), + auth_detail, None if authenticated else "Run `gh auth login`.", ) ) diff --git a/tests/test_doctor.py b/tests/test_doctor.py index f9b1238..aa94a89 100644 --- a/tests/test_doctor.py +++ b/tests/test_doctor.py @@ -36,6 +36,47 @@ def test_bad_config_is_reported_without_traceback(self) -> None: self.assertEqual(config["status"], "fail") self.assertIn("invalid merge queue config", config["detail"]) + def test_auth_output_never_returns_token_or_scope_material(self) -> None: + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + (root / ".mergequeue.toml").write_text( + '[queue]\nrequired_checks = ["CI"]\ntrusted_actors = ["trusted"]\n', + encoding="utf-8", + ) + + def fake_json(*arguments: str, cwd: Path): + joined = " ".join(arguments) + if joined == "api user": + return 0, {"login": "safe-user"}, "" + if "users/trusted" in joined: + return 0, {"login": "trusted"}, "" + if "workflow list" in joined or "label list" in joined: + return 0, [], "" + if "pr list" in joined: + return 0, [], "" + if "protection" in joined: + return 1, None, "not available" + return 0, {"nameWithOwner": "owner/repo"}, "" + + with ( + patch( + "agent_merge_queue.doctor.shutil.which", return_value="/usr/bin/gh" + ), + patch( + "agent_merge_queue.doctor._gh", + return_value=(0, "Token: gho_secret; scopes: repo"), + ), + patch("agent_merge_queue.doctor._json", side_effect=fake_json), + ): + rows = diagnose(config_path=None, repository="owner/repo", cwd=root) + + auth = next(value for value in rows if value["check"] == "authentication") + self.assertEqual( + auth["detail"], "GitHub authentication is active for safe-user" + ) + self.assertNotIn("Token", str(rows)) + self.assertNotIn("scope", str(rows)) + def test_missing_labels_and_check_name_are_advisory(self) -> None: with tempfile.TemporaryDirectory() as temp: root = Path(temp) diff --git a/tests/test_skill.py b/tests/test_skill.py index a85645f..7806df6 100644 --- a/tests/test_skill.py +++ b/tests/test_skill.py @@ -6,7 +6,7 @@ ROOT = Path(__file__).resolve().parents[1] CANONICAL = ROOT / "skills" / "deploybot" / "SKILL.md" -RELEASE_COMMIT = "2e884f65f182f6a9ddc4c4785288045bdf98f188" +RELEASE_COMMIT = "6ed5569ffbcbb4dea1dece6f889726b67d9411f2" CHECKOUT_COMMIT = "9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"