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

361 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PR 操作功能实施完成
> 实施日期: 2026-02-25
> 状态: ✅ 已完成
---
## 📋 已实现功能
### ✅ 1. 数据库字段扩展
**文件**: `app/models.py`
新增字段:
```python
# 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
**响应**
```json
{
"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**
```json
{
"reason": "测试覆盖不足,缺少边界条件测试"
}
```
**响应**
```json
{
"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` 文件:
```bash
# Gitea 配置
GITEA_URL=https://gitea.airlabs.art
GITEA_TOKEN=your_gitea_token_here
```
**获取 Gitea Token**
1. 登录 Gitea
2. 设置 → 应用 → 生成新令牌
3. 权限:`repo`(读写仓库)
4. 复制 Token 到 `.env`
### 2. 数据库迁移
需要执行数据库迁移添加新字段:
```sql
-- 手动执行或使用 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. 重启服务
```bash
# 后端
cd /log_center/app
uvicorn main:app --reload
# 前端
cd /log_center/web
npm run dev
```
---
## 🧪 测试
### 测试 Gitea API可选
使用测试脚本验证 API
```bash
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_url`Agent 创建了 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 合并率
- 平均拒绝次数
- 审核耗时
---
## ✅ 完成清单
- [x] 数据库字段扩展
- [x] Gitea API 客户端
- [x] 后端 API 接口
- [x] 前端界面实现
- [x] 拒绝原因模态框
- [x] 环境变量配置
- [x] 文档编写
**状态**: ✅ 功能已完整实现,可以部署使用!