发布于 2026-01-06 10 阅读
0

如何使用 GitHub Actions 同时将 npm 包发布到 npm 和 GitHub Package Registry

如何使用 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"
Enter fullscreen mode Exit fullscreen mode

当有人使用旧名称安装您的软件包时,这将添加一条警告消息,并且还会在 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}}
Enter fullscreen mode Exit fullscreen mode

我设置的时候,如果我尝试定义一个以字符串开头的密钥,GitHub 会报错GITHUB。所以我们把它改成类似这样的形式PUBLISH_GITHUB_TOKEN

    NODE_AUTH_TOKEN: ${{secrets.PUBLISH_GITHUB_TOKEN}}
Enter fullscreen mode Exit fullscreen mode

生成令牌

接下来,我们需要创建一个令牌并将其注册为密钥。令牌在您的GitHub 帐户设置中创建。点击“生成新令牌”。

添加此令牌的备注,例如“GPR 发布令牌”。

在“选择范围”下,选择以下范围:

  • 写入:软件包
  • 读取:软件包
  • 删除:包裹

然后点击绿色的“生成令牌”按钮。请注意,令牌只会显示在这里一次,所以务必将其复制到剪贴板,以便在下一步中使用。

定义秘密

接下来,返回您的代码库页面,然后进入“设置”页面。应该会有一个“密钥”选项卡。点击“添加新密钥”。

在“名称”下输入PUBLISH_GITHUB_TOKEN。然后将之前复制的令牌粘贴到“值”字段中。

令牌

npm 令牌

现在我们将设置 npm 发布令牌。在publish-npm工作流文件的相应部分,有一个类似这样的变量:

    NODE_AUTH_TOKEN: ${{secrets.npm_token}}
Enter fullscreen mode Exit fullscreen mode

我喜欢保持一致性,所以我把它重命名为PUBLISH_NPM_TOKEN,像这样:

    NODE_AUTH_TOKEN: ${{secrets.PUBLISH_NPM_TOKEN}}
Enter fullscreen mode Exit fullscreen mode

但这只是我个人的偏好,并非必须。如果您想保留默认名称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}}
Enter fullscreen mode Exit fullscreen mode

这样基本可以实现,只需要修改一行代码。发布命令应该改为以下内容:

    - run: npm publish --access public
Enter fullscreen mode Exit fullscreen mode

这将告诉 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}}
Enter fullscreen mode Exit fullscreen mode

首先,您需要在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
Enter fullscreen mode Exit fullscreen mode

工作流程变更到此结束。总而言之,工作流程文件现在应该类似于这样:

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}}
Enter fullscreen mode Exit fullscreen mode

提交此文件,您的工作流程就应该设置好了。

如何运行发布工作流程

该工作流程配置为在每次创建新版本时运行。以下是我通常的操作:

完成新版本的所有更改后,我更新package.json版本号并提交。然后,我创建一个带有该版本号的标签,例如:

    git tag 2.0.1
Enter fullscreen mode Exit fullscreen mode

然后我推送这个标签:

    git push origin 2.0.1
Enter fullscreen mode Exit fullscreen mode

这将会在代码仓库中创建一个新的发布版本,但不会立即运行工作流程。请前往您的 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