Skip to content

各端发布步骤(闭源 · 私密免费分享) ​

配合 发布与在线更新.md 阅读。客户端覆盖 6 端:Docker(服务端+Web UI)/ Android / iOS / macOS / 鸿蒙 / Windows;监控 Agent 是配套组件(见附录)。

核心原则:源码留 Private 仓库,只分发产物(镜像 / APK / ipa / app / zip / hap),走私密网盘 + TG 群。

0. 所有端共用的发版动作(每次发版先做) ​

  1. 改版本号(4 处同步):
  2. 更新官方 manifest JSON(见 发布与在线更新.md §3.2):把各端新版本的下载直链 + sha256 填进 targets
  3. 打 tag 触发 CI:
    bash
    git tag vX.Y.Z
    git push origin vX.Y.Z    # 必须带 v 前缀,触发全部 workflow
  4. 等 CI 跑完(约 15 分钟),产物就绪
  5. 把产物搬到私密网盘:你作为仓库 owner 能从 GitHub Release 下载(Private repo 的 Release 外部下不了),下载后传网盘,把网盘直链回填进 manifest

1. Docker(服务端 + 内嵌 Web UI) ​

主形态。一个镜像同时提供 API(:8088)和 Web UI(前端 go:embed 内嵌)。

构建

  • CI 自动(docker.yml):tag → 多架构镜像(amd64/arm64)→ ghcr.io/gntv456/pt-patronus:vX.Y.Z + :latest
  • 本地手动:make image 或 docker compose build

产物:ghcr 镜像

分发(一次性配置):ghcr 包设为 public(GitHub → Packages → ptpatronus → Package settings → Public),用户 docker pull 免登录。

用户安装:给用户一份 docker-compose.yml(基于 docker-compose.yml):

yaml
services:
  ptpatronus:
    image: ghcr.io/gntv456/pt-patronus:latest
    restart: unless-stopped
    ports: ["8088:8088"]
    environment:
      APP_ENV: release
      SECRET_KEY: <openssl rand -base64 32>        # 必填,release 模式留空拒绝启动
      ACTIVATION_SECRET: <openssl rand -base64 32> # 必填
      UPDATE_MANIFEST_URL: https://<你的gist>/update-manifest.json  # 在线更新
    volumes:
      - ./data:/app/data

docker compose up -d,访问 http://服务器:8088。

用户升级:docker compose pull && docker compose up -d;或 Web UI「设置 → 关于 → 检查更新」提示新版本后一键复制命令。

manifest:"docker": { "image": "ghcr.io/gntv456/pt-patronus:0.70.01", "instructions": "docker compose pull && docker compose up -d" }


2. Android(Flutter APK) ​

构建

  • CI 自动(flutter-release.yml):tag → APK → GitHub Release
  • 本地手动:cd mobile && flutter build apk --release

产物:app-release.apk

⚠️ 发布前必须配 release 签名(否则用 debug 签名 → 不安全 + 新版无法覆盖安装旧版):

  1. 生成 keystore(一次性,妥善保管,丢了只能换包名重装):
    bash
    keytool -genkey -v -keystore ptpatronus.jks -keyalg RSA -keysize 2048 -validity 36500 -alias ptpatronus
  2. mobile/android/key.properties(别提交 git,加进 .gitignore):
    properties
    storePassword=***
    keyPassword=***
    keyAlias=ptpatronus
    storeFile=../ptpatronus.jks
  3. build.gradle.kts 已配好 signingConfigs(见 build.gradle.kts:读 android/key.properties,存在用 release 否则回退 debug)+ key.properties.example 模板
  4. 每次发版用同一 keystore → 升级可覆盖安装

CI 自动签名(flutter-release.yml 的 android job 已配):在 GitHub Settings → Secrets and variables → Actions 配 4 个 secret,打 tag 时自动注入:

  • ANDROID_KEYSTORE_BASE64:base64 -w0 ptpatronus.jks(Linux/mac)/ [Convert]::ToBase64String([IO.File]::ReadAllBytes("ptpatronus.jks"))(PowerShell)
  • ANDROID_STORE_PASSWORD / ANDROID_KEY_PASSWORD / ANDROID_KEY_ALIAS 未配 secret 时 CI 回退 debug 签名(能出包但无法覆盖安装升级)。

分发:APK 传网盘(直链)+ TG 群。

用户安装:首次下载 → 允许「未知来源」→ 安装;升级(应用内 OTA):旧版启动自动检查 / 账户页「检查更新」→ 弹窗 → 自动下载 APK(进度条)→ sha256 校验 → 调系统安装器(apk_downloader.dart)。

manifest:"android": { "url": "https://网盘直链/ptpatronus-0.70.01.apk", "sha256": "<sha256sum>" } ⚠️ url 必须是 .apk 直链(不是网盘页面/提取码页),否则 APP 自动回退外链浏览器下载。

