基于Bitbucket 和Bamboo 的嵌入式软件持续集成方法
2022-07-11邵奇年福丰
邵奇 年福丰
(中国直升机设计研究所 江西省景德镇市 333001)
1 引言
随着嵌入式功能需求赋予软件的能力越来越多,嵌入式软件的复杂度在不断上升,规模越来越大。然而,嵌入式软件对可靠性、安全性和稳定性的要求却并未降低,特别是涉及到航空航天、汽车电子等领域的嵌入式软件,更是在逐步提升软件质量和安全的标准。
面对上述趋势,大型嵌入式软件开始降低模块间的耦合度,增加模块数量,软件开发模式也逐渐从瀑布开发模式向敏捷开发模式变化,多人多团队同时开发不同模块和功能的场景愈发常见,软件开发后期会经历痛苦的多模块集成过程。为了解决这个问题,保证高质高效的完成项目,开发人员开始提炼集成过程中重复且无需人工干预的任务如软件构建、自动化测试等,并将这些任务交给计算机完成,全自动化的持续集成模式开始出现,通过这种模式可以使软件研发过程中的回归性和敏捷性达到最优。因此,在未来的嵌入式软件开发中引入持续集成是必须的,而如何开展持续集成工作和保证持续集成工作的高效性将成为软件开发中的一个重要问题。
2 软件持续集成概述
2.1 软件持续集成的简介
软件持续集成的主要工作是通过持续集成平台,使项目团队可以频繁的集成构建以及测试代码,并及时得到反馈。它是持续交付概念中的重要一环,也是DevOps 中的重要组成部分,主要涉及软件开发人员和测试人员。对于开发人员来说,通过持续集成可以让“发现错误的时间尽可能接近引入该错误的时间”,开发人员通过高频率的集成以及运行他们的代码更快的发现错误,减少后期集成的工作难度,提高软件开发效率。对于测试人员来说,持续集成将严格的软件测试工作真正的贯穿到软件生存周期的全过程中,更加高效的发现软件问题,提高软件质量。
借助于持续集成平台和相关工具,可以高效的组织不同团队间通过自动化工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付稳定软件。当前,持续集成正在快速推广,尤其在军工软件领域,据报道,美空军和海军通过使用持续集成方式,已经在军事军工体系的软件研发中获得重大收益。2019 年的一则报道指出,美军在45 天内将kubernetes 容器调度引擎、可弹性伸缩的微服务架构用于F16 和F22 战机,并对10 万人进行过培训,指导他们使用相关的新型技术工具。美国海军更是提出了C2C24 DevSecOps 计划,以期具备更快速的响应以迎接挑战,面对国际竞争势力日益彰显的时代,搭建适用于军工行业的持续集成平台,尤其是嵌入式软件的持续集成平台,构建符合国内的军事军工体系的新型软件研发迭代体系,显得尤为迫切且重要。
2.2 持续集成平台架构
针对上述问题可知,高效的持续集成过程是基于持续集成平台的,如何搭建正确合理的持续集成平台是解决持续集成问题的重点。建立持续集成平台的目标是能够快速的开展代码管理、软件构建、持续集成以及问题反馈等工作,为了便于开发人员更方便的使用持续集成平台,持续集成平台的架构经常为B/S(Browser/Server)架构,在这种架构下开发人员只要安装了浏览器,就可以登录服务器开展相关操作。
对于持续集成平台的服务端,如图1 所示其主要包括三个部分:唯一受信源、调度及展示平台以及基础支撑服务。唯一受信源提供代码仓库和开发分支的管理;调度及展示平台是持续集成平台的主要功能,通过与其它工具的协作,完成整个持续集成过程;而基础支撑服务则提供了持续集成中需要用到的一些基础能力,包括代码提交、代码编译、代码测试等功能。
图1:持续集成平台架构图
当前实现上述三部分的工具集已经较为丰富,其中受信源管理可以使用多种代码仓库如Github,Gitee,Bitbucket等搭配版本控制系统如SVN,ClearCase,CVS,Git 等;调度及展示平台可以使用Jenkins,CruiseControl,Bamboo 等;对于基础支撑服务则要结合具体的业务类型选择,如针对嵌入式可能会使用到开发工具如VS Code,Source Insight,构建工具Tornado,Workbench,测试工具Testbed、PcLint 等。
3 嵌入式软件持续集成平台的构建方案
本文的持续集成平台构建方案主要针对嵌入式软件,部分嵌入式软件的开发环境较为独立(如军工行业),难以便捷的使用互联网资源,本着方便快捷,环境稳定易搭建的原则,选择Bitbucket 作为代码仓库管理软件,并使用Bamboo工具进行持续集成实践。
3.1 基于BitBucket的代码仓库管理
在构建方案中,持续集成的基础是服务器端的代码仓库(唯一受信源),本文使用BitBucket 作为代码仓库的管理软件。下面对该软件及代码仓库的管理思路进行说明。
3.1.1 Bitbucket 介绍
Bitbucket 是和Github 旗鼓相当的集中式代码托管系统,可以采用Git 作为分布式版本控制系统,具备fork、PR、Bug 跟踪、自定义域名等常用功能,并且易于和其它Atlassian 产品联合使用。对于Bitbucket 而言,支持Git 是其重要属性,Git 是一个开源的分布式版本控制系统,可以有效、高速得处理从很小到很大的项目版本管理,相较于另一款流行的版本管理工具SVN 而言,它提供了不依赖于服务器的分布式管理方式、灵活使用的分支系统以及更多可以操控的细节,因而受到了广泛的欢迎。Bitbucket 提供的Pull Request(PR)机制也会被频繁使用。PR 是一种通知机制。该机制结合仓库访问策略,软件拥有者或核心开发人员就可以可控的合并代码,了解其它开发成员每次的更改内容,并及时作出反馈。
3.1.2 基于BitBucket 和Git 的源码库管理
基于Bitbucket 和Git 进行源代码库管理,主要分为两方面,一是仓库的管理,二是分支的管理。对于仓库的管理选择使用如下方式:Bitbucket 提供远端仓库的访问控制,管理人员和开发人员制定访问规则,来限制不同用户对于远端仓库的操作。通过fork 功能,对中央仓库进行派生,阻止其它开发人员随意向中央仓库写入,通过PR 来向中央仓库写入。通过这种仓库管理方式,达到对开发仓库和中央仓库的隔离,如图2 所示。
图2:仓库管理策略
其次,除了仓库访问具有策略以外,开发人员是在Git的分支上进行开发的,因而要制定相应的分支管理策略:使用GitFlow 来对仓库中的分支进行管理, GitFlow 最初由Vincent Driessen 提出,是现在比较流行的分支策略,如图3所示,从总体上来看,GitFlow 属于分支开发,主干发布的分支管理策略。代码最初只具有develop 分支,开发者基于该分支上的节点创建自己的分支用于开发新功能,功能开发完毕后,将其合并到develop 分支上,当某阶段所需功能开发完全后,选定某一时间点,图中对应节点D,对开发分支进行“功能冻结(feature freeze)”,基于该节点,创建一个发布分支(release)或测试分支(test),用于测试和Debug,经过一段时间的整体测试,确保代码已经达到要求,此时再将最终代码发布到主分支上。
图3:分支管理策略
3.2 基于Bamboo的持续集成实践
在使用代码仓库管理代码的基础上,还需要一个持续集成平台来开展持续集成工作,本文使用Bamboo 作为持续集成服务器软件。下面对该软件及其持续集成思路进行说明。
3.2.1 Bamboo 介绍
Bamboo 是一款用于持续集成构建的服务器软件,可以提供编译构建管理服务、自动化测试管理服务和基础环境管理服务,用户可以使用该软件进行持续集成,持续部署和持续交付,将构建,自动化测试整合于单个工作流中。其中编译构建管理服务主要包括构建任务管理和调度、构建集群管理及执行器调度,通过上述这些功能,Bamboo 可以接收和发送构建请求,调度相应任务到构建机上、建立和管理构建环境,以及通过执行器调用相应的构建工具进行构建。同时,Bamboo 也提供了自动化测试管理服务,主要包括测试任务管理、测试用例调度和测试集群管理,通过上述功能Bamboo 可以接收测试请求,反馈测试结果,按照需要执行测试任务,以及建立和监控测试环境。
3.2.2 基于Bamboo 的持续集成
在Bamboo 中,可以针对具体的持续集成过程,制定相应的持续集成计划(Plan),每个计划中,包含多个任务(task),如:代码检出任务,构建任务和测试任务等,任务会调用多种类型的脚本文件从而实现相关功能,完成持续集成实践。
对于代码检出任务而言,Bamboo 可以获知Bitbucket 代码仓库的状态,及时获知代码更新,以及快速的拉取指定代码仓库中的文件;对于构建任务而言, Bamboo 可以通过调度服务使用远程代理功能,将构建任务发送到对应的构建机上进行构建,如对Tornado 工程的构建就发送到具有该编译环境的机器上进行编译,并得到构建结果;对于测试任务而言,Bamboo 可以进行多种测试任务如“代码规范审查”和“代码动静态扫描”等。通过编写相应脚本,Bamboo 可以调用如Testbed等专业的软件测试工具对代码进行扫描分析,并得到相应测试和扫描结果。在完成持续集成计划的制定后,便可以通过Bamboo 开展一次持续集成实践,其实践过程如图4 所示。
图4:Bamboo 持续集成流程图
(1)开发人员提交代码到Bitbucket 中的代码仓库中,Bitbucket 告知Bamboo 代码已经更新。
(2)Bamboo 持续集成服务器发现代码变更后,通过任务管理功能,选择相应的持续集成计划,开始执行指定的持续集成任务,完成对于代码的构建和审查。
(3)得到相应的集成结果报告,并将该报告通知相关的开发人员。
4 持续集成实际应用
上文已经介绍了如何通过Bitbucket 管理代码仓库以及通过Bamboo 进行持续集成工作,接下来将两款软件联合使用,使用Bitbucket 管理代码,使用Bamboo 开展持续集成过程,包括调用Tornado 进行软件构建和Testbed 进行代码审查等功能,实现完整的持续集成过程。
4.1 持续集成约定
为了使持续集成过程有效且稳定的开展,形成一份尽量详细的持续集成约定是必要的,开发人员应当严格按照该约定进行持续集成工作。
限于篇幅原因,这里只展示部分重点约定:
(1) Bitbucket 中央仓库仅对开发人员提供read 权限,新团队或成员加入时,应向管理人员申请可用的派生仓库,来自于其它派生仓库的PR 将不被接受。
(2)使用Gitflow 分支模式,开发分支应当被命名为Develop_功能名,测试人员使用test 分支进行测试,且测试分支的代码不允许与Develop 合并,避免合入测试代码。
(3)工作人员检出工作分支后,应当像软件测试人员申请,关联一个持续集成计划。
(4)针对每次提交,均需要执行持续集成计划,且得到结果报告后,再开展后续开发。
(5)功能开发完成后,应当及时告知测试人员进行用户功能验收测试,并发起PR,PR 描述中应当包含关键内容说明,附件中最好添加持续集成结果报告。
(6)在批准PR 前,请核心团队完成代码审查,并给出评价,如果拒绝PR,则应当第一时间告知开发人员。
4.2 软件持续集成工作流
依据上述的持续集成约定,最终可以形成如图5 所示的工作流。
图5:持续集成工作流
图5 展示了完整的持续集成过程,其中,代码仓库和分支的管理使用Bitbucket 实现,而持续集成过程通过Bamboo完成。持续集成将贯穿整个功能开发阶段和质量保证阶段,对于每一个分支上提交的代码,均自动执行相应的持续集成计划,计划中的任务包括,使用tornado 构建工程、使用Testbed 扫描代码、反馈相应的分析报告等。该过程可以被分成4 个阶段:
4.2.1 工作分配阶段
如图6 所示,该阶段从主分支1.0 版本到A 节点,在该阶段,工作内容和开发人员被确定,管理人员通过Bitbucket向开发团队派生开发仓库。
图6:工作分配阶段
4.2.2 功能开发阶段
如图10 所示,该阶段从A 到D 节点,这个阶段中,开发人员持续的进行功能开发,并使用代码提交工具不断的提交代码(图7),并执行持续集成平台已经制定好的持续集成计划(图8)对提交的代码开展构建和测试工作,进行持续集成。在得到软件测试报告等反馈信息(图9)后,开发人员需要确认每次提交的代码是否正确无误,无问题后方可开展下一步的工作。
图7:代码提交
图8:持续集成计划图
图9:自动化测试报告
图10:功能开发阶段
4.2.3 质量保障阶段
如图12 所示,该阶段从D 节点到E 节点间,此时所有功能开发完毕,测试人员和仿真人员可以开展软件的完整功能验证和全面的代码测试分析,并得到测试结果,如图11所示,开发人员则通过反馈继续完善代码,并继续使用平台进行持续集成工作,直到得到满足用户所有功能需求且通过测试的可发布软件。
图11:测试问题反馈
图12:质量保障阶段
4.2.4 代码提交阶段
如图15 所示,该阶段从E 节点到最后主分支的2.0 节点,在这个阶段中,开发人员发起代码合并请求,中心仓库的管理人员对代码进行最后的审查,确认代码无误且风格统一后,合入并发布新版本(如图13、图14 所示),至此完整的软件开发阶段结束。
图13:分支合并
图14:合并记录
图15:代码提交阶段
4.3 工作流优势分析
基于上述的工作流进行持续集成具有如下优势:
(1)仓库用途明确,团队工作隔离。将开发仓库和发布仓库分离,将主分支和开发分支及功能分支分离,因而可以做到,在多个团队开发时,避免相互干扰,且有利于保证开发仓库的简洁。
(2)开发流程和持续集成过程明晰,整个开发流程被分为了,工作分配,功能开发,质量保证,代码提交四个大阶段,在每个阶段上进行的工作都清晰明了,且执行持续集成的时间点也有迹可循。
(3)代码质量可以得到较好保证,通过上述工作流,发布分支上发布的程序,必须经过持续集成验证、测试人员测试和核心团队审核三次确认才可以发布,因而可以保证较高的发布质量。
(4)Bitbucket 和Bamboo 的关联性较好,工作流实现较为便捷。
5 结束语
本文通过对持续集成方法的研究,采用代码托管工具Bitbucket 和持续集成软件Bamboo 构建了适用于嵌入式软件开发的持续集成平台,并使用该本平台开展了代码仓库管理、嵌入式软件构建和自动化代码扫描等持续集成实践,得到了完整的工作流。
使用该平台进行开发工作时,可以在功能分支和开发分支上进行高效的持续集成工作,及时发现软件错误,保障软件质量和安全性。并且,该工作可以通过脚本借助于相关软件和工具自动进行,不需要开发人员花费过多的额外精力,最大程度上减轻了集成工作的难度和工作量。