注意:所有这些步骤的结果可以在这里找到,在我实际用于我的包的工作流文件中。
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_TOKEN
as 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 版本中找到我所指的所有内容: