Files
ele-HeiXiu/UpdateA.md
YoungestSongMo 6204c14b88 feat: 重构更新流程 — 无更新不抛异常、用户决定下载、更新详情展示(md文件中的)
【核心重构】
  - getLatestVersion() 不再 throw Error,无更新时返回 { version: APP_VERSION }
  - checkForUpdates() 先自行预检 → 无更新直发 IPC,有更新才交 electron-updater
  - 移除 NO_UPDATE_MESSAGE 常量及所有字符串匹配拦截代码
  - HeiXiuProvider 增加 500ms TTL 缓存,避免预检+electron-updater 重复请求 API

  【用户体验】
  - 检查到新版本后不再自动下载,展示更新内容供用户决定
  - 新增"下载更新"按钮(与"安装更新"分离为两步操作)
  - 设置页新增"查看详情"弹窗,Markdown 格式化渲染更新日志
  - available / downloading / downloaded 三个状态 UI 独立展示

  【Bug 修复】
  - 测试服务器版本排序:字符串序 → 语义版本序(_version_key),0.0.10 正确 > 0.0.9
  - 版本比较:!= → <(_version_key),防止高版本误判为有更新
  - get_best_release fallback 同样改为语义版本排序
  - Windows cmd set 命令尾部空格 → Invalid URL(.trim() 修复)
  - electron-updater 'error' 事件中拦截 NO_UPDATE_MESSAGE → UPDATE_NOT_AVAILABLE

  【文档更新】
  - CHANGELOG.md、PROJECT.md、UpdateA.md 同步更新架构图和流程说明
2026-06-04 18:31:52 +08:00

