Files

122 lines
8.5 KiB
Markdown
Raw Permalink 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.
---
name: ai-system-bootstrap
description: 为新服务器+新项目搭建完整的 AI 开发发布体系(Gitea 安装、规范目录 standards/、双仓库双环境、发布流程)。当用户要求"搭建体系/接入新项目/初始化 AI 开发流程"时使用本技能。
---
# AI 开发发布体系接入(新服务器 + 新项目)
本技能把一台新服务器和一个新项目接入标准化的 AI 开发发布体系:
```
AI 在开发目录改代码并实测 → commit 到开发分支 → push 到本机 Gitea
→ 用户在 Gitea 网页合并到生产分支 → 生产目录 git pull + 清缓存 → 验证
```
**执行原则**:按第 0~7 步顺序执行;每步的验证点没通过不进下一步;涉及生产目录/生产库的写操作必须先给用户过目并确认。
---
## 第 0 步:收集信息(缺哪项问用户,不要猜)
| 项 | 说明 |
|---|---|
| 项目生产域名 / 测试域名 | 例:`www.xxx.com` / `test.xxx.com` |
| Gitea 域名 | 建议 `git.<项目域名>`,用项目自己的域名,不要复用其他项目的 |
| 服务器面板 | 宝塔 / 其他 / 无面板(本 skill 以宝塔为默认,其他面板类比调整) |
| web 运行用户 | 宝塔默认 `www`;别的环境可能是 `www-data`/`nginx`,**后续所有属主操作用它** |
| 项目技术栈 | 语言/框架/构建方式(影响 coding 规范和 .gitignore) |
| 是否已有生产在跑 | 有则**先做全量备份**再动任何东西 |
| 域名备案状态 | 中国大陆服务器未备案的域名不能用,需用已备案的过渡域名,并记录切换计划 |
## 第 1 步:安装 Gitea(本机自建,走 `install_gitea.sh`)
```bash
sudo ./install_gitea.sh git.example.com
```
脚本做的事:建 `git` 系统用户 → `/www/gitea/{custom,data,log}` → 下载校验 Gitea 最新稳定版 → 写 app.ini(SQLite、监听 127.0.0.1:3000、禁止注册、强制私有库)→ systemd 服务 → 启动并验证 `curl 127.0.0.1:3000` 返回 200。
手工等价操作与已知坑(脚本失败时按此排查):
1. **不要**预配 `INTERNAL_TOKEN_URI`——首次启动会因文件不存在而崩溃,让 Gitea 自动生成。
2. 下载地址列表:`https://dl.gitea.com/gitea/version.json` 取最新版本号;sha256 文件校验时文件名要与原始名一致。
3. 防火墙**不开** 3000 端口,只走反代。
## 第 2 步:Gitea 域名与反代
1. **用户操作**:DNS 添加 A 记录 `<gitea域名> → 服务器公网 IP`(未备案过渡域名同理)。
2. 宝塔建反向代理站点:域名 = Gitea 域名,目标 `http://127.0.0.1:3000`,全站转发,开 WebSocket 支持。
3. **必须在 server 块加 `client_max_body_size 0;`**——否则 git push 大仓库会被 nginx 拒(默认 1m)。
4. `nginx -t` 通过后 reload,`curl -H "Host: <gitea域名>" http://127.0.0.1/` 返回 200。
5. DNS 生效后面板申请 Let's Encrypt 证书(选对域名!宝塔常会自动附加别名域名,别选错)。
6. 未备案过渡期:先用已备案域名访问,在规范里记录"备案成功后切换"待办。
## 第 3 步:管理员与项目仓库
```bash
# 管理员(密码生成后交付用户,建议用户随即改掉)
sudo -u git gitea admin user create --config /www/gitea/custom/conf/app.ini \
--admin --username admin --password '<强密码>' --email admin@<项目域名> --must-change-password=false
# 建私有仓库(也可让用户网页操作)
```
1. 建一个**私有**仓库,命名 = 项目名(如 `xxx-erp`)。
2. 生成 API token(_basic auth 调 `POST /api/v1/users/admin/tokens`,scope all),存 `/root/.gitea_token`(600)。
3. 凭据写 `/root/.git-credentials`(600),格式 `http://admin:<token>@<gitea域名>`。
## 第 4 步:开发目录 git 化
1. `.gitignore` 至少排除:运行时目录(runtime/ 等)、用户上传目录、IDE 目录。**vendor/依赖目录是否入库先问用户**(老项目倾向全量存档防兼容问题,要强制 `git add -f` 补齐依赖内部 .gitignore 排除的文件)。
2. `git init -b <开发分支>`(建议 `test` 或 `develop`)→ 配置 user.name/email → `git add -A` → 检查无垃圾文件 → 首次提交。
3. remote + 凭据(credential.helper store)→ push。
4. 提交身份、凭据都是**仓库级**配置;删过 .git 重建后要重配。
## 第 5 步:提炼 standards/ 规范目录(本技能只给骨架,内容必须重新提炼)
在项目根创建:
```
standards/
├── README.md # 目录说明+索引,开头放"AI 记忆指令"(读到即写入持久记忆)
├── behavior.md # 行为约定:硬性禁止/危险链路/工作方式(含发布流程,见第 7 步)
├── coding.md # 代码规范——通读项目代码后按真实写法提炼,禁止照抄其他项目
├── database.md # 数据库规范——含增量 SQL 约定与改库发布流程(见第 7 步)
└── manual.md # 完整手册:公共方法清单、场景配方、带文件路径/行号的实例
```
提炼要求:**只写该项目真实遵循的写法**(读代码统计套路,不抄框架官方理论);硬性约定进 standards,查阅资料进 manual,两者冲突以 standards 为准。
同批创建:根 `README.md`(顶部"导航(新 AI 由此开始)":AI 记忆指令 + 必读顺序 + 第一级目录一览 + 寻路规则"进入目录先读其 README,首次用到某目录时创建其 README")+ `ai_work/`(README 索引 + done/ 归档机制)+ `sql/`(若项目含数据库)+ 各工具入口文件(CODEBUDDY.md/CLAUDE.md 等指向 standards)。
## 第 6 步:生产目录 git 化(有生产在跑时)
**先备份**:`tar -czf /www/backup/<项目>_pre_git_$(date +%Y%m%d_%H%M%S).tar.gz -C /www/wwwroot <生产目录名>`,并**单独留存环境专属文件副本**。
1. `git init -b <生产分支>` + remote + fetch。
2. **审查差异**后再 reset:`git -C <生产目录> diff --stat FETCH_HEAD`——差异只允许是环境配置;出现业务代码差异必须先停下问用户。
3. `git reset --hard FETCH_HEAD` → **立即恢复环境专属文件**(数据库配置、密钥、extra/环境配置、宝塔 `public/.user.ini` 等)。
4. `git update-index --skip-worktree <环境专属文件...>`——**一份都不能漏**,漏一个就是生产事故。
5. ⚠️ 宝塔的 `public/.user.ini` 带 `chattr +i` 锁:改它前 `chattr -i`,改完 `chattr +i`;reset 遇 "unable to unlink" 就是它。
6. **操作后必须验证**:`git status` 干净(未跟踪除外);include/读取环境配置确认指向本环境;`chown -R <web用户>:<web用户>` 全目录(.git 和带锁文件除外);站点首页 200。
7. 设置本地 master 上游跟踪,让以后 `git pull` 直接可用。
> **操作红线**:跨目录操作一律用绝对路径或 `git -C <路径>`——Bash 会话的工作目录可能在轮次间静默复位,凭"刚才 cd 过"操作是事故之源。危险命令(rm/reset/cp 覆盖)前后必须验证位置与关键文件内容。
## 第 7 步:发布流程写入 standards/behavior.md
- 开发分支 = AI 开发环境;任务完成 → commit + push → **提醒用户去 Gitea 合并到生产分支**(不会 git 的用户给指路:拉请求 → base=生产分支 / compare=开发分支 → 创建 → 合并;合并标题格式 `发布:<改动一句话>`;标题加 `WIP:` 前缀会锁合并按钮,用于未完成的草稿)。
- 更新生产 = `git -C <生产目录> pull && sudo -u <web用户> php think clear`(按项目实际清缓存命令),**清缓存/写 runtime 的命令必须以 web 用户身份跑**,否则属主变 root 全站 500。完成后验证首页 200。
- **改库流程**:增量 SQL 存 `sql/YYYY-MM-DD_描述.sql` 与代码一起提交;**SQL 不随 git pull 走**——生产库要单独执行,顺序固定**先库后代码**;执行生产库前把 SQL 给用户确认并备份生产库。
- web 可写目录(runtime/、uploads/ 等)属主必须是 web 用户;root 操作后必须恢复。
## 完成验证清单(全部打勾才算接入完成)
- [ ] Gitea 可通过域名 HTTPS 访问,禁止注册,仓库强制私有
- [ ] 管理员密码已交付用户
- [ ] 开发分支已 push,remote/凭据可用
- [ ] standards/ 五件套齐全且内容来自项目真实代码
- [ ] 根 README 导航 + ai_work/ + 工具入口文件就位
- [ ] 生产目录 git 化完成,skip-worktree 清单核实,站点 200
- [ ] 发布流程、改库流程已写入 behavior.md
- [ ] 全量备份文件已留存并告知用户路径