Skip to content

好学云谱(yunpu)打包发布操作手册 ​

配套 云端数据中心.md 阅读。本手册 = 版本同步 + 规范命名打包 + OTA 在线更新清单,step-by-step 可直接抄。

设计参考 PTPatronus 发版体系,适配好学云谱技术栈(原生 JS + Node 认证代理 + Capacitor Android + Electron 桌面 + Docker)。

命名规范速查(软件命名规则) ​

项规则示例
版本号semver MAJOR.MINOR.PATCH1.0.1
产物文件<产品名>-<版本>+<构建日期>-<平台>.<ext>yunpu-1.0.1+20260714-windows-x64-portable.zip
发版目录release/yunpu-<版本>+<日期>/release/yunpu-1.0.1+20260714/
Docker 镜像ghcr.io/gntv456/yunpu:<版本> + :latestghcr.io/gntv456/yunpu:1.0.1
Git tagv<版本>(带 v 前缀)v1.0.1
OTA 清单update-manifest.json(latestVersion = 版本)"latestVersion": "1.0.1"
  • 产品短名统一用 yunpu(与 package.json 的 name 一致)。
  • +YYYYMMDD 是 semver 构建元数据,不影响版本优先级比较,仅作可追溯标识。
  • 平台后缀:-mobile-pwa / -windows-x64-portable / -android。

每次发版(以 1.0.0 → 1.0.1 为例) ​

0. 改版本号(4 处自动同步) ​

bash
npm run version:bump -- 1.0.1

脚本 scripts/bump-version.mjs 一次性改:

  • package.json(权威,/api/system/version 与打包脚本都从这里读)
  • js/main.js(window.Yunpu.version 运行时版本 + 控制台日志)
  • android/app/build.gradle(versionName + versionCode 自增)

「设置→关于」的版本号动态读 window.Yunpu.version,无需手改。

提交版本号:

bash
git add package.json js/main.js android/app/build.gradle
git commit -m "chore: bump 版本号 → 1.0.1"

1. 本地打包(Web PWA + Windows 便携) ​

bash
npm run package:release

脚本 scripts/package-release.mjs 产出:

  • release/yunpu-1.0.1+<日期>/yunpu-1.0.1+<日期>-mobile-pwa.zip —— 手机 PWA 静态包
  • release/yunpu-1.0.1+<日期>/yunpu-1.0.1+<日期>-windows-x64-portable.zip —— Windows 便携版(自带 node 运行时)

可用 YUNPU_MOBILE_API_BASE=https://yunpu.example.com 预填手机端默认后端地址。

2. (可选)Android APK / Electron 便携 exe ​

bash
# Android APK(需 Android SDK,本机 .android-sdk 已在)
npm run package:apk
# 产物: android/app/build/outputs/apk/debug/app-debug.apk
# 重命名为规范名后拷进 release/yunpu-1.0.1+<日期>/yunpu-1.0.1+<日期>-android.apk

# Electron Windows 便携 exe(需 electron-builder,首次会下载 electron)
npm run package:desktop-exe
# 产物: release-desktop/yunpu 1.0.1.exe(portable)

3. Docker 构建 ​

本机 Docker 被 WSL2 未启用卡住(需重启装),镜像在 ptang 服务器构建(详见下文「Docker 构建(ptang)」),或推 v* tag 让 .github/workflows/docker.yml 在 CI 出多架构镜像。镜像名:ghcr.io/gntv456/yunpu:<版本> + :latest。

首次发布后到 GitHub → Packages → yunpu → Package settings → 设 Public,用户 docker pull 免登录。

4. 回填 OTA manifest(sha256) ​

bash
npm run release:manifest

脚本 scripts/update-manifest.mjs 扫描 release/yunpu-1.0.1+<日期>/,按文件名后缀识别平台,计算 sha256 回填 update-manifest.json 的 targets.*.sha256,并同步 latestVersion 与 targets.docker.image。

然后手填两样:

  • targets.*.url:各产物上传网盘后,填网盘分享地址。当前手机/电脑安装包统一在蓝奏云 https://wwazg.lanzoub.com/b03annjefe(提取码 hxpt),三个客户端 target 都填它。
  • releaseNotes:本次更新说明(带网盘提取码)。

5. 发布 OTA manifest 到 gist(在线更新源) ​

OTA manifest 托管在一个公开 GitHub gist(只含版本号 + changelog + 下载地址,无密钥):

项值
Gist 页面https://gist.github.com/gntv456/450138b061159bc6783b1c7b786e0b02
raw 地址(最新版,带 ~5min CDN 缓存)https://gist.githubusercontent.com/gntv456/450138b061159bc6783b1c7b786e0b02/raw/update-manifest.json

docker-compose.example.yml 的 YUNPU_UPDATE_MANIFEST_URL 已默认指向它,用户开箱即用,无需配置。

