## 构建、打包与分发系统重构 (build/) - 构建系统收敛至 build/ 目录:build.mjs + electron-builder.js + 6 个脚本 - electron-builder 配置从 package.json 提取为 build/electron-builder.js - 新增 --edition (personal/enterprise) 和 --channel (stable/beta/alpha) 参数 - OSS 路径按渠道隔离 - 新增 pre-build-check.mjs:Git/CHANGELOG/版本/环境变量校验 - 新增 bump-version.mjs:版本号管理 + CHANGELOG 自动生成 - updater.ts 发送 channel/edition/deviceFingerprint - 新增 src/shared/utils/rollout.ts 灰度测试工具 - 新增 10 条 NPM 脚本 ## VCHSM 五层架构迁移 - 7 个业务模块 + ~500 处导入路径同步 ## 修复 - MediaCardContextMenu 改用共享 ContextMenu 组件 - ComboBox 尺寸参数显示统一 (size-format.ts) ## 文档 - UpdateA.md / build/README.md / README.md / .env.example 更新 Co-Authored-By: Claude <noreply@anthropic.com>
326 lines
15 KiB
Markdown
326 lines
15 KiB
Markdown
# 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/build.mjs`
|
||
|
||
```bash
|
||
node build/build.mjs --help # 查看完整帮助
|
||
npm run build:win # 打包 Windows 个人版 Stable(快捷命令)
|
||
```
|
||
|
||
### npm 命令速查
|
||
|
||
```bash
|
||
# 构建(仅打包,不上传/发布)
|
||
npm run build:win # Windows 个人版 Stable
|
||
npm run build:win:enterprise # Windows 企业版 Stable
|
||
npm run build:win:beta # Windows 个人版 Beta 渠道
|
||
npm run build:win:alpha # Windows 个人版 Alpha 渠道
|
||
npm run build:mac # macOS 个人版
|
||
npm run build:mac:enterprise # macOS 企业版
|
||
npm run build:linux # Linux 个人版
|
||
npm run build:linux:enterprise # Linux 企业版
|
||
|
||
# 版本管理
|
||
npm run version:patch # 0.0.28 → 0.0.29
|
||
npm run version:minor # 0.0.28 → 0.1.0
|
||
npm run version:pre-beta # 0.0.29 → 0.0.30-beta.1
|
||
npm run version:pre-alpha # 0.0.29 → 0.0.30-alpha.1
|
||
|
||
# 工具
|
||
npm run build:clean # 清理 release/ + dist/ + dist-electron/
|
||
|
||
# 独立脚本(需传参数)
|
||
node build/scripts/generate-update-info.mjs <平台> <版本> [渠道] [版本类型] [ossPrefix]
|
||
node build/scripts/upload-oss.mjs <平台> <版本> [渠道] [ossPrefix]
|
||
node build/scripts/publish-release.mjs <平台> <版本> [渠道] [版本类型] [ossPrefix]
|
||
```
|
||
|
||
### `build/build.mjs` 操作组合
|
||
|
||
| 操作 | 说明 |
|
||
|-------------|------------------------------------------------------------|
|
||
| `--build` | 构建(校验 → tsc → vite → electron-builder → update-info.json) |
|
||
| `--clean` | 清理旧产物 |
|
||
| `--sign` | 代码签名(配合 `--cert` 或环境变量) |
|
||
| `--upload` | 上传 OSS |
|
||
| `--publish` | POST 版本信息到后端 API |
|
||
| `--all` | 全流程 = clean + build + sign + upload + publish |
|
||
| `--edition` | 版本类型:personal(默认)或 enterprise |
|
||
| `--channel` | 发布渠道:stable(默认)、beta 或 alpha |
|
||
|
||
---
|
||
|
||
## 三、渠道与灰度测试
|
||
|
||
### 渠道体系
|
||
|
||
| 渠道 | OSS 路径 | 生命周期 | 适用场景 |
|
||
|------|----------|----------|----------|
|
||
| `stable` | `releases/{version}/` | 永久 | 正式发布 |
|
||
| `beta` | `releases/beta/{version}/` | 可设 OSS 30 天自动过期 | 灰度测试 |
|
||
| `alpha` | `releases/{version}/alpha/` | 手动管理 | 内部开发测试 |
|
||
|
||
### 灰度发布工作流
|
||
|
||
```bash
|
||
# 1. 创建 beta 预发布版本号
|
||
npm run version:pre-beta # 0.0.29 → 0.0.30-beta.1
|
||
|
||
# 2. 写 CHANGELOG.md 更新日志
|
||
|
||
# 3. 构建并发布到 beta 渠道
|
||
node build/build.mjs --win --channel beta --upload --publish
|
||
|
||
# 4. 后端 API 设置 rolloutPercent: 10 → 30 → 100 逐步放量
|
||
# 客户端通过 deviceFingerprint 哈希分组(同一用户始终在同一组)
|
||
```
|
||
|
||
### 灰度原理
|
||
|
||
1. 客户端 `HeiXiuProvider` 请求 `/api/v1/update/check` 时携带 `channel`、`edition`、`deviceFingerprint`
|
||
2. 服务端根据 `rolloutPercent` + `deviceFingerprint` 哈希判断是否返回新版本
|
||
3. `src/shared/utils/rollout.ts` 提供 `isInRolloutGroup()` / `getRolloutGroup()` 工具函数
|
||
|
||
---
|
||
|
||
## 四、发版工作流
|
||
|
||
### 路径 A:快速打包(日常开发 / 内部测试)
|
||
|
||
```bash
|
||
# 1. 升级版本号
|
||
npm run version:patch # package.json + CHANGELOG.md 自动更新
|
||
|
||
# 2. 写更新日志
|
||
# CHANGELOG.md → 编辑自动生成的 ## 0.1.0(日期)条目
|
||
|
||
# 3. 打包
|
||
npm run build:win
|
||
|
||
# 4. 产物在 release/0.1.0/ 下:
|
||
# - xxx-Setup.exe(安装包)
|
||
# - xxx-Setup.exe.blockmap(块映射,增量更新用)
|
||
# - xxx-update-info.json(channel、SHA512、blockmap 等全字段)
|
||
|
||
# 5. 手动上传 exe + .blockmap 到 OSS releases/0.1.0/
|
||
# 6. 将 update-info.json 内容录入数据库 releases 表
|
||
```
|
||
|
||
### 路径 B:先上传再确定 URL
|
||
|
||
```bash
|
||
# 打包
|
||
npm run build:win
|
||
|
||
# 上传到 OSS(自动打印实际 URL)
|
||
node build/scripts/upload-oss.mjs win32 0.1.0
|
||
|
||
# 用实际 URL 重新生成 update-info.json
|
||
node build/scripts/generate-update-info.mjs win32 0.1.0 stable personal \
|
||
--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/build.mjs --win --upload --publish
|
||
```
|
||
|
||
---
|
||
|
||
## 五、代码签名
|
||
|
||
### 证书获取
|
||
|
||
| 平台 | 格式 | 渠道 | 年费 |
|
||
|---------|-------------------|---------------------------------|----------|
|
||
| Windows | `.pfx` / `.p12` | DigiCert / Sectigo / GlobalSign | $200-700 |
|
||
| macOS | `.p12` / Keychain | Apple Developer Program | $99 |
|
||
|
||
> EV 证书立即消除 SmartScreen 警告;OV 证书需积累下载量。
|
||
|
||
### 签名方式
|
||
|
||
```bash
|
||
# 方式 1:build.mjs 参数
|
||
node build/build.mjs --win --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
|
||
|
||
客户端版本检查,请求参数:
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `platform` | string | `win32` / `darwin` / `linux` |
|
||
| `version` | string | 当前客户端版本号 |
|
||
| `channel` | string | 客户端渠道:`stable` / `beta` / `alpha` |
|
||
| `edition` | string | 版本类型:`personal` / `enterprise` |
|
||
| `deviceFingerprint` | string | 设备指纹(SHA-256 前 16 位,灰度分组用) |
|
||
|
||
响应字段含 `channel`、`rolloutPercent` 等灰度相关字段。
|
||
|
||
### POST /api/v1/releases
|
||
|
||
前端构建脚本发布新版本,需 `Authorization: Bearer <UPDATE_API_KEY>` 鉴权。请求体包含 `channel`、`edition` 等字段。
|
||
|
||
---
|
||
|
||
## 七、客户端行为
|
||
|
||
| 场景 | 行为 |
|
||
|-------|------------------------------------------------|
|
||
| 启动 | 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
|
||
# 场景 1:npm 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/ ← 构建系统(2026-06-29 重构)
|
||
│ ├ build.mjs ← 构建总管(npm run build 入口)
|
||
│ ├ electron-builder.js ← electron-builder 配置(从 package.json 提取)
|
||
│ ├ README.md ← 构建系统文档
|
||
│ └ scripts/
|
||
│ ├ clean.mjs ← 清理产物
|
||
│ ├ pre-build-check.mjs ← 构建前校验(Git/CHANGELOG/版本一致性)
|
||
│ ├ generate-update-info.mjs← 生成 update-info.json(SHA512 + blockmap + channel)
|
||
│ ├ upload-oss.mjs ← 上传 OSS(安装包 + blockmap)
|
||
│ ├ publish-release.mjs ← 发布到 API(axios)
|
||
│ └ bump-version.mjs ← 版本号管理(major/minor/patch/pre)
|
||
├ CHANGELOG.md ← 更新日志(打包时自动提取)
|
||
├ UpdateA.md ← 本文档
|
||
├ package.json ← 不含 "build" 字段(已提取到 build/electron-builder.js)
|
||
├ release/ ← 构建产物目录
|
||
│ ├ .build-meta.json ← 最近一次构建元数据
|
||
│ └ 0.1.0/ ← Stable 版本
|
||
│ ├ xxx-Setup.exe
|
||
│ ├ xxx-Setup.exe.blockmap ← 差分更新块映射文件
|
||
│ └ xxx-update-info.json
|
||
├ dist/ ← Vite 前端产物
|
||
└ dist-electron/ ← Electron 主进程产物
|
||
```
|
||
|
||
---
|
||
|
||
_如有接口或流程变更,请同步更新此文档。_
|