Skip to content

Commit 32dfdf4

Browse files
Pigbibicodex
andcommitted
fix: avoid red PR review runs without AI backend
Co-Authored-By: Codex <noreply@openai.com>
1 parent b092fc5 commit 32dfdf4

2 files changed

Lines changed: 38 additions & 5 deletions

File tree

scripts/run_codex_pr_review.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
"rate limit",
4444
"quota",
4545
)
46+
NO_REVIEW_BACKEND_CONFIGURED = (
47+
"No Codex service URL or API key configured. "
48+
"Set CODEX_AUDIT_SERVICE_URL, ANTHROPIC_API_KEY, or OPENAI_API_KEY."
49+
)
4650

4751
# Risk → block mapping
4852
BLOCK_SEVERITIES = frozenset({"critical", "high"})
@@ -480,6 +484,10 @@ def _service_review_should_fallback(exc: ReviewError) -> bool:
480484
return any(signal in message for signal in CODEX_SERVICE_FALLBACK_SIGNALS)
481485

482486

487+
def _review_backend_is_unconfigured(exc: ReviewError) -> bool:
488+
return str(exc).strip() == NO_REVIEW_BACKEND_CONFIGURED
489+
490+
483491
def run_codex_review_with_fallback(
484492
prompt: str,
485493
timeout_minutes: int,
@@ -570,10 +578,7 @@ def run_direct_api_review(prompt: str, complexity: str = "") -> str:
570578
model=_direct_api_model_for_complexity(provider, normalized),
571579
)
572580

573-
raise ReviewError(
574-
"No Codex service URL or API key configured. "
575-
"Set CODEX_AUDIT_SERVICE_URL, ANTHROPIC_API_KEY, or OPENAI_API_KEY."
576-
)
581+
raise ReviewError(NO_REVIEW_BACKEND_CONFIGURED)
577582

578583

579584
def _run_anthropic_review(prompt: str, api_key: str, model: str = "") -> str:
@@ -985,7 +990,10 @@ def main() -> int:
985990
upsert_pr_comment(token, repo, pr_number, warning_body)
986991
return 0
987992

988-
# High-risk changes should not fail open on review infrastructure errors.
993+
# Caller repositories may not have the central AI backend secrets configured.
994+
# In that case, leave an explicit human-review note but do not create
995+
# persistent red workflow runs. Other high-risk review infrastructure
996+
# failures still fail closed.
989997
warning_body = (
990998
"<!-- codex-pr-review -->\n"
991999
"## 🤖 Codex PR Review\n\n"
@@ -994,6 +1002,9 @@ def main() -> int:
9941002
"Please ensure a human reviewer checks this PR before merging.\n"
9951003
)
9961004
upsert_pr_comment(token, repo, pr_number, warning_body)
1005+
if _review_backend_is_unconfigured(exc):
1006+
print("::warning::Codex review backend is not configured; leaving human-review note without failing the workflow.")
1007+
return 0
9971008
return 1
9981009

9991010
print(f"Codex output: {len(output)} chars")

tests/test_run_codex_pr_review.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,28 @@ def test_main_allows_low_risk_docs_on_review_infra_error(self) -> None:
124124

125125
comment.assert_called_once()
126126

127+
128+
def test_main_allows_unconfigured_backend_with_human_review_note(self) -> None:
129+
with tempfile.TemporaryDirectory() as tmpdir:
130+
event_path = self._write_event(tmpdir, ["scripts/run_codex_pr_review.py"])
131+
env = {
132+
"GH_TOKEN": "token",
133+
"GITHUB_REPOSITORY": "org/repo",
134+
"GITHUB_EVENT_PATH": event_path,
135+
"GITHUB_EVENT_NAME": "pull_request",
136+
}
137+
with (
138+
patch.dict(os.environ, env, clear=True),
139+
patch("scripts.run_codex_pr_review.fetch_pr_files", return_value=[{"filename": "scripts/run_codex_pr_review.py"}]),
140+
patch("scripts.run_codex_pr_review.fetch_pr_diff", return_value="diff --git a/scripts/run_codex_pr_review.py b/scripts/run_codex_pr_review.py"),
141+
patch("scripts.run_codex_pr_review.run_codex_review_with_fallback", side_effect=ReviewError(run_codex_pr_review.NO_REVIEW_BACKEND_CONFIGURED)),
142+
patch("scripts.run_codex_pr_review.upsert_pr_comment") as comment,
143+
):
144+
self.assertEqual(run_codex_pr_review.main(), 0)
145+
146+
comment.assert_called_once()
147+
self.assertIn("Human review required", comment.call_args.args[3])
148+
127149
def test_service_timeout_does_not_fall_back_to_direct_api(self) -> None:
128150
with (
129151
patch.dict(os.environ, {"CODEX_AUDIT_SERVICE_URL": "https://service.example"}, clear=True),

0 commit comments

Comments
 (0)