

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 了解 CI/CD
<a name="understanding-cicd"></a>

持续集成和持续交付（CI/CD）是自动执行软件发布生命周期的过程。在某些情况下，CI/CD 中的 *D* 也可以表示*部署*。*持续交付*和*持续部署*之间的区别体现在发布对生产环境的变更时。对于持续交付，在推动对生产环境的变更之前需要手动批准。持续部署的特点是可以不间断地贯穿整个管线，不需要显式批准。由于此策略讨论的是通用 CI/CD 概念，因此所提供的建议和信息适用于持续交付和持续部署两种方法。

对于传统上需要手动完成的将新代码从提交到投入生产的流程，CI/CD 可以自动执行该手动流程的大部分或全部。CI/CD 管线包括源代码、构建测试、暂存和生产阶段。在每个阶段，CI/CD 管线都会预调配部署或测试代码所需的任何基础设施。通过使用 CI/CD 管线，开发团队可以对代码进行更改，然后进行自动测试并推送到部署。

让我们回顾一下基本的 CI/CD 流程，然后再讨论一些有意或无意地偏离完全 CI/CD 的方法。下图显示 CI/CD 阶段和每个阶段的活动。



![\[CI/CD 流程的五个阶段以及每个阶段的活动和环境。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/strategy-cicd-litmus/images/cicd-stages.png)


## 关于持续集成
<a name="about-continuous-integration"></a>

持续集成在代码存储库中进行，例如 GitHub 中的 Git 存储库。您将一个主分支视为代码库的真实来源，为功能开发创建短期分支。当您准备好将功能部署到上层环境时，可以将该功能分支集成到主分支中。功能分支永远不会直接部署到上层环境。有关更多信息，请参阅本指南中的[基于主干的方法](fully-cicd-process-differences.md#trunk-based-approach)。

*持续集成流程*

1. 开发人员从主分支创建一个新分支。

1. 开发人员在本地进行更改、构建和测试。

1. 更改准备就绪后，开发人员会创建一个以主分支为目标的[拉取请求](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests)（GitHub 文档）。

1. 代码将进行审查。

1. 当代码获得批准后，其会合并到主分支中。

## 关于持续交付
<a name="about-continuous-delivery"></a>

持续交付在开发环境和生产环境等隔离环境中进行。每种环境中进行的操作可能有所不同。通常，第一个阶段之一用于对管线本身进行更新，然后再继续。部署的最终结果是，每个环境均更新为最新的更改。用于构建和测试的开发环境的数量也各不相同，但我们建议您使用至少两个。在管线中，每个环境都按其重要性顺序进行更新，最后更新最重要的环境，即生产环境。

*持续交付流程*

管线的持续交付部分通过以下方式启动：从源存储库的主分支提取代码并将其传递到构建阶段。存储库的基础设施即代码（IaC）文档概述了在每个阶段执行的任务。尽管使用 IaC 文档并非强制要求，但强烈建议使用 IaC 服务或工具，例如 [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) 或 [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html)。最常见的步骤包括：

1. 单元测试

1. 代码构建

1. 资源预调配

1. 集成测试

如果在管线的任何阶段出现任何错误或任何测试失败，则当前阶段将回滚到其之前的状态，并且管线将终止。后续更改必须从代码存储库开始，并经历完全 CI/CD 流程。

# CI/CD 管线的测试
<a name="tests-for-cicd-pipelines"></a>

部署管线中经常提到的两种类型的自动化测试是*单元测试*和*集成测试*。但是，有许多类型的测试可以在代码库和开发环境中运行。[AWS Deployment Pipeline Reference Architecture](https://pipelines.devops.aws.dev/application-pipeline/) 定义了以下类型的测试：
+ **单元测试**：这些测试构建并运行应用程序代码，以验证其性能是否符合预期。它们模拟代码库中使用的所有外部依赖关系。单元测试工具的示例包括 [JUnit](https://junit.org/)、[Jest](https://jestjs.io/) 和 [pytest](https://pytest.org/)。
+ **集成测试**：这些测试通过对预调配的测试环境进行测试来验证应用程序是否满足技术要求。集成测试工具的示例包括 [Cucumber](https://cucumber.io/)、[vRest NG](https://vrest.io/) 和 [integ-tests](https://docs.aws.amazon.com/cdk/api/v2/docs/integ-tests-alpha-readme.html)（适用于 AWS CDK）。
+ **验收测试**：这些测试通过对预调配的测试环境进行测试来验证应用程序是否满足用户要求。验收测试工具的示例包括 [Cypress](https://cypress.io/) 和 [Selenium](https://selenium.dev/)。
+ **综合测试**：这些测试在后台持续运行，以生成流量并验证系统是否正常运行。综合测试工具的示例包括 [Amazon CloudWatch Synthetics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries.html) 和 [Dynatrace Synthetic Monitoring](https://www.dynatrace.com/monitoring/platform/synthetic-monitoring/)。
+ **性能测试**：这些测试模拟生产环境的容量。其确定应用程序是否满足性能要求，并将指标与过去的性能进行比较。性能测试工具的示例包括 [Apache JMeter](https://jmeter.apache.org/)、[Locust](https://locust.io/) 和 [Gatling](https://gatling.io/)。
+ **韧性测试**：也称为*混沌测试*，这些测试将故障注入环境中，以识别风险区域。然后，将注入故障的时间段与没有故障的时间段进行比较。韧性测试工具的示例包括 [AWS Fault Injection Service](https://aws.amazon.com/fis/) 和 [Gremlin](https://www.gremlin.com/)。
+ **静态应用程序安全测试（SAST）**：这些测试分析代码中是否存在安全违规行为，例如 [SQL 注入](https://owasp.org/www-community/attacks/SQL_Injection)或[跨站脚本攻击（XSS）](https://owasp.org/www-community/attacks/xss/)。SAST 工具的示例包括 [Amazon CodeGuru](https://aws.amazon.com/codeguru/)、[SonarQube](https://www.sonarqube.org/) 和 [Checkmarx](https://checkmarx.com/)。
+ **动态应用程序安全测试（DAST）**：这些测试也称为*渗透测试*或 *pen 测试*。其可以识别漏洞，例如预调配测试环境中的 SQL 注入或 XSS。DAST 工具的示例包括 [Zed Attack Proxy（ZAP）](https://www.zaproxy.org/)和 [HCL AppScan](https://www.hcltechsw.com/appscan)。有关更多信息，请参阅 [Penetration Testing](https://aws.amazon.com/security/penetration-testing/)。

并非所有完全 CI/CD 管线都运行所有这些测试。但是，管线至少应对代码库运行单元测试和 SAST 测试，并对测试环境运行集成测试和验收测试。

# CI/CD 管线的指标
<a name="metrics-for-cicd-pipelines"></a>

根据 [AWS Deployment Pipeline Reference Architecture](https://pipelines.devops.aws.dev/application-pipeline/)，您至少应跟踪 CI/CD 管线的以下四项指标：
+ **前置时间**：单次提交到完全进入生产环境所需的平均时间。我们建议根据您的使用案例，将前置时间设定在 1 小时到 1 天之间。
+ **部署频率**：给定时间段内的生产部署次数。我们建议根据您的使用案例，将部署频率设定为每天多次到每周两次之间。
+ **平均故障间隔时间（MTBF）**：从成功管线启动到故障管线启动之间的平均时间。我们建议设定尽可能高的 MTBF。有关更多信息，请参阅 [Increasing MTBF](https://docs.aws.amazon.com/whitepapers/latest/availability-and-beyond-improving-resilience/increasing-mtbf.html)。
+ **平均恢复时间（MTTR）**：从故障管线启动到下一个成功管线启动之间的平均时间。我们建议设定尽可能低的 MTTR。有关更多信息，请参阅 [Reducing MTTR](https://docs.aws.amazon.com/whitepapers/latest/availability-and-beyond-improving-resilience/reducing-mttr.html)。

这些指标可以帮助团队跟踪其实现完全 CI/CD 的进度。团队应与组织的利益相关者就最佳目标应该是什么进行公开讨论。不同组织，甚至不同团队的情况和需求差异很大。

重要的是要记住，快速、剧烈的变化通常会增加出现问题的风险。设定目标，力求实现小幅、渐进式的改进。对于完全 CI/CD 管线，常见的最佳前置时间少于 3 小时。如果一个团队开始时的前置时间为 5.2 天，则目标应为每隔几周缩短一天。在该团队的前置时间达到一天或更短时间后，其可以保持在该水平数月，仅当团队和组织利益相关者认为有必要时，才转向更为激进的前置时间目标。