Github Action Day2:矩阵工作流(Matrix Workflows)

这是我的 Github Action Advent Calendar 的第二天的内容,如果您想要了解更多已经发布的 tips 信息,查看此处的 索引

拥有一个 CI/CD 系统的最大优势之一是它可以让你高效地构建(build)以及测试 (test)多种不同的配置。在推送到远程仓库之前,在本机电脑上构建(build)以及测试(test)当然是必要的,但是这远远不够。毕竟你电脑或许只有一个版本节点,代表一种平台运行环境,但是,如果能在多种平台上构建(build)的话,这将使你对你所支持的所有生态系统中的更改具有信心和洞察力。

Translate Note:

对于一个成熟的应用软件,应该能适用于多种不同的环境,如适用于Windows、Linux、MacOS三种不同的系统环境,软件开发中,某个小软件的版本或者发行者不同都会影响软件的运行环境。我们在每种环境下 build && test 是我们写代码绕不开的操作。

此外,此文中提到的多种配置 = 不同的构建/测试环境

Mozilla Tinderbox 是最早引入 基于多种配置的构建方式 这一理念的 CI 系统之一。它具有革命性,而且当我在 AbiWord 工作时,我负责 Tinderbox 的开发。我们拥有一个实验室,里面有许多的机器供我们测试 Motif 的构建 和 GTK 的构建,也可以供我们反复测试不同的依赖(大约是在将可怕的 libc5 迁移到 libc6的时候),甚至是不同的 C++编译器。

当时,我大部分的工作都是在维护这个充满昂贵电脑的实验室。所以,我最喜欢Github Action 的一部分功能就是矩阵工作流(matrix workflows),它可以让我快速地运行多个构建来支持各种各样的配置。

我依然在本机电脑上编写代码,所以我需要处理在不同的编译器以及依赖上构建的问题。但是现在我不需要一个充满机器的实验室了,我可以直接使用 Github Actions 中的矩阵工作流(matrix workflow)设置。

矩阵工作流(matrix workflows)乍一看起来有点庞大,但其实它仅仅只是简单的变量替换而已。你定义了一组的变量,以及一组应该分配给每个变量的值。之后,Github Actions 就会执行一个包含这些变量的所有不同扩展的工作流。

Translate Note:

更多关于 matrix 的用法,请参照以下链接:

GitHub Actions 的工作流程语法-strategy - GitHub Docs

这样的功能极度振奋人心,我们以三个待测试的不同变量为例。在我的例子中,我想要测试他们在两种不同的C语言编译器(gccclang),三种不同 SSL 后端(OpenSSLGnuTLSNSS),以及两种不同的 Kerberos后端(MITHeimdal)的情况。为了测试这些环境所有的不同组合,总共需要 2 * 3 * 2 = 12 种不同的配置。

相对于去定义 12 种不同的 job,或者从更坏方面说,就像以前一样在实验室配置 12 种不同的机器 —— 我只需指定一个拥有三个变量的 matrix。如果我在一个 job 中指定一个 matrix,实际上我就可以得到 12 种不同排列的任务:

matrix:
cc: [gcc, clang]
curl: [openssl, gnutls, nss]
kerberos: [libkrb5, heimdal]

现在在我的 job 中,我就可以使用 矩阵上下文对象 直接引用其中的每个变量,例如,${{matrix.cc}} 得到变量 cc 的当前值。

一个工作流实例:安装每个上述的每个依赖并运行我的自动配置,然后运行 make

Translate Note:

上方的注释段是原作者项目中要用到的,我们可以忽略。

当你运行这个 工作流(workflow),你可以很快看到它如何扩展为12个不同的 job 。在工作流运行的的左边,你可以看到所有的 job。因此,这个简单的工作流可以快速地扩展。

事实上,当你打开某个 runs 的步骤,可以看到我们可以安装自己依赖。如果我打开构建(build)(clangopenssllibkrb5)任务(job);实际上,我正在运行 clang(由${{CC}} --version 显示), libcurlOpenSSL 版本(由 curl-config 显示 )以及 MIT krb5 (由 krb5-config 表示):

image-20210805210154867

所以,你可以看到,只需在工作流种使用矩阵定义的几行代码,就可以构建拥有多种配置的强大工作流.

GitHub Actions 的工作流程语法-strategy - GitHub Docs