update-readme #4

Merged
armistace merged 2 commits from update-readme into master 2026-05-21 21:17:18 +10:00
Showing only changes of commit bc7ddd29d4 - Show all commits

View File

@ -3,7 +3,7 @@ import os
import hmac
import hashlib
import base64
from fastapi import FastAPI, HTTPException, Request
from fastapi import FastAPI, HTTPException, Request, BackgroundTasks
from fastapi.responses import JSONResponse
import uvicorn
from typing import Dict, Any, List, Optional
@ -89,8 +89,58 @@ def post_pr_comment(repo_full: str, pr_number: int, comment: str) -> None:
logger.info(f"Posted review comment to PR #{pr_number} in {repo_full}")
def _run_review_background(repo_full: str, pr_number: int, pr_title: str,
pr_description: str, repo_url: str, branch: str,
base_branch: str, files: List[Dict[str, Any]]) -> None:
converted_files = []
for f in files:
converted_files.append(FileInfo(
path=f["filename"],
content=f.get("content"),
status=f.get("status", "modified"),
additions=f.get("additions", 0),
deletions=f.get("deletions", 0),
patch=f.get("patch"),
))
flow_inputs = {
"pr_id": str(pr_number),
"pr_title": pr_title,
"pr_description": pr_description,
"pr_url": f"{repo_url}/pull/{pr_number}",
"repo_name": repo_full,
"repo_url": repo_url,
"branch": branch,
"base_branch": base_branch,
"files": [f.dict() for f in converted_files],
"context_overrides": None,
}
flow = CodeReviewFlow()
try:
flow_result = flow.kickoff(inputs=flow_inputs)
except Exception as e:
logger.error(f"Background review failed for PR #{pr_number}: {e}")
try:
post_pr_comment(repo_full, pr_number, f"**PR Review failed:** {e}")
except Exception:
pass
return
if flow_result.get("error"):
logger.error(f"PR review failed for PR #{pr_number}: {flow_result['error']}")
try:
summary = flow_result.get("review_summary", "")
if summary:
comment = f"## PR Review Results\n\n{summary}"
post_pr_comment(repo_full, pr_number, comment)
except Exception as e:
logger.warning(f"Failed to post review comment: {e}")
@app.post("/api/v1/gitea-webhook")
async def gitea_webhook(request: Request) -> Dict[str, Any]:
async def gitea_webhook(request: Request, background_tasks: BackgroundTasks) -> Dict[str, Any]:
body = await request.body()
sig = request.headers.get("X-Gitea-Signature", "")
if not verify_signature(body, sig):
@ -107,7 +157,7 @@ async def gitea_webhook(request: Request) -> Dict[str, Any]:
repo_full = repo["full_name"]
repo_url = repo.get("html_url", f"{ACCESS_GITEA_URL}/{repo_full}")
if action not in ("opened", "synchronize", "reopened"):
if action not in ("opened", "synchronized", "reopened"):
logger.info(f"Ignoring PR action: {action}")
return {"status": "ignored", "reason": f"action '{action}' not processed"}
@ -119,62 +169,24 @@ async def gitea_webhook(request: Request) -> Dict[str, Any]:
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error fetching PR files: {e}")
converted_files = []
for f in files:
converted_files.append(FileInfo(
path=f["filename"],
content=f.get("content"),
status=f.get("status", "modified"),
additions=f.get("additions", 0),
deletions=f.get("deletions", 0),
patch=f.get("patch"),
))
flow_inputs = {
"pr_id": str(pr_number),
"pr_title": pr["title"],
"pr_description": pr.get("body", ""),
"pr_url": f"{repo_url}/pull/{pr_number}",
"repo_name": repo_full,
"repo_url": repo_url,
"branch": pr["head"]["label"],
"base_branch": pr["base"]["label"],
"files": [f.dict() for f in converted_files],
"context_overrides": None,
}
flow = CodeReviewFlow()
loop = asyncio.get_event_loop()
with ThreadPoolExecutor() as pool:
try:
flow_result = await asyncio.wait_for(
loop.run_in_executor(pool, lambda: flow.kickoff(inputs=flow_inputs)),
timeout=TOTAL_FLOW_TIMEOUT,
)
except asyncio.TimeoutError:
logger.error(f"PR review timed out for PR #{pr_number}")
raise HTTPException(
status_code=504,
detail=f"PR review timed out after {TOTAL_FLOW_TIMEOUT} seconds",
)
if flow_result.get("error"):
logger.error(f"PR review failed for PR #{pr_number}: {flow_result['error']}")
try:
summary = flow_result.get("review_summary", "")
if summary:
comment = f"## PR Review Results\n\n{summary}"
post_pr_comment(repo_full, pr_number, comment)
post_pr_comment(repo_full, pr_number, "PR received — starting review, sit tight :saluting_face:")
except Exception as e:
logger.warning(f"Failed to post review comment: {e}")
logger.warning(f"Failed to post initial comment: {e}")
return {
"status": "completed" if not flow_result.get("error") else "failed",
"pr_number": pr_number,
"review_summary": flow_result.get("review_summary"),
"error": flow_result.get("error"),
}
background_tasks.add_task(
_run_review_background,
repo_full=repo_full,
pr_number=pr_number,
pr_title=pr["title"],
pr_description=pr.get("body", ""),
repo_url=repo_url,
branch=pr["head"]["label"],
base_branch=pr["base"]["label"],
files=files,
)
return {"status": "accepted", "pr_number": pr_number}
return {"status": "ignored"}