☰
Native SDK 版本发布全流程指南:从版本号同步到 npm 可信发布
2026/9/27 8:03:33 网站建设 项目流程
  • 桌面应用
  • 跨平台

【免费下载链接】native

Toolkit for building native desktop apps

项目地址:https://gitcode.com/gh_mirrors/ze/native
点击查看免费下载

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 的步骤,一次发布的本地准备如下:

  1. 创建分支,例如prepare-v1.2.0;
  2. 提升版本号:修改packages/native-sdk/package.json中的version字段(当前仓库中为0.10.1,见 package.json);
  3. 同步所有版本引用:运行npm --prefix packages/native-sdk run version:sync;
  4. 审阅自上次发布以来的 git 历史,在 CHANGELOG.md 顶部、新的## <version>标题下撰写完整的 changelog 条目,并用<!-- release:start -->与<!-- release:end -->标记包裹;
  5. 填充条目的### Contributors:从发布区间内的 commit 作者与Co-authored-by尾注中提取,优先使用 GitHub handle;这段被标记包裹的内容同时就是 GitHub Release 的正文;
  6. 移除上一条发布的<!-- release:start -->/<!-- release:end -->标记——只有最新一条发布允许保留标记;
  7. 打开 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.json8 个@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-arm64aarch64-macosnative-sdk-darwin-arm64
darwin-x64x86_64-macosnative-sdk-darwin-x64
linux-arm64-gnuaarch64-linux-gnunative-sdk-linux-arm64
linux-x64-gnux86_64-linux-gnunative-sdk-linux-x64
linux-arm64-muslaarch64-linux-muslnative-sdk-linux-musl-arm64
linux-x64-muslx86_64-linux-muslnative-sdk-linux-musl-x64
win32-arm64aarch64-windowsnative-sdk-win32-arm64.exe
win32-x64x86_64-windowsnative-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)。步骤依次为:

  1. 版本一致性门禁:npm run version:check(即上文check-version-sync.js)与scripts:check,半吊子提升的提交树会被当场拒绝;
  2. 下载并校验二进制:从 GitHub Release 下载 8 个资产,sha256sum -c CHECKSUMS.txt验证完整性;
  3. staging 到平台包:按资产名 → 平台键的映射表(与build-binaries.sh相同)把二进制放入packages/native-sdk/npm/<key>/bin/native[.exe]并置为可执行;
  4. 分批发布,顺序敏感:先发布 8 个平台包(packages/native-sdk/npm/*/,每包npm publish --provenance --access public),最后发布主包@native-sdk/cli。已存在同版本号的包自动跳过(npm view <name>@<version>检查),保证重跑幂等。这样做的原因:主包的optionalDependencies精确引脚只有在所有平台包都已上线后才能解析成功;
  5. @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 Releasev0.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

项目地址:https://gitcode.com/gh_mirrors/ze/native
点击查看免费下载

相关推荐

上一篇:揭秘github-automated-repos工作原理:GitHub API交互与数据处理流程
下一篇:性能调优检查清单

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询