如何使用 GitHub Actions 同时将 npm 包发布到 npm 和 GitHub Package Registry
这篇文章最初发表在我的博客上。
GitHub Package Registry最近正式上线了。虽然有相当不错的使用文档,但需要修改项目中的 `<package_name>`package.json和/或 `<package_name>`.npmrc配置,显式指定 GitHub 的注册表。这意味着你将无法再发布到 npm 注册表。而我的情况是,我希望同时将我的包发布到这两个注册表。
开始之前请注意:GitHub 注册表仅支持作用域包。因此,如果您的 npm 包当前名为 `<package_name>` my-package,则必须将其重命名为 `<package_name>` @username/my-package,否则 GitHub 将拒绝您的包。这很容易做到,但您需要将包的用户重定向到新的包名。这可以通过以下npm deprecate命令轻松完成:
npm deprecate my-package "This package has moved, please install @username/my-package"
当有人使用旧名称安装您的软件包时,这将添加一条警告消息,并且还会在 npm 网站上您的软件包页面上添加一条醒目的消息,显示您的弃用消息。
GitHub Actions
为了同时发布到这两个注册表,我们将使用GitHub Actions。他们实际上提供了一个完成此任务的工作流程,但需要进行一些调整才能正常工作。
首先,请访问您在 GitHub 上的仓库页面,然后点击“操作”选项卡。这里会显示一些入门工作流。其中一个工作流应该是“Node.js 包”。我们将使用这个工作流。点击“设置此工作流”。
这将打开一个编辑器,显示一些 YAML 代码。这是该作业的配置。这样基本就完成了,但我在设置过程中还需要修改一些地方。
该工作流程分为三个部分。第一部分是构建项目。第二部分是发布到 npm,第三部分是发布到 GitHub Package Registry (GPR)。
秘密
首先是密钥。你需要 npm 和 GitHub 的身份验证令牌才能通过此工作流程发布。我们稍后会填写这些信息。现在,你会注意到NODE_AUTH_TOKEN定义了两个环境变量,一个在 npm 部分,一个在 GPR 部分。
GitHub 令牌
该publish-gpr部分应该有一个类似这样的变量:
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
我设置的时候,如果我尝试定义一个以字符串开头的密钥,GitHub 会报错GITHUB。所以我们把它改成类似这样的形式PUBLISH_GITHUB_TOKEN:
NODE_AUTH_TOKEN: ${{secrets.PUBLISH_GITHUB_TOKEN}}
生成令牌
接下来,我们需要创建一个令牌并将其注册为密钥。令牌在您的GitHub 帐户设置中创建。点击“生成新令牌”。
添加此令牌的备注,例如“GPR 发布令牌”。
在“选择范围”下,选择以下范围:
- 写入:软件包
- 读取:软件包
- 删除:包裹
然后点击绿色的“生成令牌”按钮。请注意,令牌只会显示在这里一次,所以务必将其复制到剪贴板,以便在下一步中使用。
定义秘密
接下来,返回您的代码库页面,然后进入“设置”页面。应该会有一个“密钥”选项卡。点击“添加新密钥”。
在“名称”下输入PUBLISH_GITHUB_TOKEN。然后将之前复制的令牌粘贴到“值”字段中。
npm 令牌
现在我们将设置 npm 发布令牌。在publish-npm工作流文件的相应部分,有一个类似这样的变量:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
我喜欢保持一致性,所以我把它重命名为PUBLISH_NPM_TOKEN,像这样:
NODE_AUTH_TOKEN: ${{secrets.PUBLISH_NPM_TOKEN}}
但这只是我个人的偏好,并非必须。如果您想保留默认名称npm_token,只需记住在之后定义密钥时使用该名称即可。
生成令牌
要生成 npm 令牌,请登录您的npmjs.com帐户。点击页面右上角的用户图标,然后点击“令牌”。
在下一个屏幕上,单击“创建新令牌”按钮。对于访问级别,选择“读取和发布”,然后单击“创建令牌”。
系统将生成并显示令牌。与 GitHub 令牌一样,令牌仅此一次可见,因此请务必立即将其复制到剪贴板。如果您在关闭此页面后丢失了令牌,则需要重新生成一个。
定义秘密
按照上述步骤PUBLISH_NPM_TOKEN在您的存储库设置中定义密钥。
工作流程变更
至此,我们的令牌已设置完毕,我们只需要对工作流 YAML 文件进行一些小的更改。
publish-npm部分
如本文前面所述,要将您的软件包发布到 GPR,它必须是作用域软件包(例如 ` @username/package-name.github.io/ ...
截至撰写本文时,npm 默认会将作用域包发布为私有包。这可能并非您所期望的,事实上,如果您使用的是免费帐户,npm 将会拒绝发布,因为发布私有包需要付费帐户。
总之,publish-npm工作流程的这一部分应该如下所示:
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.PUBLISH_NPM_TOKEN}}
这样基本可以实现,只需要修改一行代码。发布命令应该改为以下内容:
- run: npm publish --access public
这将告诉 npm 发布你的作用域包,并允许公众访问。
这就是 npm 发布所需的一切。现在我们来修复 GPR 发布问题。
publish-gpr部分
该publish-gpr部分内容应如下所示:
publish-gpr:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://npm.pkg.github.com/
scope: '@your-github-username'
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.PUBLISH_GITHUB_TOKEN}}
首先,您需要在scope参数中设置您的用户名。在这一行中,将 `<username>` 替换'@your-github-username'为您实际的 GitHub 用户名,并在前面加上一个@字符,例如 `<username> '@joeattardi'`。
如您所见,它指定了 GPR 包注册表 URL,这看起来没问题。然而,当我进行设置时,它似乎并没有遵循该registry-url设置,而是仍然尝试发布到 npm 注册表。
幸运的是,这个问题有一个简单的(虽然有点取巧)解决方法。我们需要在.npmrc文件中创建一个临时条目来指定注册表。这仅在构建机器上临时生效,不会提交回您的代码仓库。在发布命令之前,添加以下行:
- run: echo registry=https://npm.pkg.github.com/YOUR_USERNAME >> .npmrc
工作流程变更到此结束。总而言之,工作流程文件现在应该类似于这样:
name: Node.js Package
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
- run: npm ci
- run: npm run build
- run: npm run lint
- run: npm test
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.PUBLISH_NPM_TOKEN}}
publish-gpr:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://npm.pkg.github.com/
scope: '@YOUR_USERNAME'
- run: npm ci
- run: echo registry=https://npm.pkg.github.com/YOUR_USERNAME >> .npmrc
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.PUBLISH_GITHUB_TOKEN}}
提交此文件,您的工作流程就应该设置好了。
如何运行发布工作流程
该工作流程配置为在每次创建新版本时运行。以下是我通常的操作:
完成新版本的所有更改后,我更新package.json版本号并提交。然后,我创建一个带有该版本号的标签,例如:
git tag 2.0.1
然后我推送这个标签:
git push origin 2.0.1
这将会在代码仓库中创建一个新的发布版本,但不会立即运行工作流程。请前往您的 GitHub 代码仓库页面,并导航至发布版本部分。您会在列表顶部看到刚刚推送的标签。
点击标签,然后点击“编辑标签”按钮。输入一些关于发布版本的详细信息,然后点击绿色的“发布版本”按钮。发布版本后,软件包发布工作流程应该会启动。要验证这一点,请转到代码仓库的“操作”选项卡。您应该会看到“Node.js 软件包”工作流程正在运行。
搞定了!现在,每当你创建新版本时,都应该同时发布到 npm 和 GitHub 仓库。
文章来源:https://dev.to/joeattardi/how-to-publish-an-npm-package-to-npm-and-github-package-registry-simultaneously-using-github-actions-213a

