CI/CD 作为敏捷软件开发流程一部分的好处

持续集成(CI)是每天多次集成代码的实践。为了支持这种做法,有必要使用像 Git 这样的现代版本控制系统(VCS),该系统支持单个版本库中的多个工作状态(分支),以便让开发人员能够独立处理代码,同时还允许他们进行协作并安全地集成他们的变更。

为了增强 VCS 的能力,人们创建了围绕版本库的托管和协作工具(如 GitLab 或 GitHub),允许开发人员通过网络用户界面(UI)更高效地查看和管理代码变更。

作为这些托管平台及其提供的协作工具的一部分或补充,自动检查对于在集成前、集成中和集成后保持对代码质量的高度信心至关重要。采用 CI 方法通常需要包括额外的代码质量步骤,如单元或集成测试、覆盖率检查,以及每次集成新代码时在主线分支(集成变更的分支)上构建工件。

团队在使用 Git 进行代码协作和 CI 时所遵循的约定称为 Git 工作流,通常简称为 Git 流程。

Git 流程会规定分支的命名规则,以及整合变更的方式和时间。例如,一个团队可能会决定,分支的前缀应该是票据编号,然后是简短的破折号描述,如 WRK-2334-fix-ie-11-scroll。

在 Git 流程中需要决定并遵守的约定还有提交信息的长度和标题、应该通过或允许失败的自动检查,以及合并变更请求(在 GitHub 和 GitLab 术语中分别是拉取请求或合并请求)所需的审核人数。

Git 流程大致分为两类:基于主干的开发和基于(特性)分支的开发。我们将首先介绍基于分支的开发,因为它的局限性已经非常明显,而且大多数项目都倾向于使用基于主干的开发。

在基于分支的 Git 工作流程中,仓库中会保留多个工作分支。基于分支的流程可以用来保留反映环境状态的分支。

例如,下图显示了三个分支—​生产(production)、暂存(staging)和开发(develop)。生产分支不包含暂存和开发分支的任何改动。暂存分支在生产分支之前,但除了生产分支上的改动外,暂存分支与开发分支没有任何共同改动。开发分支在暂存分支和生产分支之前:它与暂存分支在同一提交时从生产分支分支出来,但它与暂存分支没有任何共同提交:

image 2023 10 17 18 18 12 755
Figure 1. Figure 14.1: An example of a branch-based Git commit/branch tree with three environment branches

基于分支的工作流程还可用于跟踪发布线中的更改。当项目必须维护应用程序或库的两个版本,但需要对两个版本应用错误修复或安全补丁时,这非常有用。

在下面的示例中,我们有一个与环境分支类似的分支示例。 版本 1.0.0 包含一些 1.0.1 和 1.1.0 中没有的更改,但不共享任何较新的代码。 版本 1.0.1 和 1.1.0 同时从 1.0.0 分支出来,但它们不共享进一步的更改:

image 2023 10 17 18 20 16 568
Figure 2. Figure 14.2: An example of a branch-based Git commit/branch tree with three release branches

在基于主干的 Git 流程中,团队的每个成员都会从单个分支(通常是 “主” 分支)创建新分支。这个过程通常被称为 “分支”:

image 2023 10 17 18 51 16 509
Figure 3. Figure 14.3: A sample trunk-based Git commit/branch tree with two feature branches branched off of the master

基于主干的工作流程的一个极端情况是拥有一个每个人都提交的分支。

在基于主干的环境中,“发布分支” 的替代方法是使用 Git 标签来跟踪发布快照。这提供了与维护分支相同的优点,同时减少了分支噪声,并且具有不变性的额外好处,因为标签一旦创建就无法更改。

持续交付 (CD) 是团队将每个良好构建部署到生产环境的能力。

CD 的先决条件是 CI,因为 CI 提供了对构建质量的一些初步信心。作为 CD 的一部分,CI 之外还需要新的系统、工具和实践。

请参阅下图,了解与 CI 相关更多的工具和实践以及与 CD 相关更多的工具和实践:

image 2023 10 17 18 53 30 267
Figure 4. Figure 14.4: The relationship between CI and CD practices

采用 CD 所需的额外要素是对应用程序是否能按预期运行(对最终用户而言)以及是否在不知不觉中引入了新缺陷的高度信心。这意味着在 CI 检查期间或之后需要额外的端到端测试步骤,以便在部署之前验证构建。这

些端到端测试可以手动进行,也可以自动进行。在理想的 CD 设置中,后者(自动化端到端测试)是首选,因为这意味着部署不需要人工交互。如果端到端测试通过,就可以自动部署构建。

为了促进 CD,必须重新考虑用于部署软件的系统。作为 CD 的一部分,部署不能是一个冗长的手动过程。这促使企业采用云原生技术(如 Docker)和基础设施即代码工具(如 HashiCorp 的 Terraform)。

对 CD 实践的重视导致了 GitOps 和 ChatOps 等理念的诞生。

在 GitOps 和 ChatOps 中,部署和运营任务由开发人员和利益相关者日常使用的工具驱动。

在 GitOps 中,部署可以通过 GitHub/GitLab(或其它 Git 托管服务提供商)、直接使用 GitHub Actions 或 GitLab CI/CD,或通过与 GitHub/GitLab 紧密集成并提供报告的 CI/CD 软件(如 CircleCI 或 Jenkins)来完成。

就 ChatOps 而言,对话界面用于部署和操作软件。某些类型的 ChatOps 可被视为 GitOps 的子集,例如,通过对 GitHub 拉取请求的评论与 Dependabot(一种保持项目依赖关系最新的工具)等工具进行交互。ChatOps 也可以直接应用于实时聊天工具,如 Slack 或 Microsoft Teams。有人可能会发送一条消息,如 deploy <service-name> <environment>,这将把服务部署到相关的环境中。请注意,聊天界面很容易让人联想到命令行界面,开发人员可能已经习惯了这种界面,但其它利益相关者可能还需要一些时间来适应。

我们现在已经了解了 CI 和 CD 的方法,接下来我们将讨论使用 CI 和 CD 的优势:

Table 1. Figure 14.5: Advantages of CI and CD
持续集成 持续交付

确保整合的变更集很小(最多几天的工作量)。

可以更频繁、更安全地为生产创造价值。

减少对整个代码库进行大刀阔斧的修改而导致不可预见的错误的可能性。

一个小的变更集(几天的工作量)可以顺利回滚。

测试、代码质量和审查步骤让人对整洁的集成充满信心。

由于较长的固定(每月、每周、每次冲刺)发布周期(而不是 CD)而产生的较大的变更集可能会产生不可预见的后果;回滚对大型发布的影响非常复杂或难以把握。

这两种做法也会对团队的心态和绩效产生影响。能够看到您在一天内集成并在不到一周的时间内投入生产的更改意味着贡献者可以立即看到他们的工作产生影响。

CI/CD 还有助于促进敏捷原则,其中迭代地应用和部署变更。 这与项目的长期时间表相反,项目的时间表很长,估算的不准确会加剧并可能导致严重的延误。