log-center/docs/PR_OPERATIONS_IMPLEMENTATION.md
zyc 5611839fd8
Some checks failed
Build and Deploy Log Center / build-and-deploy (push) Failing after 1m55s
fix git pr
2026-02-25 10:55:26 +08:00

9.2 KiB
Raw Permalink Blame History

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() - 合并 PR
  • close_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

新增组件

  1. PR 信息展示区

    • 显示 PR 编号、分支名
    • "查看 PR" 外链按钮
    • 拒绝次数提示
  2. 操作按钮

    • 批准并合并 按钮(绿色)
    • 拒绝修复 按钮(红色)
  3. 拒绝原因模态框

    • 常用模板快速填充
    • 文本输入框(详细原因)
    • 确认/取消按钮
  4. 状态消息

    • 操作成功/失败提示
    • 上次拒绝原因显示

🎯 使用流程

场景 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

  1. 登录 Gitea
  2. 设置 → 应用 → 生成新令牌
  3. 权限:repo(读写仓库)
  4. 复制 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

手动测试流程

  1. 准备测试数据

    • 确保有一个状态为 PENDING_FIX 的 Bug
    • 确保该 Bug 有 pr_url 字段Repair Agent 创建的)
  2. 测试合并

    • 打开 Bug 详情页
    • 点击"批准并合并"
    • 检查:
      • Bug 状态变为 FIXED
      • Gitea PR 状态为 Merged
      • merged_at 字段有值
  3. 测试拒绝

    • 打开另一个有 PR 的 Bug
    • 点击"拒绝修复"
    • 输入原因:"测试覆盖不足"
    • 确认
    • 检查:
      • Bug 状态变为 PENDING_FIX
      • Gitea PR 状态为 Closed
      • PR 有评论记录原因
      • rejection_count +1
      • rejection_reason 有值

📸 界面预览

有 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
→ 结合原因重新修复

安全性

  1. 权限控制:需要有效的 Gitea Token
  2. 状态检查:只有 PENDING_FIX 状态的 Bug 才能操作
  3. PR 验证:必须有 pr_url 才能操作
  4. 错误处理API 失败会显示详细错误信息

FAQ

Q1: 按钮显示条件?

A: 只有同时满足以下条件才显示:

  1. Bug 有 pr_urlAgent 创建了 PR
  2. Bug 状态为 PENDING_FIX

Q2: 拒绝后 Agent 会立即修复吗?

A: 取决于 Agent 扫描频率:

  • 如果 Agent 定时扫描(如每小时),需等待下次扫描
  • 可以手动触发 Agent 立即扫描特定项目

Q3: 合并失败怎么办?

A: 常见失败原因:

  1. Token 权限不足 → 检查 Token 权限
  2. PR 有冲突 → 需要手动在 Gitea 解决冲突
  3. PR 已关闭 → 检查 PR 状态

Q4: 能否批量操作?

A: 当前版本不支持批量操作,计划在下个版本添加。


🎯 后续优化

Phase 2可选

  1. 批量操作

    • 批量合并多个 PR
    • 批量拒绝
  2. 通知系统

    • 邮件通知审核结果
    • 钉钉/企业微信通知
  3. 审批流程

    • 指定审批人
    • 需要多人审批
    • 审批历史记录
  4. 统计面板

    • PR 合并率
    • 平均拒绝次数
    • 审核耗时

完成清单

  • 数据库字段扩展
  • Gitea API 客户端
  • 后端 API 接口
  • 前端界面实现
  • 拒绝原因模态框
  • 环境变量配置
  • 文档编写

状态: 功能已完整实现,可以部署使用!