- 桌面应用
- 跨平台
【免费下载链接】native
Toolkit for building native desktop apps
Native SDK(@native-sdk/cli)的发布是一套人工驱动的单 PR 流程:由维护者在本地完成版本号提升、changelog 编写与 PR 合并,随后 CI(.github/workflows/release.yml)自动完成跨平台交叉编译、GitHub Release 资产上传与九个 npm 包的分批发布。本文基于仓库根目录的 RELEASING.md 编写,并结合 packages/native-sdk 下的版本同步脚本与 release.yml 工作流源码,完整讲解"准备一次发布 → 写好 changelog → CI 自动发布"的每一步,以及其中关键的版本一致性校验与 npm OIDC 可信发布配置。
发布策略:为什么是"人工 + 单 PR"
仓库的发布模型非常明确:Releases are manual, single-PR affairs——发布不依赖自动打 tag 的机器人,而是由维护者在分支上完成全部准备工作后,通过一个 PR 合并到main触发。这样设计的目的(从 RELEASING.md 原文及源码推断)在于:
- 维护者掌控 changelog 的措辞与格式:发布说明的语气、分类和细节粒度由人决定,而非自动生成的 commit 列表;
- 一次变更只走一个 PR:版本号提升、changelog 条目、以及同步脚本对多处文件的改动全部收拢在同一个 PR 中,便于 review 与回滚;
- CI 负责机械性工作:合并后流水线自动完成编译、发布和校验,人工不触碰任何 npm 凭据。
整个流程分为两段:本地准备(第 1 步到第 7 步)与 CI 自动发布(合并后触发)。
发布准备:七步操作清单
按 RELEASING.md 的步骤,一次发布的本地准备如下:
- 创建分支,例如
prepare-v1.2.0; - 提升版本号:修改
packages/native-sdk/package.json中的version字段(当前仓库中为0.10.1,见 package.json); - 同步所有版本引用:运行
npm --prefix packages/native-sdk run version:sync; - 审阅自上次发布以来的 git 历史,在 CHANGELOG.md 顶部、新的
## <version>标题下撰写完整的 changelog 条目,并用<!-- release:start -->与<!-- release:end -->标记包裹; - 填充条目的
### Contributors:从发布区间内的 commit 作者与Co-authored-by尾注中提取,优先使用 GitHub handle;这段被标记包裹的内容同时就是 GitHub Release 的正文; - 移除上一条发布的
<!-- release:start -->/<!-- release:end -->标记——只有最新一条发布允许保留标记; - 打开 PR 并合并到
main。
第 3 步version:sync是保证"一个版本号统治所有文件"的关键,下面单独展开。
版本同步:一个版本号,八处落地
version:sync由 scripts/sync-version.js 实现,其注释开宗明义:"One version number rules them all"。packages/native-sdk/package.json是唯一事实来源,脚本把该版本号逐一写入以下位置:
| 落点 | 文件路径 | 说明 |
|---|---|---|
| CLI 源码 | tools/native-sdk/main.zig(当前为const version = "0.10.1";,见 main.zig#L9) | native version命令输出的版本号 |
| 8 个平台二进制包 | packages/native-sdk/npm/<platform>/package.json | 每个包的version字段,同时把主包的repository.url与homepage一并复制过去 |
| 主包 optionalDependencies 引脚 | packages/native-sdk/package.json | 8 个@native-sdk/cli-*平台包的精确版本引脚(如"@native-sdk/cli-linux-x64-gnu": "0.10.1") |
| 打包的 TS 核心 | packages/core/package.json 与 packages/core/package-lock.json | @native-sdk/core与 CLI 共享同一发布版本;manifest 与 lockfile 的自引用版本字段都会被盖章 |
| 已提交的 TS 示例 | examples/*/package.json | 自动发现并更新所有依赖@native-sdk/core的示例的精确引脚 |
引脚之所以全部使用精确版本而非区间,是为了保证"某个版本的@native-sdk/cli安装到的二进制,一定构建自同一个 commit 的源码"——optionalDependencies的 8 个引脚精确到0.10.1,主包落地时平台包必须已存在且版本一致。同时,脚本还会传播仓库身份字段(repository.url、homepage):注释明确指出,npm 会用repository.url校验发布 provenance,若仓库改名只更新了主包而遗漏平台包,发布会在 provenance 校验处失败。
对应的校验脚本是 scripts/check-version-sync.js,它逐项核对上述所有位置是否与主包版本一致,并在 CI 发布前运行(见下文)。此外它还校验两处特殊引脚:
@typescript/old(即npm:typescript@X.Y.Z的别名引脚):CLI 与packages/core必须使用完全一致的精确别名形式,防止新安装的 CLI 解析到与开发环境不同的 TypeScript 编译器;scriptc(外部核心编译器):同样是精确版本,且两份 manifest 必须一致。
任何一处漂移都会导致version:check报错并以非零退出码终止发布。
编写 changelog:格式、语气与标记约定
CHANGELOG.md 是发布说明的唯一来源,其书写规范如下:
- 分组标题:按
### New Features、### Bug Fixes、### Improvements等描述性标题归类; - 条目格式:每条 bullet 先给加粗的引导语(如
**JSON manifests by default**),随后跟一句简洁描述,末尾在可用时标注 PR 编号(如(#385)); - 禁止前缀:不要用 commit hash 作为条目前缀;
- 覆盖完整区间:条目必须覆盖自上次发布以来的完整 git 区间,包括那些单独 PR 并未改动
CHANGELOG.md的变更; - Contributors 来源:从发布区间内 commit 作者与
Co-authored-by尾注提取,优先使用 GitHub handle。
关于标记约定,仓库现状可以验证规则:
- 最新发布条目(当前为
## 0.10.1)由<!-- release:start -->与<!-- release:end -->包裹(见 CHANGELOG.md#L5-L17); - 更早的发布(如
## 0.10.0、## 0.9.5)则没有标记——这正是"只有最新发布保留标记"规则的落地结果。
CI 提取正文的方式见 release.yml:用awk在两个标记之间截取内容写入临时文件,并校验行数不少于 2,否则报错退出。因此标记缺失或位置错误会直接阻断 GitHub Release 创建。
CI 自动发布流水线
合并到main后,.github/workflows/release.yml 触发,包含三个按依赖顺序执行的 job:
1. check-release:决定要不要发
在 ubuntu-latest 上运行,把本地packages/native-sdk/package.json的版本与 npm 上的@native-sdk/cli版本对比(release.yml#L32-L80):
- 版本不同(npm 上还没有这个版本)→
should_release=true,同时需要创建 GitHub Release; - 版本相同→ 检查
v<版本>这个 tag 的 GitHub Release 是否已包含全部 8 个二进制资产与CHECKSUMS.txt:- 资产齐全 → 跳过发布(
needs_github_release=false); - 缺少任一资产 → 仅重建/补齐 GitHub Release(
needs_github_release=true,不重新发布 npm)。
- 资产齐全 → 跳过发布(
这个分支设计保证了"npm 已有该版本但 Release 资产缺失"时,CI 可以从标记的 changelog 条目重建 GitHub Release,实现幂等修复。
2. github-release:交叉编译并上传资产
在 macos-14 上运行(条件为needs_github_release == 'true'),先用 awk 提取 changelog 正文,再执行 scripts/build-binaries.sh 用 Zig 交叉编译全部 8 个平台目标,最后gh release create/gh release upload上传二进制与校验和。
build-binaries.sh中的目标表(build-binaries.sh#L20-L29)给出了 npm 平台键、Zig 目标与 Release 资产名的完整对应关系:
| npm 平台包 | Zig 目标 | GitHub Release 资产 |
|---|---|---|
darwin-arm64 | aarch64-macos | native-sdk-darwin-arm64 |
darwin-x64 | x86_64-macos | native-sdk-darwin-x64 |
linux-arm64-gnu | aarch64-linux-gnu | native-sdk-linux-arm64 |
linux-x64-gnu | x86_64-linux-gnu | native-sdk-linux-x64 |
linux-arm64-musl | aarch64-linux-musl | native-sdk-linux-musl-arm64 |
linux-x64-musl | x86_64-linux-musl | native-sdk-linux-musl-x64 |
win32-arm64 | aarch64-windows | native-sdk-win32-arm64.exe |
win32-x64 | x86_64-windows | native-sdk-win32-x64.exe |
Zig 可以从任意宿主交叉编译全部 8 个目标;脚本只构建 CLI 可执行文件(zig build cli)以保持循环快速。你也可以传平台键子集(如build-binaries.sh darwin-arm64)只构建部分目标。
3. publish:分批发布九个 npm 包
在 ubuntu-latest 上、environment: Release中运行,条件为should_release == 'true'且 GitHub Release job 成功或被跳过(release.yml#L138-L255)。步骤依次为:
- 版本一致性门禁:
npm run version:check(即上文check-version-sync.js)与scripts:check,半吊子提升的提交树会被当场拒绝; - 下载并校验二进制:从 GitHub Release 下载 8 个资产,
sha256sum -c CHECKSUMS.txt验证完整性; - staging 到平台包:按资产名 → 平台键的映射表(与
build-binaries.sh相同)把二进制放入packages/native-sdk/npm/<key>/bin/native[.exe]并置为可执行; - 分批发布,顺序敏感:先发布 8 个平台包(
packages/native-sdk/npm/*/,每包npm publish --provenance --access public),最后发布主包@native-sdk/cli。已存在同版本号的包自动跳过(npm view <name>@<version>检查),保证重跑幂等。这样做的原因:主包的optionalDependencies精确引脚只有在所有平台包都已上线后才能解析成功; @native-sdk/core的发布开关:packages/core/package.json中"private": true字段本身就是发布开关——为 true 时跳过发布;去掉该字段后同一段逻辑会开始发布该包,无需改动工作流。注意在去掉标记之前,必须先为@native-sdk/core在 npmjs.com 配置好可信发布者,否则首个公开版本会在该步失败。
npm 可信发布(OIDC):无 token 的发布安全
发布采用npm trusted publishing(OIDC),仓库中不存在任何 npm token 密钥。其原理是:publish job 声明了id-token: write权限(release.yml#L148-L150),GitHub Actions 据此向 npm 换取短时凭证,每次发布都带--provenance。
一次性配置要求(在 npmjs.com 上完成):九个包(@native-sdk/cli加上packages/native-sdk/npm/下的 8 个@native-sdk/cli-*平台包)各自配置一个 GitHub Actions trusted publisher,指向:
- Repository:
vercel-labs/native - Workflow:
release.yml - Environment:
Release
若某个包缺少该配置,npm publish会针对该包大声失败,抛出 OIDC 认证错误——不会静默跳过。可信发布还要求 npm ≥ 11.5.1,由工作流使用的 Node 24 自带的 npm 满足。这套机制的收益是双重的:既消除了 token 泄露面,又因为每次发布都带--provenance,消费者可以审计每个发布版本的构建来源。
发布后的验证闭环
一次成功的发布最终可验证的产物包括:
- GitHub Release
v0.10.1(标题、正文来自标记的 changelog 条目,8 个二进制 +CHECKSUMS.txt); - npm 上
@native-sdk/cli-linux-x64-gnu等 8 个平台包(os/cpu/libc字段由 npm/linux-x64-gnu/package.json 等清单声明,如linux/x64/glibc); - 最后上线的
@native-sdk/cli,其optionalDependencies精确指向同版本的平台包; - 仓库内
tools/native-sdk/main.zig的const version、packages/core的 manifest 与 lockfile、各示例的引脚全部与主包版本一致(由version:check强制)。
对维护者而言,下次发布只需重复七步清单:分支 → 提升版本 → version:sync → 写 changelog(带标记)→ 填 Contributors → 清理旧标记 → 合并 PR,剩余的全交给流水线。
参考路径速查
- 发布流程文档:RELEASING.md
- 版本同步脚本:packages/native-sdk/scripts/sync-version.js
- 版本一致性校验:packages/native-sdk/scripts/check-version-sync.js
- 发布工作流:.github/workflows/release.yml
- 交叉编译脚本:packages/native-sdk/scripts/build-binaries.sh
- 主包清单:packages/native-sdk/package.json
- 平台包示例:packages/native-sdk/npm/linux-x64-gnu/package.json
- 变更日志:CHANGELOG.md
- CLI 版本号常量:tools/native-sdk/main.zig#L9
- 桌面应用
- 跨平台
【免费下载链接】native
Toolkit for building native desktop apps
相关推荐
JSONEditor 版本发布全流程指南:从版本号更新到 npm 发布
JSONEditor 版本发布全流程指南:从版本号更新到 npm 发布 导读 jsoneditor 是一个基于 Web 的 JSON 查看、编辑、格式化与校验工
前端UI组件MediaElement.js 版本发布全流程:从发布分支、版本号同步到 Grunt 构建与 npm 发布的实操指南
MediaElement.js 版本发布全流程:从发布分支、版本号同步到 Grunt 构建与 npm 发布的实操指南 本文以仓库根目录的 RELEASE.md
音视频前端UI组件webamp 项目 npm 发布流程完全指南:从版本号同步到 CI 自动化发布与 npm provenance
webamp 项目 npm 发布流程完全指南:从版本号同步到 CI 自动化发布与 npm provenance 导读 本文以 .claude/skills/re
前端音视频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考