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
1 change: 1 addition & 0 deletions .github/scripts/__tests__/bot-comment-handler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ test('default bot author allowlist recognizes canonical review bots', () => {
'copilot-pull-request-reviewer',
'copilot-pull-request-reviewer[bot]',
'github-actions[bot]',
'coderabbitai',
'coderabbitai[bot]',
'chatgpt-codex-connector',
'chatgpt-codex-connector[bot]',
Expand Down
1 change: 1 addition & 0 deletions .github/scripts/bot-comment-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const DEFAULT_BOT_AUTHORS = Object.freeze([
'copilot-pull-request-reviewer',
'copilot-pull-request-reviewer[bot]',
'github-actions[bot]',
'coderabbitai',
Comment thread
stranske marked this conversation as resolved.
'coderabbitai[bot]',
'chatgpt-codex-connector',
'chatgpt-codex-connector[bot]',
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/reusable-bot-comment-handler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ on:
default: >-
Copilot,copilot[bot],copilot-pull-request-reviewer,
copilot-pull-request-reviewer[bot],
github-actions[bot],coderabbitai[bot],
github-actions[bot],coderabbitai,coderabbitai[bot],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
chatgpt-codex-connector,chatgpt-codex-connector[bot]
skip_if_human_replied:
description: 'Legacy option: skip active threads after any non-bot reply'
Expand Down Expand Up @@ -72,7 +72,7 @@ on:
default: >-
Copilot,copilot[bot],copilot-pull-request-reviewer,
copilot-pull-request-reviewer[bot],
github-actions[bot],coderabbitai[bot],
github-actions[bot],coderabbitai,coderabbitai[bot],
chatgpt-codex-connector,chatgpt-codex-connector[bot]
skip_if_human_replied:
description: 'Legacy option: skip active threads after any non-bot reply'
Expand Down
2 changes: 1 addition & 1 deletion docs/bot-comment-handler.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ By default, the workflow processes comments from:
- `copilot-pull-request-reviewer` - GitHub Copilot pull-request review
- `copilot-pull-request-reviewer[bot]` - GitHub Copilot reviewer bot variant
- `github-actions[bot]` - GitHub Actions (lint, type check suggestions)
- `coderabbitai[bot]` - CodeRabbit AI review
- `coderabbitai` and `coderabbitai[bot]` - CodeRabbit AI review identities
- `chatgpt-codex-connector` - Codex connector review
- `chatgpt-codex-connector[bot]` - Codex connector bot identity

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const DEFAULT_BOT_AUTHORS = Object.freeze([
'copilot-pull-request-reviewer',
'copilot-pull-request-reviewer[bot]',
'github-actions[bot]',
'coderabbitai',
'coderabbitai[bot]',
'chatgpt-codex-connector',
'chatgpt-codex-connector[bot]',
Expand Down
28 changes: 27 additions & 1 deletion tests/workflows/test_bot_comment_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ def _load_yaml(path: Path) -> dict:
return yaml.safe_load(path.read_text(encoding="utf-8")) or {}


def _bot_author_tokens(bot_authors: str) -> set[str]:
return {item.strip() for item in bot_authors.split(",") if item.strip()}


def test_reusable_bot_comment_handler_ignores_agents_paths() -> None:
workflow = _load_yaml(ROOT / ".github/workflows/reusable-bot-comment-handler.yml")
triggers = workflow.get("on") or workflow.get(True) or {}
Expand All @@ -18,12 +22,30 @@ def test_reusable_bot_comment_handler_ignores_agents_paths() -> None:
assert ignored_paths is not None
assert ".agents/" in ignored_paths.split(",")

bot_authors = inputs.get("bot_authors", {}).get("default", "")
bot_authors = _bot_author_tokens(inputs.get("bot_authors", {}).get("default", ""))
assert "copilot-pull-request-reviewer" in bot_authors
assert "copilot-pull-request-reviewer[bot]" in bot_authors
assert "coderabbitai" in bot_authors
assert "coderabbitai[bot]" in bot_authors
assert "chatgpt-codex-connector[bot]" in bot_authors


def test_reusable_bot_comment_handler_default_bot_authors_include_coderabbit_identities() -> None:
workflow = _load_yaml(ROOT / ".github/workflows/reusable-bot-comment-handler.yml")
triggers = workflow.get("on") or workflow.get(True) or {}

call_authors = _bot_author_tokens(triggers["workflow_call"]["inputs"]["bot_authors"]["default"])
dispatch_authors = _bot_author_tokens(
triggers["workflow_dispatch"]["inputs"]["bot_authors"]["default"]
)

for identity in ("coderabbitai", "coderabbitai[bot]"):
assert identity in call_authors
assert identity in dispatch_authors

assert call_authors == dispatch_authors


def test_canonical_bot_comment_handler_keeps_source_templates_in_scope() -> None:
workflow = _load_yaml(ROOT / ".github/workflows/agents-bot-comment-handler.yml")
ignored_paths = workflow["jobs"]["handle"]["with"]["ignored_paths"].split(",")
Expand Down Expand Up @@ -72,6 +94,9 @@ def test_reusable_bot_comment_handler_has_manual_terminal_probe() -> None:

assert dispatch_inputs["pr_number"].get("required") is True
assert dispatch_inputs["dry_run"].get("default") is True
assert dispatch_inputs["bot_authors"].get("default") == call_inputs["bot_authors"].get(
"default"
)
assert dispatch_inputs["ignored_paths"].get("default") == call_inputs["ignored_paths"].get(
"default"
)
Expand Down Expand Up @@ -421,6 +446,7 @@ def test_template_event_hub_uses_reusable_bot_comment_handler_defaults() -> None
== "stranske/Workflows/.github/workflows/reusable-bot-comment-handler.yml@main"
)
assert "ignored_paths" not in inputs
assert "bot_authors" not in inputs


def test_reusable_bot_comment_handler_dismisses_ignored_reviews() -> None:
Expand Down
Loading