fyang 的博客

首页 文章

Devops实践——语义化版本发布

前言

本文我将介绍 Semantic Release,并提供一个例子来演示如何在实际的项目中使用它。

什么是语义化版本发布

在项目实践中我们通常需要对软件进行版本管理,良好的版本管理是项目长期稳定维护的基石。在现代版本管理中我们通畅会遵循 semver 规范,即软件版本号遵循 MAJOR.MINOR.PATCH 模式。

其中:

MAJOR 为主版本号,通常表示软件发生了不兼容的更新(迭代),比如 2.x.x 版本删除了 1.x.x 版本中某项功能

MINOR 为次版本号,用来表示我们的软件是向后兼容的,比如 1.1.x 版本中的某项功能在 1.2.x 版本中依然保持不变(至少对外接口和功能不变)。

PATCH 为补丁版本号,表示对当前版本的某项功能修复,比如 1.1.2 版本修复了 1.1.1 版本中某项功能的缺陷。

规范化的版本管理在外部对接是非常关键的,通过语义化的版本迭代,能够清楚的表达项目版本存在哪些重大变更,给下游依赖以明确的信息暗示。

Semantic Release 则是对 semver 规范的一次实践,通过 Semantic Release 的配置,我们能够轻松的把版本管理整合进我们的 Devops 流程中,开发人员只需要遵循一定的规范提交commit 即可,无需进行手动的版本管理。

比如以下一些 commit 信息:

  • feat: support user account creation 表示我们的项目发布了一个创建账户的新功能,则项目的 MINOR 版本会自动升级
  • fix: fixed a bug that halt the machine 表示我们修复了一个导致死机的 BUG ,则项目的 PATCH 版本会自动升级
  • chore: rewrite some configuration 表示我们修改了一些项目配置,不影响版本迭代

更多规范请参考 Semantic Release 文档

在规范化的 commitSemantic Release 会自动进行版本管理,以及生成对应版本的 CHANGELOG,而开发人员只需要关注项目内容即可。

为什么要使用语义化版本发布

首先,在软件工程的实践中我们通常会遵循一定的开发约定(规范),模式化的信息通常能够嵌入部分语义到现有数据结构中,从而在我们review时给以暗示,而不是频繁的沟通。

而语义化版本发布同样也是利用了这一部分信息,使得我们的开发流程尽可能的通畅,只要我们遵循一定的约定,那么就可以把这一部分模式交给机器处理,减少人为干预,这在 Devops 实践中是很重要的。

项目实践

接下来我将通过一个 rust 项目来演示如何配置 Semantic Release 并整合到 Github Actions 中,完成自动版本发布。

环境依赖

  • Docker
  • 任意编辑器
  • Github 账号

构建项目

我们先创建一个 rust 项目:

docker run --rm --workdir=/app --user=$UID -v.:/app rust cargo new semantic-release-rs-demo

我们使用容器初始化 rust 项目,无需本地安装 rust 工具链

然后在项目下创建 .releaserc.yaml 文件,内容如下:

branches:
    - release
plugins:
    - '@semantic-release/commit-analyzer' # semantic release 内置插件
    - '@semantic-release/release-notes-generator' # semantic release 内置插件
    - '@semantic-release/github' # github 版本发布集成插件,可以自动生成github 的 release 内容

配置文件中声明了我们的 release 分支,并声明了一些必要的插件

注:该项目假设开发分支为main, 版本发布分支为release,可以根据实际情况配置

创建.github/workflows/release.yaml,并添加如下内容:

name: Release Action
run-name: ${{ github.actor }} is releasing out Action
on: 
  push:
    branches: 
      - release
jobs:
  Semantic-Release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      issues: write
      pull-requests: write
    steps:
      - name: Check out repository code
        uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Release
        env: 
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
        run: npx semantic-release@23

注:关于 Github Actions 的内容我会在其他文章介绍,读者也可以参照 官方文档

以上配置的大致功能为,当有代码 pushrelease 分支时,会在虚拟机中自动执行下步骤:

  • clone 当前分支代码
  • 安装 nodejs 运行环境(semantic release 依赖)
  • 执行 semantic release 生成 release tag 以及对应的CHANGELOG

在上传到 Github 之后最终结果执行结果如下: semantic release result

结尾

每个项目都有自己的版本管理约定,我认为我们应该思考的是如何更高效的进行版本管理,以及在流程上尽可能减少人为干预,DO NOT REPEAT! 我想这正是 Devops 的核心理念之一。

Semantic Release 更多的内容和配置需要读者自行查阅。

关于 容器化 以及 Devops 我有一个 演示案例,大家有兴趣可以看看。

参考文档