每次发版要更新这个 gist 的内容(把新版 update-manifest.json 推上去)。两种方式:

  • Web UI(最简单):打开上面 gist 页面 → 编辑 update-manifest.json → 粘贴本地新版内容 → 保存。
  • 命令行(在 ptang 上跑,本机连不上 GitHub):用带 gist 权限的 PAT,
    bash
    ssh ptang 'curl -sS -X PATCH https://api.github.com/gists/450138b061159bc6783b1c7b786e0b02 \
      -H "Authorization: token <PAT>" -H "Accept: application/vnd.github+json" \
      -d @<(python3 -c "import json;print(json.dumps({\"files\":{\"update-manifest.json\":{\"content\":open(\"/root/yunpu-build/update-manifest.json\").read()}}}))")"
    token 用完即弃,不落盘。

6. 提交 + 打 tag ​

bash
git add update-manifest.json
git commit -m "build: 发版 1.0.1(manifest + sha256)"
git tag v1.0.1
git push origin main --tags

7. 验证 ​

  • 版本号:curl http://<部署地址>/api/system/version → {"ok":true,"version":"1.0.1"}
  • OTA:curl http://<部署地址>/api/system/update-check → manifest.latestVersion = 1.0.1
  • 客户端:设置→关于,版本显示 v1.0.1;点「检查更新」,配了 YUNPU_UPDATE_MANIFEST_URL 时提示最新/新版,未配时提示「未配置更新源」。
  • Docker:docker pull ghcr.io/gntv456/yunpu:1.0.1(或 :latest)启动后关于页版本号变 1.0.1。

在线更新机制(两条,别混淆) ​

机制触发你要做的
客户端「检查更新」客户端调本服务 /api/system/update-check,本服务代理官方 manifest,客户端与 window.Yunpu.version 比对部署 compose 设 YUNPU_UPDATE_MANIFEST_URL,维护好 update-manifest.json
Docker 镜像更新用户 docker compose pull && up -d 拉 :latestpush 完 :latest 即可

客户端不直连官方源(由本服务中转),避墙 + 不泄露官方地址。没设 YUNPU_UPDATE_MANIFEST_URL 只是客户端「检查更新」提示未配置,不影响拉镜像更新。


常见坑 ​

  • 网盘拿不到直链:用支持直链的网盘/对象存储,或自建静态站;manifest 的 url 必须是直链,否则客户端「前往下载」打不开。
  • APK 升级签名不一致无法覆盖安装:每次发版用同一签名(debug 包同 debug 签名可覆盖;正式发布建议配 release keystore)。
  • manifest CDN 缓存:上传后 raw 约 5 分钟才更新,验证时等一下。
  • ARM 部署:x86 build 出单 amd64,ARM 用户需 buildx 多架构。
  • /api/system/version 返回 0.0.0:说明 server.js 读不到 package.json,检查 Dockerfile 是否 COPY 了 package.json(已 COPY)。

附录:Docker 构建(ptang 服务器) ​

本机 Docker 被 WSL2 未启用卡住(WSL_E_WSL_OPTIONAL_COMPONENT_REQUIRED,需管理员 wsl --install --no-distribution + 重启),所以镜像在 ptang 服务器构建(能直连 GitHub/Docker Hub,且就是 PTPatronus 那台)。流程:

bash
# 1. 传代码(只传 Dockerfile 需要的文件,经 ssh 管道)
tar czf - index.html manifest.webmanifest runtime-config.js service-worker.js \
  server.js package.json package-lock.json README.md Dockerfile .dockerignore \
  css icons js \
  | ssh ptang 'rm -rf /root/yunpu-build && mkdir -p /root/yunpu-build && tar xzf - -C /root/yunpu-build'

# 2. ptang 上构建(ghcr 全名 tag,方便后续推送)
ssh ptang 'cd /root/yunpu-build && docker build -t ghcr.io/gntv456/yunpu:1.0.1 -t ghcr.io/gntv456/yunpu:latest .'

# 3. 验证
ssh ptang 'docker run --rm -d --name yunpu-t -p 5199:5173 -e JIAPU_AUTH_SECRET=dev ghcr.io/gntv456/yunpu:1.0.1
  && sleep 2 && curl -s http://127.0.0.1:5199/api/system/version && docker rm -f yunpu-t'

推到 GHCR(让用户 docker pull,需 device flow 授权一次,token 用完即 logout):见 PTPatronus 手册的 ghcr device flow(client_id 178c6fc778ccc68e1d6a,scope write:packages),或在 GitHub 仓库建一个 PAT 给 CI 用,打 v* tag 让 docker.yml 自动推。

ARM 部署需多架构:CI workflow 已配 linux/amd64,linux/arm64;ptang 本地只出 amd64。