01.概述
CI/CD的核心概念是持续集成、持续交付,是一种通过在软件开发阶段引入自动化来频繁向客户交付软件的方法,能够预先解决新代码集成过程时可能引发的问题。
实际上,CI/CD在传统IT行业早已风靡多时,但汽车行业相比于传统IT行业有一定差异性,导致在车载软件的开发过程中,CI/CD的流程和标准会有所不同,如:车载软件的CI/CD流程短于传统,CD的过程只到持续交付环节,CI使用的静态检查和自动化测试的范围和工具会更针对汽车行业标准等。总的来说,其差异性体现在以下两个方面:
( 1 ) 车载软件多数为嵌入式软件的开发
与传统软件的CI/CD不同,车载软件的开发大部分是嵌入式开发,整个过程严重依赖硬件,而随着汽车电子电气架构变得越来越复杂,会出现更多硬件、软件及更多连接,硬件部分是传统 CI/CD 中从未遇到过的难题。
( 2 ) 车载软件对质量和安全要求更高
相比于传统IT行业,汽车电子对软件和硬件的质量和要求都远高于消费电子类,甚至高于医疗电子类和工业控制类产品。为了满足功能安全等方面的要求,汽车软件往往需要做一些额外设计。面对这样的复杂系统,开发人员也需要比传统开发更现代、更强大的软件开发流程、开发环境以及开发工具。
02.持续集成
持续集成(CI)是指频繁地(每天至少一次)将代码集成到主干,其好处主要有:
快速发现错误。每完成一点更新就集成到主干,可以快速发现、定位错误。
防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。
软件开发教父Martin Fowler说过:“持续集成并不能消除Bug,而是让它们非常容易被发现和改正。”持续集成(CI)开发人员将会频繁地向主干提交代码,这些新提交的代码在最终合并到主干前,需要经过自动化集成、静态代码解析和自动化测试流进行验证,目标是快速确认开发人员新提交的变更是正确且适合在代码库中进一步使用的,有助于降低总体构建成本,并在开发周期的早期发现缺陷。
( 1 ) 持续集成流程
▲图1 持续集成流程
如图1所示,典型的持续集成流程大致可以归结为以下4个步骤:
提交代码到代码仓库
触发持续集成
进行代码静态检查→ 自动集成→提交前的自动化测试→提交后的自动化测试
结果反馈
( 2 ) 代码管理
代码管理是CI/CD流程中不可或缺的一部分,包含了版本管理和代码审核两部分,版本管理方式决定了是否能够实践 CI/CD 及其实践策略。目前比较常用的版本管理工具有 GIT、SVN、RTC等,可以方便在CI阶段针对不同的分支和版本制定不同的集成和检查策略。代码管理部分目前比较主流的做法是:针对不同的分支和主干,采用不同的策略,包括触发策略和审查策略。
在触发策略上,可对个人分支采用提交触发的方式,即该分支上每次的提交都会触发检查,主要检查本次提交的代码本身有没有问题;而在集成分支上,一般则采用定时触发或合并触发方式,即设定固定的触发时间或每次有新的合并时才去检查,这部分则主要检查本次合并过来的代码是否会对原来的代码造成影响。
在审查策略上,对于个人分支部分,主要进行代码本身的静态、动态测试等;而对于集成分支,除了静态、动态的测试,往往还需要集成测试、系统测试等。当然,在代码集成时,除了自动化的测试审查外,引入人工审查也是有必要的,以最大程度保证代码的质量。
▲图2 代码管理
目前,市面上也有很多基于GIT的优秀工具,如Github、Gitlab、Gerrit等,集成了版本管理、代码审核等基本功能,再配合合适的分支模式(主干开发模式、Git-Flow模式、GithubFlow模式、Gitlab-Flow模式等),即可方便地支撑CI/CD流程。
( 3 ) 静态检查
代码静态检查可不需要代码运行,基于源代码层面对源代码使用规则进行分析和检查,有效提高代码质量。一些优秀的工具可以深入到代码程序的逻辑检查、内存使用情况的检查甚至更高层面的检查,有效提高代码的安全性、健壮性和运行性能。代码静态检查环节是持续集成中最常进行以及最容易实现的环节。在该环节中,一般输入源代码以及检查规则即可完成自动化的检查,但在此之外,还应该关注代码需要满足哪些规则,以及为何要满足这些规则,以此来提高开发工程师的开发能力。
在通常使用的静态解析工具中,开源的有Cppcheck、Cpplint、Findbugs、Spotbugs等,商用的有QAC、Klocwork等。部分汽车功能安全件有代码质量的要求,静态代码检查规则需要满足车载行业检查标准,常见的标准有Misra C,Misra C++;安全编码层面常用的标准有Cert C,Cert C++,Cert Java标准。商用软件能够覆盖目前的大部分检查规则。
自动化集成本质上是一个自动编译和打包的验证过程,借助软件开发时使用的编译和打包工具,对源代码进行编译、链接、打包,提前发现代码编译过程中的编写问题、链接过程中的依赖问题、打包过程中的配置等问题。
在汽车行业中,不同的目标平台往往需要不同的编译器,导致编译器工具繁多,常用的有HighTec、Tasking、Greenhills等。同时,车载软件的复杂性也导致编译环境非常复杂。在持续集成中,编译过程的自动化可较轻松实现,而复杂的编译环境适配才是持续集成在车载软件编译环节中需要重点关注的事情。
( 4 ) 提交前自动化测试
代码管理的分支审查策略建议在代码合并到正式分支前进行自动化测试。该步骤是为了保证计划合并到正式分支的代码本身没有质量问题,这样不仅能够减少开发人员测试工作,同时还能确保软件的质量。
对于这部分提交前的自动化测试,一般有以下几方面的要求:
测试需要尽可能快地完成。提交前的自动化测试每天可能发生几次到几十次,这取决于开发人员提交代码的频率,每个开发人员每次的提交都会触发该测试,因此开发人员需要尽快得到反馈,了解本次提交的代码是否有问题,如果有就进行修复,如果没有则进行后续的开发。因此,尽可能快的测试,能够保证开发的效率。
测试的范围通常是单个模块,为此提交前的自动化测试的测试方法通常是采用单体测试。对于功能安全件,对测试结果有一定的要求,需要根据测试的通过率对代码的行覆盖和条件覆盖有一定的要求。该项测试可以根据具体的内容要求来设定合适的评判标准。
在持续集成(CI)中,从检查策略来看,该环节的测试可以包含代码的静态、动态等环节的测试,目的是保证代码本身没有问题。从触发方式来看,一般会采用提交触发的方式。
( 5 ) 提交后自动化测试
相比于提交前的自动化测试,提交后的自动化测试强调的是代码合并到主干或者生产分支之后进行的测试,该环节的测试旨在验证集成进来的代码是否会对之前的系统产生影响,以减少集成完整系统后出现的问题。
对于该部分测试,执行的频率相对于提交前的测试频率较低,但同时执行时间较长,测试的范围更广,因为该环节会涵盖完整的系统。而对于测试的类型,该环节往往包含了集成测试、系统测试等。部分汽车功能安全件对测试结果有一定要求,而该项测试可以根据具体的内容要求来设定合适的评判标准。
在持续集成中,该部分的测试由于执行时间长、测试范围广等特点,一般触发策略会选择定时触发,时间点往往设定在资源长时间空闲的半夜去执行。一方面可以保证长时间的测试,另一方面也可以有效地利用资源。
03.持续交付
持续交付(CD)可以理解为持续集成流程的扩展,是对软件交付流程进一步自动化,以便随时快速安装到生产环境中。持续交付指在完成持续集成的情况下将软件进行发布,使软件随时处于可部署的状态,对于汽车行业中的持续发布,往往指的是将其发布到制品库中进行管理。它强调的是,不管怎么更新,软件是随时随地可以交付的。
当今时代是智能机械和智能系统的时代。据世界经济论坛等机构研究,2021-2030年,全球经济的主要增长动力来自机器经济,即智能化、互联化、自动化的机械,以及由此带来的经济驱动是这个世界目前主要的经济增长点。CI/CD有助于车企加快软件研发速度、更好地挖掘车辆在运营之后的商业价值,以及运营之后为客户提供更好的服务,是车企必须准备的能力,也是车企努力的方向。
文章来源:
AUTOSEMO《中国汽车基础软件发展白皮书 3.0》