2026-08-28 02:08:12 +08:00
|
|
|
|
# Koring Launcher 自动更新方案(v1 规划稿)
|
|
|
|
|
|
|
|
|
|
|
|
> 状态:**M1 已完成(2026-08-28)**;M2 待开始
|
|
|
|
|
|
> 目标平台:**Windows 优先**(NSIS exe 安装包),macOS/Linux 后续复用同一套架构
|
|
|
|
|
|
> 决策记录:
|
|
|
|
|
|
> - 安装器模式:**保持 assisted 安装器(`oneClick: false` + 可改安装目录)→ 每次更新整包下载**
|
|
|
|
|
|
> - 更新托管:**GitHub Releases**
|
|
|
|
|
|
> - 当前交付:**M1 基础设施已完成**(electron-updater 依赖 + publish 配置 + 1.2.0 打包验证)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 背景与目标
|
|
|
|
|
|
|
|
|
|
|
|
- 项目:Electron 33 + React 19 + TS + electron-builder 25(Windows NSIS 安装包,`dist:dev/beta/run` 三模式打包)
|
|
|
|
|
|
- 现状:`package.json` 版本 1.1.2,无任何更新机制;用户需手动下载新版安装包
|
|
|
|
|
|
- 目标:客户端内自动检查新版本 → 下载 → 静默重装 → 自动重启,先跑通 Windows
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 技术选型
|
|
|
|
|
|
|
|
|
|
|
|
**选 electron-updater**(electron-builder 官方配套,与现有打包链无缝衔接)。
|
|
|
|
|
|
|
|
|
|
|
|
| 方案 | 说明 | 结论 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| electron-updater | 自动生成 `latest.yml` 清单、SHA512 校验、进度事件、失败重试、断点续传 | ✅ 选用 |
|
|
|
|
|
|
| electron-simple-updater | 只支持替换 asar,不支持 NSIS 重装 | ❌ |
|
|
|
|
|
|
| update-electron-app | 只面向 GitHub,定制性差 | ❌ |
|
|
|
|
|
|
| 自研差分/自建服务 | 灰度、强制更新、统计需要时再评估 | 后期可选 |
|
|
|
|
|
|
|
|
|
|
|
|
**版本兼容**:electron-builder 25.1.8 ↔ electron-updater ^6.x(官方同仓库发布,6.x 与 24/25/26 打包器配套)。
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 关键约束(已确认)
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 assisted 安装器 → 整包下载
|
|
|
|
|
|
|
|
|
|
|
|
当前 `electron-builder.yml` 为 assisted 安装器:
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
nsis:
|
|
|
|
|
|
oneClick: false
|
|
|
|
|
|
allowToChangeInstallationDirectory: true
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
electron-updater 的 NSIS **差分更新(blockmap 增量)只支持一键安装(per-user oneClick)**;
|
|
|
|
|
|
assisted 安装器安装目录不固定,**退化为每次下载完整 `koring-launcher-<version>-setup.exe`**。
|
|
|
|
|
|
|
|
|
|
|
|
**已决策:接受整包下载**,不改安装体验。含义:
|
|
|
|
|
|
- 每次更新下载全量安装包(预计几十 MB 级别),CDN/带宽按此评估;
|
|
|
|
|
|
- 后续若用户量大、包体过大,可再评估改 oneClick 启用差分,或自研增量(代价高,不优先)。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 代码签名(重要)
|
|
|
|
|
|
|
|
|
|
|
|
Windows 下 electron-updater 会对下载的安装包做 Authenticode 校验:当前 exe 有签名时,要求新安装包发布者一致;
|
|
|
|
|
|
当前 exe 未签名时校验会被跳过(记警告)。
|
|
|
|
|
|
|
|
|
|
|
|
- **未签名**:开发/内测可跑通全流程,但国内杀软对未签名 exe 误报率高;
|
|
|
|
|
|
- **正式对外发布前必须做代码签名**(OV 证书起步,EV 更佳),并让发布流水线对 setup.exe 签名;
|
|
|
|
|
|
- 签名后 electron-builder 默认会校验一致性,无需额外配置,但要保证**发布流水线签名证书与产物一致**。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 整体架构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
┌───────────────────────────── 客户端 ─────────────────────────────┐
|
|
|
|
|
|
│ React UI (src/) ⇄ preload.ts (contextBridge) ⇄ 主进程 │
|
|
|
|
|
|
│ │ electronAPI.onUpdateStatus() │ │
|
|
|
|
|
|
│ └────────── IPC ────────────────┘ │
|
|
|
|
|
|
│ 主进程 electron/updater.ts(封装 electron-updater) │
|
|
|
|
|
|
│ electron/handlers/update.ts(IPC handler) │
|
|
|
|
|
|
└──────────────────────────────┬──────────────────────────────────┘
|
|
|
|
|
|
│ HTTPS
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌───────────────────────────┐
|
|
|
|
|
|
│ GitHub Releases (仓库) │
|
|
|
|
|
|
│ · koring-launcher-1.2.1 │
|
|
|
|
|
|
│ -setup.exe │
|
|
|
|
|
|
│ · latest.yml │
|
|
|
|
|
|
└───────────────────────────┘
|
|
|
|
|
|
(国内网络差 → 见 §5.3 加速对策)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 服务端:GitHub Releases
|
|
|
|
|
|
|
|
|
|
|
|
### 5.1 发布产物
|
|
|
|
|
|
|
|
|
|
|
|
electron-builder 配置 `publish: { provider: github }` 后,`electron-builder --publish always`
|
|
|
|
|
|
(或 `--publish` 搭配 CI token)会自动:
|
|
|
|
|
|
|
|
|
|
|
|
1. 打包 Windows 产物;
|
|
|
|
|
|
2. 创建/更新 GitHub Release(tag 取自版本号,如 `v1.2.1`);
|
|
|
|
|
|
3. 上传 `koring-launcher-1.2.1-setup.exe` + `latest.yml`(+ `latest.yml.blockmap`,assisted 模式下不用但会生成)。
|
|
|
|
|
|
|
|
|
|
|
|
`latest.yml` 是更新清单(版本、文件路径、大小、sha512),electron-updater 靠它发现新版本并校验完整性:
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
version: 1.2.1
|
|
|
|
|
|
files:
|
|
|
|
|
|
- url: koring-launcher-1.2.1-setup.exe
|
|
|
|
|
|
sha512: <base64-sha512>
|
|
|
|
|
|
size: 81234567
|
|
|
|
|
|
path: koring-launcher-1.2.1-setup.exe
|
|
|
|
|
|
sha512: <base64-sha512>
|
|
|
|
|
|
releaseDate: '2025-01-01T00:00:00.000Z'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5.2 配置示例(electron-builder.yml 增加段)
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
publish:
|
|
|
|
|
|
provider: github
|
|
|
|
|
|
owner: <GitHub 用户名/组织>
|
|
|
|
|
|
repo: <仓库名>
|
|
|
|
|
|
# releaseType: release # 默认 release;beta 通道可设 draft/prerelease
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
打包时 electron-builder 会把 `app-update.yml`(含 provider 信息)写进 `resources/`,
|
|
|
|
|
|
electron-updater 在运行时读取它——**没有 publish 配置就不会生成 app-update.yml,更新会直接报错**(M1 验收点)。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3 国内网络注意(务必先评估)
|
|
|
|
|
|
|
|
|
|
|
|
electron-updater 的 GitHub provider 走 `api.github.com`(发现版本)与 `github.com/.../releases/download/...`(下载),
|
|
|
|
|
|
国内部分网络环境访问慢或不稳定。对策(按需选):
|
|
|
|
|
|
|
|
|
|
|
|
- **现状接受**:很多应用直接走 GitHub,配合失败重试 + 手动"下载最新版"兜底按钮;
|
|
|
|
|
|
- **CDN 加速(推荐后续做)**:改为 `generic` provider,把 `latest.yml` + exe 同步到
|
|
|
|
|
|
OSS/COS + CDN(或 ghproxy 类代理),`app-update.yml` 指向 CDN URL;
|
|
|
|
|
|
- **自建/商业 CDN 代理 GitHub Releases**:等用户量上来再评估。
|
|
|
|
|
|
|
|
|
|
|
|
> 方案设计上保持 provider 可切换:`electron/updater.ts` 只面向 electron-updater 统一 API,
|
|
|
|
|
|
> 未来从 `github` 切 `generic` 只需改 electron-builder.yml + 重新打包,业务代码不动。
|
|
|
|
|
|
|
|
|
|
|
|
## 6. Windows 更新流程(整包下载版)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
应用启动
|
|
|
|
|
|
├─ 加载完成且空闲后(延迟 10~15s)→ 静默 checkForUpdates()
|
|
|
|
|
|
│ (避开启动加载与 Minecraft 下载抢带宽;首启/开发模式跳过)
|
|
|
|
|
|
├─ 无更新 → 结束,静默
|
|
|
|
|
|
└─ 有更新 → 发 update:status{state:'available', version}
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
前端提示"发现新版本 vX.Y.Z"(非强制,可忽略/稍后)
|
|
|
|
|
|
│ 用户点"下载更新"
|
|
|
|
|
|
▼
|
|
|
|
|
|
autoUpdater.downloadUpdate()
|
|
|
|
|
|
├─ download-progress → update:status{state:'downloading', percent, speed, ...}
|
|
|
|
|
|
├─ 下载完成 → SHA512 校验(latest.yml)→ update:status{state:'downloaded'}
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
前端提示"重启并安装"(可暂缓;退出时 autoInstallOnAppQuit 兜底)
|
|
|
|
|
|
│ 用户确认
|
|
|
|
|
|
▼
|
|
|
|
|
|
autoUpdater.quitAndInstall()
|
|
|
|
|
|
├─ 应用退出 → NSIS 静默安装(不弹 UI,沿用原安装目录)
|
|
|
|
|
|
└─ 安装完成自动重启 → 运行新版本
|
|
|
|
|
|
|
|
|
|
|
|
失败路径:
|
|
|
|
|
|
· 网络失败 → 提示重试(electron-updater 自带断点续传/重试)
|
|
|
|
|
|
· 校验失败 → 清除缓存重下;仍失败则提示手动下载最新版
|
|
|
|
|
|
· 静默安装失败 → 提示手动下载;保留旧版本可用
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 更新状态机(前端 store 用)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
idle → checking → available → downloading → downloaded → installing → relaunch
|
|
|
|
|
|
└─not-available→ idle └─ error → idle(可重试)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 代码结构规划
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
electron/
|
|
|
|
|
|
updater.ts # 新增:封装 electron-updater
|
|
|
|
|
|
# · 初始化(读 app-update.yml、设日志)
|
|
|
|
|
|
# · 守卫:!app.isPackaged 时跳过(开发模式)
|
|
|
|
|
|
# · check() / download() / quitAndInstall() / 状态查询
|
|
|
|
|
|
# · 订阅 checking/available/not-available/download-progress/downloaded/error
|
|
|
|
|
|
# · 转发为 update:status 事件(带完整 payload)
|
|
|
|
|
|
handlers/update.ts # 新增:IPC handler
|
|
|
|
|
|
# · update:check → 触发检查
|
|
|
|
|
|
# · update:download → 触发下载
|
|
|
|
|
|
# · update:quitAndInstall → 重启安装
|
|
|
|
|
|
# · update:getState → 查询当前状态/版本信息
|
|
|
|
|
|
main.ts # 改:import { registerUpdateHandlers };注册;启动后延迟静默检查
|
|
|
|
|
|
preload.ts # 改:暴露
|
|
|
|
|
|
# · checkForUpdates() / downloadUpdate() / quitAndInstall()
|
|
|
|
|
|
# · onUpdateStatus(cb) → 订阅 update:status(沿用现有 on() 模式)
|
|
|
|
|
|
|
|
|
|
|
|
src/
|
|
|
|
|
|
api/update.ts # 新增:IPC 封装 + TS 类型(UpdateStatus)
|
|
|
|
|
|
stores/update.ts # 新增:zustand store,维护状态机
|
|
|
|
|
|
components/settings/... # 更新 UI:设置页"关于/更新"区块
|
|
|
|
|
|
# · 当前版本号 + 检查更新按钮
|
|
|
|
|
|
# · 下载进度条(百分比/速度/剩余大小)
|
|
|
|
|
|
# · "重启并安装"确认
|
|
|
|
|
|
components/... # 可选:新版可用 toast / 弹窗(非强制打扰)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**依赖注意**:`electron-updater` 必须放 **`dependencies`**(不能是 devDependencies),
|
|
|
|
|
|
否则 asar 打包后运行时找不到模块——最常见事故,M1 验收必须覆盖。
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 版本与多通道
|
|
|
|
|
|
|
|
|
|
|
|
- 沿用现有 `scripts/version.js` 升版(`pnpm version:set 1.2.0`),版本必须严格 semver 递增;
|
|
|
|
|
|
- electron-updater 只认 package.json 的 `version`,升版后需重新打包发布;
|
|
|
|
|
|
- **dev / beta / run 三模式的通道隔离放加固阶段(M5)**:
|
|
|
|
|
|
- GitHub provider 多通道依赖 tag 约定(如 `v1.2.1-beta.1`),行为略绕,先只用默认 latest 通道跑通;
|
|
|
|
|
|
- 届时按产品需要决定:beta 走 prerelease/draft release,run 走正式 release,或切 generic + 不同 URL。
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 里程碑与验收
|
|
|
|
|
|
|
|
|
|
|
|
| 阶段 | 内容 | 验收标准 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| **M1 基础设施** | ① `dependencies` 加 electron-updater;② electron-builder.yml 加 publish(github);③ 升版打包 `pnpm dist:run` | 产物目录出现 `latest.yml`;解包 asar 的 `resources/app-update.yml` 存在;electron-updater 在 asar 内可 require |
|
|
|
|
|
|
| **M2 主进程** | updater.ts + handlers/update.ts + preload 暴露 | 手动触发 `update:check` 能返回状态;事件能推送到渲染进程(dev 下用 `forceDevUpdateConfig` 或打包版验证) |
|
|
|
|
|
|
| **M3 前端 UI** | update store + 设置页更新区块 + 启动静默检查 | 完整交互:检查/提示/进度/重启安装/失败重试 |
|
|
|
|
|
|
| **M4 联调冒烟** | 发布 v1.2.0 → 再发布 v1.2.1,真机从 1.2.0 升到 1.2.1 | Windows 真机全流程通过,含取消下载、断网重试、校验失败场景 |
|
|
|
|
|
|
| **M5 加固** | ~~代码签名~~(SignPath 远程签名已接入 CI,见 §12);国内加速(CDN/generic)评估;通道隔离;强制更新开关;临时文件清理 | 可对外发布 |
|
|
|
|
|
|
|
|
|
|
|
|
## 10. 风险与对策
|
|
|
|
|
|
|
|
|
|
|
|
| 风险 | 影响 | 对策 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| electron-updater 误放 devDependencies | 打包后更新直接报错 | M1 验收强制检查 asar 内依赖 |
|
|
|
|
|
|
| 未配置 publish → 无 app-update.yml | 运行时报 "app-update.yml not found" | M1 验收点;文档示例已给 |
|
|
|
|
|
|
| 未签名 exe 被杀软拦截 | 下载/安装被拦,更新失败 | 正式发布前签名(M5);内测接受现状 |
|
|
|
|
|
|
| assisted 静默安装弹 UI / 请求管理员 | 更新中断 | M4 用现有 `build/installer-custom.nsh` 专门联调;必要时加 `runAfterFinish`/静默参数处理 |
|
|
|
|
|
|
| api.github.com 国内访问差 | 检查/下载慢或失败 | 失败重试 + 手动下载兜底;后续 CDN 加速(§5.3) |
|
|
|
|
|
|
| 检查频率过高 | 浪费带宽、触发限流 | 启动延迟 10~15s + 手动按钮;间隔建议 ≥1h |
|
|
|
|
|
|
| 磁盘满 / %LOCALAPPDATA% 权限 | 下载/解压失败 | 失败回退提示,清理 `updaterCacheDirName` 缓存 |
|
|
|
|
|
|
| 版本号不递增 | 永远查不到更新 | CI/脚本校验 `version:set` 只允许升版 |
|
|
|
|
|
|
| 更新失败后应用状态异常 | 用户卡在旧版本 | 保持旧版可用;UI 提供手动下载入口;错误上报(可复用现有 crash 体系) |
|
|
|
|
|
|
|
|
|
|
|
|
## 11. 后续待决策(不阻塞 M1~M4)
|
|
|
|
|
|
|
|
|
|
|
|
- 是否需要强制更新 / 最低版本策略
|
|
|
|
|
|
- 国内加速方案何时落地(generic + OSS/COS/CDN)
|
|
|
|
|
|
- macOS / Linux 更新的排期(架构已预留,届时分别补 zip/dmg 与 AppImage 产物与签名)
|
|
|
|
|
|
|
|
|
|
|
|
## 12. SignPath 代码签名接入(2026-08-28 落地)
|
|
|
|
|
|
|
|
|
|
|
|
**方案**:electron-builder 自定义签名(`win.sign: scripts/signpath-sign.js`),
|
|
|
|
|
|
构建时对内部 exe(`Koring Launcher.exe`、elevate.exe、卸载器)与最终 `setup.exe`
|
|
|
|
|
|
逐个提交 SignPath 远程签名,签名发生在 blockmap / latest.yml 生成之前,
|
|
|
|
|
|
**清单 sha512 与 blockmap 自动对应签名后产物**,electron-updater 校验无缝。
|
|
|
|
|
|
|
|
|
|
|
|
**SignPath 后台准备(已确认值)**:
|
|
|
|
|
|
- Organization ID:`31ecd033-d59e-492b-a70b-b00a54bbc7c2`(已写入 workflow env)
|
|
|
|
|
|
- API Token:用户详情页生成(CI 用途),放入 GitHub Secrets `SIGNPATH_API_TOKEN`
|
|
|
|
|
|
- slug:项目 `Koring_Launcher`;签名策略 `Koring_Launcher_Dev_builder`(均写入 workflow env);
|
|
|
|
|
|
产物配置 DEFAULT 在项目仅一个配置时可省略 `SIGNPATH_ARTIFACT_CONFIG_SLUG`
|
|
|
|
|
|
|
|
|
|
|
|
**⚠️ 待办约束**:
|
|
|
|
|
|
- **测试证书**:当前策略 Purpose 为 **Test signing**(测试证书),用户机器默认不信任
|
|
|
|
|
|
(SmartScreen / 杀软警告;`signtool verify` 会报"不受信任"——预期现象),
|
|
|
|
|
|
正式对外发布需生产证书(OV/EV)+ 对应生产签名策略(届时只换 `SIGNPATH_SIGNING_POLICY_SLUG`)。
|
|
|
|
|
|
- 审批流程:已在 SignPath 后台关闭人工审批(自动批准),CI 可全自动;策略 Purpose 已改为 Release signing。
|
|
|
|
|
|
|
|
|
|
|
|
**新增/改动文件**:
|
|
|
|
|
|
- `scripts/signpath-sign.js` — 签名模块(无 token 自动跳过,本地构建不受影响)
|
2026-08-28 02:33:47 +08:00
|
|
|
|
- `.github/workflows/release.yml` — 手动触发:选择 beta/run → 构建 → 签名 → 发布 GitHub Release(见 §13)
|
|
|
|
|
|
- `scripts/release-notes.ps1` — 中文 Release 发布说明生成器
|
2026-08-28 02:08:12 +08:00
|
|
|
|
- `electron-builder.yml` — `win.sign` 挂载
|
|
|
|
|
|
|
|
|
|
|
|
**CI Secrets**:仅 `SIGNPATH_API_TOKEN`(必填)+ `SIGNPATH_ARTIFACT_CONFIG_SLUG`(可选);
|
|
|
|
|
|
组织 ID 与 slugs 已在 workflow 中写死。
|
|
|
|
|
|
|
|
|
|
|
|
**2026-08-28 实测结果**(与官方 PowerShell 模块对齐后的真实签名):
|
|
|
|
|
|
- 协议:`POST {base}/v1/{orgId}/SigningRequests`(**multipart/form-data**,字段 ProjectSlug /
|
|
|
|
|
|
SigningPolicySlug / ArtifactConfigurationSlug? / Description / 文件部件 **Artifact**)→
|
|
|
|
|
|
响应 **Location 头** = 请求 URL → 轮询 `status`/`isFinalStatus` → 完成后取 **signedArtifactLink** 下载;
|
|
|
|
|
|
认证 `Authorization: Bearer <token>`。
|
|
|
|
|
|
- ✅ 98.3MB setup.exe 提交成功(无大小限制问题);自动批准生效(InProgress → Completed 无人工介入)
|
|
|
|
|
|
- ✅ 小文件端到端签名成功,`signtool verify` 显示签名链 **Issued to: Lingke Network**
|
|
|
|
|
|
- ⚠️ 本机到 SignPath 下载 100MB+ 产物极慢(20min+),CI(GitHub Actions)网络环境不受影响;
|
|
|
|
|
|
模块已加下载重试(3 次)+ 临时文件替换
|
|
|
|
|
|
|
|
|
|
|
|
**验证点(首次 CI 运行)**:确认 SignPath 请求全部 Completed、`latest.yml` 的 sha512
|
|
|
|
|
|
与上传的 signed setup.exe 一致、签名链显示 "Lingke Network"。
|
2026-08-28 02:33:47 +08:00
|
|
|
|
|
|
|
|
|
|
## 13. 发布流水线(手动触发 / BUILD ID / 中文 Release)
|
|
|
|
|
|
|
|
|
|
|
|
**触发方式**:Actions 页面 → Run workflow,仅手动触发(不再使用 tag 触发)。
|
|
|
|
|
|
- `mode`:`beta`(测试,发布为 GitHub prerelease)/ `run`(正式,发布为普通 release)
|
|
|
|
|
|
- `version`:基础版本号(如 `1.2.0`)
|
|
|
|
|
|
|
|
|
|
|
|
**版本号与 BUILD ID**:
|
|
|
|
|
|
- BUILD ID = Action 运行的 **UTC 时刻**,格式 `YYMMDDHHMM`(如 `2608280224`)
|
|
|
|
|
|
- 最终版本 = `{version}-{BUILD ID}`(如 `1.2.0-2608280224`),tag = `v{version}-{BUILD ID}`,
|
|
|
|
|
|
electron-builder 产物 = `koring-launcher-{version}-{BUILD ID}-setup.exe`,`latest.yml` 同步更新
|
|
|
|
|
|
|
|
|
|
|
|
**发布内容**(`gh release create`,中文正文由 `scripts/release-notes.ps1` 生成):
|
|
|
|
|
|
- `# Koring Launcher Releases {version}` + 版本信息(当前版本 / 编译状态 BETA/RUN)
|
|
|
|
|
|
- `## 更新了什么内容`:自上个 `v*` tag 以来的提交记录,每条默认折叠
|
|
|
|
|
|
(`<details><summary>·Commit 1cf906d</summary>…</details>`)
|
|
|
|
|
|
- 上传产物:setup.exe + latest.yml(electron-updater 更新清单)
|
|
|
|
|
|
|
|
|
|
|
|
**⚠️ 版本语义注意(electron-updater)**:
|
|
|
|
|
|
- `{version}-{BUILD ID}` 属 semver prerelease:同格式版本之间可正常升级(BUILD ID 更大者胜)
|
|
|
|
|
|
- 若未来发布**不带** BUILD ID 的稳定版本(如 `1.2.0`),稳定版用户不会自动升级到带 BUILD ID 的构建
|
|
|
|
|
|
- 同一分钟内重复触发会产生相同 BUILD ID → tag 冲突,`gh release create` 会失败,稍候重试即可
|