持续集成 (CI) 是一项软件开发流程;在此流程中,开发人员会在整个开发周期中将新代码集成到代码库中。
提交代码后,CI 工具会通过创建构建迭代并运行一系列自动化测试来验证每个集成,以便更快地检测和解决集成错误。
CI 的创建是为了应对传统软件开发的挑战;即,与整合和部署相关的流程。在传统开发中,每个开发人员均负责手动将新代码集成到应用程序或服务的新迭代中,从而致使整合流程速度缓慢且容易出错,对于大型开发团队而言更是如此。
不同的代码片段并不总能良好地协同工作,且开发人员会在不同的时间线整合其更改(有时甚至是在最后一刻),因此有关集成问题的反馈常会出现延迟。与不一致集成相关的延迟使得团队更难找出哪项更改引入了该错误,因此调试也成为一个艰巨的流程。
此外,由于软件测试不充分且会一次性进行大批量更新,因此错误可能会被忽略并在代码库中积累,从而引发面向最终用户的错误和故障。(对于开发人员,故障排除也更为困难。)
CI 工具是现代 DevOps 实践、持续整合/持续部署 (CI/CD) 管道和微服务架构的基础;它们可通过提供有关整合性能的快速反馈来帮助简化构建流程。
对于 CI 系统,新代码会添加到中央存储库(通常每天会进行多次)中,并在此驻留以便进行构建和测试。如果系统检测到错误,便会发出通知、更正相关代码并确认更新后的代码正确无误,然后再将其与代码库完全合并。
因此,CI 方法有助于软件开发团队在错误影响软件性能之前发现并修复错误,从而提高软件质量和更可预测的交付时间表。
虽然持续整合系统的确切配置会因团队和企业而异,但每个 CI 系统均会使用某些组件和流程来优化集成任务。
CI 始于一个中央存储库,而所有开发人员均会在此处提交代码。中央存储库是 CI 实践的基石,且通常由 Git 和 Bitbucket 等版本控制系统 (VCS) 来管理。当开发人员提交更改时,中央存储库会跟踪这些更改,以便创建完整的代码更改历史记录,而开发团队可使用该记录来更有效地开展协作。
此外,存储库还使用分支策略(例如,基于主干的开发或 GitFlow)来促进并行开发。分支功能有助于开发人员创建功能分支和短期分支,以便在将其合并回主代码分支之前隔离其工作。
CI 服务器可集中所有 CI 操作,并为软件开发提供一个稳定、可靠的平台,从而为不同平台构建各种项目。这些服务器会对工作流(用于持续交付)进行建模和可视化,并为构建持续交付 (CD) 管道提供一个直观的界面。
CI 服务器还可运行自动化的构建、测试和发布,编排版本控制协议,监视代码存储库,处理状态报告,并为可增强系统功能性的插件提供支持。
CI 系统鼓励开发人员每天多次提交代码更改,从而优先考虑对特定任务或功能进行小规模、有针对性的更改。通过使用拉取请求(描述)和合并请求等工具,团队可在合并新代码之前启动代码审查并讨论问题,以便及早发现错误。
持续整合服务器和工具(包括流行的开源 CI 工具,如 Jenkins、CircleCI、GitHub、AWS CodePipeline 和 GitLab CI)可监控中央存储库中是否出现代码变更。检测到新更改时,构建服务器会触发构建流程并执行预定义的工作流程和构建脚本,从而编译并打包此代码,以便为测试和最终部署进行准备。
CI 工具会运行一系列测试,以便在代码与代码库合并之前对其进行验证。单元测试可验证各个组件或功能,从而提供有关代码行为的即时反馈。集成测试可评估软件组件与模块之间的交互,以确保它们能正确协同工作,并发现单元测试可能会遗漏的所有问题。
在某些 CI 工作流程中,端到端测试会通过模拟用户交互来验证软件,以便从用户的角度验证该软件的行为是否正确。此外,团队还可运行代码质量测试和静态分析,以检查应用程序在负载情况下的响应度和稳定性,以及识别违反编码标准的行为和安全漏洞。
如果构建或测试失败,CI 服务器则会立即通知开发人员。出现故障时,开发人员会优先修复相关代码,以确保主分支仍可部署。
如果构建成功,这些服务器则会生成工件(例如,编译后的二进制文件、Docker 映像和安装程序),而这些工件会受到版本控制并存储在工件存储库中,以供未来的测试和部署使用。无论结果如何,顶尖 CI 系统均会记录整合尝试、成功率和其他指标,以确保团队成员始终能访问全面的版本文档。
测试是持续集成流程的重要组成部分。测试至少会占 CI 活动的三分之一左右;但仅当团队运行单个测试阶段时,情况才是如此。实际上,测试活动可能会构成 CI 工具的大部分工作负载。
CI 环境中的持续测试始于开发人员生成构建和包(也称为可安装实体或打包实体),且终于将此包投入生产环境。此端到端流程的每个步骤可形成测试套件。
作为 CI 中自动化测试流程的一部分,测试驱动式开发会以迭代的方式构建代码,并一次测试一个用例;然后,它会告知团队此代码在应用程序的各个功能区域中的执行情况。
但是,开发人员必须在本地环境中运行所有测试(和测试子集),以确保他们仅在新代码更改通过测试后才将源代码提交到版本控制环节。这种方法可以最大限度地提高测试覆盖率、防止代码退化,为持续交付打下基础。
在 DevOps 框架中,持续集成处于软件开发流程的起始位置。DevOps 管道可通过自动完成并整合过往存在于各自孤岛中的开发与 IT 运营团队的工作来加快高质量软件的交付。
最出色的 DevOps 流程和文化不仅限于开发和运营,还包括平台和基础设施工程、安全性、合规性、治理、风险管理、业务线、最终用户和客户。换言之,优秀的 DevOps 应将所有应用程序利益相关者的意见全部纳入软件开发生命周期。
作为 DevOps 的一部分,CI 有助于开发人员每天至少检查一次其代码,以防止本地副本大幅偏离代码构建的主分支。此方法有助于团队避免出现灾难性的合并冲突,而这些冲突可能会在交付与部署阶段“破坏”构建。
持续整合和敏捷开发具有很多相同的特性,其中包括测试自动化,因此讨论两者如何相互作用很有意义。
敏捷开发是一种将开发流程组织为更小规模的工作组或“冲刺”的实践,它旨在最大限度地减少障碍、实现开发人员协作并加快软件交付。敏捷方法认识到软件开发实践和客户需求均会动态变化,因而使得它们可能会随着时间的推移而改变。
因此,敏捷思想提供了一种迭代开发方法,以便团队和企业更轻松地适应变化,并随着时间的推移扩展和发展软件解决方案。同时,由于 CI 鼓励频繁进行更新和代码验证,因此它还有助于敏捷团队更快推出高质量的产品,使其成为一种本质上的敏捷实践。
持续集成可帮助 DevOps 开发运维团队依赖共享存储库来进行编码、测试、部署和支持软件,但企业还可采取某些其他步骤来优化此流程。常用的 CI 最佳实践包括:
合并后的集中代码库可简化分发和可见性。很多组织使用源代码控制管理来维护单个存储库,而该存储库可用于跟踪并控制与产品构建相关的所有文件。
组织可通过要求开发人员每天至少一次将其更改提交到主开发流来营造一种一致性文化。此举也使开发人员能验证自己的工作副本是否与主开发流一致。
优化构建脚本、并行执行任务和使用缓存机制可缩短构建时间。团队还可配置 CI 管道,以便在出现问题时,新的整合在此流程的早期便会失败。如此,开发人员便可快速解决问题并缩短调试时间。
使测试环境尽可能与最终生产环境相似,可确保测试结果准确呈现软件在现实环境下的执行情况。
通过实施功能标志来控制新功能的发布,CI 系统可将不完整或实验性的功能合并到主分支中,而不会影响整体生产。
定期审查和更新 CI 管道以整合新的工具、技术和最佳实践,可让该管道随着项目的需求而不断发展。
设置强大的 CI 管道(尤其是作为 DevOps 和敏捷开发的一部分)需进行仔细规划和配置,其中包括选择适当的工具、定义构建和测试工作流程以及配置基础设施。CI 管道还需进行定期维护,以适应代码库、依赖项(如 API)和基础设施的变化。
但是,实施 CI 可为软件开发团队提供一系列好处,其中包括:
CI 流程有助于团队及早解决错误—有时是在签入后的几分钟内。
团队中的每个成员均可更改代码、整合代码更改并识别代码不兼容问题和集成错误,从而简化知识共享并通过同行反馈来提高代码和软件的质量。
由于新代码会持续进行整合,因此团队在整合和测试大批量代码上所花费的时间更少。CI 工具提供的加速反馈回路可帮助开发人员更快地进行迭代,并向最终用户加速交付软件更新和新产品。
频繁提交代码意味着规模更小、更具增量性质的更改,而这些更改也更容易理解、审查和测试。此举可降低开发流程中将重大问题引入代码库的风险。
实现本地、云端或大型机上任何应用程序的自动化软件交付
。使用开发运维软件和工具,在多种设备和环境中构建、部署和管理云原生应用程序。
利用 IBM 的云咨询服务发掘新功能并提升业务敏捷性。了解如何通过混合云战略和专家合作共同制定解决方案、加快数字化转型并优化性能。