auto-sync: 2026-06-08 20:00:46
This commit is contained in:
@@ -1,614 +0,0 @@
|
|||||||
# 工具链 Skill 设计 + 自动部署 + 端到端验证
|
|
||||||
|
|
||||||
> **状态**: v1.1 — 仲达评审 M1/M2 修正 + S1-S4 采纳
|
|
||||||
> **作者**: 庞统(副军师)🐦
|
|
||||||
> **评审**: 司马懿(仲达)🗡️
|
|
||||||
> **日期**: 2026-06-08
|
|
||||||
> **前置**: `13-toolchain-and-dev-workflow.md` v2.2(事件中枢已闭环)
|
|
||||||
> **定位**: 工具链从"设计完成"到"正式投入使用"的落地设计
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §1. 目标
|
|
||||||
|
|
||||||
把工具链从设计态推进到可使用态:
|
|
||||||
1. **L1 TOOLS.md**:每个 Agent 的 TOOLS.md 加入 Gitea API 操作模板,收到 Mail 后开箱即用
|
|
||||||
2. **L2 Skill 升级**:7 个现有 Skill 对齐事件中枢 + CI 实际运行
|
|
||||||
3. **deploy.sh + deploy.yml**:补完自动部署的实际脚本
|
|
||||||
4. **端到端验证**:用 sanguo/moziplus-v2 实验项目验证全链路
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §2. 知识体系四层定位
|
|
||||||
|
|
||||||
> 来源: `architecture-v3.0.md` §10 BootstrapBuilder
|
|
||||||
|
|
||||||
| 层 | 定位 | 载体 | Token | 工具链职责 |
|
|
||||||
|----|------|------|-------|-----------|
|
|
||||||
| **L0** | 铁律层 | AGENTS.md / MEMORY.md | ~500 | 不涉及 |
|
|
||||||
| **L1** | 角色层 | SOUL.md + **TOOLS.md** | ~2000 | **Gitea API 操作模板**(Agent 自带,开箱即用) |
|
|
||||||
| **L2** | 引擎注入 | BootstrapBuilder 注入 Skill 全文 | ~1500 | **7 个 Skill v2**(流程规范,Daemon 确定性注入) |
|
|
||||||
| **L3** | 被动参考 | Skill description,Agent 按需加载 | 按需 | 复用 L2 Skill,不新建 |
|
|
||||||
|
|
||||||
**核心原则**:
|
|
||||||
- L1 给操作手段("怎么做"):curl 命令模板、参数说明
|
|
||||||
- L2 给流程规范("什么时候做什么"):审查清单、分支规范、测试策略
|
|
||||||
- L3 是 L2 的被动触发版本,不需要单独维护
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §3. L1:TOOLS.md Gitea 操作模板
|
|
||||||
|
|
||||||
### 3.1 设计原则
|
|
||||||
|
|
||||||
1. **开箱即用**:收到 Mail 后直接复制粘贴 curl 命令即可执行,不需要查文档
|
|
||||||
2. **按角色定制**:不是每个 Agent 都需要全套 API,只给该角色需要的
|
|
||||||
3. **统一格式**:所有模板使用相同的环境变量约定
|
|
||||||
|
|
||||||
### 3.2 公共变量约定
|
|
||||||
|
|
||||||
每个 Agent 的 TOOLS.md 头部加入:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
## Gitea 工具链
|
|
||||||
- **地址**: http://192.168.2.154:3000
|
|
||||||
- **组织**: sanguo
|
|
||||||
- **认证**: `Authorization: token $GITEA_TOKEN`(各 Agent 使用自己的 token)
|
|
||||||
- **CI 管理界面**: http://192.168.2.154:3000/sanguo/{repo}/actions
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.3 按角色模板
|
|
||||||
|
|
||||||
#### A. 开发者(张飞/关羽/赵云)— PR 创建 + Merge
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
### 创建 PR
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/pulls" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"head": "{branch}",
|
|
||||||
"base": "main",
|
|
||||||
"title": "{标题}"
|
|
||||||
}'
|
|
||||||
# 返回 .number 即 PR 号
|
|
||||||
```
|
|
||||||
|
|
||||||
### 查看 PR diff
|
|
||||||
```bash
|
|
||||||
curl "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/pulls/{pr_number}.diff" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Merge PR(Review 通过后)
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/pulls/{pr_number}/merge" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"Do": "merge", "merge_title_field": "Merge PR #{pr_number}"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 查看 CI 状态
|
|
||||||
```bash
|
|
||||||
curl "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/commits/{sha}/status" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN"
|
|
||||||
# .state = "success" | "pending" | "failure" | "error"
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
#### B. 审查者(司马懿)— Review 操作
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
### 读取 PR diff
|
|
||||||
```bash
|
|
||||||
curl "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/pulls/{pr_number}.diff" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 查看 PR 改动文件列表
|
|
||||||
```bash
|
|
||||||
curl "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/pulls/{pr_number}/files" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN"
|
|
||||||
# 每个文件有 .filename, .additions, .deletions, .changes
|
|
||||||
```
|
|
||||||
|
|
||||||
### 提交 Review
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/pulls/{pr_number}/reviews" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"body": "{审查意见}",
|
|
||||||
"event": "APPROVE"
|
|
||||||
}'
|
|
||||||
# event 可选: APPROVE | REQUEST_CHANGES | COMMENT
|
|
||||||
```
|
|
||||||
|
|
||||||
### 风险级别判定(自动 + 确认)
|
|
||||||
规则见 code-review Skill。改动者不能降级,只能维持或升级。
|
|
||||||
```
|
|
||||||
|
|
||||||
#### C. 协调者(庞统)— 全套管理
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
### 创建 Issue + 指派
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/issues" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"title": "{标题}",
|
|
||||||
"body": "{描述}",
|
|
||||||
"assignees": ["{agent_id}"],
|
|
||||||
"labels": [1, 2]
|
|
||||||
}'
|
|
||||||
# labels 需用数字 ID,先 GET /repos/{owner}/{repo}/labels 查询
|
|
||||||
```
|
|
||||||
|
|
||||||
### 查询仓库 Labels
|
|
||||||
```bash
|
|
||||||
curl "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/labels" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 查询 PR 列表
|
|
||||||
```bash
|
|
||||||
curl "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/pulls?state=open" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 创建 Release
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/releases" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"tag_name": "v{version}",
|
|
||||||
"name": "v{version}",
|
|
||||||
"body": "{changelog}",
|
|
||||||
"target_commitish": "main"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 关闭 Issue
|
|
||||||
```bash
|
|
||||||
curl -X PATCH "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/issues/{issue_number}" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"state": "closed"}'
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
#### D. 平台运维(姜维)— deploy + runner 管理
|
|
||||||
|
|
||||||
在开发者模板基础上追加:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
### 触发手动部署(需要 push 到 main 或手动 re-run)
|
|
||||||
```bash
|
|
||||||
# Re-run 最近一次 workflow
|
|
||||||
curl -X POST "http://192.168.2.154:3000/api/v1/repos/sanguo/{repo}/actions/runs/{run_id}/rerun" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 查看 deploy-history
|
|
||||||
```bash
|
|
||||||
cat ~/.sanguo_projects/{project}/data/deploy-history.jsonl
|
|
||||||
```
|
|
||||||
|
|
||||||
### deploy.sh 规范
|
|
||||||
见 §5 deploy.sh 设计。所有项目必须遵循统一接口。
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.4 实施清单
|
|
||||||
|
|
||||||
| Agent | TOOLS.md 新增 | 预计行数 |
|
|
||||||
|-------|--------------|---------|
|
|
||||||
| zhangfei-dev | 开发者模板(PR/Merge/CI状态) | ~30 行 |
|
|
||||||
| guanyu-dev | 开发者模板 | ~30 行 |
|
|
||||||
| zhaoyun-data | 开发者模板 | ~30 行 |
|
|
||||||
| simayi-challenger | 审查者模板(diff/review/风险判定) | ~40 行 |
|
|
||||||
| pangtong-fujunshi | 协调者模板(全套管理) | ~50 行 |
|
|
||||||
| jiangwei-infra | 开发者 + 平台运维模板 | ~45 行 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §4. L2:Skill 升级到 v2
|
|
||||||
|
|
||||||
### 4.1 升级原则
|
|
||||||
|
|
||||||
1. **不重写已有内容**,在现有 Skill 基础上追加/修改
|
|
||||||
2. **对齐事件中枢**:每个 Skill 说明在事件中枢链路中的位置
|
|
||||||
3. **对齐 CI 实际运行**:ci.yml/deploy.yml 已有实际配置,Skill 要反映真实情况
|
|
||||||
4. **对齐 Gitea v1.23.4 限制**:不支持 failure()、concurrency、permissions 等
|
|
||||||
|
|
||||||
### 4.2 升级内容
|
|
||||||
|
|
||||||
#### git-workflow(小改动)
|
|
||||||
|
|
||||||
| 改动 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| 追加"事件中枢集成"节 | PR 创建 → Gitea Webhook → 中枢通知司马懿 → Review → 中枢通知作者 → Merge → deploy.yml 自动触发 |
|
|
||||||
| 追加"CI 自动触发"说明 | push 非 main 分支自动触发 ci.yml;push main 自动触发 deploy.yml |
|
|
||||||
| 追加"分支感知"强化 | Agent spawn 后必须 `git branch --show-current`,确认分支正确 |
|
|
||||||
|
|
||||||
#### code-review(中等改动)
|
|
||||||
|
|
||||||
| 改动 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| 追加"事件中枢触发"节 | 收到 Mail → 读 PR diff → 审查 → 提交 Review → Webhook 自动通知作者 |
|
|
||||||
| 更新风险判定规则 | 对齐 §6.1 实际规则(按文件路径自动判定 + 只升不降) |
|
|
||||||
| 追加 Gitea Review API 操作 | curl 模板(和 L1 TOOLS.md 一致,这里放流程说明) |
|
|
||||||
| 追加审查结论格式 | APPROVE / REQUEST_CHANGES 的标准格式 |
|
|
||||||
|
|
||||||
#### testing-workflow(小改动)
|
|
||||||
|
|
||||||
| 改动 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| 追加"CI 集成"节 | UT 在 CI 自动跑(ci.yml test job)、coverage 在 deploy.yml ci job 跑 |
|
|
||||||
| 追加"E2E 触发方式" | 通过 e2e.yml 手动触发或 `RUN_INTEGRATION=1 pytest` 本地跑 |
|
|
||||||
| 追加"测试数据隔离" | CI 使用临时 venv + 临时 SQLite + 临时端口 |
|
|
||||||
| 追加"广播风暴禁止" | **禁止在 daemon 运行时跑含创建项目/Task/Mail 的测试**,否则会触发 Agent spawn 导致广播风暴。E2E 测试必须在 CI 隔离环境或 daemon 停止后跑 |
|
|
||||||
|
|
||||||
#### bugfix-workflow(小改动)
|
|
||||||
|
|
||||||
| 改动 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| 追加"事件中枢链路"节 | Bug Issue 创建/指派 → 中枢发 Mail → 修复 → PR → CI → Review → merge |
|
|
||||||
| 追加"CI 验证"步骤 | 修复后必须等 CI 通过再创建 PR |
|
|
||||||
|
|
||||||
#### hotfix-workflow(小改动)
|
|
||||||
|
|
||||||
| 改动 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| 追加"CI 自动跑"说明 | hotfix push main → deploy.yml 自动跑 CI + 部署 |
|
|
||||||
| 追加"失败自动创建 Issue" | deploy.yml notify-on-failure 已实现 |
|
|
||||||
| 更新 24h 复盘流程 | 复盘结论写到 Issue 评论中 |
|
|
||||||
|
|
||||||
#### ci-cd-ops(重写)
|
|
||||||
|
|
||||||
| 改动 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| 重写为 v2 | 对齐实际 ci.yml/deploy.yml 结构 |
|
|
||||||
| 新增 Gitea v1.23.4 限制清单 | 不支持 failure()/concurrency/permissions 等,workaround 方案 |
|
|
||||||
| 新增覆盖率渐进策略 | P1 只报告 → P2 40% 阈值 → P3 60% 阈值 |
|
|
||||||
| 新增 deploy.sh 规范 | 统一接口:--version / --source / --target / --health-check / --rollback |
|
|
||||||
| 新增 CI secret 配置 | CI_TOKEN 作为 repository secret 配置 |
|
|
||||||
|
|
||||||
#### release-workflow(中等改动)
|
|
||||||
|
|
||||||
| 改动 | 说明 |
|
|
||||||
|------|------|
|
|
||||||
| 追加"自动部署触发" | tag 创建 → deploy.yml 自动触发 |
|
|
||||||
| 追加 deploy-history.jsonl 规范 | 每次 deploy 记录 tag + commit + 时间戳 |
|
|
||||||
| 更新 schema 变更规范 | 向前兼容 Checklist(加列不加删、默认值、迁移脚本) |
|
|
||||||
|
|
||||||
### 4.3 不新建 Skill
|
|
||||||
|
|
||||||
现有 7 个 Skill 覆盖所有工具链流程。不需要为事件中枢、CI 操作新建 Skill——这些流程固化在 Mail 模板(§15.5)中,Skill 只提供共通知能。
|
|
||||||
|
|
||||||
### 4.4 实施清单
|
|
||||||
|
|
||||||
| Skill | 改动级别 | 预计改动行数 |
|
|
||||||
|-------|---------|------------|
|
|
||||||
| git-workflow | 小 | +15 行 |
|
|
||||||
| code-review | 中 | +40 行 |
|
|
||||||
| testing-workflow | 小 | +25 行(含广播风暴禁止约束) |
|
|
||||||
| bugfix-workflow | 小 | +15 行 |
|
|
||||||
| hotfix-workflow | 小 | +15 行 |
|
|
||||||
| ci-cd-ops | 重写 | ~120 行(原 114 行) |
|
|
||||||
| release-workflow | 中 | +30 行 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §5. deploy.sh + deploy.yml 补完
|
|
||||||
|
|
||||||
### 5.1 deploy.sh 统一接口
|
|
||||||
|
|
||||||
每个项目的 `scripts/deploy.sh` 必须遵循以下接口:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# scripts/deploy.sh — 项目部署脚本
|
|
||||||
# 用法:
|
|
||||||
# bash scripts/deploy.sh --version # 显示当前版本
|
|
||||||
# bash scripts/deploy.sh --source=DIR --target=DIR --health-check # 部署
|
|
||||||
# bash scripts/deploy.sh --rollback # 回滚到上一版本
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SOURCE_DIR=""
|
|
||||||
TARGET_DIR=""
|
|
||||||
HEALTH_CHECK=false
|
|
||||||
ACTION="deploy"
|
|
||||||
|
|
||||||
for arg in "$@"; do
|
|
||||||
case $arg in
|
|
||||||
--version) ACTION="version" ;;
|
|
||||||
--source=*) SOURCE_DIR="${arg#*=}" ;;
|
|
||||||
--target=*) TARGET_DIR="${arg#*=}" ;;
|
|
||||||
--health-check) HEALTH_CHECK=true ;;
|
|
||||||
--rollback) ACTION="rollback" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
PROJECT_NAME="{project_name}"
|
|
||||||
DEPLOY_HISTORY="{target_dir}/data/deploy-history.jsonl"
|
|
||||||
|
|
||||||
version() {
|
|
||||||
echo "${PROJECT_NAME} deploy version: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
||||||
}
|
|
||||||
|
|
||||||
deploy() {
|
|
||||||
echo "=== Deploying ${PROJECT_NAME} ==="
|
|
||||||
echo "Source: ${SOURCE_DIR}"
|
|
||||||
echo "Target: ${TARGET_DIR}"
|
|
||||||
|
|
||||||
# 1. 同步文件(排除不需要部署的)
|
|
||||||
# ⚠️ --delete 会删除目标中源没有的文件,必须排除 data/(生产数据)
|
|
||||||
rsync -av --delete \
|
|
||||||
--exclude='.git' \
|
|
||||||
--exclude='__pycache__' \
|
|
||||||
--exclude='.venv' \
|
|
||||||
--exclude='data' \
|
|
||||||
--exclude='tests' \
|
|
||||||
--exclude='docs' \
|
|
||||||
--exclude='.gitea' \
|
|
||||||
--exclude='node_modules' \
|
|
||||||
"${SOURCE_DIR}/" "${TARGET_DIR}/"
|
|
||||||
|
|
||||||
# 2. 安装依赖
|
|
||||||
if [ -f "${TARGET_DIR}/pyproject.toml" ]; then
|
|
||||||
cd "${TARGET_DIR}"
|
|
||||||
python3 -m venv .venv
|
|
||||||
.venv/bin/pip install --quiet -e ".[dev]" 2>/dev/null || \
|
|
||||||
.venv/bin/pip install --quiet -e . 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. 重启服务
|
|
||||||
if command -v pm2 &>/dev/null; then
|
|
||||||
pm2 restart ${PROJECT_NAME} 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. 健康检查
|
|
||||||
if [ "$HEALTH_CHECK" = true ]; then
|
|
||||||
sleep 3
|
|
||||||
curl -sf http://localhost:8083/api/health && echo " ✓" || {
|
|
||||||
echo " ✗ Health check failed!"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 5. 记录版本(rollback 时可通过 DEPLOY_OVERRIDE_COMMIT 覆盖)
|
|
||||||
local commit_hash
|
|
||||||
if [ -n "${DEPLOY_OVERRIDE_COMMIT:-}" ]; then
|
|
||||||
commit_hash="${DEPLOY_OVERRIDE_COMMIT}"
|
|
||||||
else
|
|
||||||
commit_hash=$(cd "${SOURCE_DIR}" && git rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
|
||||||
fi
|
|
||||||
local timestamp
|
|
||||||
timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
||||||
echo "{\"timestamp\": \"${timestamp}\", \"commit\": \"${commit_hash}\", \"source\": \"${SOURCE_DIR}\"}" >> "${DEPLOY_HISTORY}"
|
|
||||||
|
|
||||||
# 保留最近 10 条
|
|
||||||
tail -10 "${DEPLOY_HISTORY}" > "${DEPLOY_HISTORY}.tmp" && mv "${DEPLOY_HISTORY}.tmp" "${DEPLOY_HISTORY}"
|
|
||||||
|
|
||||||
echo "=== Deploy complete: ${commit_hash} at ${timestamp} ==="
|
|
||||||
}
|
|
||||||
|
|
||||||
rollback() {
|
|
||||||
if [ ! -f "${DEPLOY_HISTORY}" ]; then
|
|
||||||
echo "No deploy history, cannot rollback"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 读取倒数第二行的 commit(不依赖 SOURCE_DIR 的 git 状态)
|
|
||||||
local prev_line
|
|
||||||
prev_line=$(tail -2 "${DEPLOY_HISTORY}" | head -1)
|
|
||||||
local prev_commit
|
|
||||||
local prev_source
|
|
||||||
prev_commit=$(echo "${prev_line}" | python3 -c "import sys,json; print(json.load(sys.stdin)['commit'])" 2>/dev/null)
|
|
||||||
prev_source=$(echo "${prev_line}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('source',''))" 2>/dev/null)
|
|
||||||
|
|
||||||
if [ -z "${prev_commit}" ] || [ "${prev_commit}" = "unknown" ]; then
|
|
||||||
echo "Cannot determine previous version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "=== Rolling back to ${prev_commit} ==="
|
|
||||||
# checkout 到指定 commit,部署,然后回到 main
|
|
||||||
cd "${SOURCE_DIR}"
|
|
||||||
local current_branch
|
|
||||||
current_branch=$(git branch --show-current)
|
|
||||||
git checkout "${prev_commit}"
|
|
||||||
# 部署时明确传 commit hash,不依赖 HEAD
|
|
||||||
DEPLOY_OVERRIDE_COMMIT="${prev_commit}" deploy
|
|
||||||
git checkout "${current_branch:-main}"
|
|
||||||
}
|
|
||||||
|
|
||||||
case $ACTION in
|
|
||||||
version) version ;;
|
|
||||||
deploy) deploy ;;
|
|
||||||
rollback) rollback ;;
|
|
||||||
esac
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 deploy.yml 更新
|
|
||||||
|
|
||||||
替换当前 placeholder:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
deploy:
|
|
||||||
runs-on: macos-arm64
|
|
||||||
needs: ci
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Deploy
|
|
||||||
env:
|
|
||||||
CI_TOKEN: ${{ secrets.CI_TOKEN }}
|
|
||||||
run: |
|
|
||||||
bash scripts/deploy.sh --source="$GITHUB_WORKSPACE" \
|
|
||||||
--target="$HOME/.sanguo_projects/sanguo_moziplus_v2" \
|
|
||||||
--health-check
|
|
||||||
|
|
||||||
- name: Rollback on failure
|
|
||||||
if: always()
|
|
||||||
env:
|
|
||||||
CI_TOKEN: ${{ secrets.CI_TOKEN }}
|
|
||||||
run: |
|
|
||||||
STATUS=$(curl -sf \
|
|
||||||
-H "Authorization: token $CI_TOKEN" \
|
|
||||||
"${{ gitea.api_url }}/repos/${{ gitea.repository }}/commits/${{ gitea.sha }}/status" \
|
|
||||||
| python3 -c "import sys,json; print(json.load(sys.stdin).get('state',''))" 2>/dev/null || echo "")
|
|
||||||
if [ "$STATUS" != "success" ]; then
|
|
||||||
echo "Deploy failed, rolling back..."
|
|
||||||
bash scripts/deploy.sh --rollback || echo "Rollback failed, manual intervention needed"
|
|
||||||
fi
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.3 实施清单
|
|
||||||
|
|
||||||
| # | 内容 | 文件 | 说明 |
|
|
||||||
|---|------|------|------|
|
|
||||||
| D1 | 创建 deploy.sh | moziplus-v2 `scripts/deploy.sh` | 从模板创建,项目名填 sanguo_moziplus_v2 |
|
|
||||||
| D2 | 更新 deploy.yml | moziplus-v2 `.gitea/workflows/deploy.yml` | 替换 placeholder |
|
|
||||||
| D3 | 同步到 Gitea | push 到 moziplus-v2 | 触发 CI 验证 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §6. 端到端验证:sanguo/moziplus-v2 实验项目
|
|
||||||
|
|
||||||
### 6.1 为什么用实验项目
|
|
||||||
|
|
||||||
- moziplus-v2 主项目已有正式数据(黑板项目、Mail、Task),不适合做破坏性验证
|
|
||||||
- sanguo/moziplus-v2 当前是空项目(只有 README.md + .gitea/workflows),可以随意实验
|
|
||||||
|
|
||||||
### 6.2 验证场景
|
|
||||||
|
|
||||||
| 场景 | 操作 | 预期结果 |
|
|
||||||
|------|------|---------|
|
|
||||||
| **S1: CI 触发** | push 分支到实验项目 | ci.yml 自动跑 lint + test |
|
|
||||||
| **S2: PR Review 流程** | 创建 PR → 中枢 Mail → 司马懿 Review → 中枢通知作者 | 全链路 Mail 通知 |
|
|
||||||
| **S3: CI 失败通知** | push 含 lint 错误的代码 | ci.yml 失败 → 写 PR 评论 → 中枢发 Mail |
|
|
||||||
| **S4: 部署流程** | merge PR → push main | deploy.yml 自动跑 + 部署 + 健康检查 |
|
|
||||||
| **S5: Issue 指派** | 创建 Issue 并指派 | 中枢发 Mail 给被指派人 |
|
|
||||||
| **S6: 幂等验证** | 重复触发同一 delivery_id Webhook | 第二次返回 200 duplicate,不创建重复 Mail |
|
|
||||||
|
|
||||||
### 6.3 实验项目 CI 配置
|
|
||||||
|
|
||||||
从 moziplus-v2 的 ci.yml 精简,实验项目只需要基本验证:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
name: CI
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: ['**', '!main']
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
runs-on: macos-arm64
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: echo "lint placeholder"
|
|
||||||
|
|
||||||
test:
|
|
||||||
runs-on: macos-arm64
|
|
||||||
needs: lint
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: echo "test placeholder"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §7. 覆盖率渐进策略
|
|
||||||
|
|
||||||
### 7.1 P1 阶段(启用后 2 周)— 只报告不阻断
|
|
||||||
|
|
||||||
**零改动**。当前 deploy.yml 的 ci job 已包含 `--cov=src --cov-report=term-missing`(push main 时自动跑)。
|
|
||||||
|
|
||||||
注意:ci.yml(非 main 分支)没有 coverage 配置——快速门控不需要覆盖率,这是有意为之。
|
|
||||||
|
|
||||||
收集基线数据后决定 P2 阈值。
|
|
||||||
|
|
||||||
### 7.2 后续阶段(仅设计,暂不实施)
|
|
||||||
|
|
||||||
| 阶段 | 时间 | 策略 | 触发方式 |
|
|
||||||
|------|------|------|---------|
|
|
||||||
| P2 | 启用后 1 月 | 40% 阈值,低于警告不阻断 | ci.yml 加 coverage threshold check |
|
|
||||||
| P3 | 启用后 2 月+ | 60% 阈值,低于阻断 | ci.yml 加 `exit 1` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §8. 前端展示
|
|
||||||
|
|
||||||
### 8.1 Gitea 自带管理界面
|
|
||||||
|
|
||||||
Gitea v1.23.4 自带完整的 CI 管理界面:
|
|
||||||
|
|
||||||
| 功能 | URL |
|
|
||||||
|------|-----|
|
|
||||||
| CI Runs 列表 | `http://192.168.2.154:3000/sanguo/{repo}/actions` |
|
|
||||||
| 单次 Run 日志 | `http://192.168.2.154:3000/sanguo/{repo}/actions/runs/{id}` |
|
|
||||||
| PR CI Status | PR 页面自动显示 CI 状态徽章 |
|
|
||||||
| Webhook 管理 | 仓库 Settings → Webhooks |
|
|
||||||
|
|
||||||
**不需要自己做 CI 前端。**
|
|
||||||
|
|
||||||
### 8.2 moziplus v2 前端展示
|
|
||||||
|
|
||||||
工具链事件的 Mail 通知已在 moziplus v2 前端展示(Mail 列表页)。
|
|
||||||
|
|
||||||
如果未来要加,唯一值得做的是:在 moziplus 前端加一个「工具链状态」面板,聚合展示各仓库最近 CI 状态。这是 P4,不阻塞使用。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §9. 实施路线
|
|
||||||
|
|
||||||
| 优先级 | 内容 | 耗时 | 前置 |
|
|
||||||
|--------|------|------|------|
|
|
||||||
| **P1** | L1 TOOLS.md(6 个 Agent) | 2h | 无 |
|
|
||||||
| **P1** | L2 Skill 升级(7 个) | 1d | 无 |
|
|
||||||
| **P2** | deploy.sh + deploy.yml | 2h | P1 Skill 升级(ci-cd-ops 定义了 deploy.sh 规范) |
|
|
||||||
| **P3** | sanguo/moziplus-v2 端到端验证 | 2h | P1 + P2 |
|
|
||||||
| **P4** | 前端工具链状态面板 | 按需 | 不阻塞 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §10. 前置条件 Checklist
|
|
||||||
|
|
||||||
工具链投入使用前必须确认:
|
|
||||||
|
|
||||||
| # | 条件 | 状态 | 谁确认 |
|
|
||||||
|---|------|------|--------|
|
|
||||||
| 1 | act-runner 已注册且 label = `macos-arm64` | ✅ CI 已跑过 24 次 | 已确认 |
|
|
||||||
| 2 | Gitea repository secrets 已配置(CI_TOKEN) | ⚠️ 需确认 | 姜维 |
|
|
||||||
| 3 | Gitea 组织级 Webhook 已启用(Hook ID=28) | ✅ 已确认 | 已确认 |
|
|
||||||
| 4 | 各 Agent 的 GITEA_TOKEN 环境变量 | ⚠️ 待分配 | 庞统协调 |
|
|
||||||
| 5 | main 分支保护规则(Review 才能 merge) | ⚠️ 需确认 | 姜维 |
|
|
||||||
| 6 | 禁止在 daemon 运行时跑全量 E2E | ✅ 已警告司马懿 | 已确认 |
|
|
||||||
|
|
||||||
> 第 5 点很关键——如果 main 分支没有保护规则,开发者可以直接 push main 跳过 Review。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## §11. 评审记录
|
|
||||||
|
|
||||||
### v1.0 → v1.1 修订清单(仲达评审)
|
|
||||||
|
|
||||||
| 编号 | 类型 | 问题 | 修订内容 |
|
|
||||||
|------|------|------|----------|
|
|
||||||
| M1 | 必须修 | rsync --delete 会删 data/ | §5.1 --exclude 加 `data` + `node_modules` |
|
|
||||||
| M2 | 必须修 | runs-on 与实际环境不一致 | 实际 ci.yml/deploy.yml 已用 `macos-arm64`,CI 已跑通,属仲达误判。文档 §6.3 已明确说明 |
|
|
||||||
| S1 | 建议 | rollback commit 获取有竞态 | §5.1 rollback 改用 DEPLOY_OVERRIDE_COMMIT 显式传递,不依赖 git HEAD |
|
|
||||||
| S2 | 建议 | pip install 缺 lock file | 采纳但 P3,当前单一部署环境风险低 |
|
|
||||||
| S3 | 建议 | 缺前置条件 checklist | 新增 §10 前置条件 Checklist |
|
|
||||||
| S4 | 建议 | 验证场景补 S6 幂等 | §6.2 新增 S6 幂等验证场景 |
|
|
||||||
| — | 评审 | 庞统模板缺关闭 Issue curl | §3.3 C 节补关闭 Issue 模板 |
|
|
||||||
| — | 评审 | testing-workflow 加广播风暴禁止 | §4.2 testing-workflow 补充约束 |
|
|
||||||
| — | 评审 | ci-cd-ops 行数估算措辞 | 修正:重写后预计 ~120 行(原 114 行) |
|
|
||||||
| — | 评审 | 覆盖率 P1 前提需确认 | §7.1 明确指出 deploy.yml 已有 coverage,ci.yml 有意不加 |
|
|
||||||
Reference in New Issue
Block a user