aa7099ba94
将单一 CI/CD 流水线拆成三条互不影响的发布流水线,各有 tag 前缀、独立版本
序列与独立 CHANGELOG:
- client(client-v*):Flutter 全平台 + version.yaml 自更新清单
- site(site-v*):web/ Eleventy 营销站,不含 web 版 app
- server(server-v*):backend Go 服务 + 共享基建 nginx/systemd
新增 3 个 workflow(deploy-client/site/server.yml)替换 deploy.yml;CI 脚本
按 part 拆分为 compile-/release-/deploy-{client,site,server}.sh,抽出公共函数
lib-forgejo.sh;compile-{macos,android,ios,windows}.sh 改去 client-v 前缀;
manual.yml 按前缀路由回滚。
跨流水线解耦:version.yaml 归 client,后端每请求实时读取(不重启、不触发
server 流水线);官网下载页的版本徽章/下载链接/更新日志时间线运行时经
/api/v1/public/release 动态拉取(API 不可达回退构建时静态内容)。为此一次性
扩展后端 changelog 字段(version.go/public.go)与 download.njk 动态渲染。
CHANGELOG.md 重命名为 CHANGELOG-client.md,新增 CHANGELOG-site/server.md;
重写 /release 命令为 /release <part> [version];同步更新 CLAUDE.md 与部署文档。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
181 lines
5.8 KiB
Markdown
181 lines
5.8 KiB
Markdown
# NAS + Gitea 部署文档
|
||
|
||
## 概述
|
||
|
||
岩美酒库管理系统使用 **群晖 NAS 上自托管的 Gitea(Forgejo)** 作为代码仓库和 CI/CD 平台。代码推送到 `main` 分支后,NAS 上的 Gitea Runner 自动构建并部署到 EC2 服务器。
|
||
|
||
---
|
||
|
||
## 服务地址
|
||
|
||
| 服务 | 地址 |
|
||
|------|------|
|
||
| Gitea Web UI | `https://git.51yanmei.com` |
|
||
| Gitea SSH | `ssh://git@git.51yanmei.com:2222` |
|
||
| Actions 面板 | `https://git.51yanmei.com/wangjia/jiu/actions` |
|
||
| 线上应用 | `https://jiu.51yanmei.com` |
|
||
| 管理端 Web | `https://jiu.51yanmei.com/app/` |
|
||
|
||
---
|
||
|
||
## Gitea Runner 说明
|
||
|
||
Runner 实际运行在**本机 Mac**(不是 NAS),通过 LaunchAgent 开机自启,连接 NAS 上的 Forgejo。
|
||
|
||
### 本机文件布局
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `/Users/wangjia/bin/act_runner` | act_runner 二进制(v0.2.11) |
|
||
| `/Users/wangjia/bin/act_runner_start.sh` | 启动脚本(含 TCP 中继逻辑) |
|
||
| `/Users/wangjia/bin/tcp_relay.py` | Python3 TCP 中继(旧内网方案,现已通过域名直连) |
|
||
| `/Users/wangjia/.act_runner` | Runner 注册信息 |
|
||
| `/Users/wangjia/.act_runner_config.yaml` | Runner 配置(label: `mac:host`,capacity: 1) |
|
||
| `~/Library/LaunchAgents/com.jiu.act-runner.plist` | LaunchAgent plist,开机自启 |
|
||
| `/tmp/act_runner.log` | 运行日志 |
|
||
|
||
### Workflow 标签
|
||
|
||
`.gitea/workflows/deploy-{client,site,server}.yml` 中使用 `runs-on: mac`,对应 runner label `mac:host`。
|
||
|
||
### 检查 Runner 状态
|
||
|
||
```bash
|
||
# 查看日志
|
||
tail -f /tmp/act_runner.log
|
||
|
||
# 确认进程在跑
|
||
ps aux | grep act_runner | grep -v grep
|
||
|
||
# 手动重启(LaunchAgent 会自动重启,一般不需要)
|
||
kill $(pgrep -f act_runner_start.sh)
|
||
```
|
||
|
||
### Runner 不工作时的排查步骤
|
||
|
||
1. **确认 Gitea 可达**:`curl -sf https://git.51yanmei.com/api/v1/version`
|
||
2. **查看最近日志**:`tail -30 /tmp/act_runner.log`
|
||
3. **手动测试**:`/Users/wangjia/bin/act_runner daemon --config ~/.act_runner_config.yaml`(从终端运行应直接成功)
|
||
4. **强制重启**:`kill $(pgrep -f act_runner_start.sh)` — LaunchAgent 会在几秒内自动重拉
|
||
|
||
### 重新注册 Runner(token 失效时)
|
||
|
||
```bash
|
||
# 1. 停止当前 runner
|
||
kill $(pgrep -f act_runner_start.sh)
|
||
|
||
# 2. 删除旧注册文件
|
||
rm ~/.act_runner
|
||
|
||
# 3. 在 Forgejo 获取新 token:
|
||
# Settings → Actions → Runners → Create Runner Token
|
||
|
||
# 4. 注册(从终端运行,不要从 LaunchAgent)
|
||
/Users/wangjia/bin/act_runner register \
|
||
--no-interactive \
|
||
--instance https://git.51yanmei.com \
|
||
# SSH remote: ssh://git@git.51yanmei.com:2222/wangjia/jiu.git
|
||
--token <新token> \
|
||
--name mac-runner \
|
||
--labels mac:host
|
||
|
||
# 5. 重启(LaunchAgent 自动接管)
|
||
kill $(pgrep -f act_runner_start.sh)
|
||
```
|
||
|
||
---
|
||
|
||
## Workflows
|
||
|
||
仓库根目录 `.gitea/workflows/` 下有三个 workflow 文件:
|
||
|
||
### `deploy-{client,site,server}.yml` — 三条独立部署流程
|
||
|
||
发版已拆成三条互不影响的流水线,按 tag 前缀触发:
|
||
|
||
| workflow | 触发 tag | 范围 |
|
||
|----------|---------|------|
|
||
| `deploy-client.yml` | `client-v*.*.*` | Flutter 全平台 + version.yaml |
|
||
| `deploy-site.yml` | `site-v*.*.*` | Eleventy 营销站 |
|
||
| `deploy-server.yml` | `server-v*.*.*` | Go 后端 + nginx |
|
||
|
||
**步骤(各自):** `compile-<part>*.sh` 编译打包 → `test.sh <part>` 门禁 → `release-<part>.sh` 创建 Forgejo Release → `deploy-<part>.sh` SSH 到 EC2 部署 → Telegram 通知。公共函数在 `scripts/ci/lib-forgejo.sh`。
|
||
|
||
### `manual.yml` — 手动部署 / 回滚
|
||
|
||
**触发条件:** Forgejo UI 手动触发(workflow_dispatch),输入带前缀 tag(如 `client-v1.0.55`),按前缀路由到对应 `deploy-<part>.sh`
|
||
|
||
**步骤:** 只运行 `deploy.sh`,从 Forgejo Release 下载已有产物直接部署,跳过编译和测试。
|
||
|
||
### `ci.yml` — PR 测试流程
|
||
|
||
**触发条件:** 非 `main` 分支的 push 或 PR
|
||
|
||
**步骤:** 只跑测试(`go test` + `flutter test`),不构建不部署。
|
||
|
||
---
|
||
|
||
## Secrets 配置
|
||
|
||
在 Gitea 仓库的 **Settings → Secrets** 中配置以下密钥:
|
||
|
||
| Secret 名称 | 用途 |
|
||
|-------------|------|
|
||
| `EC2_SSH_KEY` | EC2 服务器的 SSH 私钥(PEM 格式,完整内容) |
|
||
| `EC2_HOST` | EC2 服务器 IP 或域名 |
|
||
| `EC2_USER` | EC2 SSH 用户名(如 `ec2-user`、`ubuntu`) |
|
||
| `FORGEJO_TOKEN` | Gitea 个人访问 Token(用于创建 Release、下载 asset) |
|
||
| `FORGEJO_URL` | Gitea 地址:`https://git.51yanmei.com` |
|
||
| `TELEGRAM_TOKEN` | Telegram Bot Token(部署通知) |
|
||
| `TELEGRAM_CHAT_ID` | Telegram Chat ID(接收通知的对话) |
|
||
|
||
---
|
||
|
||
## 触发部署方式
|
||
|
||
```bash
|
||
# 开发完成,确认测试通过后打 tag
|
||
git tag -a v1.1.0 -m "v1.1.0"
|
||
git push nas main && git push nas v1.1.0
|
||
# → CI 自动:compile → test → release → deploy → Telegram 通知
|
||
```
|
||
|
||
**回滚:** Forgejo UI → Actions → Manual Deploy → 输入旧 tag → Run
|
||
|
||
---
|
||
|
||
## EC2 服务器目录结构
|
||
|
||
```
|
||
/opt/jiu/
|
||
├── backend/
|
||
│ ├── jiu-server # Go 可执行文件
|
||
│ └── config/
|
||
│ └── version.yaml # 版本信息(由 CI 自动更新)
|
||
├── web/ # Flutter Web 构建产物(/app/ 路径)
|
||
├── marketing/ # 营销站点静态 HTML
|
||
│ ├── assets/
|
||
│ ├── index.html
|
||
│ ├── docs.html
|
||
│ └── download.html
|
||
├── images/ # 商品图片上传目录
|
||
└── web-old/ # 上一版本 Flutter Web(回滚备用)
|
||
```
|
||
|
||
Systemd 服务名:`jiu`
|
||
日志:`journalctl -u jiu -f`
|
||
|
||
---
|
||
|
||
## Nginx 路由说明
|
||
|
||
配置文件:`deploy/nginx-jiu.conf`(CI 部署时自动更新)
|
||
|
||
| 路径 | 服务 |
|
||
|------|------|
|
||
| `/api/*`, `/health`, `/version` | Go 后端 API |
|
||
| `/images/*` | 商品图片静态文件 |
|
||
| `/app/` | Flutter 管理端 SPA |
|
||
| `/product/<uuid>` | 商品扫码公开页(Flutter Web 路由) |
|
||
| `/` | 营销首页 |
|