263 lines
12 KiB
Markdown
Raw 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.
# HeiXiu 构建 & 发布手册
> 面向前端发版 + 后端 API 对接
---
## 一、整体架构
```
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ 客户端 (Electron)│ │ ECS (API 服务) │ │ OSS (阿里云) │
│ │ GET │ │ │ │
│ 版本检查 ─────────┼────────▶│ /api/v1/update/ │ │ │
│ │ │ check │ │ │
│ │◀────────│ 返回 JSON │ │ │
│ │ │ (含 blockmap 信息) │ │ │
│ │ │ │ │ │
│ 增量下载(未来)────┼─────────┼──────────────────┼────────▶│ 静态文件托管 │
│ 仅下载变化块 │◀────────┼──────────────────┼─────────│ .exe + .blockmap │
│ │ │ │ │ │
│ 本地重建安装包 │ │ │ │ │
│ 校验 SHA512 │ │ │ │ │
│ NSIS /S 静默安装 │ │ │ │ │
│ → app.quit() │ │ │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
```
> **当前状态**:客户端已集成 `electron-updater` + 自定义 `HeiXiuProvider`,支持增量下载。`electron-builder` 打包已生成
`.exe.blockmap` 文件。主进程通过 `netRequest` 调用自有 API 获取版本信息electron-updater 自动处理差分下载和 SHA512 校验。
| 角色 | 技术 | 职责 |
|-----|-----------------------------|--------------------------------------------|
| 客户端 | Electron + electron-updater | 调用 API → 下载 blockmap → 差分下载 → 重建 → 校验 → 安装 |
| ECS | 任意后端语言 | 提供版本检查 API含 blockmap 信息) |
| OSS | 阿里云对象存储 | 托管 .exe / .dmg / .AppImage + .blockmap |
---
## 二、项目脚本速查
### 总入口:`build.mjs`
```bash
node build.mjs --help # 查看完整帮助
npm run build:win # 打包 Windows 个人版(快捷命令)
```
### npm 命令速查
```bash
# 构建(仅打包,不上传/发布)
npm run build:win # Windows 个人版
npm run build:win:enterprise # Windows 企业版
npm run build:mac # macOS 个人版
npm run build:linux # Linux 个人版
# 工具
npm run build:clean # 清理 release/ + dist/ + dist-electron/
node build.mjs --win --personal --help # 查看完整 CLI 指南
# 独立脚本(需传参数)
node scripts/generate-update-info.mjs <平台> <版本类型> [版本号] [--url <url>]
node scripts/upload-oss.mjs <平台> <版本类型> [版本号]
node scripts/publish-release.mjs <平台> <版本类型> [版本号] [--url <url>]
```
### `build.mjs` 操作组合
| 操作 | 说明 |
|-------------|------------------------------------------------------|
| `--build` | 构建tsc + vite + electron-builder + update-info.json |
| `--clean` | 清理旧产物 |
| `--sign` | 代码签名(配合 `--cert` 或环境变量) |
| `--upload` | 上传 OSS |
| `--publish` | POST 版本信息到后端 API |
| `--all` | 全流程 = clean + build + sign + upload + publish |
---
## 三、发版工作流
### 路径 A快速打包日常开发 / 内部测试)
```bash
# 1. 修改版本号
# package.json → "version": "0.1.0"
# 2. 写更新日志
# CHANGELOG.md → 顶部新增 ## 0.1.02026-xx-xx...
# 3. 打包
npm run build:win && npm run build:win:enterprise
# 4. 产物在 release/0.1.0/ 下:
# - xxx-Setup.exe安装包
# - xxx-Setup.exe.blockmap块映射增量更新用
# - xxx-update-info.json所有 API 字段downloadUrl 为预判 URL
# 5. 手动上传 exe + .blockmap 到 OSS releases/0.1.0/
# 6. 将 update-info.json 内容录入数据库 releases 表
```
### 路径 B先上传再确定 URL
```bash
# 打包
npm run build:win
# 上传到 OSS自动打印实际 URL
node scripts/upload-oss.mjs win32 personal 0.1.0
# 用实际 URL 重新生成 update-info.json
node scripts/generate-update-info.mjs win32 personal 0.1.0 \
--url "https://heixiu.oss-cn-hangzhou.aliyuncs.com/releases/0.1.0/xxx.exe"
# 将 update-info.json 录入数据库
```
### 路径 C全自动上传 + 发布一条龙)
```bash
# 一步到位(需先配置环境变量)
OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com \
OSS_BUCKET=heixiu \
OSS_ACCESS_KEY_ID=xxx \
OSS_ACCESS_KEY_SECRET=xxx \
UPDATE_API_KEY=xxx \
node build.mjs --win --personal --upload --publish
```
---
## 四、代码签名
### 证书获取
| 平台 | 格式 | 渠道 | 年费 |
|---------|-------------------|---------------------------------|----------|
| Windows | `.pfx` / `.p12` | DigiCert / Sectigo / GlobalSign | $200-700 |
| macOS | `.p12` / Keychain | Apple Developer Program | $99 |
> EV 证书立即消除 SmartScreen 警告OV 证书需积累下载量。
### 签名方式
```bash
# 方式 1build.mjs 参数
node build.mjs --win --personal --sign --cert ./cert.pfx --cert-password xxx
# 方式 2环境变量CI/CD 友好)
CSC_LINK=/path/to/cert.pfx CSC_KEY_PASSWORD=xxx npm run build:win
```
> SHA512 校验值会在签名后自动计算(签名改变文件字节,必须先签后校)。
---
## 五、API 接口
客户端调用的两个端点,完整规格见 [test-server/README.md](test-server/README.md)(可直接发给后端程序员)。
| 端点 | 用途 |
|----------------------------|-------------------------------------|
| `GET /api/v1/update/check` | 客户端版本检查,返回最新版本信息(含 blockmap 用于增量更新) |
| `POST /api/v1/releases` | 前端构建脚本发布新版本,需 Bearer Token 鉴权 |
---
## 七、客户端行为
| 场景 | 行为 |
|-------|------------------------------------------------|
| 启动 | 5 秒后静默检查更新(仅检查,不自动下载) |
| 手动检查 | 点击按钮 → 调用 API → 展示结果 |
| 发现新版本 | 展示版本号 + 更新日志 + "查看详情"弹窗 + "下载更新"按钮 |
| 下载 | 用户点击"下载更新" → electron-updater 差分下载 → SHA512 校验 |
| 安装 | 下载完成后用户点击"安装更新" → quitAndInstall → NSIS /S |
| 强制更新 | `forceUpdate=true` 时不可跳过 |
| 开发模式 | 不跳过(已取消注释),通过 `.env.development` 指向测试服务器 |
### 环境变量加载顺序(主进程)
```
① OS 环境变量set UPDATE_API_URL=... ← 最高优先级,不覆盖
② .env.local不进 git个人覆盖用
③ .env.{mode}(开发→.env.development打包→.env.production
④ updater.ts 硬编码默认值https://www.heixiu.com
```
### 测试场景
```powershell
# 场景 1npm run dev 自动走 .env.development → http://127.0.0.1:8000
# 场景 2打包后连本地测试方式 A — .env.local
echo UPDATE_API_URL=http://127.0.0.1:8000 > .env.local
.\release\0.0.3\win-unpacked\船长·HeiXiu.exe
# 场景 3打包后连本地测试方式 B — OS 环境变量)
set UPDATE_API_URL=http://127.0.0.1:8000 && .\release\0.0.3\win-unpacked\船长·HeiXiu.exe
# 启动测试服务器
cd test-server && python server.py --release-dir ../release --port 8000
```
---
## 八、环境变量速查
| 变量 | 默认值 | 用途 |
|-------------------------|--------------------------------------------------------|----------------------|
| `UPDATE_API_URL` | `https://www.heixiu.com` | 版本检查 API 基地址 |
| `UPDATE_API_KEY` | — | 发布 API 鉴权 Key |
| `UPDATE_DOWNLOAD_BASE` | `https://heixiu.oss-cn-hangzhou.aliyuncs.com/releases` | 预判 URL 基地址 |
| `OSS_ENDPOINT` | — | 阿里云 OSS endpoint |
| `OSS_BUCKET` | — | 阿里云 OSS bucket |
| `OSS_ACCESS_KEY_ID` | — | 阿里云 AccessKey ID |
| `OSS_ACCESS_KEY_SECRET` | — | 阿里云 AccessKey Secret |
| `OSS_BASE_PATH` | `releases` | OSS 内基路径 |
| `CSC_LINK` | — | 签名证书路径 |
| `CSC_KEY_PASSWORD` | — | 签名证书密码 |
| `UPDATE_FORCE` | `false` | 强制更新标记(打包时) |
| `UPDATE_CHANGELOG` | 读取 CHANGELOG.md | 覆盖更新日志CI/CD |
### .env 文件说明
| 文件 | 何时加载 | 进 git | 用途 |
|--------------------|---------------------|:-----:|----------------------|
| `.env.development` | `npm run dev` | ✅ | 开发环境API 指向本地/测试服务器) |
| `.env.production` | `npm run build:xxx` | ❌ | 生产构建API 指向正式服务器) |
| `.env.local` | 始终(后加载,覆盖前者) | ❌ | 个人特殊配置(如打包后连本地测试) |
> **重要**`.env.production` 和 `.env.local` 不打包进 ASAR。打包后运行 `.exe` 时这些文件不存在,自动使用 `updater.ts`
> 硬编码默认值。如需覆盖,使用 OS 环境变量或 `.env.local` 放在 exe 同目录(需配合 `loadEnvFile()` 的路径查找)。
---
## 九、文件结构
```
ele-heixiu/
├ build.mjs ← 构建总管npm run build 入口)
├ CHANGELOG.md ← 更新日志(打包时自动提取)
├ UpdateA.md ← 本文档
├ package.json ← 仅保留简短的 npm 快捷命令
├ scripts/
│ ├ clean.mjs ← 清理产物
│ ├ generate-update-info.mjs ← 生成 API 信息 JSON含 blockmap 信息)
│ ├ upload-oss.mjs ← 上传 OSS安装包 + blockmap
│ └ publish-release.mjs ← 发布到 APIaxios
├ release/ ← 构建产物目录(按版本分)
│ └ 0.1.0/
│ ├ xxx-Setup.exe
│ ├ xxx-Setup.exe.blockmap ← 差分更新块映射文件
│ └ xxx-update-info.json
├ dist/ ← Vite 前端产物(构建输入)
└ dist-electron/ ← Electron 主进程产物(构建输入)
```
---
_如有接口或流程变更,请同步更新此文档。_