npm 包发布 turborepo、trusted publisher、pnpm
Source: Dev.to
一周前,我开始着手更新我的个人 monorepo(我们仍在继续开发)。
在所有任务中,发布包是最复杂的之一,下面我将解释为什么会如此困难。
旧方式
- 进入 npmjs。
- 生成一个访问令牌。
- 将令牌添加到你的发布流程中。
- 创建环境变量
NPM_TOKEN和GITHUB_TOKEN用于 semantic‑release。
就完成了!
然而,npmjs 更改了其安全策略,现在建议使用 trusted publishing,它使用 OpenID Connect 而不是传统的令牌。
Trusted Publishing 配置
1. 至少发布一次包
在 npmjs 上创建 trusted publisher 配置之前,包必须已经存在于注册表中。
如果要发布一个新包,请先手动发布一次(例如 pnpm publish --tag dummy),或使用工具 setup-npm-trusted-publish。
2. 添加 trusted publisher
进入你的包的配置页面:
https://www.npmjs.com/package//access- 或
https://www.npmjs.com/package///access
随后,添加你的 trusted publisher(GitHub 或 GitLab)信息。
页面应显示类似如下内容:
需要填写的字段
- 组织或用户
- 仓库
- 工作流文件名(包括扩展名)。注意:文件必须位于
.github/workflows目录下。

在我的案例中:
- 组织:
dezkareid - 仓库:
dezkareid - 工作流文件:
ci-packages.yml
完成!配置已完成,现在我们可以继续编写工作流。
Source: …
在 GitHub Actions 中配置 Trusted Publishing
1. Job 权限
我们需要启用 id-token 权限,以便 GitHub 能获取 OIDC 令牌:
permissions:
id-token: write
如果同时使用 semantic‑release 来创建标签、生成 changelog 并在 GitHub 上发布,则需要额外的权限:
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
2. 工作流示例
semantic‑release 仓库中提供了一个用于 GitHub Actions 的配置示例。
3. semantic-release 配置
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"]
}
],
"@semantic-release/github"
]
}
在使用 pnpm 的 monorepo 中遇到的问题
monorepo + pnpm 架构
- 项目位置:在 monorepo 中我们必须指向对应要发布的包的 workspace。
- pnpm 认证:pnpm 对 workspaces 的处理方式不同于 npm,导致了认证错误。
具体错误
-
workflow 文件名错误
没有在 trusted publishing 配置中正确添加文件名,导致 npm 找不到 OIDC 配置。 -
Turborepo 过滤环境变量
release命令是通过 turborepo 执行的,它会过滤环境变量。我通过将工作目录 (working-directory) 设置为包的文件夹,并直接运行semantic-release来解决此问题。 -
@semantic-release/npm插件在 pnpm 下不可用
该插件默认使用 npm 作为包管理器,在 pnpm 环境下认证会失败。解决办法是使用专门的插件:npm i -D @anolilab/semantic-release-pnpm
semantic-release 最终配置
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@anolilab/semantic-release-pnpm",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"]
}
],
"@semantic-release/github"
]
}
通过这些调整,使用 pnpm 管理的 monorepo 并结合 trusted publishing 的包发布可以顺利进行。Happy releasing!
semantic-release 配置
{
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits",
"releaseRules": [
{ "type": "feat", "release": "minor" },
{ "type": "fix", "release": "patch" },
{ "type": "perf", "release": "patch" },
{ "type": "refactor", "release": "patch" },
{ "type": "docs", "release": false },
{ "type": "style", "release": false },
{ "type": "chore", "release": false },
{ "type": "test", "release": false }
]
}
],
"@semantic-release/github"
],
"extends": "semantic-release-monorepo"
}
有了这个,我现在可以使用我喜欢的技术栈重新发布包了。我把我的 workflow 放在这里,供你查看,如果对你有帮助,也可以复制使用 :D
