工作区根 own/vps 不是 git 仓库,.qoder/rules 与 .qoder/agents 长期无版本化、无异地备份。 现将两类手写指令资产实体迁入本仓库 .qoder/ 下,工作区根原路径改为相对符号链接指回仓库, IDE 加载路径与规则 glob(vps-manager/**/*.py)保持不变。 .gitignore 仅跟踪 .qoder/rules 与 .qoder/agents,repowiki、better-harness 报告等可重生成产物不入库。
3.3 KiB
3.3 KiB
description, alwaysApply
| description | alwaysApply |
|---|---|
| 部署验收检查点,git push 或执行 deploy/deploy.sh 后必须完成 /health 与核心 API 验证 | true |
部署验收检查点
触发条件
当 Agent 执行以下任一操作后,必须自动进入部署验收流程:
git push到 Gitea(触发 cc1 自动更新)- 执行
deploy/deploy.sh - 任何会导致远端代码变更并触发 cc1 自动拉取的操作
验收流程
1. 等待自动更新
cc1 上的 vps-manager-update.timer 每 1 分钟触发一次 update.sh,push 后最多 60 秒开始更新。
2. 调用 /health 端点
轮询 https://dify.taile5765c.ts.net/health,直到 commit 追平或超时。
端点契约:
{
"status": "ok",
"app": "vps-manager",
"version": "x.x.x",
"commit": "7位短hash"
}
验收标准:
| 字段 | 预期值 | 说明 |
|---|---|---|
status |
"ok" |
服务可用 |
commit |
与本地 git rev-parse --short=7 HEAD 一致 |
代码已生效 |
version |
与本地 VERSION 文件一致 |
版本号正确 |
轮询参数:
- 间隔:15 秒
- 单次请求超时:10 秒(
curl --max-time 10) - 总超时:120 秒(Agent 验收场景;deploy.sh 用 720 秒含首次部署余量)
3. 核心 API 验证
commit 追平后,逐一验证以下端点返回 HTTP 200:
/api/assets
/api/accounts
/api/providers
/api/stats/overview
4. 记录验收结果
验收完成后,在终端输出结构化结果:
✅ 部署验收通过
commit: abc1234
version: v0.5.0
health: ok
apis: 4/4 passed
失败处理
网络超时
当 curl 请求超时或无响应时,输出明确提示:
❌ 部署验收失败:网络超时
可能原因:
1. cc1 节点不可达(Tailscale 连接断开)
2. vps-manager 服务未启动或启动中
3. 防火墙/网络策略阻断
排查:ping cc1 / curl -v https://dify.taile5765c.ts.net/health
Commit 未追平
超时后 commit 仍不一致:
❌ 部署验收失败:版本未追平
期望 commit: abc1234
线上 commit: def5678
超时: 120s
排查:ssh cc1 'journalctl -u vps-manager-update.service -n 30'
API 验证失败
commit 追平但核心 API 返回非 200:
❌ 部署验收失败:API 异常
/api/assets -> 200 ✓
/api/accounts -> 200 ✓
/api/providers -> 500 ❌
/api/stats/overview -> 200 ✓
排查:ssh cc1 'journalctl -u vps-manager -n 50'
实现参考
Agent 执行验收时,使用以下命令序列:
# 1. 获取本地版本
LOCAL_SHORT=$(git rev-parse --short=7 HEAD)
# 2. 轮询 health(带超时)
deadline=$(( $(date +%s) + 120 ))
while [ "$(date +%s)" -lt "$deadline" ]; do
response=$(curl -s --max-time 10 https://dify.taile5765c.ts.net/health 2>/dev/null) || {
echo "⚠️ 请求超时,15s 后重试…"
sleep 15; continue
}
remote=$(echo "$response" | python3 -c "import json,sys; print(json.load(sys.stdin).get('commit',''))" 2>/dev/null)
if [ "$remote" = "$LOCAL_SHORT" ]; then
echo "✅ commit 已追平: $LOCAL_SHORT"
break
fi
sleep 15
done
# 3. 验证核心 API
for path in /api/assets /api/accounts /api/providers /api/stats/overview; do
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "https://dify.taile5765c.ts.net$path")
echo " $path -> $code"
done