持续集成、交付和部署简介

简介

开发和发布软件可能是一个复杂的过程,特别是在应用程序、团队和部署基础设施日益复杂的情况下。通常,随着项目的发展,挑战变得更加明显。为了以快速一致的方式开发、测试和发布软件,开发人员和组织创建了三个相关但不同的策略来管理和自动化这些过程。

持续集成侧重于每天多次将单个开发人员的工作集成到主存储库中,以及早捕获集成错误并加速协作开发。持续交付关注的是减少部署或发布过程中的摩擦,自动化部署构建所需的步骤,以便随时可以安全地发布代码。持续部署通过在每次代码更改时自动部署,进一步推进了这一步。

在本指南中,我们将讨论这些策略中的每一个,它们如何相互关联,以及如何将它们合并到您的应用程序生命周期中以改变您的软件开发和发布实践。要更好地了解各种开源CI/CD项目之间的差异,请查看我们的CI/CD工具comparison.

什么是持续集成,为什么有用?

持续集成 是一种鼓励开发人员及早并经常将代码集成到共享存储库的主分支中的做法。代码不是孤立地构建功能并在开发周期结束时集成它们,而是由每个开发人员在一天中多次与共享存储库集成。

这个想法是通过及早考虑将整合的成本降至最低。开发人员可以在早期发现新代码和现有代码之间的冲突,而冲突仍然相对容易协调。一旦冲突得到解决,工作就可以继续进行,相信新代码符合现有代码库的要求。

通常,集成代码本身并不能保证新代码或新功能的质量。在许多组织中,集成成本很高,因为使用手动过程来确保代码符合标准,不会引入错误,也不会破坏现有功能。当实现自动化的方法与适当的质量保证措施不一致时,频繁的集成可能会产生摩擦。

为了解决集成过程中的这种摩擦,在实践中,持续集成依赖于健壮的测试套件和自动化系统来运行这些测试。当开发人员将代码合并到主存储库中时,自动化流程将启动新代码的构建。然后,针对新版本运行测试套件,以检查是否引入了任何集成问题。如果构建或测试阶段失败,团队会收到警报,以便他们能够修复构建。

持续集成的最终目标是使集成成为一个简单的、可重复的过程,它是日常开发工作流程的一部分,以便降低集成成本并及早响应缺陷。努力确保系统健壮、自动化和快速,同时培养鼓励频繁迭代和响应以构建问题的团队文化,这是CI成功的基础。

什么是不间断递送?为什么会有帮助?

持续交付 是持续融合的延伸。它专注于自动化软件交付过程,以便团队可以随时轻松、自信地将其代码部署到生产环境中。通过确保代码库始终处于可部署状态,发布软件变得平淡无奇,没有任何复杂的例行公事。团队可以相信,他们可以在需要的时候发布,而不需要复杂的协调或后期测试。与持续集成一样,持续交付是一种需要混合技术和组织改进才能有效的实践。

在技术方面,持续交付在很大程度上依赖于部署管道来自动化测试和部署流程。部署管道 是一个自动化系统,它针对构建运行越来越严格的测试套件,作为一系列连续的阶段。这在持续集成停止的地方重新开始,因此可靠的持续集成设置是实现持续交付的先决条件。

在每个阶段,构建要么测试失败,这会警告团队,要么通过测试,这会导致自动升级到下一个阶段。 随着构建在管道中的移动,后面的阶段将构建部署到尽可能接近生产环境的环境中。 这样,构建、部署过程和环境就可以同时进行测试。 管道以一个构建结束,该构建可以在任何时候通过一个步骤部署到生产环境中。

持续交付的组织方面鼓励将)来协助这一领域。

持续交付之所以引人注目,是因为它自动化了将代码签入存储库和决定是否将经过良好测试的功能性构建发布到您的生产基础设施之间的步骤。帮助断言代码的质量和正确性的步骤是自动化的,但关于发布什么的最终决定留在组织手中,以实现最大的灵活性。

什么是持续部署,为什么有用?

