diff --git a/docs/superpowers/specs/2026-09-29-git-and-deploy-automation-design.md b/docs/superpowers/specs/2026-09-29-git-and-deploy-automation-design.md new file mode 100644 index 0000000..ec9b0c4 --- /dev/null +++ b/docs/superpowers/specs/2026-09-29-git-and-deploy-automation-design.md @@ -0,0 +1,87 @@ +# Git 托管接入 + 一键部署方案 — 设计文档 + +日期:2026-09-29 +分支:m1 +状态:设计已获用户批准 +远程仓:http://219.157.255.213:25311/xinyouhe/fangke.git(用户自建) + +## 背景与目标 + +当前部署是"约定驱动的手工链":流程存在于对话上下文与一条记忆中,每次由 AI 手工执行 6-8 步(构建→scp 经跳板→解压→cp 到正确挂载点→docker 重建→探活→哈希核对)。已两次踩中"解压到错误目录"同类坑(/opt/cms-cj/dist 而非 admin/dist)。仓库无 git remote,无任何部署脚本。 + +目标: +1. 项目托管到用户提供的自建 git 远程仓(版本化/备份)。 +2. 部署固化为仓库内一键脚本 `deploy/deploy.sh`——用户说"部署到线上"时 AI 执行该命令;日常任务完成后的标准部署走同一条命令。 +3. 消灭手工多步流程的错误类(错误目录/静默半部署/漏验证)。 + +## Part 1:Git 远程仓初始化 + +1. `git remote add origin http://219.157.255.213:25311/xinyouhe/fangke.git` +2. **推送前卫生处理**(实现时以当时 `git status` 实测为准,按以下原则逐文件决策): + - 被代码引用的资产(如 LoginLeftView 引用的图片)→ 提交入库 + - 设计文档/设计稿(assets/design 等)→ 提交入库(团队知识) + - 临时验证产物(根目录截图、测试页 html、.playwright-mcp/、.tmp-*)→ .gitignore + - 敏感文件扫描:确认无 .env/私钥/明文密码入库(.env.example 除外);deploy/.env 不存在于本机(仅服务器有) +3. 推送 `m1` 与 `main` 两分支(m1 为当前功能分支)。 +4. 后续提交按既有节奏正常 push(不做 push 即部署——见"明确不做")。 + +## Part 2:deploy/deploy.sh 一键部署脚本 + +### 用法 + +``` +bash deploy/deploy.sh [--skip-tests] [--allow-dirty] +``` + +- 单目标只走对应子集(如仅改 admin 时 30 秒级完成) +- `all` 按依赖序执行:**server → admin → sdk**(SDK 新事件依赖 server 白名单先上线) + +### 脚本顶部配置(环境变量可覆盖) + +``` +JUMP_HOST=root@8.152.213.143 # 跳板 +TARGET=root@47.254.176.10 # 生产服务器 +SSH_KEY=~/.ssh/id_ed25519 +REMOTE_DIR=/opt/cms-cj +SITE_URL=https://tracker.12418113.xyz +``` + +### all 完整流程(固化现手工链 + 全部已知陷阱防御) + +| 步骤 | 内容 | 防的坑 | +|---|---|---| +| 1 前置 | git 工作区干净(`--allow-dirty` 逃生舱);跳板 SSH 可达 | 部署未提交状态 | +| 2 测试门禁 | server: pytest tracker/tests(188 基线);sdk: vitest run + tsc;admin: vue-tsc(build 内含) | 带病上线 | +| 3 构建 | admin: `NODE_OPTIONS=--max-old-space-size=6144 pnpm build`;sdk: build + gzip 字节数记录 | 本机 OOM | +| 4 传输 | tar(排除 __pycache__/db.sqlite3/.pytest_cache)→ scp 经跳板 → /tmp | — | +| 5 服务器侧 | 解压到 $REMOTE_DIR;**cp -rf dist/* admin/dist/、cp dist/v1.js sdk/dist/**(后清理误解压的 dist/);server: `docker compose up -d --build web`(Dockerfile 内自动 migrate) | 错误挂载点目录(×2 历史) | +| 6 验证 | tracker-web 容器 Up;站点 curl 200;admin 线上 index.html 哈希 === 本机产物哈希;sdk 线上 v1.js 含新 build_id | 部署无效/缓存误判 | +| 7 记录 | deploy/logs/deploy-<时间戳>.log:git 哈希/部署目标/版本标识/验证结果/耗时(logs 目录 gitignore) | 无部署历史可追溯 | + +### 失败语义 + +`set -euo pipefail`;任一步失败立即中止并输出失败步骤与原因——**杜绝静默半部署**。单目标失败时 `all` 序列停止(不做部分继续)。 + +### 平台约束 + +- 脚本为 bash(开发机 Git Bash 执行;服务器侧命令经 ssh 执行,无 Windows 依赖) +- 服务器现有 1Panel/OpenResty 等其他项目**严格不触碰**(既有红线) + +## Part 3:使用约定(更新 CLAUDE.md 部署策略段) + +- 用户说"部署到线上" → AI 执行 `bash deploy/deploy.sh all`(或按改动范围选目标)并汇报验证结果与版本标识 +- 任务完成后的标准部署 = 同一条命令;原"tar→scp→…"手工步骤描述作废,指向本脚本 +- 部署日志位于 deploy/logs/ 供追溯 + +## 明确不做(本期) + +- push 触发自动部署(webhook/CI):git 服务器无暴露接收端口必要;未来升级时 CI 可直接调用本脚本(接口即命令行) +- 服务器侧构建:构建留在开发机,服务器保持纯 Docker 运行态 +- 自动回滚机制:出问题走"再改再发"(单管理员低频部署,YAGNI;部署日志保留上一版哈希可供人工对照) + +## 验证计划 + +1. 脚本干跑:单目标 admin 部署一次(近期 admin 已是最新,重部署无损)验证全流程 +2. `all` 全量部署一次(当前三端均为最新代码,等价幂等重部署)验证顺序与哈希核对 +3. 故意注入失败(如断开跳板模拟)验证"失败即停"语义 +4. git push 后远程仓确认两分支与提交历史完整