semantic-release 是一个自动化版本控制和发布管理的工具,主要用于 JavaScript 项目。它通过分析提交信息来确定版本号的更新,并自动生成发布日志、创建 Git 标签和发布到 npm 等平台。

  • 重新整理几种情况工作流及其典型配置,并在 GitHub 上验证,整理成一个 semantic-release 的教学 repo 发布(semantic-release-workflows),附带示例 ➕ 2025-07-10
    • 源码或相关构建文件中是否有地方需要更新版本号为将语义版本号
      • 典型的如有的 python 工具的主脚本顶端会有 __version__ = "1.0.0" 这种字样
      • 有的项目配置文件中有对项目版本号的定义,如 CMakeLists.txt, conanfile.py 等
    • 发布的目标是 GitHub/GitLab Release,还是其他第三方包管理平台(如)
    • 是否构建复杂(是单平台构建、多平台构建、跨平台构建等)

验证 semantic-release dry-run + 条件构建方案

多平台构建场景下,先 dry-run 获取版本号再条件触发构建的方案尚未实际验证。 - 或者另一种方案, 设置 release 分支一个 .releaserc.yml, tag 另一个 .releaserc.tag.yml, …

有些乱… 感觉可以参考参考其他发布多平台工具的仓库的做法 (实际基本非 nodejs 仓库都会自己构建发布脚本)

关于 semantic-release 在完整 ci 链中的一些思考:

感觉 semantic-release 官方还是有点太固执了,连一个指定配置文件的 —config 参数的功能都不愿意加…

emm… 散了吧, semantic-release 只是对 npm 包项目适配得比较好


工作流

基于 semantic-release 的代码开发 CI 工作流:

  1. dev 分支开发
  2. 代码 push/merge 到 release 分支(如 main,master,release/xxx)
  3. semantic-release 检索 commit,判断是否需要更新版本,如是,更新 CHANGLOG.md 以及其他可能需要改动的地方(如源码或配置文件中定义的版本号),并将改动 push 到 release 分支,触发下一步,否则,结束
  4. semantic-release-bot 推送代码的同时会打一个 tag,在 tag 的 ci 中触发 Release 版本的构建,并由 semantic-release 发布(通过 @semantic-release/github@semantic-release/gitlab

项目一般要配置两个文件: Semantic-Release 配置文件(一般是 .releaserc.yml) 和 CI 配置文件。

示例(非 nodejs 项目)

示例:winguake (笔者的一个小项目),其两个配置文件分别为:

branches:
  - main
  - master
plugins:
  - "@semantic-release/commit-analyzer"
  - "@semantic-release/release-notes-generator"
  - - "@semantic-release/changelog"
    - changelogFile: CHANGELOG.md
  - - "@semantic-release/exec"
    - prepareCmd: |
        powershell -File .\.prepare.ps1 ${nextRelease.version}
  - - "@semantic-release/git"
    - assets:
        - CHANGELOG.md
        - winguake.ahk
      message: |-
        chore(release): ${nextRelease.version} [skip ci]
 
        ${nextRelease.notes}
  - - "@semantic-release/github"
    - assets:
        - bin/winguake_*.exe
        - winguake.ahk
 
name: Build and Release winguake
 
on:
  push:
    branches:
      - main
      - master
  workflow_dispatch:
 
permissions:
  contents: write
 
jobs:
  build:
    runs-on: windows-latest
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # semantic-release 需要完整的 git 历史
 
      # If semantic-release decides to release, it will build package by running .prepare.ps1 in plugin @semantic-release/exec.
      - name: Semantic Release
        uses: cycjimmy/semantic-release-action@v4
        with:
          # semantic-release 需额外安装的插件
          extra_plugins: |
            @semantic-release/changelog
            @semantic-release/git
            @semantic-release/exec
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CI 很简单,就只有执行 semantic-release 一个 action,里面做了什么可在 .releaserc.yml 中查看。

  • 前两个插件 @semantic-release/commit-analyzer@semantic-release/release-notes-generator 是基本固定的,用于分析语义版本号以及改动汇总
  • @semantic-release/clanglog 用于生成或更新 changlog,可选
  • @semantic-release/exec 执行用于自定义命令,这里执行的是自己定义的构建脚本,里面包含了包的构建过程
    • 之所以构建过程放在这里,是因为需要用到前面分析得到的语义版本号, 需要将该版本号更新到源码中,然后才能执行构建
      • 如果不需要对源码或需包含进发行包的文件进行修改,则可将构建工作放在 semantic-release action 之前
    • 因为该项目发布的目标是 GitHub Release 页面,需要在 semantic-release 的 @semantic-release/github 执行前就构筑好发行包,因此只能将构建工作放在 exec 插件中
      • 如果发布的目标不是 GitHub Release,而是第三方包管理库(如 python 包,nodejs 包),则构建和发布完全可以放 semantic-release action 之后,此时 GitHub Release 页面仅会有源码压缩包。

示例(nodejs 项目)

semantic-release-action