Scalar SDK 发布机制深度解析:配置开关、GitHub Actions 工作流与 OIDC 免密发布到 npm/PyPI 等注册表
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
本文基于 Scalar 官方文档 Publishing 展开,完整讲解 Scalar 如何将你生成的 SDK 发布到各语言包注册表:从在目标(target)上打开发布开关,到自动生成release-please.yml等 GitHub Actions 工作流、通过 release 拉取请求(pull request)驱动版本切分,最终在合并时把包发布到 npm、PyPI、crates.io 等注册表。读完后,你将能独立完成:启用发布、选择认证方式(OIDC 可信发布或令牌)、指定精确版本号、以及理解发布流程中每个生成文件的职责与权限边界。
核心思想:发布是"搭便车"式的,且默认关闭
Scalar 的发布(Publishing)能力直接构建在你已经在使用的SDK 生成 + GitHub 仓库同步流程之上,没有一条需要单独维护的额外流水线。它代替你执行npm publish这类手工操作:Scalar 把 GitHub Actions 工作流写进你的 SDK 仓库,并由你的 SDK 配置来驱动整个发布过程。当你合并一次 release 时,包就发出去了。
两个关键前提:
- 发布是opt-in(主动选择加入)的,默认关闭。在某个 target 上明确开启之前,什么都不会发布;
- 发布要求已关联 GitHub 仓库(GitHub Repositories)。一个没有配置
destinations.production的 target 不会生成任何工作流。
发布流程五步走
完整流程分为五个阶段,每一步都发生在你的仓库与注册表之间,逻辑透明可查:
- 为 target 启用发布:从仪表盘(dashboard)或 SDK 配置中打开发布开关。这是唯一需要拨动的总开关,它会一次性接通后续所有环节。
- 构建 SDK:每次构建会生成 SDK,将其推送到你关联仓库 的
scalar-generated分支,并与你在scalar-next分支上的自定义代码合并。生成的.github/workflows文件同样会落到仓库里——也就是说发布逻辑住在你自己的仓库中,而不是某个黑盒。 - 审查 release 拉取请求:Scalar 始终保持一个从
scalar-next指向默认分支的release pull request处于打开状态,标题格式为release: X.Y.Z。它的 diff 就是完整的待发版内容:生成的代码变更、你的自定义代码、changelog 以及版本号提升。 - 合并 release 拉取请求:合并会触发默认分支上的
release-please.yml,它负责切出vX.Y.Ztag、更新CHANGELOG.md、并创建 GitHub Release。 - publish 作业执行发布:在同一次工作流运行中,release 状态会同步回
scalar-next,随后内联的publishjob 检出刚刚切出的 tag,把包发布到对应注册表。发布步骤是幂等的:如果该版本已经在注册表上,会直接跳过,因此重复运行既不会失败也不会造成双重发布。
仓库里会生成什么:发布机器的完整清单
每一个已关联仓库的 target 都会把整套"发布机器"随 SDK 一起提交。它们都是普通的、可读的文件,你可以(也可以)在仓库中检查和编辑它们:
| 文件 | 触发条件 | 作用 |
|---|---|---|
.github/workflows/sdk-ci.yml | push、pull_request | 安装依赖并构建 SDK,确保每个变更都经过检查。 |
.github/workflows/release-please.yml | 向默认分支push | release 拉取请求合并时切 tag、写 changelog、创建 GitHub Release;由其内联publishjob 完成发布;并把 release 状态同步回scalar-next。 |
.github/workflows/release-title-edit.yml | pull_request | 运行Release PR version检查,把被编辑过的 release PR 标题转换为 Scalar 用来重新渲染该 PR 的Release-As提交。 |
.github/workflows/sdk-release.yml | workflow_dispatch | 手动重新发布一个已存在的 tag。仅当 target 配置为"发布时(release time)"发布才生成。 |
release-please-config.json、.release-please-manifest.json | — | release-please 的配置与版本状态文件。manifest 只播种一次,之后由你的仓库自己拥有。 |
VERSIONING.md | — | 面向维护者的文档:分支模型、如何指定精确版本、仓库前置条件。 |
注意(tag 供给型生态):Swift Package Manager、Packagist 这类"以 tag 为交付物"的生态没有可上传的制品,因此它们没有
publishjob,也没有sdk-release.yml。对它们而言,vX.Y.Ztag 和 GitHub Release本身就是发布动作。Go 同样是 tag 供给,但 Scalar 仍会生成一个 release 工作流,用于在 tag 切出后预热公共模块代理(module proxy)。各注册表的完整对照见 Package Registries。
从这份清单可以推断出 Scalar 的设计取向:CI 检查(sdk-ci.yml)、自动发布(release-please.yml)、手动补发(sdk-release.yml)三条路径彼此独立,且全部落在.github/workflows下,任何一步都能在 GitHub 上直接看到运行记录。
启用发布:仪表盘开关或配置块,二者等价
开启发布有两种方式,设置的是同一个东西:
方式一:仪表盘。打开某个 target,在 Git settings 下切换Publish to <registry> on merge开关。
方式二:SDK 配置。给 target 添加一个publish块:
{ "targets": { "typescript": { "packageName": "demo-api", "publish": { "npm": true } } } }注册表键名(registry key)取决于 target 的语言:npm、pypi、cargo、maven、nuget、rubygems、packagist、swiftpm、pub等。完整的键名—注册表—默认认证方式—所需 secrets 对照表见 Package Registries 的快速参考;每个 target 各自的publish选项则记录在其配置页。
以 npm 为例(TypeScript (npm)),"npm": true即默认启用 OIDC 可信发布;带作用域的包(如@acme/api)会以--access public发布;如果不想用 OIDC,可以改用令牌认证(见下文"认证"一节)。
包名可用性检查:把命名冲突挡在发布之前
启用发布时,对话框会把 target 的包名与其注册表核对,提前告知你该名字看起来"可用"还是"已被占用"——这样能在一次 release 合并后 publish 步骤失败之前,就把命名冲突暴露出来。
两点关键规则:
- 名字被占用只是警告,绝不阻断。注册表无法判断一个已占用的名字是不是本来就是你的,而"以自己已有的名字重新发布"是正常操作;
- 该校查目前只对npm和PyPI生效,其他注册表不显示检查结果。
认证:OIDC 可信发布优先,令牌兜底
默认情况下,只要注册表支持,Scalar 一律使用OIDC 可信发布(trusted publishing):publish job 在发布时用一个短生命周期的 GitHub 身份令牌去换取注册表凭证,因此没有需要创建、存储或轮换的 token。你只需在注册表侧一次性地把你的仓库和工作流登记为可信发布者。
重要:登记可信发布者时,工作流文件名应填
release-please.yml,而不是sdk-release.yml。自动发布是作为release-please.yml内部的一个 job 运行的,所以 OIDC 声明(claims)中命名的是这个文件。sdk-release.yml只用于手动补发;只有你确实会 dispatch 它时,才把它作为额外的可信发布者登记一份。
各注册表的默认认证方式与所需 secrets(摘自 Package Registries):
| Target | publish键 | 注册表 | 默认认证 | 需添加的 Secrets |
|---|---|---|---|---|
| TypeScript | npm | npm | OIDC | 无(OIDC)或NPM_TOKEN |
| Python | pypi | PyPI | OIDC | 无(OIDC)或PYPI_API_TOKEN |
| Go | go | Go modules | Git tag | 无 |
| Rust | cargo | crates.io | OIDC | 无(OIDC)或CARGO_REGISTRY_TOKEN |
| Java / Kotlin | maven | Maven Central | 令牌 + GPG | MAVEN_CENTRAL_USERNAME、MAVEN_CENTRAL_PASSWORD、MAVEN_GPG_PRIVATE_KEY、MAVEN_GPG_PASSPHRASE |
| C# | nuget | NuGet | OIDC | NUGET_USER(OIDC)或NUGET_API_KEY |
| Ruby | rubygems | RubyGems | API key | RUBYGEMS_API_KEY |
| PHP | packagist | Packagist | Git tag | 无 |
| Swift | swiftpm | Swift Package Manager | Git tag | 无 |
| Dart | pub | pub.dev | OIDC | 无(OIDC)或PUB_TOKEN |
| CLI | npm、binaries、homebrew | npm / GitHub Release / Homebrew | OIDC 或令牌 | npm 用 OIDC 则无需;或NPM_TOKEN,Homebrew 另需HOMEBREW_TAP_TOKEN |
| C++ | — | — | — | 无(CI 内构建,无注册表) |
不支持 OIDC 的注册表(RubyGems,以及同样需要 GPG 签名的Maven Central)改用仓库 secrets:你在注册表创建令牌/密钥,添加到 SDK 仓库的 Actions secrets 中(添加 secrets 的操作步骤)。生成的工作流按精确名称读取这些 secrets,所以名字必须与上表完全一致;secrets 的作用域是单个仓库,若同一仓库发布多个 target,需要把各注册表的 secret 都加到这个仓库上。
切换到令牌认证的配置写法:
{ "targets": { "typescript": { "publish": { "npm": { "authMethod": "access-token" } } } } }以 npm 为例,工作流会把NPM_TOKENsecret 作为NODE_AUTH_TOKEN读取。(另据 TypeScript 发布说明:npm 可信发布要求 npm 11.5.1 或更高版本,但生成的工作流会在发布前自动升级 npm,无需手工处理。)
版本与发布:Conventional Commits 驱动,也可手动指定精确版本
版本号由release-please 根据你的提交历史计算,遵循 Conventional Commits 规范。Scalar 会写入描述 SDK 表面(surface)实际变更的 conventional commit 消息,而你在scalar-next上的自有提交同样计入版本计算。一个值得注意的细节:1.0 之前,破坏性变更提升的是次版本号(minor),而不是直接跳到1.0.0。
如果想让某次发版使用精确指定的版本,编辑 release 拉取请求的标题即可:
release: 1.0.0配套的机制:
Release PR version检查在标题与已提交版本不一致时为红;- Scalar 会按你指定的版本重新渲染该 PR,检查随之转绿;
- 等绿色再合并;
- 等价的 git 原生做法:在
scalar-next上打一个空提交,带Release-As: 1.0.0页脚(由 文件清单 中的release-title-edit.yml负责处理这条路径)。
每次发版都会得到三样东西:一个vX.Y.Ztag、一个 GitHub Release、以及仓库CHANGELOG.md中新增的一条记录——你的发布历史与代码同仓共存。生成的VERSIONING.md会把上述规则完整讲给你的维护者听。
权限最小化:工作流只申请需要的 permissions
生成的工作流遵循最小权限原则。release-please.yml需要写 tag、changelog 和 Release:
permissions: contents: write pull-requests: write其内部的publishjob 再把权限收窄到"发布底线":
permissions: contents: read id-token: write packages: write其中id-token: write正是启用 OIDC 可信发布的关键。CLI target 是特例:当它附带二进制文件或更新 Homebrew tap 时,publish job 会保留contents: write,因为它需要向 GitHub Release 上传资产。Scalar 从不申请组织级(organization-wide)的发布权限。
前置条件与后续步骤
理解整个流程前,建议先确认仓库侧的前置条件(详见 GitHub Repositories):
- 分支模型为三分支:
scalar-generated(纯净生成产物,你从不向其提交)、scalar-next(生成产物 + 你的自定义代码,每次重新生成由三方合并带入,自定义代码不会被覆盖)、默认分支(只接收已发布状态,且只通过合并 release PR 前进);另有scalar-merge-conflict分支承载无法干净合并的重新生成结果; scalar-next与默认分支的分支保护需允许 Scalar 应用和github-actions机器人推送,或保持不保护;- 不需要任何 Actions 设置变更:生成的工作流自行声明权限,且从不创建拉取请求。
启用发布后的两条标准后续路径:
- 关联 GitHub 仓库:把每个 target 连到一个仓库,让构建自动同步过去(GitHub Repositories);
- 配置注册表:为所选注册表登记可信发布者,或添加所需的 secrets(Package Registries)。
小结
Scalar 的 SDK 发布机制可以概括为一句话:把发布基础设施作为可读文件生成进你的仓库,用"合并 release PR"作为唯一的发布触发点,用 OIDC 免密认证作为默认凭证通道。它带来的工程收益是:发布逻辑随仓库可见可审、发布幂等可重跑、版本历史(tag + Release + CHANGELOG)与代码同仓、权限按 job 精确收窄。对于多语言 SDK 分发场景,这套"一份配置、按 target 选择注册表键名与认证方式"的模型,比在每个仓库手工维护npm publish/twine upload脚本更一致、也更易审计。
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考