fix(gitea-review): PR/push AI analysis always failing — 兩個根因修復
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 17m26s

Root cause 1 (push review): local_code_review_service.review_push() 回傳
dict,但呼叫端直接存取 analysis.issues → AttributeError。
修復:_call_openclaw_push_review 將 dict 轉成 CodeReviewResult。

Root cause 2 (PR review): openclaw_http_service 呼叫
/api/v1/analyze/code-review 但 OpenClaw 從未實作此 endpoint(404)。
修復:_call_openclaw_code_review 改走 local_code_review_service.review_pr()
(Ollama qwen2.5-coder + Gemini fallback)。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-04-21 15:19:02 +08:00
parent 3c266190cf
commit acab1cd95e

View File

@@ -214,22 +214,27 @@ class GiteaWebhookService:
Phase 22 P0 修復: 使用 OpenClawHttpService (2026-03-31)
"""
try:
from src.services.openclaw_http_service import get_openclaw_http_service
service = get_openclaw_http_service()
data = await service.code_review(
repo_name=repo_name,
pr_title=pr_title,
pr_body=pr_body,
diff_content=diff_content,
changed_files=changed_files,
additions=additions,
deletions=deletions,
prefer_local=True,
timeout=120.0,
from src.services.local_code_review_service import get_local_code_review_service
svc = get_local_code_review_service()
pr_id = f"{repo_name}-{pr_title[:20]}"
result = await svc.review_pr(
pr_id=pr_id,
repo=repo_name,
title=pr_title,
diff=diff_content,
)
if data:
return CodeReviewResult(**data)
if result and isinstance(result, dict):
review_text = result.get("review_text", "")
issues_count = result.get("issues_count", 0)
return CodeReviewResult(
summary=review_text[:300] if review_text else "PR review completed",
issues=[{"text": line} for line in review_text.split("\n") if "⚠️" in line],
suggestions=[],
security_concerns=[],
quality_score=max(0.0, 100.0 - issues_count * 15),
analyzed_by=result.get("model", "ollama"),
confidence=0.7,
)
return None
except Exception as e:
@@ -268,7 +273,20 @@ class GiteaWebhookService:
commit_summary=commit_msgs,
files_summary=files_summary,
)
return result
# local_code_review_service 回傳 dict需轉成 CodeReviewResult
if result and isinstance(result, dict):
issues_count = result.get("issues_count", 0)
review_text = result.get("review_text", "")
return CodeReviewResult(
summary=review_text[:300] if review_text else "Push review completed",
issues=[{"text": line} for line in review_text.split("\n") if "⚠️" in line],
suggestions=[],
security_concerns=[],
quality_score=max(0.0, 100.0 - issues_count * 15),
analyzed_by=result.get("model", "ollama"),
confidence=0.7,
)
return result # type: ignore[return-value] # None case
except Exception as e:
logger.exception("openclaw_push_review_error", error=str(e))