Some checks failed
Build and Deploy Log Center / build-and-deploy (push) Failing after 1m55s
9.2 KiB
9.2 KiB
PR 操作功能实施完成
实施日期: 2026-02-25 状态: ✅ 已完成
📋 已实现功能
✅ 1. 数据库字段扩展
文件: app/models.py
新增字段:
# PR Tracking
pr_number: Optional[int] # PR 编号
pr_url: Optional[str] # PR 链接
branch_name: Optional[str] # 分支名称
# Rejection Tracking
rejection_reason: Optional[str] # 拒绝原因 JSON
rejection_count: int # 拒绝次数
last_rejected_at: Optional[datetime] # 最后拒绝时间
merged_at: Optional[datetime] # 合并时间
✅ 2. Gitea API 客户端
文件: app/gitea_client.py
功能:
merge_pr()- 合并 PRclose_pr()- 关闭 PR(带原因评论)add_pr_comment()- 添加评论merge_pr_by_url()- 通过 URL 直接合并close_pr_by_url()- 通过 URL 直接关闭
✅ 3. 后端 API 接口
文件: app/main.py
新增接口:
POST /api/v1/bugs/{bug_id}/merge-pr
批准并合并 PR
请求:无需 body
响应:
{
"message": "PR 已合并",
"pr_url": "https://gitea.xxx/owner/repo/pulls/45",
"bug_id": 123,
"new_status": "FIXED"
}
POST /api/v1/bugs/{bug_id}/close-pr
拒绝修复并关闭 PR
请求 Body:
{
"reason": "测试覆盖不足,缺少边界条件测试"
}
响应:
{
"message": "PR 已拒绝,Bug 将重新修复",
"rejection_count": 1,
"bug_id": 123,
"new_status": "PENDING_FIX"
}
✅ 4. 前端界面
文件: web/src/pages/BugDetail.tsx
新增组件:
-
PR 信息展示区
- 显示 PR 编号、分支名
- "查看 PR" 外链按钮
- 拒绝次数提示
-
操作按钮
- ✅ 批准并合并 按钮(绿色)
- ❌ 拒绝修复 按钮(红色)
-
拒绝原因模态框
- 常用模板快速填充
- 文本输入框(详细原因)
- 确认/取消按钮
-
状态消息
- 操作成功/失败提示
- 上次拒绝原因显示
🎯 使用流程
场景 1:批准并合并
1. 打开 Bug 详情页
2. 查看 PR 信息(可点击"查看 PR"跳转到 Gitea)
3. 确认修复正确
4. 点击 "批准并合并" 按钮
↓
✅ PR 合并成功,Bug 状态 → FIXED
场景 2:拒绝修复
1. 打开 Bug 详情页
2. 查看 PR 信息
3. 发现问题,点击 "拒绝修复" 按钮
4. 弹出模态框:
- 可点击模板快速填充常用原因
- 或手动输入详细原因
5. 点击 "确认拒绝"
↓
✅ PR 已关闭,Bug 状态 → PENDING_FIX
✅ 原因已记录,Agent 将结合原因重新修复
⚙️ 配置步骤
1. 配置 Gitea 凭证
创建 /log_center/app/.env 文件:
# Gitea 配置
GITEA_URL=https://gitea.airlabs.art
GITEA_TOKEN=your_gitea_token_here
获取 Gitea Token:
- 登录 Gitea
- 设置 → 应用 → 生成新令牌
- 权限:
repo(读写仓库) - 复制 Token 到
.env
2. 数据库迁移
需要执行数据库迁移添加新字段:
-- 手动执行或使用 Alembic
ALTER TABLE errorlog ADD COLUMN pr_number INT;
ALTER TABLE errorlog ADD COLUMN pr_url VARCHAR(500);
ALTER TABLE errorlog ADD COLUMN branch_name VARCHAR(200);
ALTER TABLE errorlog ADD COLUMN rejection_reason TEXT;
ALTER TABLE errorlog ADD COLUMN rejection_count INT DEFAULT 0;
ALTER TABLE errorlog ADD COLUMN last_rejected_at TIMESTAMP;
ALTER TABLE errorlog ADD COLUMN merged_at TIMESTAMP;
3. 重启服务
# 后端
cd /log_center/app
uvicorn main:app --reload
# 前端
cd /log_center/web
npm run dev
🧪 测试
测试 Gitea API(可选)
使用测试脚本验证 API:
cd /log_center/repair_agent
python test_gitea_api.py \
--gitea-url https://gitea.airlabs.art \
--token YOUR_TOKEN \
--owner owner \
--repo repo \
--pr-number 45
手动测试流程
-
准备测试数据:
- 确保有一个状态为
PENDING_FIX的 Bug - 确保该 Bug 有
pr_url字段(Repair Agent 创建的)
- 确保有一个状态为
-
测试合并:
- 打开 Bug 详情页
- 点击"批准并合并"
- 检查:
- ✅ Bug 状态变为
FIXED - ✅ Gitea PR 状态为
Merged - ✅
merged_at字段有值
- ✅ Bug 状态变为
-
测试拒绝:
- 打开另一个有 PR 的 Bug
- 点击"拒绝修复"
- 输入原因:"测试覆盖不足"
- 确认
- 检查:
- ✅ Bug 状态变为
PENDING_FIX - ✅ Gitea PR 状态为
Closed - ✅ PR 有评论记录原因
- ✅
rejection_count+1 - ✅
rejection_reason有值
- ✅ Bug 状态变为
📸 界面预览
有 PR 的 Bug 详情页
┌─────────────────────────────────────────────────────┐
│ TypeError: 'NoneType' object is not iterable │
│ 项目: rtc_backend 来源: 运行时 级别: ERROR │
│ 状态: [待修复] │
├─────────────────────────────────────────────────────┤
│ Pull Request │
│ PR #45 | fix/auto-20260225-1430 │
│ [查看 PR →] 已拒绝 0 次 │
├─────────────────────────────────────────────────────┤
│ 文件位置: app/views.py : 第 24 行 │
│ ... │
├─────────────────────────────────────────────────────┤
│ [✅ 批准并合并] [❌ 拒绝修复] │ ← 关键按钮
└─────────────────────────────────────────────────────┘
拒绝原因模态框
┌─────────────────────────────────────────┐
│ 拒绝修复 │
├─────────────────────────────────────────┤
│ 请说明拒绝原因,Agent 将根据反馈重新修复 │
│ │
│ 常用模板: │
│ [测试覆盖不足] [业务逻辑调整] [代码质量] │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ [文本输入框] │ │
│ │ │ │
│ │ │ │
│ └─────────────────────────────────────┘ │
│ │
│ [取消] [❌ 确认拒绝] │
└─────────────────────────────────────────┘
🔍 技术细节
状态流转
【合并】
PENDING_FIX → 点击"批准并合并" → 调用 Gitea API merge
→ 更新 Bug 状态 FIXED → 设置 merged_at
【拒绝】
PENDING_FIX → 点击"拒绝修复" → 添加评论到 PR
→ 调用 Gitea API close → 更新 Bug 状态 PENDING_FIX
→ rejection_count +1 → 记录 rejection_reason
→ Agent 检测到 PENDING_FIX + 有 rejection_reason
→ 结合原因重新修复
安全性
- 权限控制:需要有效的 Gitea Token
- 状态检查:只有
PENDING_FIX状态的 Bug 才能操作 - PR 验证:必须有
pr_url才能操作 - 错误处理:API 失败会显示详细错误信息
❓ FAQ
Q1: 按钮显示条件?
A: 只有同时满足以下条件才显示:
- Bug 有
pr_url(Agent 创建了 PR) - Bug 状态为
PENDING_FIX
Q2: 拒绝后 Agent 会立即修复吗?
A: 取决于 Agent 扫描频率:
- 如果 Agent 定时扫描(如每小时),需等待下次扫描
- 可以手动触发 Agent 立即扫描特定项目
Q3: 合并失败怎么办?
A: 常见失败原因:
- Token 权限不足 → 检查 Token 权限
- PR 有冲突 → 需要手动在 Gitea 解决冲突
- PR 已关闭 → 检查 PR 状态
Q4: 能否批量操作?
A: 当前版本不支持批量操作,计划在下个版本添加。
🎯 后续优化
Phase 2(可选)
-
批量操作:
- 批量合并多个 PR
- 批量拒绝
-
通知系统:
- 邮件通知审核结果
- 钉钉/企业微信通知
-
审批流程:
- 指定审批人
- 需要多人审批
- 审批历史记录
-
统计面板:
- PR 合并率
- 平均拒绝次数
- 审核耗时
✅ 完成清单
- 数据库字段扩展
- Gitea API 客户端
- 后端 API 接口
- 前端界面实现
- 拒绝原因模态框
- 环境变量配置
- 文档编写
状态: ✅ 功能已完整实现,可以部署使用!