diff --git a/docs/cicd-design.html b/docs/cicd-design.html new file mode 100644 index 0000000..d051014 --- /dev/null +++ b/docs/cicd-design.html @@ -0,0 +1,170 @@ + + + + + +Pangolin CI/CD 全流程 · 设计方案(#30) + + + +
+← 文档索引 +

Pangolin CI/CD 全流程 · 设计方案

+

#30 · 2026-07-05 · 设计定稿待审 · 范围 A~F(排除 iOS、备份#26、TLS#25)· 真相源 docs/superpowers/specs/2026-07-05-cicd-design.md

+ +
+目标:tag 触发的 编译 → 测试 → 发版(Gitea release)→ 部署 全自动。参考 jiu 的 +.gitea/workflows + scripts/ci/*.sh 结构,适配 pangolin 的部署目标(pangolin1 / +pangolin.yanmeiai.com)与多端产物。现状:仅 ci.yml 校验无部署,服务端手动部署、官网未部署、下载死链。 +
+ +

1. 范围

+ + + + + + + + +
子块内容
A 基座scripts/ci/*(env/provision/test/release/notify/lib-forgejo)+ checks 保留
B 官网Astro 构建 → 部署 pangolin.yanmeiai.com
C 服务端交叉编译 server/agent/migrate → release → ssh pangolin1(备份→migrate→换二进制→重启→健康检查)
D Androidapk(arm64,release keystore 签名)→ release 资产
E macOS公证 dmg(Developer ID + notarytool)→ release 资产
F Windowsexe/installer(Inno Setup)→ release 资产
+

排除:iOS(G,未来)、SQLite 备份/容灾(#26)、控制面 TLS(#25)。

+ +

2. 已锁定决策

+ + + + + + + + +
维度决定理由
runnernas=官网+服务端(容器化)· mac=Android+macOS · windows=Windowsnas 常在线且 Astro/Go 轻量(非 Flutter Web);mac/windows 做必须它们的活
触发tag site-v* / server-v* / client-v* + manual.yml 手动派发同 jiu,发版即部署,可手动重放
macOS 签名mac 自动 Developer ID 签名 + notarytool 公证 + staple凭据入 secret(见 §6)
Android 签名正式 release keystoreapp 级专属签名身份
下载链接官网 href 指向 Gitea release 稳定资产 URL发版即更新,见 §5
镜像goproxy.cn / flutter-io.cn国内网络
+ +

3. 架构

+

3.1 共享基座 scripts/ci/(镜像 jiu)

+ +

每个 compile-* 封装该端已验证的构建命令(Android 走 build-libbox.sh android + +flutter build apk --split-per-abi;macOS 走 Developer ID 签名 + notarytool submit --wait + +stapler)。工作流只调脚本,逻辑在脚本里、便于本地复现。

+ +

3.2 工作流 .gitea/workflows/

+ + + + + + + + +
工作流触发runner步骤
checks.yml(现 ci.yml)push 分支nas保留:shellcheck / openapi / redline / flutter analyze+test / go test
deploy-site.ymlsite-v*nasnode:20 构建 Astro(注入 SITE_URL)→ deploy-site.sh
deploy-server.ymlserver-v*nasgolang:1.25 交叉编译 → test → release → deploy-server.sh
build-android.ymlclient-v*macprovision → compile-android.sh(签名 apk)→ release
build-macos.ymlclient-v*macprovision → compile-macos.sh(签名+公证 dmg)→ release
build-windows.ymlclient-v*windowscompile-windows.sh(exe/installer)→ release
+ +

3.3 服务端部署(固化 F3/F4 手动那套,带回滚)

+
+
    +
  1. scp pangolin-{server,agent,migrate} 到 pangolin1 /tmp
  2. +
  3. systemctl stop pangolin-server
  4. +
  5. wal_checkpoint(TRUNCATE)cp 备份 pangolin.db.bak-pre-<tag>
  6. +
  7. pangolin-migrate up(pangolin 用户);失败即恢复备份 + 重启旧 server + 退出非零
  8. +
  9. install 新二进制到 /usr/local/bin(旧的备份为 .bak-<tag>
  10. +
  11. systemctl start + /healthz 健康检查;agent 随连接自恢复
  12. +
+
+ +

4. 官网部署

+

Astro npm ci && npm run buildSITE_URL=https://pangolin.yanmeiai.com)→ dist/ +rsync 到服务器 web 根 → nginx/Caddy 静态托管。DNS:CF 加记录 +pangolin.yanmeiai.com → 服务器(首次部署时做,记 baize)。

+ +

5. 下载链接闭环(30A)

+

web/website/src/config/site.tsdownloads:{ android, macos, windows },值为 Gitea release +稳定 latest 资产 URL(Forgejo 支持 …/releases/latest/download/<asset> 则直用;否则构建期用 +FORGEJO_TOKEN 查最新 client-v* 版本烘焙进 href)。Download.astro 各平台按钮读 +SITE.downloads.<platform>。客户端发版后官网重部署即刷新(或 build-* 完成触发 deploy-site)。

+ +

6. 密钥与作用域(solo / wangjia)

+ + + + + + +
Secret作用域说明
FORGEJO_TOKEN账户级建 release,jiu 复用
DEVELOPER_ID_P12 / P12_PASSWORD / ASC_KEY_P8 / ASC_KEY_ID / ASC_ISSUER_ID账户级Apple 账号级签名+公证,所有 app 共用,续期改一处
DEPLOY_SSH_KEYpangolin 仓库级授权到 pangolin1,最小权限
RELEASE_KEYSTORE / KEYSTORE_PASSWORD / KEY_ALIAS / KEY_PASSWORDpangolin 仓库级Android app 级专属签名,绝不共享
+

工作流用 secrets.XXX 引用,账户级/仓库级对写法透明。macOS 另需主 app + PacketTunnel +sysext 两个 .provisionprofile(base64 存 secret,签名期落盘嵌入)。

+ +

7. 实现顺序

+

范围虽 A~F,按风险/依赖递增落地,每阶段独立可发、独立验收:

+
    +
  1. A 基座 + checks 迁移(抽 scripts/ci 骨架)
  2. +
  3. B 官网(最简,验证 release/deploy 骨架)
  4. +
  5. C 服务端(固化手动部署)
  6. +
  7. D Android(解锁下载链接;需 keystore 就绪 + gradle 接签名)
  8. +
  9. E macOS(最复杂:证书 + 2 描述文件 + 公证)
  10. +
  11. F Windows(windows runner + Inno Setup)
  12. +
+ +

8. 验证

+ + +

9. 风险与缓解

+ + + + + + + +
风险缓解
nas 内存(3.8G)构建 OOM容器化单 job、Astro/Go 轻量;必要时该端移 mac
migrate 在生产出错部署前备份 + 失败自动回滚(§3.3),已在 F3/F4 手动验证
Android keystore 丢失存 Bitwarden(文件+密码);终身签名身份
macOS 公证凭据泄露账户级 secret,不落盘;.p8/.p12 用完即删临时文件
发版后下载链接不刷新build-* 成功触发 deploy-site 重烘焙,或用 latest-download 稳定 URL
+ +

10. 不在本方案

+

iOS 流水线(G)、SQLite 备份/容灾(#26)、TLS(#25)、上架 Play、Windows 代码签名(先不签)。

+
+ + diff --git a/docs/index.html b/docs/index.html index 760ffae..d63e5b9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -44,6 +44,11 @@

设计方案 / Specs

+ +
CI/CD 全流程(tag 触发编译/发版/部署)HTML
+
#30。参考 jiu 的 scripts/ci + .gitea/workflows:tag 触发(site-v*/server-v*/client-v*)→ 编译 → 测试 → Gitea release → 部署。runner 混合(nas=官网+服务端容器化 / mac=Android+macOS / windows=Windows)。服务端部署固化 F3/F4「备份→migrate→换二进制→重启→健康检查+回滚」;官网部署 pangolin.yanmeiai.com;客户端 apk/dmg/exe 挂 release 喂官网下载链接。密钥作用域:Apple/token 账户级、部署 key/Android keystore 仓库级。范围 A~F(排除 iOS/#26/#25)。
+
docs/cicd-design.html · 真相源 docs/superpowers/specs/2026-07-05-cicd-design.md
+
联系我们 · 渠道二级页(Telegram 频道/群组,DB 配置)HTML
点 Telegram 进二级页,按 kind 分组(频道/群组/Bot)列多条链接,含 @handle/说明/认证/「打开·加入」动作,全渠道(含邮箱/发卡)统一一张 contact_link 表(靠 url 协议区分 mailto/https/tg)。独立 GET /v1/contact。规则:平台 >1 条链接才进二级,否则点击直达。LINE 同构但先灰置「即将开放」(registry comingSoon 开关,配好即去灰)。不展示成员数、群组=加入。含可点原型。