2.3 CI平台:CircleCI
在本节中,你将配置CircleCI,在发票应用发生变更时,它将执行测试并构建Docker容器镜像。本节示例是针对CircleCI的,但使用CI平台测试和构建应用的思路是通用的,可以轻松地在其他CI平台上复制。
代码仓库和像GitHub和CircleCI这样的CI平台实现了叫作网络钩子(webhook)的概念,它用来传递通知。当代码仓库发生变更时,webhook会将通知推送到一个由CI平台托管的网络地址上。通知的正文包含了关于变更的信息,CI平台需要这些信息来执行任务。
当你用GitHub账户登录CircleCI之后,CircleCI会请求你允许它代表你在GitHub账户中执行操作。其中的一个操作就是在发票应用的GitHub代码仓库中设置一个webhook,将新发生的事件通知给CircleCI。图2.2就是GitHub中自动设置好的webhook配置。
图2.2 GitHub和CircleCI之间的webhook会在发票应用的代码仓库中自动创建,在变更被应用时触发软件构建。
图2.1中的步骤(2)和步骤(4)都要使用webhook。每当GitHub要将变更告知CircleCI的时候,它就会向GitHub网站的CircleCI主页(链接2.4)发送一个通知。CircleCI接收通知并触发一次发票应用的构建。webhook的简单性让它流行于不同实体运维的接口服务中。
安全提示
GitHub拥有复杂的权限模型,允许用户将细粒度的权限委托给第三方应用。然而,CI平台需要一个用户对所有代码仓库的读写访问权限。在第6章中,我们将讨论如何使用低权限账户并控制对仓库的访问,而不是使用你自己的高权限用户来集成CI平台。
图2.3中的config.yml文件放在应用代码仓库里。它采用了YAML格式,并配置了CI环境来执行一些特定的任务,GitHub记录的每次变更都要执行这些任务。更具体地说,你要设置CircleCI,让它测试并编译发票应用,然后构建和发布Docker容器镜像,随后该镜像会被部署到AWS环境中。
图2.3 CircleCI的配置存放在应用代码仓库中的.circleci目录下。
注意 YAML是一种常见的用来配置应用的数据序列化语言。和JSON、XML等格式相比,YAML的优势在于更容易被人理解。
接下来展示的是完整的CircleCI配置文件。你可能注意到了,文件中有些部分是命令行操作,而有些部分是CircleCI的专用参数。大多数CI平台都允许运维人员列出命令行操作,这使得它们非常适合于运行自定义任务。
文件中的某些部分可能比较晦涩,尤其是Docker和Go的部分。我们稍后再来解释这部分内容,现在暂且忽略它们,先聚焦在这份配置文件背后的概念上。如你所见,以上代码清单中的语法是声明式的,就像是我们在编写执行这些操作的shell脚本一样。
配置文件必须放在代码仓库中。如果该文件存在,那么CircleCI在收到来自GitHub的webhook通知后,将按照文件中的指令执行操作。要想触发流水线的第一次运行,只用将代码清单2.1中的配置文件添加到Git仓库的一个特性分支中,并将该分支推送到GitHub即可。
要让CircleCI运行在config.yml中定义的测试,只用创建一个拉取请求(Pull Request),将特性分支中的补丁合并到master分支。
什么是拉取请求?
“拉取请求”是一个由GitHub推广出来的术语,它代表了这样一个请求:把来自一个特定分支的变更拉取到另一个分支上,通常是从特性分支拉取到master分支。当开发人员提交一个补丁供评审时,拉取请求就会创建。拉取请求将触发在CI中执行自动化测试的webhook(图2.1中的步骤(2)),而其他开发人员在同意合并拉取请求之前要先对提出的补丁进行评审(图2.1中的步骤(3))。
图2.4展示的是CircleCI中待测试的GitHub拉取请求的用户界面。CircleCI获取一份特性分支的副本,读取config.yml中的配置,并按照完整的步骤构建和测试应用。
图2.4 GitHub推送请求的Web界面显示了CircleCI中测试正在运行的状态。正在运行的测试表示为黄色;如果CircleCI成功执行完测试,界面就会变成绿色;如果发生错误则会变成红色。
注意,按照你的配置,只有作为go test命令一部分运行的单元测试才会被执行。只有当拉取请求被接受并且代码被合并到master分支之后,配置中的deploy部分才会被执行。
现在,我们假设评审人员对这些变更满意,并批准了这次拉取请求,完成了流水线中的步骤(3)。补丁被合并到了master分支,并且流水线进入了图2.1中的步骤(4)和步骤(5)。CircleCI将再次运行,这次执行的是部署部分,即构建一个应用的Docker容器镜像并推送到Docker Hub。