2.2 流程和方法论:敏捷开发与CI/CD
DevOps可以看作基于敏捷开发的方法论,其核心是通过CI/CD(持续集成/持续交付/持续部署)工具自动化研发流程,从而实现快速交付。而DevSecOps则基于DevOps自动化并左移应用安全检查。因此,在企业内推动DevSecOps,不仅需要了解应用安全,也需要对DevOps的基础流程和方法论——敏捷开发和CI/CD,有深刻的理解。
2.2.1 敏捷开发
敏捷是软件开发的一种方法论。它以用户的需求实现为核心,采用小步快跑、快速反馈和持续改进的方式进行软件开发。在敏捷开发中,软件开发项目被拆分成多个相互联系,但也可以独立运作的小项目,并分别完成,而整个过程中软件一直处于可运行状态。有两种主流的框架通常用来实现敏捷方法论:迭代和看板。首先我们介绍一下敏捷开发的一个重要概念——MVP。
1. 最小可行产品(MVP)
MVP(Minimum Viable Product)是指可以产生预期成果的最小产品发布。“最小”没有严格的定义,根据具体产品和场景而定。一般来说,最小可行产品/方案是指可以产生预期成果的最小发布方案。此外,我们需要设置更小规模的实验和原型来验证我们对“最小”和“可行”的猜测。通过《用户故事地图》这本书的介绍,第一个产品就是试验品,其后的版本是不断实验的结果,直到证明产品是对的。所以MVP可能不是产品,而是为了验证假设而做的最小规模的实验。那么,如何找到MVP呢?
1)创建用户故事地图。用户故事地图用来建立共识,帮助团队以可视化的方式展示依赖关系,并且发现设计中遗漏的关键环节。
2)划分MVP发布计划。在用户故事地图上识别并划分第一个发布需要的内容,其他切分的发布内容在之后的版本实现。MVP聚焦于成果,即发布后用户能使用或者感知的东西,切分发布计划应该以成果为导向。换成另一句话,即就算做的需求再多,没有上线被用户体验并进行反馈,都是没有意义的。
3)划分发布路线图。排定开发工作优先级是为了聚焦于特定的目标成果。
4)为成果排列优先级,而非功能。拆分复杂需求是为了聚焦小的、特定的输出成果。
使用用户故事地图输出MVP的发布计划,是为了更快地开发、及时地反馈和修正,以及减少返工成本,并且按时发布。在使用用户故事地图时,需要考虑以下三件事:
- 尽可能全面地描述用户故事。
- 可视化你的用户行为。
- 在地图前重新审视下一个开发阶段要实现什么。
2. 迭代
迭代是一种敏捷框架或者实现方式。它将项目分解成各个需求并于特定的时间段内完成,然后不停地循环这种流程,完成分解出来的各个需求,最终完成整个项目。迭代周期没有固定的时长,一般是1~2周,最多不建议超过一个月。在迭代过程中,可以使用一些不同的方法帮助团队跟踪进度、计划和评审。在一个敏捷团队中,一般会有三种不同的角色以及对应的职责:
1)产品经理/负责人(product owner):负责需求的收集、筛选、分析、描述,以及需求优先级的制定、需求的排期等,从而保证团队最大价值的输出。
2)Scrum Master:负责运作各种迭代会议,并且保证团队按照敏捷的方式进行交付。与项目经理关注人的管理不同,Scrum Master更关注流程的管理。
3)开发团队:负责每个迭代中产品功能的开发和缺陷的修复。
除了角色之外,迭代是通过四种会议落实下去的。一个标准的迭代流程包含四个迭代会议(图2-5):计划会议、例会、评审会议和回顾会议。
图2-5 迭代框架
(1)计划会议
会议前,产品经理/负责人需要进行相关的需求收集和筛选,最终建立好产品功能列表(product backlog),也就是需求池。然后从需求池中预选出本次迭代需要完成的需求和任务,进行分析和排期,并对需求进行详细的描述,方便开发测试人员对需求的充分理解,避免因为需求理解不正确造成的返工。
计划会议一般在每个迭代的第一天召开,时长一般为1~2小时。会议的目的主要是确定本次迭代的工作项(sprint backlog)、优先级、工作量和时间表。会议最好涵盖产品、开发、测试、运维和业务人员。会议中,产品经理/负责人需要从需求池中预先选出本次迭代需要完成的工作项,基于现有资源,与团队共同确定本次迭代需要完成的工作项和评估相关工作量,业务人员或产品经理确定优先级并与团队针对各任务优先级达成一致。首先由产品经理/负责人讲解整体需求、场景和产品目标,再按照需求优先级依次讲解,并且最好可以确定用户故事的验收标准。团队成员一起讨论实现方式,以及评估工作量,并最终领取和分配相关任务。在产品经理/负责人讲解过程中,团队成员需要尽量提问,保证对需求的真正理解,避免变成产品经理/负责人的个人发言。另外,在需求讨论过程中,需要避免陷入细节讨论从而跑题和浪费时间,Scrum Master需要有会议控场能力。
在迭代工作项被选定并且分配任务后,相关需求需要被分解,一般来说工作量的粒度最好为1~3天。分配任务和拆分需求后,再制定时间表进行排期。理论上,Scrum Master定好计划后,不建议中间额外加入任务,打乱计划,但在实际工作中,有时会发生临时/紧急需求的加入。为了应对这种突发现象,相关的策略也可以在排期时制定。最后,Scrum Master可以与大家再做一次审阅,确认没有遗漏互相依赖的任务,确认相关人员都已经了解迭代工作项的内容,确认所有任务都被定义、评估和排期等。
(2)例会
例会(也称作站会)作为敏捷的几个典型会议之一,一般比较频繁(每天)但简短。例会要以价值交付为线索,从右向左检视需求的状态,聚焦于发现和处理价值流动中的问题。不应该依赖例会检查每个人的工作,价值交付的状态和问题应该已经清晰地体现在看板上,一个好的例会应该帮助团队了解整体的价值流动状况,促进有效的协作,并及时处理价值流动的问题,保障价值顺畅流动。
良好地设计和使用看板是高效例会的基础,因此,开例会前,需要在物理看板或者电子看板上搭建需求工作流。确保需求已经拆分成任务并分配给相关人员,并且拆分的粒度确保每天都能看得到进展,方便及时暴露风险和问题,最后保证每个人负责的需求和任务的状态及截止日期已经被更新。
开例会时,需要找一位协调人(比如Scrum Master)带领团队遵循看板六原则,从右往左检视各列任务和事项。从右往左,一方面体现价值拉动的方向,另一方面是为了更好地贯彻“暂缓开始,聚焦完成”的原则,让接近完成的需求尽快完成,以发挥它该有的机制,而不是开始更多的需求开发。每天例会的主要目的在于沟通和暴露问题。时间一般控制在10~15分钟,最好涵盖产品、开发、测试、运维和业务人员。参与例会的团队成员轮流进行更新——“昨天做了什么,今天计划做什么,困难和问题”。前两个问题更多是让大家了解彼此之间的工作,从而更好地协作,达到迭代的目的。陈述过程中应避免细节的陈述和讨论。一般来说,如果一分钟之内无法解决的话,就需要安排在会后进行解决。在整个例会过程中,Scrum Master需要控制会议节奏,并且关注项目/任务的进度和问题。比如,如果有人陈述或者讨论时间过长,这时Scrum Master需要站出来进行提醒或者阻止其发言,并建议线下继续讨论。除此之外,Scrum Master还需要注意开发中的工作量是否已超过预留的开发资源,开发中任务是否向需求对齐,以及需求是否按照既定的流转规则进行流转。当会议中识别出阻碍需求流动的问题时,要么现场解决,要么需要跟进记录要跟踪的问题和依赖项,方便会后处理。除了需求,也需要单独、快速地过一下缺陷的总体状况,从而保持缺陷库存的低水位。
在整个例会过程中,可以使用物理白板或者电子屏幕和工具进行可视化操作。团队可以根据场景,选择适合自己的物理看板或者电子看板。一般来说,团队在预算有限或者敏捷建设初期可以选用物理看板,这样上手容易。当敏捷建设已经进入状态,并且需要开始沉淀数据进行统计分析时,可以考虑更换成电子看板。物理看板的优势包括成本更低;可视化程度更高,更改方便;方便团队成员面对面交流。电子看板的优势包括可解决远距离协作的问题,打破空间限制;留档容易,保存方便,不会轻易丢失数据;可同时展示更多项目和数据,并且可进行数据的统计,方便分析。
例会中讨论带来的变化以及引入的新问题,需要即时在看板上进行更新。对于例会而言,它只是给团队提供了一个沟通的机会和渠道,更多的协作和沟通应该即时或者在平时和更小范围内发生,而不是过度依赖例会来做团队协作和沟通。另外,对于例会迟到的同事需要有相关的处理办法,最终尽量避免此类事件。总之,例会上不需要检视每一个需求或任务项,本着“促进价值顺畅流动和交付”的目的,需要重点关注影响价值流动的问题和阻碍项。
例会过程中的信息需要透明,会上遗留的风险和问题需要跟进,做小范围讨论或者解决。另外,例会后看板应处于最新的状态,反映例会讨论的结果。最后团队成员需要了解项目的整体进展和状态,并且清楚工作的优先级。
(3)评审会议
评审会议的主要目的是验收完成的需求是否达标和利益相关方或者客户是否满意,并且收集客户反馈。评审会议一般在一个迭代的最后一天进行,时长1~2小时。会议前,产品经理/负责人或者开发人员需要准备好演示环境和演示数据。另外,在会议开始前最好重申本次迭代的目标,起到提醒团队成员的作用。敏捷开发中,计划会议和评审会议是两个不同目的的会议,但在实际工作中,计划会议和评审会议经常会一起召开,或者连续召开,因为参会的角色基本上是相同的(产品负责人和开发、测试、运维人员等)。会议目的是对上一个迭代的完成情况、问题和反馈的回顾和总结,以及下一个迭代的计划制定。
评审会议的主要形式是产品团队根据需求的优先级展示本次迭代的结果和产品新功能,或者缺陷的修复情况。在展示过程中,尽量简要陈述,不要陷入技术细节的陈述和讨论,也不要演示太多缺陷的修复,除非这个很有必要。利益相关方可以在演示过程中提出意见,但不做讨论,只是做记录收集意见,会后再进行沟通。除非利益相关方要求,否则不展示未完成的功能,因为只有已经完成的功能才能给客户带来价值。如果使用了电子看板,则可以用来展示计划的工作。应保证所有人员都目标清晰,如果有人对产品不了解,则需要花几分钟对产品进行描述。在产品新功能实现结果的描述过程中,如果产品负责人想要改变功能,或者有一个新的想法,以及项目遇到的阻碍还没有解决,则需要把这个新的改动、想法和问题都添加到待做功能列表里。整个迭代验收评审的输出需要包括:产品负责人是否认可团队的完成结果;用户故事是否满足验收标准;相关文档是否具备;是否存在其他的技术约定限制以及用户的反馈等。
(4)回顾会议
回顾会议是Scrum Master的几个会议中最重要的,但往往是最容易被忽略的,因为不像其他会议都是在讨论与项目和需求相关的工作,回顾会议是以人为本,其目的更多是针对团队本身的问题和改进,提高产能和提升团队工作效率,而非项目本身。会议建议控制在1~2小时。
回顾会议一般不直接进入主题,而是需要营造一个轻松的便于讨论问题的环境。Scrum Master可以在期间重申此次回顾会议的目的。接下来开始收集数据和信息,可以围绕三个问题展开——本次迭代做得好的部分、不够好的部分和可以改进的部分。针对可改进方面制定目标。问题暴露出来后,需要进行的改进不需要选择太多,集中精力在一到两个优先的问题上改进,制定解决方案和计划,并且跟踪改进状况。
进行回顾会议需要注意的事项包括:
1)不要让回顾会议变成批判会议,防止大家不敢开口,激励团队成员发言。
2)讨论的内容不要不着边际,空洞无物。
3)不能对大的问题视而不见。
4)碰到问题时不要互相指责、推脱。
5)收集数据一定要落到具体实处,并且对事不对人。
6)一定要探求根本原因并且制定解决方法,持之以恒贯彻执行。
7)不要因为所谓的“忙”而放弃回顾会议。
3. 看板
看板是以价值流动为基础进行设计的。为了分析价值流,需要首先识别团队交付的价值类型,一般团队交付的价值类型包括业务需求、关联需求、改进需求和其他任务等。其他任务一般包含开发和测试过程中发现的缺陷。一般来说业务需求占的比重会比较大。在进行看板设计时,首先要确定的是价值流动所经历的主要工作步骤,如需求收集、开发、测试等。在这些步骤之间可能会存在明显的交接或等待,如计划后等待开始实现、开发完成后向测试移交等。等待环节虽然没有具体的工作,却也占用了价值流动的时间,并可能产生积压,而且对于研发效能来说这些都是无效时间,即不产生价值的时间,最终影响了整个交付周期。
图2-6显示,用户需求在流动过程中要么正在被处理,要么已处理完成,等待进入下一个阶段,所以会停留在某个状态并形成队列(工作列和等待列)。队列的划分可多可少,具体细化到哪一个级别,需要考虑任务是否会在某个阶段显著停留,或者使用者是否需要特别关注某些阶段。另一个需要注意的问题是从哪个阶段开始,到哪个阶段结束。理论上,端到端的看板应该是从需求或者问题被提出开始,到需求被交付或者问题被解决结束。但实际上,团队可以从自己关注或者可以影响到的局部流程开始,并随着时间的推移,寻求向上游和下游的延伸,以促进整个组织的协作和需求端到端的顺畅流动。明确了看板的起止阶段后,就可以根据团队的具体情况设置中间的各阶段了。
图2-6 看板中的需求工作流
看板的目标是实现顺畅和高质量地交付有效价值,所以看板的设计就是使用可视化元素建模和反映价值流动过程,需要真实反映团队协作交付的价值和暴露问题。看板的设计可以分为以下几个阶段:
1)分析价值流动过程。
2)选取可视化设计元素。
3)用看板建模价值流动过程。
在分析完价值流动过程和选取可视化设计元素之后,就可以开始设计团队的可视化看板了。需求作为价值,是产品经理的输入,看板关注的是价值流动,不是任务完成的情况。需求的状态和问题需要在看板上清晰地表现出来。同时,在开发中的需求也可以拆分成各种子任务,从而拉通各角色之间的协同。这样既可以看到价值的流动,也可以看到任务的进展和问题。需求管理中常见的问题如下:
1)瓶颈:在软件开发的每个阶段,可能会出现需求积压形成队列的情况,这就是瓶颈所在。瓶颈是例会首先需要关注的问题,因为系统的流量往往是由瓶颈决定的,不解决瓶颈问题,价值将无法顺畅地流动。看板上的表现就是某个阶段的卡片数量特别多。另外,在安排任务时,对于同一个开发人员,建议同时进行中的任务数量不要超过两个,以便集中精力完成单个需求,促成价值的流动,避免队列中出现积压形成瓶颈。
2)缺陷:缺陷会阻碍需求的流动,而且缺陷数量多,容易造成需求积压产生瓶颈,从而阻碍其他需求进行流动。这种影响需求流动的缺陷需要及时解决。所以平时的例会需要简单了解一下缺陷的整体状况,保证缺陷被及时发现、解决并关闭。为了保证让存量的缺陷保持在低水平,建议缺陷可以做到日清,也就是当天的缺陷当天解决。
3)重点关注的需求:需要标注需求的优先级,价值或风险偏高的需要重点关注。
4)阻碍和问题:即因为外部(如依赖)或内部(如缺陷)等原因无法正常流动的需求。团队需要关注被阻碍的需求,分析、跟踪并推动问题解决,及时恢复需求的流动。另外,没有反映在看板上的问题也需要被思考和关注。
5)即将到期的需求:对于有明显完成时间要求的需求,在即将到期之际,需要特别关注(比如用颜色标注进行突出),以确保承诺的达成。
6)中断和闲置:指某个阶段没有正在进行中的需求和任务,价值流出现中断。此时可能会出现某些资源被闲置的状况,从而影响整个交付效能。
2.2.2 持续集成、持续交付和持续部署
持续集成(Continuous Integration)是指在软件开发过程中,频繁地将代码集成到主干上,然后进行自动化构建和单元测试,方便团队快速、频繁地得到构建和单元测试的结果和发现的错误,确定新代码和原代码是否能正确地集成在一起。持续集成的目的就是让产品可以快速迭代,同时还能保持高质量。其核心是,代码集成到主干之前,必须构建成功(有时也需要通过自动化单元测试),否则不能进行集成,从而最大限度地减少风险,降低修复错误代码的成本。Martin Fowler曾经说过:“持续集成并不能消除缺陷,但是让它们非常容易被发现和改正。”
持续交付(Continuous Delivery)是指在持续集成的基础上,将集成后的代码部署到测试环境进行接口测试、UI测试、性能测试或者安全测试,验证通过后再手动部署到生产环境。持续交付能够以较短的周期频繁地完成小粒度的需求交付。频繁短小的交付周期使得开发团队可以更快地收到软件开发的反馈,从而实现更有效率的修正和反应。
持续部署(Continuous Deployment)是指在持续交付的基础上,将评审通过的代码自动化部署到生产环境。由于整个流程全部自动化、无人工参与,所以也就是我们通常意义上的生产环境一键部署。
图2-7对比了持续集成、持续交付和持续部署的区别。然而,实际软件开发环境的搭建、配置和管理是非常复杂的,从头到尾全部实现自动化持续部署比较困难。大部分情况,尤其在传统行业中,生产环境部署是需要通过一道甚至几道评审批准才可以执行自动化部署的。因此,实际工作场景下大部分情况仍然是持续交付。在技术和工具能力具备的情况下,对一些小的、独立的、不重要的变更,可以尝试进行持续部署。
图2-7 持续集成、持续交付和持续部署