持续部署 是持续交付的扩展,自动部署通过整个测试周期的每个构建。持续部署系统将部署成功通过部署管道的所有内容,而不是等待人工把关人员决定部署什么以及何时部署到生产。请记住,当新代码自动部署时,以后仍可以有条件地激活新功能或为部分用户激活新功能。部署自动将功能和修复程序快速推送给客户,鼓励范围有限的较小更改,并有助于避免混淆当前部署到生产中的内容。

对于担心放弃对其自动化系统发布内容的控制的组织来说,这种完全自动化的部署周期可能是焦虑的来源。自动化部署提供的权衡有时被认为与它们提供的回报相比过于危险。

其他团体利用这种方法作为确保始终遵循最佳做法的一种手段。如果在部署一段代码之前没有最终的手动验证,开发人员必须负责确保他们的代码设计良好,并且测试套件是最新的。 这将围绕什么以及何时提交到主存储库以及什么以及何时发布到生产环境的任何决策整合到开发团队的单个决策点中。

持续部署还允许组织从一致的早期反馈中受益。特性可以立即提供给用户,缺陷或无用的实现可以在团队向无效方向投入大量努力之前及早发现。快速得到某项功能没有帮助的反馈,可以让团队转移注意力,而不是将更多精力投入到影响最小的领域。

连续流程的关键概念和实践

尽管持续集成、交付和部署所涉及的范围各不相同,但仍有一些概念和实践是每个项目成功的基础。

小的、迭代的更改

采用持续集成时最重要的实践之一是鼓励小的更改。开发人员应该练习将较大的工作分解为小块,并尽早提交这些工作。诸如_By Abstraction_和Feature标志(见下文)这样的特殊技术有助于保护主分支的功能不受正在进行的代码更改的影响。

微小的更改将集成问题的可能性和影响降至最低。通过在尽可能早的阶段致力于共享分支,然后在整个开发过程中持续进行,可以降低集成成本,并定期同步不相关的工作。

Trunk开发

在基于主干的开发中,工作在存储库的主分支()中完成,或者频繁地合并回共享存储库中。只要存在时间较短的功能分支代表较小的更改并尽快合并回来,就可以使用它们。

基于主干的开发背后的思想是避免违反上面讨论的小的、迭代的更改的概念的大提交。对等点可以及早获得代码,这样当它们的范围很小时,冲突就可以得到解决。

从主分支执行发布,或者从从主干专门为该目的创建的发布分支执行发布。在发布分支上没有发生任何发展,以保持对作为真理的唯一来源的主要分支的关注。

保持构建和测试阶段的快速

每个流程都依赖于自动化构建和测试来验证正确性。由于构建和测试步骤必须频繁执行,因此必须简化这些过程,以最大限度地减少这些步骤所花费的时间。

构建时间的增加应该被视为一个主要问题,因为每次提交都会启动一个构建,这一事实加剧了这一影响。由于持续的流程迫使开发人员每天都要从事这些活动,因此减少这些领域的摩擦是非常值得的。

如果可能,并行运行测试套件的不同部分可以帮助更快地在管道中移动构建。还应注意确保每种类型的测试的比例合理。单元测试通常非常快,并且维护开销最小。相比之下,验收测试通常很复杂,而且容易出错。为了解决这一问题,一个好主意通常是高度依赖单元测试,执行相当数量的集成测试,并最大限度地减少更复杂的测试数量。

部署管道全线一致性

因为连续交付或部署实施应该测试发布的价值,所以在过程的每个步骤--构建本身、部署环境和部署过程本身--期间保持一致性是至关重要的:

  • 代码应该在管道开始时构建一次 :生成的软件应该存储起来,供后续进程访问,而不需要重新构建。通过在每个阶段使用完全相同的构件,您可以确保不会因为不同的构建工具而引入不一致。
  • 部署环境应一致 :配置管理系统可以控制各种环境,环境变化可以通过部署管道本身进行,以确保正确性和一致性。应在每个测试周期配置干净的部署环境,以防止遗留条件影响测试的完整性。试运行环境应尽可能与生产环境相匹配,以减少升级构建时存在的未知因素。
  • 在每个环境中部署Build应该使用一致的流程 :每个部署都应该是自动化的,每个部署都应该使用相同的集中式工具和程序。应该取消临时部署,而只使用管道工具进行部署。

