敏捷开发





3.00/5 (2投票s)
持续集成五步法
引言
在这份白皮书中,我主张引入敏捷或极限编程技术时,受影响最大的人不是软件或质量保证工程师,而是构建经理。构建经理不能再仅仅使用自制工具;需要软件生产自动化工具才能使敏捷开发成为构建现实。
现实是,敏捷技术是对开发者能够以小团队处理小项目的时代的回归。每个开发者(有时是两名开发者)专注于小的代码构建块(以及相关的单元测试),并定期与其他开发者集成,以确保整个软件项目正在进展。对于开发者来说,敏捷技术是自然的契合,因为它们反映了开发者最喜欢的工作方式:处理小的、可管理的代码片段,并获得定期反馈。
尽管开发者正在处理小的代码片段,但他们所属的整体项目现在非常庞大。因此,对于构建经理来说,在单台机器上进行小规模构建的日子一去不复返了。虽然开发者可能已将他们的工作分解成可以编码和测试的小单元,但大多数企业软件项目的整体规模正在不断增长。构建经理需要处理的是大量的代码,而不是开发者处理的可管理的代码块。
事实上,构建经理需要应对越来越大的软件,在越来越多的平台上,同时还要处理开发者对快速集成构建的需求。这些集成构建使软件工程师能够在桌面上进行敏捷开发,因为他们能够将本地更改集成到大型构建中,但这导致构建经理每天需要生成多达一两个数量级的构建。
持续集成
对构建经理来说,“每天多次集成”和“每次集成都通过自动化构建进行验证”这些词意味着从每晚一次的构建发生了根本性变化。所有这些变化都是由敏捷开发的核心原则之一带来的:持续集成。
关于持续集成的开创性论文(以及对该主题的优秀且易读的介绍)是马丁·福勒(Martin Fowler)题为“持续集成”的文章,可以在此处获取。
其摘要指出
持续集成是一种软件开发实践,团队成员频繁地集成他们的工作;通常每个人每天至少集成一次——导致每天多次集成。每次集成都通过自动化构建(包括测试)进行验证,以尽快检测集成错误。
对构建经理来说,“每天多次集成”和“每次集成都通过自动化构建进行验证”这些词意味着从每晚一次的构建发生了根本性变化。
福勒接着列举了许多“持续集成实践”。第一个与构建相关的实践是“自动化构建”。他认为,从源代码到最终发布二进制文件所需的一系列任务非常复杂,因此应该自动化,使其可重复。他认为,如果构建未自动化,构建过程将容易出错。
他还认为,构建远不止编译软件和构建二进制文件。他设定的目标是,“任何人都应该能够拿一台干净的机器,从存储库中检出源代码,执行一个命令,并在他们的机器上运行系统。”
值得停下来思考一下这句话对您的构建组织的影响。从一个通常由一系列 Makefile、Perl 脚本和其他功能或操作往往不明确的程序组成的吱呀作响的构建系统开始,达到这样一个自动化阶段很可能看起来是不可能的。
显然,从一台干净的机器到完全运行的代码的目标是一个挑战,但我认为这是一个很好的总体目标。一旦达到这个阶段,您将建立一个非常可靠的构建系统,并且如果编写和文档完善,应该很容易随着软件的变化进行修改和适应。
这样一个完全自动化的构建具有敏捷开发直接领域之外的优势。您的构建团队有多少次被要求重建旧版本的软件却无法做到?重要的客户有时会要求修补或更新旧版本的代码,或者安全问题可能意味着公司当前支持的所有版本的代码都需要修复和发布。
通常,只有准备非常充分的团队才能构建任意版本的代码。即使在发布时对源代码进行了良好的存档,软件的其他组件也可能已经分解:您可能不再拥有正确的构建脚本、正确的编译器或正确版本的第三方组件。
福勒的目标,我称之为“腌制构建”(整个构建都像腌在罐子里一样,随时可用),如果做得好,意味着可以随意重建旧版本的软件,并帮助开发者向敏捷开发迈进。
福勒的第二个构建实践是:“让您的构建自测试。”这意味着自动化构建也包括自动化测试。他要求任何代码库都有一套自动化测试,可以检查代码库的很大一部分是否存在错误。许多开发者实际上已经通过极限编程对单元测试的关注,或者通过执行测试驱动开发(开发者在编写代码之前编写测试)来编写此类测试套件。
有了这个测试套件,福勒要求自动化构建通过运行测试套件并报告结果来测试自身。如果构建和测试是在远程运行的,结果通常会在屏幕上或通过电子邮件报告。
福勒的接下来的两个实践对构建管理产生了深远的影响:“每个人每天提交”和“每次提交都应该在集成机器上构建主干。”这意味着每个开发者每天(至少)会提交一次代码,并且每次提交都会在由构建经理管理的一些构建资源(“集成机器”)上引起构建和测试。从这个角度来看,对于一个20名工程师的团队,在8小时工作日内每天提交一次,这意味着每24分钟进行一次构建和测试。对于大型团队,这个数字会增加,并且构建之间的时间会大大缩短。
敏捷开发者需要这些每次提交构建的原因是为了确保开发者之间的集成正常工作,并且构建的软件始终能够工作且可测试。软件应该始终运行的思想是敏捷开发的核心,而每次提交构建和测试的健康状况成为整个项目健康状况的重要标志。如果每次提交构建足够快速和频繁地完成,构建将反映单个开发者单个签入所做的更改,从而提供无与伦比的机会来缩小故障原因。
事实上,这个构建如此重要,我称之为敏捷心跳。敏捷团队将安装监控设备(例如红色和绿色熔岩灯),使心跳构建的状态对所有人可见。福勒指出,任何开发者都不应“在主干构建通过他们添加的任何提交之前回家”。这意味着所有工程人员每天都查看心跳以衡量自己的进展(福勒在“每个人都能看到正在发生什么”的实践中提到了这一点)。
福勒的论文中提到的另一个重要实践是“保持构建快速”。这似乎是前面实践的必然结果,因为一个需要每隔几分钟和每次代码更改时进行构建的团队必然需要非常快速的构建。事实上,极限编程提出了“十分钟”构建的目标,我之前曾写过我称之为浓缩咖啡构建(只需要咖啡休息时间那么长的构建)。
快速构建也很重要,因为开发者正在将构建的状态作为衡量其进度的标准。构建中节省的每一分钟,都是所有已将代码提交到该构建的开发者节省的一分钟。由于有许多开发者和许多构建,节省的时间会迅速累积,快速构建可以提高整个团队的生产力。
福勒建议这个整个过程要么由人工管理(如果团队很小),要么通过使用“持续集成服务器”进行管理。这份白皮书稍后将描述可用于实现持续集成的工具,但首先,持续集成的概念本身可能令人生畏。幸运的是,它可以分解成可管理大小的垫脚石。
持续集成的垫脚石
尽管“腌制”整个构建系统(将构建时间缩短到十分钟以内,每次开发者签入时都进行构建并提供自动反馈)是一项巨大的任务,但采用垫脚石方法可以使您实现持续集成,而无需一次痛苦地推动改变组织中的一切。
而且,通常,构建经理根本没有时间或资源来对其所做的一切进行重大更改。当构建经理被自然地期望在改进其流程以满足敏捷开发需求的同时,继续生成他们当前创建的构建时,情况尤其如此。
然而,一种五阶段的方法可以帮助简化持续集成之路。这五个阶段是:完全自动化构建、快速构建、熔岩灯、构建和测试以及预检构建。在每个阶段,构建经理都应仔细考虑可用于自动化软件生产过程的工具,因为持续集成需要非常大的努力。
1. 完全自动化
尽管有些构建已经完全自动化,但大多数集成和敏捷构建都需要构建经理进行一些手动干预(例如,在软件安装过程中,当对话框软件自动需要点击时,为了能够构建您的示例)。但持续集成和敏捷构建的核心是能够自动构建您的软件。
因此,第一块垫脚石是使构建能够通过单个命令调用运行(构建经理只需输入 `build`,然后是一些指定要构建的特定分支或软件版本的参数)。一旦构建脚本到位,构建系统就应该设置为自动运行。
这主要是在检测源代码管理系统中的源代码何时发生了变化。一种方法是设置一个简单的定期作业来检查更改。一旦检测到更改,作业就会等待存储库稳定(给开发者时间提交所有代码)。然后,作业可以在提交后等待十五分钟的静默期。静默期结束后,构建系统将使用构建脚本从代码主线启动完整的构建和测试。
这可能是唯一可以在不借助新的软件生产管理软件的情况下完成的垫脚石。构建脚本可以使用现有工具(如 GNU Make 或 Perl)编写,但值得研究可用的自动化工具(开源或商业),因为检测源代码更改和启动自动化构建是一个常见功能。以有限的方式(仅用于更改检测和构建启动)开始使用新工具是学习该工具的好方法,而无需承诺持续集成的所有五个步骤。
2. 快速构建
自动化构建之后,下一步是加快构建本身的速度。尽管极限编程提倡十分钟的自动化构建和测试,但我认为对于现有项目来说,一个现实的目标是将自动化构建和测试控制在一小时以内。
随着多核处理器和多处理器机器的普及,利用构建中可用的并行性是实现显着构建加速的相对简单的方法。然而,缺少或不完整的依赖信息使得实现自制的并行构建容易出错……
实现快速构建可能很困难。
对于某些项目,这仅仅是从过时的构建硬件升级到新机器(通常是更新、更快的磁盘,因为构建需要大量的磁盘访问来获取源和写入对象),但对于其他项目,构建要么需要重构(以便可以分解成在单独机器上运行的部分),要么需要一个专门构建的并行构建系统。并行构建系统既有开源产品,也有商业产品(包括来自 Electric Cloud)。随着多核处理器和多处理器机器的普及,利用构建中可用的并行性是实现显著构建加速的相对简单方法。然而,缺少或不完整的依赖信息使得实现自制的并行构建容易出错,并且需要专门的工具来克服几乎所有大型构建系统固有的串行性质。
3. 熔岩灯
熔岩灯(20世纪70年代流行的那种冒泡的彩色液体灯)可能看起来像是监控构建进度的愚蠢方式,而且在物理上较大的团队中(或者远程团队或复杂项目),它们可能实际上不适合,但引入某种构建监控是第三块垫脚石。熔岩灯只是监控系统的一个有趣、易于实现的例子。
构建监视器可以是红色和绿色的熔岩灯,或者是显示实时构建状态的内部网页,或者是安装在墙壁高处的平板显示器,显示构建状态。引入一种清晰(例如,红色代表失败,绿色代表成功)、易于查看(或许那些熔岩灯就在饮水机旁边)并持续更新的构建反馈机制。
构建监视器将从第一个阶段设置的完全自动化构建中获取其输入(好或坏)。每个人都会在早上和全天,随着新构建的运行,首先查看构建监视器。
尽管构建可能每天只运行并提供少量反馈(可能少至四次),但构建监视器将开始代表工程团队的脉搏,向所有人展示构建的健康状况,从而展示软件的健康状况。这是朝着每个提交都启动一个构建并向所有人显示结果的目标迈出的另一个重要步骤。
即使每天只有四次构建并提供反馈,开发者也能比夜间构建更快地识别集成问题。通过第一个阶段的自动化努力,这些自动化构建将是可靠和可重复的,并且是软件健康状况的良好指示。
4. 构建和测试
如果开发者遵循敏捷方法,他们将使用 JUnit 或 cppunit 等工具开发自动化测试套件。第三步是将这些测试(以及可能已有的其他“冒烟测试”)集成到现有构建系统中。
考虑到测试本身已经是自动化的,这可能是一个相对简单的任务。这一步也很重要,因为它将提高构建的可见性和重要性,并成为敏捷心跳的开始。
5. 预检构建
实践敏捷开发的开发人员最主要的需求是能够看到他们的代码与其他开发人员所做的更改集成的结果。尽管他们可以在本地机器上完成此操作(通过获取所有相关源并运行像 Make 这样的工具),但集成构建可能需要太长时间,或者需要特殊的构建资源才能构建软件的每个部分。通常,这意味着开发人员被迫将他们的构建限制在整个项目的小部分。即使开发人员可以在他们的机器上运行完整的构建,生产构建环境通常也与开发人员机器上的环境不同,因此在开发人员机器上运行正常的构建可能无法在生产环境中运行。由于这些问题,开发人员在最终通过签入代码与完整系统集成时经常引入错误。
一个好的第一步是让开发者能够进行完整构建。构建经理需要分配一台机器(如果涉及多个平台,可能不止一台),并设置一个内部网页,开发者可以在其中请求构建。
开发者的请求应包括他们的电子邮件地址、他们希望构建的软件位置(这可以是要构建的分支名称,或开发者放置个人源代码副本的共享服务器上的目录),以及确定构建范围的机会(例如,开发者可以请求在所有平台上进行构建,或将构建限制为单个操作系统)。
系统应维护一个待处理构建请求队列(通过另一个内部网页可见),并应按先到先得的顺序处理构建。当开发者的构建完成运行后(可能在他们的请求之后几个小时),开发者会收到一封电子邮件,其中包含构建状态以及构建系统生成的任何错误输出。
此外,构建系统会获取构建的全部输出并将其存储在共享磁盘上,供开发人员检查。经过一段固定时间(可能是一周)后,构建系统会自动删除构建输出以释放空间。
敏捷开发人员的优势是立竿见影的:他们不再需要等待夜间构建(具有固有的 24 小时延迟)来确定他们的更改是否导致任何问题,并且通过将构建隔离到他们的源代码或分支中,他们能够更快地解决问题,即使他们的预检构建需要数小时才能完成,因为他们可以更快地缩小代码更改部分的范围。此外,他们可以确信他们的签入不会引入与环境相关的构建中断,因为预检构建是在生产环境中运行的。
此时,整个团队可以决定引入一个新规则:在成功运行预检构建之前,任何人都不允许提交到源代码控制的主线。这里您引入了敏捷开发的另一个部分,它将大大减少夜间构建中的错误数量。通过开发人员在提交之前通过预检系统对完整构建进行代码检查,他们确保大多数集成错误在影响整个团队之前被清除。
对于团队来说,预检构建的巨大优势在于,夜间构建或自动化构建突然变得更加可靠。如果开发者在签入之前对照预检构建检查他们的代码是否存在中断,那么夜间构建的可靠性将大大提高。对于构建经理来说,实施预检构建面临两个重大挑战:自动化和构建资源可用性。
预检构建系统的首要前提是自动化构建,因此解决第一个垫脚石至关重要。事实上,这是福勒的第一个与构建相关的实践,也是持续集成的基石。实现完全自动化构建(在此阶段不含自动化测试)的代价必须预先支付,这将是转向持续集成中最昂贵(就时间而言)的部分。
其次,需要编写内部网页。这相对容易,因为免费的 Web 服务器(如 Apache)和免费工具(如 PHP 和 Perl)广泛可用且文档齐全。
最后,随着开发者开始使用该系统(如果他们试图保持敏捷,他们会使用),可用的构建机器数量将成为一个问题。随着许多开发者开始请求预检构建,构建队列可能会变长(尤其是在构建时间也很长的情况下)。
至此,构建经理已经实现了敏捷构建。开发者可以随时进行构建;当代码签入时,它会自动(且快速地)进行构建,每个人都能看到构建状态。如果构建中断,开发者可以停止工作以快速集成代码。
构建经理也可以选择完全停止进行夜间构建。有了预检构建和每次签入构建,夜间构建可能已成为过去。
可以提供帮助的工具
在寻找持续集成工具时,一个好的起点是维基百科上名为“持续集成”的页面。在那里您会找到一份长长的商业和开源持续集成服务器工具列表。
为了保持团队的理智并减少开发者和构建团队在查看工具或考虑自建与购买决策时的停机时间,您应该尽量减少对现有构建环境的更改。目标应该是完全自动化构建(以便可以通过单个命令启动),而无需更改整个系统。要启动持续集成,只需要一个能够运行整个构建的单个命令:该命令需要从源代码管理中提取源代码并执行构建。
一旦脚本到位,合适的工具选择归结为几个关键问题
- 该工具是否支持计划构建?如果该工具不支持“cron”风格的构建,那么就不值得考虑。这些是最基本的构建类型,即使您引入了敏捷开发方法,它们仍然很重要。
- 该工具是否可扩展?敏捷开发的特点之一是,随着工程师开始运行自己的构建,构建资源将迅速承受巨大的负载。当每次提交都启动一个构建时,这些资源将承受更大的压力。从一开始就必须考虑可扩展性,以避免在持续集成的垫脚石过程中不得不更换服务器。任何工具都必须随着资源的增加(例如服务器)而扩展,并且能够随着工作日期间需求波动而同时利用资源池。业务需求也应予以考虑,因为对额外目标平台或新团队集成的要求将随着时间的推移对系统提出额外要求。
- 该工具是否提供报告或分析工具?每天数百次构建,管理输出甚至仅仅是每次构建的状态都是令人头疼的问题。单个夜间构建时很简单的事情,每隔十分钟进行一次构建就变得非常困难,因此能够了解构建系统的性能以及构建服务器的负载和使用情况随时间的变化至关重要。
- 该工具是否易于采用?避免任何需要重写现有 Makefile 或构建脚本的工具:在不需要从头开始的情况下采用新方法已经够难的了。该工具应该与现有工具协同工作并与现有源代码管理系统集成。
- 该工具是否支持预检构建和每次提交构建?由于这两种构建方式是持续集成的基础,因此该工具必须易于与源代码管理集成,以检测源代码库的更改并自动启动构建,并允许任何用户随意启动构建。
- 该工具是否支持访问控制?由于构建服务器现在将与所有开发团队共享(而不仅仅是小的构建团队),访问控制对于确保开发人员可以从任何本地或远程位置访问适当的资源,以及构建团队能够覆盖正在运行的构建以随意执行高优先级构建至关重要。
- 该工具是否支持多个团队,或者每个组或部门是否都需要对其工具(加上配置和维护)进行单独投资?一旦自动化,许多构建过程(例如监控源代码管理系统变更的作业)很可能具有通用性,并且可以在整个组织中轻松共享。为了最大化对工具的投资并减少重复工作,通用过程或公司标准是否可以在团队之间推广?
在许多(如果不是所有)情况下,自制方法将在这些领域中的一个或多个方面表现不足。或者,如果自制系统在持续集成垫脚石的开始时是足够的,它可能会随着负载的增加、目标平台数量的增加或用户数量的增加而逐渐不足。商业工具还将在减少手动设置所需的管理和维护方面带来回报。
结论
极限编程和敏捷开发正在被许多软件工程组织采用。实现敏捷性并非易事,但团队可以通过循序渐进的方法实现敏捷开发的一些好处。工程团队的所有部分都需要仔细规划,并特别关注构建资源。一旦实施敏捷方法,构建团队将承受巨大压力,因此建议采用循序渐进的方法来实施敏捷构建。
从任何敏捷方法的推广开始,仔细选择合适的构建工具至关重要。这些工具必须能够应对构建资源的各种需求,以及构建数量和规模可能出现的增长。
使用 ElectricCommander 启用敏捷构建
更快的构建,自动化的测试
为了保持积极的产品发布计划,LSI Logic 消费产品工程团队希望转向每日集成模型,在每 24 小时内集成、构建和测试 25 到 50 个独特的软件构建。
公司首先选择了 Electric Cloud 的 ElectricAccelerator 来解决集成模型中的构建速度问题,成功地将构建时间缩短了 7-8 倍(从 150 分钟缩短到 20-30 分钟)。
看到 ElectricAccelerator 的成功,LSI 决定将其测试环境转换为 ElectricCommander,Electric Cloud 的生产自动化解决方案。他们以前的环境在处理 250 个并发步骤时就已过载,而 ElectricCommander 能够使用相同的硬件设置调度和执行 1,000 多个并发步骤,极大地简化和加快了冒烟测试过程。
ElectricCommander 是在企业环境中实施敏捷生产流程的值得考虑的工具。它是一个基于网络的解决方案,用于自动化软件构建和其他生产任务,以实现敏捷、迭代开发。只有 ElectricCommander 足够简单,可以在小型构建中使用,但又足够可扩展,可以支持最复杂的软件生产环境。它只需最少的流程更改即可开始或跨团队部署。它提供了组织合规性工作和发布计划所需的报告和可见性,以及前所未有的灵活性和可定制性,以适应敏捷组织。对于敏捷团队,ElectricCommander 支持
- 快速构建:在同一资源上并行运行多个过程,或将过程或单个步骤分发到任意数量的机器上,以实现更快的周转和更高效的生产。为了进一步提高构建步骤的速度,ElectricAccelerator 提供了细粒度的并行性,可将构建速度提高多达 20 倍(参见下文)。
- 自动化和计划构建:安排生产过程在指定的日期或时间、每小时或每天运行,或每当有人将代码签入指定的存储库或分支时运行。
- 预检构建和每次提交构建:底层信息架构允许构建和发布团队将生产资产组织成虚拟的、受访问控制的项目,同时也可以限制或控制对生产机器的访问。通过这种方式,发布团队可以根据需要为开发人员提供用于预检构建的专用或指定资源。此外,ElectricCommander 支持与领先的 SCM 工具集成,以促进每次提交构建。
- 可见性和报告:ElectricCommander 独特的分析功能提供了对构建细节的宝贵洞察力,而不仅仅是成功或失败。分析引擎提取信息并将其存储为作业步骤的持久属性,从而可以轻松访问精确的统计数据和趋势报告。
关于 Electric Cloud
Electric Cloud 是领先的软件生产管理解决方案提供商,可加速、自动化和分析新代码签入后的软件开发任务。这些任务包括软件构建、打包、测试和部署流程。
现实是,自制系统维护成本高昂,难以在企业范围内标准化,而且通常无法支持敏捷开发核心的频繁迭代。Electric Cloud 使在整个组织中实现可扩展、敏捷的软件生产环境变得简单。Electric Cloud 的产品套件——ElectricAccelerator、ElectricCommander 和 ElectricInsight——通过加速、自动化和分析整个软件生产管理生命周期,提高了开发生产力和产品质量。除了 ElectricCommander 生产自动化工具,Electric Cloud 还提供
ElectricAccelerator
ElectricAccelerator™ 准确地在廉价服务器集群上执行并行构建,将构建时间缩短多达 20 倍。ElectricAccelerator 无缝集成到现有构建基础设施中,无需修改现有脚本。更快、更准确的构建显着减少了开发者等待构建完成的时间,并使他们能够在签入更改之前完成构建。
ElectricInsight
ElectricInsight™ 是一款软件构建可视化工具,与 ElectricAccelerator 结合使用时,可提供作业级别的并行构建详细信息,并提供前所未有的构建结果可见性,以简化故障排除和性能调优。Qualcomm、Intuit、Motorola 和 Expedia 等领先公司已信任 Electric Cloud 的软件生产管理解决方案,将软件构建和整个生产流程从负债转变为竞争优势。