快速!怎么用发布自动化方案

573 阅读9分钟

当我们继续通过DevOps、CIOps和GitOps提高生产力时,我们不仅要实现编译和测试的自动化,还要实现发布的自动化。 因为我们发布的时候很多工作需要做,而且不是很频繁,所以每次都会有提醒和错误。

特别是,做更新记录是一项复杂的、对用户影响很大的任务,因此,将其自动化可以对提高文件的质量和发布的频率做出重大贡献。 在这篇文章中,我想通过介绍我在Node/Java社区看到的发布自动化技术。

本文中的术语 "发布" 是指将构建工件(如jar文件或容器镜像)上传到仓库或GitHub Releases,并将其提供给其他项目或环境。"发布" 与 "部署" 不一样。

在你实现自动化之前

1. 考虑更新记录的要求

描述对一个软件版本所做更新记录被称为Changelog或Release Note。 有些机构对Changelog和Release Note赋予了不同的含义,但为了介绍多个社区的自动化技术,本文将不对它们进行区分。

更新记录有一个众所周知的格式,叫做Keep a Changelog。 许多自动化系统都知道这种格式,所以如果你对它没有问题,我们就会使用它。

更新日志最常见的OSS位置是在项目根目录下的文本文件中,如 CHANGELOG.md,或在GitHub Releases的正文中。Dependabot和其他依赖管理方法使用GitHub Releases,所以如果有选择的话,最好是使用GitHub Releases。当然,你也可以把GitHub Releases与文本文件结合起来使用,或者考虑其他方法,如GitHub Pages、维基或聊天工具。

在Java社区,交付物的校验和也可以包括在更新日志中。 这有助于用户验证交付物的完整性。参考资料:

选择一种自动化方法

1. Release Drafter

Release Drafter是一个GitHub Actions。 它几乎可以用于任何使用PR(Pull Request)开发的项目,甚至可以用于Maven等历史悠久的项目

我们更新该分支的时候,Release Drafter会做个GitHub Release草案。 这GitHub Releases草案的主体包含了更新记录,所以我们可以在发表草案之前审查更新记录。

为了使用标签分类PR,你要确保标签适用于所有的PR,你可能用autolabeler标签管理系统。

2. GitHub Releases

GitHub Releases本身具有根据PR生成更新记录的能力。你不需要配置任何东西来使用这个功能,所以尝试一下很有用:

Automatically generated release notes - GitHub Docs

为了使用标签分类PR,你要确保标签适用于所有的PR,你可能要考虑一个自动化的标签管理系统,如actions/labeler。它主要有两种可能的用途:

  1. 这是一种基于GitHub Releases的发布方法,你可以用浏览器在创建Release时直观地检查GUI中生成的更新记录。工作流程是,构建工件→上传工件到GitHub Release→并发布GitHub Release。

  2. 这是一种使用CLI的自动化方法。工作流程是,用GitHub Actions构建工件→为标签起草GitHub Release→上传工件到GitHub Release→并发布GitHub Release。GitHub Actions通常是由一个标签或推送到一个发布分支来触发的。

与其他自动化方法相比,版本不是自动确定的,但这可以作为一个优势,因为它使采用SemVer以外的版本政策(如CalVer)更加容易。

3. semantic-release

这是一种根据提交信息自动执行发布的机制。每次推送到默认分支或发布分支都会触发发布。假设使用SemVer2Conventional Commits

semantic-release - Fully automated version management and package publishing

它的特点是灵活配置和自动化的结合,无需人工干预。毕竟,你看,这是它的标志:

spaces_-LGsE7zdvzHI5cG-XV6p-887967055_uploads_git-blob-acfbb3069a10929a23a54018da020462722b928a_bender.png

例如,生产要求每个开发人员遵循Conventional Commits,但你可以使用commitizen来降低采用的门槛,commitlint来验证提交时的提交信息格式。您还可以使用semantic-pull-requests,在您的提交信息不符合格式的情况下让GitHub Checks失败。你也可以压制合并你的PR,把对提交信息的决定推迟到合并时间。

可共享的配置允许在多个存储库中对项目进行一致的配置。并且可以通过插件机制进行扩展。所以这对一些较大的组织来说可能是有用的。

要使用它,只需将npx semantic-release嵌入到你的构建工作流程中。当semantic-release根据分支名称和其他信息确定需要进行发布时,它将自动生成并发布更新记录。发布可以使用npm publish./gradlew publish,所以现有的发布程序可以被连续使用。

