1

这是一种问答,我已将我的解决方案放在答案中。

我是 GitHub Actions 测试版和 GitHub 包注册表测试版的成员。由于我是一个非常懒惰的人,我不仅自动化了我的 npm 包的构建过程,而且我还想自动化它的发布。
为了做到这一点,我不得不面对一些问题:

  1. 如何确保在刚刚构建的版本上执行“发布”作业?
  2. 如何检测包版本何时在 GitHub Actions 中更新?
  3. 如何使用该检查的结果来编辑操作工作流的行为?
  4. 如何从工作流中将包发布到 npm?
  5. 发布到 npm 后,如何将相同的版本发布到 GitHub 包注册表?
4

1 回答 1

5

注意:所有这些步骤的结果可以在这里找到,在我实际用于我的包的工作流文件中。

1. 确保“发布”作业在刚刚构建的版本上执行

我发现的最简单的方法是将这两个作业放在同一个工作流中,并让它们都在每个push事件上触发:然后将发布作业限制为仅在master分支上和第一个之后执行。

  • 构建工作:

它需要构建新版本的包,然后将其提交到存储库:提交至关重要,因为这允许其他作业选择构建的版本。要提交在工作流运行中所做的更改,您可以使用我的操作之一add-and-commit:它将使用“假”git 用户将更改推送到 GitHub 存储库。
您的工作流程作业应如下所示:

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest

    steps: 
    - name: Checkout repository
      uses: actions/checkout@v1.0.0

    - name: Set up Node.js
      uses: actions/setup-node@v1.2.0
      with:
        node-version: '10.x'
    
    - name: Install dependencies
      run: npm install

    - name: Compile build
      run: npm run build # This can be whatever command you use to build your package

    - name: Commit changes
      uses: EndBug/add-and-commit@v2.1.0
      with: # More info about the arguments on the action page
        author_name: Displayed name
        author_email: Displayed email
        message: "Message for the commit"
        path: local/path/to/built/version
        pattern: "*.js" # Pattern that matches the files to commit
        force: true # Whether to use the --force flag
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This gets generated automatically
  • 发布工作:

我们希望它在完成后只在master分支中运行build,所以我们可以这样设置:

publish:
  name: Publish to NPM & GitHub Package Registry
  runs-on: ubuntu-latest
  if: contains(github.ref, 'master') # This sets the branch
  needs: build # This makes it wait for the build job

2.检测版本变化

我没有找到一个好的方法,所以我做了另一个动作,version-check:这个动作扫描每次推送的提交,并试图找出它们是否包含版本更改。
您需要设置以下两个步骤:

steps:
- name: Checkout repository
  uses: actions/checkout@v1.0.0
  with:
    ref: master

- name: Check version changes
  uses: EndBug/version-check@v1.0.0 # More info about the arguments on the action page
  id: check # This will be the reference for later

3. 使用检查结果编辑工作流的行为

version-check提供两个输出:(changed是否有更新)和type(更新的类型,如“patch”、“minor”、...)。
这些输出可以通过steps上下文访问,您可以使用它们来决定是否运行一个步骤,使用if属性。这是一个例子:

# check is the id we gave to the check step in the previous paragraph
- name: Version update detected
  if: steps.check.outputs.changed == 'true'
  run: 'echo "Version change! -> ${{ steps.check.outputs.type }}"'

4. 发布包到 NPM

将包发布到 NPM 非常简单:您只需要设置 Node.js 然后使用npm publish,就像在您自己的机器上一样。唯一的区别是您需要一个令牌来进行身份验证:您可以在npmjs.com上创建一个。创建后不要将其放入工作流程本身:您可以将其存储为“秘密”,您可以在此处找到有关这些内容的更多信息。
在这个例子中,我假设你的秘密被称为NPM_TOKEN

- name: Set up Node.js for NPM
  if: steps.check.outputs.changed == 'true'
  uses: actions/setup-node@v1.2.0
  with:
    registry-url: 'https://registry.npmjs.org' # This is just the default registry URL

- name: Install dependencies
  if: steps.check.outputs.changed == 'true'
  run: npm install

- name: Publish the package to NPM
  if: steps.check.outputs.changed == 'true'
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # NPM will automatically authenticate with this

5. 将包发布到 GitHub 包注册表

就目前而言,如果您想继续将现有包发布到 npm,使用 GitHub 包注册表不是很愉快:这就是为什么它需要对包进行范围限定,这可能会搞砸(您的包可能没有限定范围或范围在不同的名称下)。
我发现解决这个问题的最简单方法是执行此解决方法:

  • 在您的工作流程中,重新设置 Node.js,但添加 GPR 的注册表 URL 和您的名称范围
  • 创建一个编辑您的 package.json 的 npm 脚本,以便它将包的原始名称更改为您需要发布到 GPR 的名称(包括范围)
  • 在您的工作流程中调用该脚本后,npm publish像以前一样使用,但这次使用内置的GITHUB_TOKENas NODE_AUTH_TOKEN
{
  "name": "YourPackageName",
  ...
  "scripts": {
    "gpr-setup": "node scripts/gpr.js"
  }
}
// scripts/gpr.js

const fs = require('fs')
const { join } = require('path')

// Get the package obejct and change the name
const pkg = require('../package.json')
pkg.name = '@yourscope/YourPackageName'

// Update package.json with the udpated name
fs.writeFileSync(join(__dirname, '../package.json'), JSON.stringify(pkg))
- name: Set up Node.js for GPR
  if: steps.check.outputs.changed == 'true'
  uses: actions/setup-node@v1.2.0
  with:
    registry-url: 'https://npm.pkg.github.com/'
    scope: '@endbug'

- name: Set up the package for GPR
  if: steps.check.outputs.changed == 'true'
  run: npm run gpr-setup

- name: Publish the package to GPR
  if: steps.check.outputs.changed == 'true'
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

结果

您的包现在同时发布到 NPM 和 GPR(尽管需要手动将描述添加到 GPR)。你可以在 dbots 的 5.0.4 版本中找到我所指的所有内容:

于 2019-10-11T19:58:44.923 回答