算 sha256:sha256sum app-release.apk(Linux/mac)/ certutil -hashfile app-release.apk SHA256(Windows)。


3. iOS(Flutter IPA) ​

构建(需 macOS + Xcode + Apple 开发者账号):

bash
cd mobile
flutter build ipa --release    # 产物 build/ios/ipa/ptpatronus.ipa

需在 Apple Developer 后台配好证书(Distribution)+ Provisioning Profile。

签名:Apple Developer 证书签名;分发方式决定 Profile 类型。

分发(私密,不进 App Store)—— 三选一:

方式适合上限更新机制
AltStore / AltSource(推荐私密)圈内邀请分享需用户 7 天重签(自签)用户 AltStore 订阅 AltSource.json 源 → 自动检测更新
TestFlight半公开测试10000 测试员App Store Connect 推送,自动更新
Ad-Hoc固定设备≤100 台(设备 UDID 绑定)手动重装

AltStore 方案:用 mobile/altsource/gen_altsource.py 生成 AltSource.json(私密分发版,手动传参,不走 GitHub API——因 ipa 在网盘)。每次发 iOS 版:

bash
cd mobile/altsource
cp config.json.example config.json      # 首次:填 app_id / icon_url / website 等
cd .. && flutter build ipa --release    # 出 build/ios/ipa/*.ipa,传网盘拿直链
cd altsource && python3 gen_altsource.py \
  --version 0.70.01 \
  --url https://网盘直链/ptpatronus-0.70.01.ipa \
  --size $(wc -c < ../build/ios/ipa/*.ipa | tr -d ' ') \
  --notes "本次更新内容..."

把生成的 AltSource.json 推到公开 URL(gist / 轻量仓库 raw / 静态站),用户在 AltStore「添加源」订阅该 URL → 自动检测并安装/更新 ipa。

用户安装:AltStore 侧载 / TestFlight 邀请链接。

升级:iOS 端主要靠 AltStore/TestFlight 自身的更新机制;manifest 的 targets.ios 条目已常驻(url 指向下载页或 AltSource.json URL),Flutter iOS 端「检查更新」有新版时外链打开该页并提示走 TestFlight/分发渠道安装(实际安装仍走 AltStore)。

manifest:"ios": { "url": "<下载页或 AltSource.json URL>", "sha256": "<ipa 的 sha256,可选>" };ipa 拷进 dist 目录后 node scripts/update-manifest.mjs 会自动回填 sha256。

⚠️ CI:iOS 构建需 Apple 签名 secrets(证书 + Profile + 设备列表),CI 配置复杂,建议本地手动构建后传网盘,不放 GitHub Actions。


4. macOS(Flutter .app) ​

构建(需 macOS 机器):

bash
cd mobile
flutter build macos --release    # 产物 build/macos/Build/Products/Release/ptpatronus.app

打包:整个 .app 打成 zip 或 dmg:

bash
cd build/macos/Build/Products/Release
zip -r ptpatronus-macos-0.70.01.zip ptpatronus.app

签名 / 公证(二选一):

  • 私密分发不公证(最简):用户首次「右键 → 打开」绕过 Gatekeeper(会提示「未识别开发者」)。适合圈内小范围。
  • Developer ID 签名 + 公证(体验最好):需 Apple 开发者账号 + xcrun notarytool 提交公证。用户双击即可运行。

分发:网盘 zip/dmg + TG 群。

用户安装:解压 zip → 拖到「访达 → 应用程序」→(首次右键打开,或在「系统设置 → 隐私与安全性」点「仍要打开」)。

升级:macOS 客户端「检查更新」→ 外链打开下载页 → 手动替换 .app(Flutter 桌面无应用内自更新,走外链兜底对话框)。

manifest:"macos": { "url": "https://网盘/ptpatronus-macos-0.70.01.zip", "sha256": "..." };zip 拷进 dist 目录后 node scripts/update-manifest.mjs 会自动回填 sha256。

CI 已自动:flutter-release.yml 的 macos job(runs-on: macos-latest)已配好,打 tag 自动出未签名 zip 挂 Release。无需任何 secret。


5. 鸿蒙 HarmonyOS ​

CI 没有鸿蒙 runner(需华为 flutter 分支 + DevEco Studio),纯手动。

构建(在配好鸿蒙 SDK + 华为 flutter 分支的机器上):

bash
cd mobile
flutter build hap --release    # 仅鸿蒙分支的 flutter 有 build hap

产物:.hap 包。

分发:网盘。

用户安装:DevEco Studio 或 hdc install <hap>。

升级:手动重装(鸿蒙端暂未接在线更新;如需可加 harmony target 到 manifest,外链提示)。


6. Windows(Flutter Windows) ​

构建

  • CI 自动(flutter-release.yml):tag → Windows → GitHub Release(zip)
  • 本地手动:cd mobile && flutter build windows --release,产物在 mobile/build/windows/x64/runner/Release/

产物:ptpatronus-windows-x64.zip(整个 Release 目录打包)

分发:网盘 + TG 群。

用户安装:解压 → 运行 ptpatronus.exe(可能需在「Windows 安全中心」允许「更多信息 → 仍要运行」,因无代码签名证书)。

升级:Windows 客户端「检查更新」→ 外链打开下载页 → 手动替换文件(Flutter 桌面无应用内自更新,走外链兜底)。

manifest:"windows": { "url": "https://网盘/ptpatronus-windows-x64-0.70.01.zip", "sha256": "..." }

💡 代码签名(可选增强):购买 Windows 代码签名证书(EV/普通),用 signtool 签 exe,消除 SmartScreen 警告。私密分发可不签。


附录 A. 监控 Agent(配套组件,非客户端) ​

装在被监控服务器上,WS 主动上报指标到主面板。

构建

  • CI 自动(release.yml):tag → linux amd64/arm64 二进制 → GitHub Release
  • 本地手动:cd backend && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o ptpatronus-agent-linux-amd64 ./cmd/ptpatronus-agent

⚠️ 闭源关键坑:agent_install.sh 默认从 GitHub Release 下载,Private 仓库外部下不了。脚本已支持 AGENT_DOWNLOAD_BASE 环境变量——把两个架构二进制传网盘,安装命令带上 AGENT_DOWNLOAD_BASE=https://网盘/path,脚本即从 ${BASE}/ptpatronus-agent-linux-<arch> 下载,绕过 GitHub。或单独建 Public 仓库只放 agent Release(AGENT_REPO 指向它)。

用户安装:主面板「设备监控 → Agent 管理 → 新建」生成一键命令,被监控机执行 curl -fsSL <面板>/api/v1/monitor/agents/install.sh | AGENT_ID=.. AGENT_SECRET=.. DASHBOARD_URL=.. bash(自动 systemd 注册)。

升级:Agent 无自动更新,靠重装。manifest:"agent-linux-amd64": {"url":"...","sha256":"..."}、"agent-linux-arm64": {...}。


7. 一次完整发版 checklist ​

发版前(main 分支):

  • [ ] 4 处版本号改成 X.Y.Z
  • [ ] Flutter release keystore 已配(首次)/ 仍有效
  • [ ] make test 全绿(后端 go test + 前端 npm build + Flutter analyze)

发版:

  • [ ] git tag vX.Y.Z && git push origin vX.Y.Z
  • [ ] 等 CI 全绿
  • [ ] 从 GitHub Release / 本地构建产物:Android APK、Windows zip(+ macOS zip 若加 CI)
  • [ ] 本地手动出:iOS ipa(Apple 签名)、macOS app(若未加 CI)、鸿蒙 hap
  • [ ] 算各产物 sha256
  • [ ] 全部传私密网盘,拿直链;iOS 的 AltSource.json 上传到公开 URL
  • [ ] 更新官方 manifest:latestVersion + targets 各端 url + sha256
  • [ ] 网盘 + TG 群发新版公告

验证:

  • [ ] Docker:docker compose pull && up -d,Web 关于页版本号变 X.Y.Z
  • [ ] 旧 Android:启动弹更新 → 下载 → 安装 → 新版启动
  • [ ] iOS:AltStore 检测到新版本
  • [ ] macOS / Windows:检查更新 → 外链下载替换

8. 闭源分发的特殊处理(汇总) ​

问题解法
Private repo 的 GitHub Release 外部匿名下不了所有产物走私密网盘;manifest url 指向网盘直链
docker 镜像默认跟随 repo 私有ghcr 包单独设 public(用户 pull 免登录)
agent_install.sh 写死 GitHub Release改 URLS 指向网盘,或建公开 release 仓库
APK 升级签名不一致无法覆盖安装配 release keystore,每次同一签名
iOS 不进 App Store 怎么分发AltStore/AltSource(私密推荐)或 TestFlight
macOS 未签名被 Gatekeeper 拦用户右键打开绕过;或 Developer ID 签名+公证
Windows 未签名被 SmartScreen 拦用户点「仍要运行」;或买代码签名证书
网盘页面/提取码拿不到直链用支持直链的网盘/对象存储,或自建静态站
防中间人替换产物manifest 每个产物填 sha256,下载后校验

9. 各端在线更新方式速查 ​

端manifest target key更新落地方式
DockerdockerWeb UI 提示 docker compose pull && up -d(一键复制)
Androidandroid应用内 OTA:dio 下载 APK → sha256 → 系统安装
iOSios(可选)AltStore/TestFlight 自更新为主
macOSmacos外链下载 zip → 手动替换 .app
鸿蒙harmony(可选)手动重装
Windowswindows外链下载 zip → 手动替换
Agentagent-linux-*重装(暂无自动)