使用 GitHub Actions 和 semantic-release 实现自动版本控制和包发布

2025-06-07

使用 GitHub Actions 和 semantic-release 实现自动版本控制和包发布

当我们开发 JavaScript 包时,每次向 npm 发布新版本时,我们都必须手动完成一系列重复性任务:

  • 更改版本字段package.json
  • 创建新的 Git 标签和 GitHub 版本
  • 执行任何构建步骤来创建发布工件
  • 更新变更日志
  • 发布到 npm

如果我们可以自动化所有这些任务,那不是很好吗?
GitHub Actionssemantic-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
Enter fullscreen mode Exit fullscreen mode

从 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 发布操作,该操作将在每次向mainbeta分支推送提交时运行。如果需要,该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
Enter fullscreen mode Exit fullscreen mode

这里我们使用 Node.js 版本 20,因为这是 的要求semantic-release,所以请确保它与您的项目的 Node 版本保持一致。
我们还提供了代码检查、测试和构建的步骤。您可以根据需要删除或更改这些步骤。

重要的部分是Install semantic-release extra pluginsRelease步骤。

请注意,我们不必安装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.jsonrelease.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}'
      }
    ]
  ]
}
Enter fullscreen mode Exit fullscreen mode

branches属性包含发布应在哪些分支上进行。除了 之外,main我们还包含一个beta分支prerelease: true,这样我们就可以使用分支发布Beta 版本beta

在本节中,我们定义了要使用的semantic-release 插件plugins列表。我们定义的插件已经是semantic-release的一部分,因此我们无需单独安装它们。

  • @semantic-release/commit-analyzer
    它通过使用conventional-changelog分析提交来确定我们 发布类型(例如major,, ) semantic-release默认使用Angular 提交消息约定。minorpatch

  • @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使用传统的提交格式来自动化版本控制,我们需要确保存储库中的所有提交都遵循适当的格式。

为此,我们将使用commitlinthusky
我们将利用husky添加一个 Git 钩子,该钩子使用commitlint在每次提交时检查提交消息是否符合常规提交格式。

安装 commitlint

npm install -D @commitlint/cli @commitlint/config-conventional
Enter fullscreen mode Exit fullscreen mode

将 commitlint 配置文件添加到项目的根目录中
commitlint.config.js

module.exports = {
  extends: ['@commitlint/config-conventional']
}
Enter fullscreen mode Exit fullscreen mode

安装 Husky

npm install -D husky
Enter fullscreen mode Exit fullscreen mode

启用 Husky

npx husky init
Enter fullscreen mode Exit fullscreen mode

该命令通过在中创建脚本并在中插入/更新脚本npx husky init来在项目中设置 husky pre-commit.husky/preparepackage.json

在创建提交之前,使用commitlint添加一个钩子来检查提交,使用huskycommit-msg钩子:

echo 'npx --no-install commitlint --edit "$1"' > .husky/commit-msg
Enter fullscreen mode Exit fullscreen mode

准备发布

我们已经在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-releaseGitHub Actions将负责其余工作,确定下一个版本号,生成发行说明并将包发布到 npm。

文章来源:https://dev.to/kouts/automated-versioning-and-package-publishing-using-github-actions-and-semantic-release-1kce
PREV
保护 React Native 应用程序
NEXT
书籍与在线课程