|
|
|
@ -1,44 +1,246 @@ |
|
|
|
# 测试服发布规则 |
|
|
|
# AI开发规范 |
|
|
|
|
|
|
|
测试服发布必须严格遵循:少假设、小发布、强验证、可回滚。 |
|
|
|
## 核心原则 |
|
|
|
1. 优先最小改动 |
|
|
|
2. 优先兼容现有架构 |
|
|
|
3. 优先复用已有能力 |
|
|
|
4. 禁止主动重构 |
|
|
|
5. 禁止引入新基础设施 |
|
|
|
6. 所有改动必须支持回滚 |
|
|
|
7. 所有接口必须向后兼容 |
|
|
|
8. 所有设计必须可灰度发布 |
|
|
|
9. 所有方案必须考虑监控与告警 |
|
|
|
10. 输出必须包含风险分析 |
|
|
|
|
|
|
|
## 技术栈限制 |
|
|
|
|
|
|
|
- 不允许新增核心框架 |
|
|
|
- 不允许替换现有 ORM |
|
|
|
- 不允许修改微服务通信协议 |
|
|
|
- 不允许引入实验性技术 |
|
|
|
- 优先复用现有组件和基础设施 |
|
|
|
- 新增依赖必须说明必要性 |
|
|
|
- 能使用现有 SDK 时禁止重新封装 |
|
|
|
|
|
|
|
## 架构约束 |
|
|
|
|
|
|
|
- 本次需求默认属于增量迭代 |
|
|
|
- 禁止进行系统级重构 |
|
|
|
- 禁止拆分新微服务 |
|
|
|
- 禁止引入事件驱动重构 |
|
|
|
- 禁止新增中间件 |
|
|
|
- 优先兼容现有DDD边界 |
|
|
|
- 优先遵循现有模块分层 |
|
|
|
- 除非需求明确要求,否则不允许进行架构升级 |
|
|
|
|
|
|
|
## 数据库限制 |
|
|
|
|
|
|
|
- 禁止删除字段 |
|
|
|
- 禁止修改历史字段语义 |
|
|
|
- 禁止破坏向后兼容 |
|
|
|
- 数据迁移必须可回滚 |
|
|
|
- 大表禁止全表扫描方案 |
|
|
|
- 新增索引必须说明影响 |
|
|
|
- 默认兼容灰度发布 |
|
|
|
- 不允许跨库事务设计 |
|
|
|
|
|
|
|
## API设计规范 |
|
|
|
|
|
|
|
- API优先向后兼容 |
|
|
|
- 不允许删除已有字段 |
|
|
|
- 新增字段必须可选 |
|
|
|
- 错误码遵循统一规范 |
|
|
|
- 分页参数统一 |
|
|
|
- 时间统一使用UTC |
|
|
|
- ID统一使用string |
|
|
|
- 禁止返回数据库内部字段。 |
|
|
|
|
|
|
|
## 前端约束 |
|
|
|
|
|
|
|
- 优先复用现有组件 |
|
|
|
- 不允许替换UI框架 |
|
|
|
- 不允许新增全局状态管理 |
|
|
|
- 禁止重构路由体系 |
|
|
|
- 样式遵循现有Design System |
|
|
|
- 默认兼容移动端 |
|
|
|
- 不允许引入大型图表库 |
|
|
|
|
|
|
|
## 安全要求 |
|
|
|
|
|
|
|
- 所有接口必须鉴权 |
|
|
|
- 禁止绕过RBAC |
|
|
|
- 禁止明文存储敏感信息 |
|
|
|
- 禁止日志打印token |
|
|
|
- 禁止拼接SQL |
|
|
|
- 输入必须校验 |
|
|
|
- 输出必须脱敏 |
|
|
|
- 新增外部依赖必须经过安全评审 |
|
|
|
|
|
|
|
## 性能要求 |
|
|
|
|
|
|
|
- 禁止N+1查询 |
|
|
|
- 默认分页查询 |
|
|
|
- 默认异步处理耗时任务 |
|
|
|
- 禁止循环调用远程接口 |
|
|
|
- 缓存优先复用现有方案 |
|
|
|
- 大批量任务必须支持限流 |
|
|
|
- 接口P99响应时间目标 < 500ms |
|
|
|
|
|
|
|
## 禁止事项 |
|
|
|
|
|
|
|
禁止: |
|
|
|
- 大规模重构 |
|
|
|
- 修改基础框架 |
|
|
|
- 修改CI/CD |
|
|
|
- 修改认证体系 |
|
|
|
- 修改网关 |
|
|
|
- 修改数据库主键策略 |
|
|
|
- 引入新消息队列 |
|
|
|
- 引入新缓存系统 |
|
|
|
- 修改公共协议 |
|
|
|
|
|
|
|
## AI行为约束 |
|
|
|
|
|
|
|
- 不要主动重构 |
|
|
|
- 不要主动升级依赖 |
|
|
|
- 不要主动优化无关代码 |
|
|
|
- 不要修改未涉及模块 |
|
|
|
- 不要假设不存在的问题 |
|
|
|
- 不要引入未来需求设计 |
|
|
|
|
|
|
|
Codex 执行发布时必须按以下顺序,不允许跳步: |
|
|
|
## 设计方案输出要求 |
|
|
|
|
|
|
|
1. 先执行 `git status --short`,说明改动范围。 |
|
|
|
方案必须包含: |
|
|
|
|
|
|
|
1. 需求理解 |
|
|
|
2. 影响范围 |
|
|
|
3. 模块改动点 |
|
|
|
4. 数据结构变更 |
|
|
|
5. API变更 |
|
|
|
6. 风险分析 |
|
|
|
7. 回滚方案 |
|
|
|
8. 测试方案 |
|
|
|
9. 灰度方案 |
|
|
|
10. 工时评估 |
|
|
|
|
|
|
|
禁止输出纯理论架构设计。 |
|
|
|
|
|
|
|
## 代码生成规则 |
|
|
|
|
|
|
|
- 优先修改已有代码 |
|
|
|
- 禁止重复造轮子 |
|
|
|
- 优先复用现有service |
|
|
|
- 单函数不超过100行 |
|
|
|
- 禁止过度抽象 |
|
|
|
- 禁止生成未使用代码 |
|
|
|
- 必须补充单元测试 |
|
|
|
|
|
|
|
## 设计优先级 |
|
|
|
|
|
|
|
优先级从高到低: |
|
|
|
|
|
|
|
1. 不破坏线上稳定性 |
|
|
|
2. 向后兼容 |
|
|
|
3. 最小改动 |
|
|
|
4. 复用现有能力 |
|
|
|
5. 快速上线 |
|
|
|
6. 易于回滚 |
|
|
|
7. 可维护性 |
|
|
|
8. 理论最佳实践 |
|
|
|
|
|
|
|
# Git 提交管理规范 |
|
|
|
|
|
|
|
## 核心原则 |
|
|
|
|
|
|
|
AI Agent 可以协助管理 Git 提交,但必须遵守以下原则: |
|
|
|
|
|
|
|
1. 不允许自动提交未确认的改动 |
|
|
|
2. 不允许自动 push |
|
|
|
3. 不允许修改远程分支 |
|
|
|
4. 不允许执行 force push |
|
|
|
5. 每次提交必须是最小语义单元 |
|
|
|
6. 提交前必须展示 diff 摘要 |
|
|
|
7. 提交信息必须清晰、可追踪 |
|
|
|
8. 禁止把无关改动混入同一次提交 |
|
|
|
|
|
|
|
## 提交流程 |
|
|
|
|
|
|
|
1. 执行 `git status --short`,说明改动范围。 |
|
|
|
2. 只处理本次相关 tracked diff,不提交 logs、截图、bundle、临时文件或无关改动。 |
|
|
|
3. 执行本次改动相关的最小必要测试。 |
|
|
|
4. 执行构建检查,例如 `npm run build`。 |
|
|
|
5. 如有既有检查失败,只记录,不修无关问题。 |
|
|
|
6. 创建干净 commit。 |
|
|
|
7. commit 信息必须包含: |
|
|
|
- 为什么改 |
|
|
|
- 验证了什么 |
|
|
|
- 未验证什么 |
|
|
|
- 风险范围 |
|
|
|
- 回滚注意事项 |
|
|
|
8. 测试服只部署指定 commit SHA。 |
|
|
|
9. 部署前记录测试服旧 SHA。 |
|
|
|
10. 测试服执行: |
|
|
|
- `git fetch` |
|
|
|
- `git checkout <目标 SHA>` |
|
|
|
- 按锁文件安装依赖 |
|
|
|
- 构建 |
|
|
|
- 重启服务 |
|
|
|
- 记录新 SHA |
|
|
|
11. 做 smoke test。 |
|
|
|
12. 检查服务日志。 |
|
|
|
13. 失败立即回滚旧 SHA。 |
|
|
|
|
|
|
|
最终输出必须包含: |
|
|
|
- 发布 SHA |
|
|
|
- 旧 SHA / 回滚点 |
|
|
|
- 变更范围 |
|
|
|
- 执行的测试和构建结果 |
|
|
|
- 测试服验收结果 |
|
|
|
- 未验证项和剩余风险 |
|
|
|
|
|
|
|
|
|
|
|
## 测试服发布报告 |
|
|
|
4. 建议提交拆分方案 |
|
|
|
5. 创建干净 commit进行提交,要求commit message必须清晰、可追踪 |
|
|
|
|
|
|
|
但执行 `git commit` 前,必须确认: |
|
|
|
|
|
|
|
- 改动范围正确 |
|
|
|
- 没有敏感信息 |
|
|
|
- 没有调试代码 |
|
|
|
- 测试已通过或已说明未执行原因 |
|
|
|
|
|
|
|
|
|
|
|
# 测试服发布规则 |
|
|
|
|
|
|
|
测试服发布必须严格遵循:少假设、小发布、强验证、可回滚。 |
|
|
|
## 测试服SSH |
|
|
|
ssh root@101.42.99.35 |
|
|
|
|
|
|
|
## 部署架构 |
|
|
|
/opt/popiart-canvas |
|
|
|
├── current -> 当前线上版本 |
|
|
|
├── releases/ |
|
|
|
│ ├── 20260521104810-6b5c645/ |
|
|
|
│ ├── 20260520102122-1f2e3d4/ |
|
|
|
├── shared/ |
|
|
|
│ ├── .env |
|
|
|
│ ├── uploads/ |
|
|
|
│ ├── logs/ |
|
|
|
|
|
|
|
设计原则: |
|
|
|
|
|
|
|
current 永远是软链接 |
|
|
|
release 永远不可修改 |
|
|
|
部署必须原子切换 |
|
|
|
环境变量必须外置 |
|
|
|
build 必须隔离执行 |
|
|
|
|
|
|
|
## 部署流程 |
|
|
|
Codex 执行发布时主要流程如下,通过脚本执行: |
|
|
|
|
|
|
|
#### 第一阶段:Build Release |
|
|
|
1. 测试服只部署指定 commit SHA。 |
|
|
|
2. 部署前记录测试服旧 SHA: "$OLD"。 |
|
|
|
3. 本地针对指定部署 commit SHA代码进行打包,并上传测试服务器 |
|
|
|
4. 测试服创建release:格式为YYYYMMDDHHMMSS-<short_commit> |
|
|
|
5. 解压源码包到新SHA的release目录 |
|
|
|
6. 复用node_modules,从旧 SHA复制依赖 |
|
|
|
7. 注入环境变量 |
|
|
|
8. 写入版本信息 |
|
|
|
9. Docker隔离build |
|
|
|
10. Build 成功标记 |
|
|
|
|
|
|
|
#### 第二阶段:Smoke Test |
|
|
|
1. 创建Smoke容器 |
|
|
|
2. 注册Cleanup |
|
|
|
3. 启动 Smoke 容器 |
|
|
|
4. Smoke Health Check |
|
|
|
5. 检查日志 |
|
|
|
6. Smoke 成功标记 |
|
|
|
|
|
|
|
#### 第三阶段:正式发布 |
|
|
|
1. 从current获取当前版本 |
|
|
|
2. 原子软链接切换 |
|
|
|
3. 重启正式容器 |
|
|
|
4. 正式健康检查 |
|
|
|
|
|
|
|
#### 发布后验证 |
|
|
|
- 当前版本 |
|
|
|
- 容器版本 |
|
|
|
|
|
|
|
#### 特别注意 |
|
|
|
失败立即回滚旧 SHA。 |
|
|
|
|
|
|
|
#### 输出测试服发布报告: |
|
|
|
|
|
|
|
- 发布 SHA: |
|
|
|
- 旧 SHA / 回滚点: |
|
|
|
@ -52,22 +254,117 @@ Codex 执行发布时必须按以下顺序,不允许跳步: |
|
|
|
- 剩余风险: |
|
|
|
- 回滚方式: |
|
|
|
|
|
|
|
#### 部署脚本 |
|
|
|
完整部署流程通过脚本执行,可根据具体情况调整: |
|
|
|
``` |
|
|
|
#!/usr/bin/env bash |
|
|
|
set -euo pipefail |
|
|
|
|
|
|
|
## 测试服部署 |
|
|
|
APP="/opt/popiart-canvas" |
|
|
|
IMAGE="docker.m.daocloud.io/library/node:23-alpine" |
|
|
|
REV="${1:?Usage: ./deploy-popiart-canvas.sh <git-revision>}" |
|
|
|
|
|
|
|
测试服 SSH: |
|
|
|
SHORT="${REV:0:7}" |
|
|
|
SRC="/tmp/popiart-canvas-${SHORT}-src.tgz" |
|
|
|
OLD="$(readlink -f "$APP/current")" |
|
|
|
RELEASE="$APP/releases/$(date +%Y%m%d%H%M%S)-$SHORT" |
|
|
|
RELEASE_FILE="/tmp/popiart-canvas-new-release.txt" |
|
|
|
SMOKE="popiart-canvas-smoke-$(date +%H%M%S)" |
|
|
|
|
|
|
|
ssh root@101.42.99.35 |
|
|
|
cleanup() { |
|
|
|
docker stop "$SMOKE" >/dev/null 2>&1 || true |
|
|
|
} |
|
|
|
trap cleanup EXIT |
|
|
|
|
|
|
|
项目目录: |
|
|
|
echo "Deploy Info:" |
|
|
|
echo "- Revision: $REV" |
|
|
|
echo "- Old Release: $OLD" |
|
|
|
echo "- New Release: $RELEASE" |
|
|
|
echo "- Docker Image: $IMAGE" |
|
|
|
|
|
|
|
/opt/popiart-canvas |
|
|
|
echo "==> Build release" |
|
|
|
|
|
|
|
test -s "$SRC" |
|
|
|
mkdir -p "$RELEASE" |
|
|
|
|
|
|
|
tar -xzf "$SRC" -C "$RELEASE" |
|
|
|
cp -al "$OLD/node_modules" "$RELEASE/node_modules" |
|
|
|
cp "$APP/shared/.env" "$RELEASE/.env.local" |
|
|
|
printf '%s\n' "$REV" > "$RELEASE/REVISION" |
|
|
|
|
|
|
|
docker run --rm \ |
|
|
|
-v "$RELEASE:/app" \ |
|
|
|
-w /app \ |
|
|
|
--env-file "$APP/shared/.env" \ |
|
|
|
"$IMAGE" \ |
|
|
|
sh -lc 'npm run build' |
|
|
|
|
|
|
|
echo "$RELEASE" > "$RELEASE_FILE" |
|
|
|
echo "BUILD_OK" |
|
|
|
|
|
|
|
echo "==> Smoke test" |
|
|
|
|
|
|
|
docker rm -f "$SMOKE" >/dev/null 2>&1 || true |
|
|
|
|
|
|
|
docker run -d --rm \ |
|
|
|
--name "$SMOKE" \ |
|
|
|
-p 127.0.0.1:3101:3000 \ |
|
|
|
-v "$RELEASE:/app:ro" \ |
|
|
|
-w /app \ |
|
|
|
--env-file "$APP/shared/.env" \ |
|
|
|
"$IMAGE" \ |
|
|
|
node server.js |
|
|
|
|
|
|
|
sleep 8 |
|
|
|
|
|
|
|
curl -fsSI --max-time 10 http://127.0.0.1:3101/ | sed -n '1,8p' |
|
|
|
docker logs --tail 20 "$SMOKE" |
|
|
|
|
|
|
|
echo "SMOKE_OK" |
|
|
|
|
|
|
|
echo "==> Switch release" |
|
|
|
|
|
|
|
ln -s "$RELEASE" "$APP/current.new" |
|
|
|
mv -Tf "$APP/current.new" "$APP/current" |
|
|
|
|
|
|
|
docker restart popiart-canvas |
|
|
|
|
|
|
|
sleep 8 |
|
|
|
|
|
|
|
if curl -fsS --max-time 10 http://127.0.0.1:3100/ > /tmp/popiart-canvas-health.html; then |
|
|
|
echo "DEPLOY_HEALTH_OK" |
|
|
|
else |
|
|
|
echo "DEPLOY_HEALTH_FAILED_ROLLING_BACK" |
|
|
|
|
|
|
|
ln -s "$OLD" "$APP/current.rollback" |
|
|
|
mv -Tf "$APP/current.rollback" "$APP/current" |
|
|
|
|
|
|
|
docker restart popiart-canvas |
|
|
|
exit 1 |
|
|
|
fi |
|
|
|
|
|
|
|
echo "==> Verify" |
|
|
|
|
|
|
|
readlink -f "$APP/current" |
|
|
|
|
|
|
|
docker exec popiart-canvas sh -lc ' |
|
|
|
cat /app/REVISION |
|
|
|
test ! -f /app/.env.local && echo NO_ENV_LOCAL_IN_RELEASE || true |
|
|
|
' |
|
|
|
|
|
|
|
docker ps \ |
|
|
|
--filter name=popiart-canvas \ |
|
|
|
--format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' |
|
|
|
|
|
|
|
curl -fsSI --max-time 15 https://wwwtestcanvas.popi.art/ | sed -n '1,8p' |
|
|
|
|
|
|
|
echo "DEPLOY_DONE" |
|
|
|
``` |
|
|
|
|
|
|
|
使用方式: |
|
|
|
|
|
|
|
禁止行为: |
|
|
|
``` |
|
|
|
chmod +x deploy-popiart-canvas.sh |
|
|
|
|
|
|
|
- 禁止 scp 上传源码 |
|
|
|
- 禁止 rsync 本地目录 |
|
|
|
- 禁止在测试服直接修改代码 |
|
|
|
- 禁止部署 dirty workspace |
|
|
|
- 禁止使用 latest/tag 代替 SHA |
|
|
|
- 禁止自动修复无关问题 |
|
|
|
./deploy-popiart-canvas.sh "指定发布的 commit SHA" |
|
|
|
``` |