部署与发布解耦

将代码的部署与向用户发布的代码分开是持续交付和部署的一个极其强大的部分。代码可以部署到生产环境中,而无需最初将其激活或使其可供用户访问。然后,组织决定何时发布独立于部署的新功能或特性。

通过将业务决策与技术流程分开,这为组织提供了极大的灵活性。如果代码已经在服务器上,那么部署不再是发布过程的微妙部分,这将最大限度地减少参与者的数量和发布时涉及的工作量。

有许多技术可以帮助团队在不发布代码的情况下部署负责功能的代码。功能标志设置条件逻辑,以检查是否根据环境变量的值运行代码。抽象分支允许开发人员通过在流程输入和输出之间创建抽象层,以增量方式重写流程。仔细规划合并这些技术将使您能够分离这两个流程。

测试类型

持续集成、交付和部署在很大程度上依赖于自动化测试来确定每次代码更改的有效性和正确性。在这些过程中,需要不同类型的测试来确定对给定解决方案的信心。

虽然下面的类别并不是一个详尽的列表,而且尽管对每种类型的确切定义存在分歧,但这些测试的大类别代表了在不同上下文中评估代码的各种方法。

烟雾测试

烟雾测试是一种特殊的初始检查,旨在确保核心功能以及一些基本实施和环境假设。烟雾测试通常在每个测试周期的最开始时运行,作为在运行更完整的测试套件之前的健全检查。

这种类型的测试背后的想法是帮助捕捉实现中的大红旗,并注意可能表明进一步测试是不可能的或不值得的问题。 烟雾测试不是很广泛,但应该非常快。 如果一个更改没有通过冒烟测试,这是一个早期的信号,表明核心断言被破坏了,在问题解决之前,您不应该再花时间进行测试。

在任何新阶段测试开始时,可以采用特定环境的烟雾测试,以确定基本假设和要求得到满足。 例如,冒烟测试既可以在集成测试之前使用,也可以在部署到登台服务器之前使用,但是要测试的条件在每种情况下都不同。

单元测试

单元测试负责以隔离和高度有针对性的方式测试代码的各个元素。各个函数和类的功能都是自己测试的。任何外部依赖项都会被存根或模拟实现替换,以便将测试完全集中在所讨论的代码上。

在将单个代码组件放入更复杂的上下文之前,单元测试对于测试其内部一致性和正确性的正确性至关重要。测试的有限范围和依赖项的移除使得查找任何缺陷的原因变得更容易。这也是测试各种输入和代码分支的最佳时机,这些输入和代码分支稍后可能很难重现。通常,在任何冒烟测试之后,单元测试是在进行任何更改时运行的第一个测试。

单元测试通常由个别开发人员在提交更改之前在其自己的工作站上运行。但是,持续集成服务器几乎总是在开始集成测试之前再次运行这些测试作为安全措施。

集成测试

在单元测试之后,通过将组件组合在一起并将它们作为一个程序集进行测试来执行集成测试。虽然单元测试单独验证代码的功能,但集成测试确保组件在相互连接时协作。这种类型的测试有机会捕获通过组件之间的交互暴露的完全不同类型的错误。

通常,当代码签入到共享存储库中时,会自动执行集成测试。持续集成服务器签出代码,执行任何必要的构建步骤(通常执行快速冒烟测试以确保构建成功),然后运行单元和集成测试。模块以不同的组合连接在一起并进行测试。

集成测试对于共享工作非常重要,因为它们保护项目的健康。更改必须证明它们不会破坏现有功能,并且它们会按预期与其他代码交互。集成测试的第二个目标是验证更改是否可以部署到干净的环境中。这通常是第一个不在开发人员自己的机器上执行的测试周期,因此在此过程中还可能发现未知的软件和环境依赖关系。这通常也是第一次针对真实的外部库、服务和数据测试新代码。