semantic-release本身是在CI环境中运行的,因此不需要将Node.JS放在开发者手中。但是上述的相关工具,例如commitizen、commitlint和husky,大多是由Node.JS社区管理和维护的,因此你可以决定将Node.JS包括在内。对于为Node.JS以外的环境开发的项目来说,这可能会使项目设置更加复杂。

semantic-release类似的还有standard-versionrelease-it。我喜欢semantic-release,尊重并赞助它背后的人。 我在几个开放源码软件项目中使用了它,比如spotbugs-gradle-plugin,它对我来说效果很好。

4. changesets

这是一个来自Atlassian的专门针对monorepo的机制。如果你用Node.JS开发monorepo,你可能要考虑它,但我还没有试过。

changesets - A way to manage your versioning and changelogs with a focus on monorepos

5. JReleaser

它是一种与JVM而不是Node.JS一起工作的机制。 与其他机制相比,它还很年轻,但它已经有了Maven和Gradle的支持。

JReleaser

jreleaser-tools.png

从我在快速入门中看到的情况来看,它似乎有自己的发布配置,而不是maven-publish插件。 这就与semantic-release不一样,semantic-release./gradlew publish或者npm publish的配置。这是一个维护成本较高的选择,因为JReleaser需要自己跟上社区的进度。 就我个人而言,我很期待,但我必须拭目以待。

发布自动化后

1. 仍有手工作业的领域

除了更新记录之外,其他文件仍然需要手动创建。 这些措施包括:

  • 向终端用户解释变化的文件
  • 从以前主要版本到新主要版本的迁移指南
  • 手册、新闻、等等

通过Slack等发出的通知可以自动化,但如果你正在创建精心设计的文本,那也会保持。

然而,这些文件和通知在补丁发布期间不应经常创建,我们期望自动化将足以使补丁发布更快、更稳定、更频繁。

2. 适合发布自动化的项目结构

对CI和发布自动化的推动使得需要人工干预的项目更难建立和发布。 例如,你必须手工下载库,或者改写版本号的项目结构。

幸运的是,在Java世界里,你可以从Maven中心下载大部分库。 以前不会被下载的库,如Oracle JDBC driver,也现在可以下载。

如果你想使用Maven Central或其他公共仓库中没有的库,你会管理自己的Maven Private Repository并把它放在那里。

你需要能够自动更新版本号。 在某些情况下,这里介绍的机制支持这种做法,或者你可以使用Maven Release Plugin等功能。 构建工具配置之外的文件,如META-INF/MANIFEST.MF中的Bundle-Version,应该由构建工具自动生成,而不是手动。

3. 适合发布自动化的分支策略

发布自动化通常假定默认分支或发布分支 "始终可来发布"。应尽可能地遵循这一点。

如果该分支并不是可发布的,那么在发布之前就必须由人去验证该分支是否可发布。自动化的最初目的是为了减少人类的参与,提高发布的稳定性和频率,所以在这个过程中增加人类的干预是一个错误。至少,可发布性验证的过程应该自动化,以便在合并前或发布构建中自动完成。

需要注意的是,【一个项目在被合并后才发布】的意思不是【不应该合并它,直到它完成】。 这是因为主题分支的寿命越短,对发展效率的影响就越大。 你可能需要使用Feature Toggle来避免公开那些你知道不会被公开的修改,并更频繁地合并修改。

总结

在这篇文章中,作者介绍了一些我们在Node/Java社区经常看到的发布自动化技术。

自动化技术特点注意点
Release Drafter只要你使用PR,无论何种语言或构建工具都可以使用。它只生成更新记录,发布过程本身需要单独完成。
GitHub Releases不需要配置。根据标签对PR进行分类,并将其反映在更新记录中。你需要自己决定版本号。它只生成更新记录,发布过程本身需要单独完成。
semantic-release灵活的可扩展性与彻底的自动化相结合。需要最新的LTS版本的Node.JS来运行。不支持monorepo。
changesets支持monorepo。专注于Node.JS项目。
JReleaser与Maven和Gradle等构建工具集成。专注于JVM项目。

发布自动化是一个强大的机制,可以提高发布的稳定性和频率。 其中一些需要审查,如更新记录、提交注释、分支策略和发布验证自动化,但大多数也被认为有助于提高开发效率和生产力,所以为什么不考虑它们来改善你的开发经验呢?