使用 GitHub Actions 和 semantic-release 实现自动版本控制和包发布
当我们开发 JavaScript 包时,每次向 npm 发布新版本时,我们都必须手动完成一系列重复性任务:
- 更改版本字段
package.json
- 创建新的 Git 标签和 GitHub 版本
- 执行任何构建步骤来创建发布工件
- 更新变更日志
- 发布到 npm
如果我们可以自动化所有这些任务,那不是很好吗?
GitHub Actions和semantic-release为我们提供了帮助!
GitHub Actions是 GitHub 的一项功能,可让我们构建、测试和部署 GitHub 托管的项目。您可以将其视为 GitHub 的 CI/CD 流水线。它使用名为 的 YAML 文件,workflows
这些文件会根据特定事件(例如,推送提交时)触发。
semantic-release是一款使用约定式提交消息格式来确定代码库变更类型的工具。它会自动设置下一个语义版本号、生成变更日志并发布版本。
让我们从准备我们的存储库开始。
检查现有的版本标签
如果我们要在现有存储库中使用语义发布,我们首先必须确保上次发布的 npm 版本中包含的最新提交位于发布分支历史记录中,并带有已发布的版本标记。
如果您在新存储库中设置语义发布,则可以跳过此步骤。
假设我们的发布分支是main
,最后一次提交SHA
是,1234567
并且我们项目的当前发布版本是v1.1.0
# Make sure the commit 1234567 is in the release branch history
$ git branch --contains 1234567
# If the commit is not in the branch history
# we need to configure our repository to have the last release
# commit in the history of the release branch
# List the tags for the commit 1234567
$ git tag --contains 1234567
# If v1.1.0 is not in the list we have to add it with
$ git tag v1.1.0 1234567
$ git push origin v1.1.0
从 package.json 中删除版本
由于semantic-release负责在发布到 npm 之前更新 package.json 的版本,因此我们可以"version": "0.0.0-semantic-release"
在我们的内部进行设置package.json
。
创建 npm 令牌
为了让我们的 GitHub 操作能够将包发布到 npm,我们需要一个npm 身份验证令牌。
登录你的npm帐户,点击个人资料图标,然后选择“访问令牌”。然后点击“生成新令牌” -> “经典令牌”,填写令牌名称(例如) ,从列表中my_token
选择“自动化令牌”,然后点击“生成令牌”。复制令牌并确保不要丢失,因为下一步我们会用到它。
将 npm 令牌添加到 GitHub 的存储库机密中
导航到你的 GitHub 仓库页面,点击“设置”,然后点击“机密和变量” -> “操作”。点击“新建仓库机密”,填写NPM_TOKEN
“名称”,将上一步创建的 npm token 粘贴到“值”字段中,然后点击“添加机密”。
接下来,在左侧菜单中,导航到“操作” -> “常规”向下滚动,然后在“工作流权限”中选择“读写权限”。
就是这样,现在NPM_TOKEN
可以将其用作 GitHub 发布操作中的环境变量。
创建 GitHub 发布操作
让我们创建一个 GitHub 发布操作,该操作将在每次向main
和beta
分支推送提交时运行。如果需要,该beta
分支将用于预发布。
.github/workflows/release.yml
在项目根目录中创建一个包含以下内容的文件。
.github/workflows/release.yml
name: Release
on:
push:
branches: [main, beta]
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Install dependencies
run: npx ci
- name: Install semantic-release extra plugins
run: npm install --save-dev @semantic-release/changelog @semantic-release/git
- name: Lint
run: npm run lint-fix
- name: Test
run: npm run test:unit
- name: Build
run: npm run build
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
这里我们使用 Node.js 版本 20,因为这是 的要求semantic-release
,所以请确保它与您的项目的 Node 版本保持一致。
我们还提供了代码检查、测试和构建的步骤。您可以根据需要删除或更改这些步骤。
重要的部分是Install semantic-release extra plugins
和Release
步骤。
请注意,我们不必安装semantic-release,因为它默认已在 GitHub Actions 中预装。我们只需要
@semantic-release/changelog
和@semantic-release/git
插件。
在操作中Release
你会注意到两个环境变量
-
GITHUB_TOKEN
这是用于向 GitHub 进行身份验证的令牌。这是我们工作流程中自动创建的密钥,semantic-release需要它才能创建 Git 标签。 -
NPM_TOKEN
是我们之前创建并添加到仓库的 npm 身份验证令牌。我们需要它才能将包发布到 npm。
语义发布配置
semantic-release.releaserc
配置可以通过文件、文件release
内部的 keypackage.json
或release.config.js
项目根目录中的文件来设置。我们将使用后者。
release.config.js
module.exports = {
branches: [
'main',
{
name: 'beta',
prerelease: true
}
],
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
[
'@semantic-release/changelog',
{
changelogFile: 'CHANGELOG.md'
}
],
'@semantic-release/npm',
'@semantic-release/github',
[
'@semantic-release/git',
{
assets: ['CHANGELOG.md', 'dist/**'],
message: 'chore(release): set `package.json` to ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}'
}
]
]
}
该branches
属性包含发布应在哪些分支上进行。除了 之外,main
我们还包含一个beta
分支prerelease: true
,这样我们就可以使用分支发布Beta 版本beta
。
在本节中,我们定义了要使用的semantic-release 插件plugins
列表。我们定义的插件已经是semantic-release的一部分,因此我们无需单独安装它们。
-
@semantic-release/commit-analyzer
它通过使用conventional-changelog分析提交来确定我们的 发布类型(例如major
,, ) 。semantic-release默认使用Angular 提交消息约定。minor
patch
-
@semantic-release/release-notes-generator
它为变更日志生成发行说明。 -
@semantic-release/changelog
release-notes-generator
它使用上一步 创建的内容来创建并更新变更日志文件。 -
@semantic-release/npm
它发布 npm 包 -
@semantic-release/github
它发布 GitHub 版本和评论。 -
@semantic-release/git
它将发布工件提交到项目的 Git 仓库。在本例中,我们提交了变更日志文件以及dist
文件夹中的所有文件。我们还定义了发布提交的消息。注意:
[skip ci]
在提交消息中使用是为了不触发新的构建。
使用 commitlint 和 husky 强制执行常规提交
由于semantic-release
使用传统的提交格式来自动化版本控制,我们需要确保存储库中的所有提交都遵循适当的格式。
为此,我们将使用commitlint和husky。
我们将利用husky添加一个 Git 钩子,该钩子使用commitlint在每次提交时检查提交消息是否符合常规提交格式。
安装 commitlint
npm install -D @commitlint/cli @commitlint/config-conventional
将 commitlint 配置文件添加到项目的根目录中commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional']
}
安装 Husky
npm install -D husky
启用 Husky
npx husky init
该命令通过在中创建脚本并在中插入/更新脚本npx husky init
来在项目中设置 husky 。pre-commit
.husky/
prepare
package.json
在创建提交之前,使用commitlint添加一个钩子来检查提交,使用husky的commit-msg
钩子:
echo 'npx --no-install commitlint --edit "$1"' > .husky/commit-msg
准备发布
我们已经在GitHub仓库中完成了semantic-release的设置和配置。从现在开始,我们的提交信息必须遵循约定式提交 (Conventional Commits) 规范。
例如,如果我们的包现在是版本 1.0.0,则提交消息的格式如下:
fix(homepage): fixed image gallery
将版本升级至 1.0.1
feat(logging): added logs for failed signups
将版本升级至 1.1.0
就这些!
semantic-release和GitHub Actions将负责其余工作,确定下一个版本号,生成发行说明并将包发布到 npm。
文章来源:https://dev.to/kouts/automated-versioning-and-package-publishing-using-github-actions-and-semantic-release-1kce