系统测试

一旦执行了集成测试,称为系统测试的另一个级别的测试就可以开始了。在许多方面,系统测试充当集成测试的扩展。系统测试的重点是确保组件组作为一个有凝聚力的整体正确运行。

系统测试通常不关注组件之间的接口,而是评估整个软件的向外功能。这组测试忽略了组成部分,以便将组成的软件作为一个统一的实体来衡量。由于这种区别,系统测试通常集中在用户可访问或外部可访问的界面上。

验收测试

验收测试是在交付之前对软件执行的最后类型的测试之一。验收测试用于从业务或用户的角度确定一件软件是否满足所有需求。这些测试有时是针对原始规范构建的,并且经常测试某些预期功能和可用性的接口。

验收测试通常是一个更复杂的阶段,可能会延续到软件发布之后。自动化验收测试可以用来确保满足设计的技术要求,但手动验证通常也起到一定作用。

通常,验收测试从将构建部署到镜像生产系统的临时环境开始。从这里,自动测试套件可以运行,内部用户可以访问系统以检查它是否以他们需要的方式运行。在发布软件或向用户提供测试版访问权限后,通过评估软件在实际使用中的功能并通过收集其他反馈来执行进一步的验收测试。

附加术语

虽然我们在上面讨论了一些更广泛的概念,但在学习持续集成、交付和部署时,您可能会遇到许多相关的概念。让我们定义几个您可能会看到的其他术语:

  • 蓝绿部署 :蓝绿部署是一种在类似生产的环境中测试代码,并以最少的停机时间部署代码的策略。维护了两组能够生产的环境,并将代码部署到可以进行测试的非活动集。当准备好发布时,生产流量将被路由到具有新代码的服务器,立即使更改可用。
  • 抽象分支 :抽象分支是一种在活动项目中执行主要重构操作的方法,在源代码库中没有长期的开发分支,这是持续集成实践所不鼓励的。在现有实现中构建和部署抽象层,以便可以在抽象后面并行构建新的实现。
  • Build(名词) :Build是从源代码创建的软件的特定版本。根据语言的不同,这可能是编译代码,也可能是一致的解释代码包。
  • 金丝雀发布 :金丝雀发布是一种向有限用户子集发布更改的策略。我们的想法是确保在生产工作负载下一切正常工作,同时在出现问题时将影响降至最低。
  • 暗启动 :暗启动是将代码部署到生产中,接收生产流量,但不影响用户体验的做法。新的更改与现有实现一起部署,并且相同的流量通常被路由到这两个地方进行测试。旧的实现仍然与用户界面挂钩,但在幕后,可以在生产环境中使用真实的用户请求来评估新代码的正确性。
  • 部署管道 :部署管道是一组组件,通过越来越严格的测试和部署场景来移动软件,以评估其发布准备情况。管道通常以自动部署到生产或提供手动执行此操作的选项结束。
  • 功能标志 或** 功能切换** :功能标志是一种在条件逻辑后面部署新功能的技术,条件逻辑根据环境变量的值来确定是否运行。通过适当设置此标志,无需激活即可将新代码部署到生产环境中。功能标志通常包含允许部分用户访问新功能的逻辑,从而创建了一种逐步推出新代码的机制。
  • 升级 :在持续流程的背景下,升级意味着将软件构建转移到下一阶段的测试。
  • 浸泡测试 :浸泡测试是指在大量生产或类似生产的负载下对软件进行较长时间的测试。

结论

在本指南中,我们介绍了持续集成、持续交付和持续部署,并讨论了如何使用它们安全快速地构建和发布经过良好测试的软件。这些流程利用广泛的自动化,并鼓励持续的代码共享以及早修复缺陷。虽然实现这些解决方案所需的技术、流程和工具是一笔巨大的投资,但一个设计良好并正确使用的系统可能会带来巨大的好处。

要了解哪种CI/CD解决方案可能适合您的项目,请查看我们的CI/CD工具比较guide》以了解更多信息。

Published At
Categories with 技术
Tagged with
comments powered by Disqus