Files
ele-HeiXiu/UpdateA.md
YoungestSongMo 337d6c1205 feat: 构建系统重构 + VCHSM 架构迁移 + 右键菜单修复 + 尺寸参数统一
## 构建、打包与分发系统重构 (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>
2026-06-29 18:41:07 +08:00

326 lines
15 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/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.jsonchannel、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
# 方式 1build.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
# 场景 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/ ← 构建系统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.jsonSHA512 + blockmap + channel
│ ├ upload-oss.mjs ← 上传 OSS安装包 + blockmap
│ ├ publish-release.mjs ← 发布到 APIaxios
│ └ 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 主进程产物
```
---
_如有接口或流程变更,请同步更新此文档。_