Files
fangke/docs/superpowers/specs/2026-09-29-git-and-deploy-automation-design.md
T
2026-09-29 16:11:06 +08:00

88 lines
5.0 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.
# 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 <server|admin|sdk|all> [--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 后远程仓确认两分支与提交历史完整