经过十多年的发展,敏捷软件开发已经从一种前卫的开发方式转变为广泛应用于各大软件公司的主流技术,成为汽车行业的主要技术。互联网行业。种趋势。随着软件定义汽车等概念的兴起,汽车软件的价值不断增加。电气化、网络化、智能化、共享化背后需要强大的软件能力。软件能力不仅体现在构建高质量的软件产品上,更体现在软件产品的快速迭代,以满足快速发展的需求。能够适应不断变化的市场需求。这样的变化无疑给汽车软件开发带来了新的挑战,同时也带来了巨大的机遇。新玩家陆续进入市场,期望在软件和用户体验上赢得市场,而传统汽车制造商正在重新审视组织架构、人才、流程、职责等方面,以适应新的变化,成为软件驱动的公司。持续集成/持续发布(ContinuousIntegrationandContinuousDelivery)是敏捷软件开发中的核心流程。本文将从持续集成/持续发布的角度探讨汽车软件开发过程中的代码管理和发布过程。01传统汽车软件的开发过程传统汽车软件的开发严重依赖于供应商。汽车制造商提出要求,供应商负责软件编写和实现。近十年来,汽车电子设备数量快速增长,车内电子控制单元(ECU)的数量从十几个增加到数百个,带来了软件复杂度的快速增加。除了汽车的各种功能带来的软件复杂性之外,汽车电子产品往往在软件和硬件方面对设备的高可靠性和稳定性有严格的要求。这些要求在消费电子,甚至医疗电子和工控产品中都没有。因此,为了满足功能安全等需求,往往需要对汽车的软硬件进行额外设计。面对如此复杂的系统,汽车行业制定了很多标准和方法论来规范开发过程,而在软件开发过程中,最著名的就是ASPICE(AutomotiveSoftwareProcessImprovementandCapabilitydEtermination)。AutomotiveSPICE,简称ASPICE,是汽车领域ISO/IEC15504(SPICE)国际标准的修改版。其目的是评估汽车行业电子控制器供应商开发的流程。ASPICE建立在V模型之上,它需要与每个开发阶段相对应的测试阶段。这是一个严格的模型,需要严格的评估以确保持续的评估和开发。下图是ASPICE中定义的一个典型的开发流程:来自:https://www.automotivespice.com左侧V模型包括需求分析、系统设计、架构设计、模块设计、编码;V模型右侧包括单元测试、集成测试、系统测试、验收测试。从上面可以看出,V模型是一种类似于瀑布的开发模型。开发模式是线性的,直到整个过程结束,厂商才能看到开发结果。虽然在实际过程中,可以进一步分解成更小的任务进行验证,但是阶段的划分还是比较固定,阶段之间会需要大量的文档。02敏捷开发理念传统上,汽车上装载的软件一旦售出就不会更改,升级需要在线下4S店完成。在这种情况下,基于V模型的软件开发有利于需??求和过程管理,明确范围和进度。然而,这种情况正在改变。一方面,消费者对新技术越来越感兴趣,尤其是与用户直接交互的信息娱乐系统或智能驾驶功能。用户希望不断完善功能,获得新技术。无需换新车;另一方面,随着车载固件升级(FOTA)和应用软件升级(SOTA)技术的成熟,汽车制造商已经可以远程完成软件更新。软件和硬件的开发过程逐渐解耦,软件需要实现小步快迭代。这时候汽车软件的新老从业者开始思考如何转变,是将敏捷开发的理念应用到汽车行业,还是将敏捷开发与传统开发模式相结合。目标是实现效率和质量的平衡。与传统的计划驱动开发相比,敏捷开发有两个核心理念:1.适应性而非预测性;2.以人为本而非过程为本。计划驱动的工程期望在开发之前提出一个预测计划。该计划列出了整个项目的人员、资源和进度。软件设计也已预先完成,预计实现将符合此设计。衡量成功的标准是该计划的执行情况。敏捷计划是用于帮助控制变更的基线。敏捷团队的计划与传统团队一样仔细,但计划会不断修改以反映在项目中学到的知识。成功取决于软件提供的价值。计划驱动工程寻求一种结构,使个体差异最小化。这样的工业流程更具可预测性,能够更好地应对人员变动,并且更容易定义技能。敏捷工程将软件开发视为一项人类活动,参与其中的人员以及他们如何协作是成功背后的主要驱动力。03持续集成在敏捷开发的理念下,持续集成和持续交付(CI/CD)软件产品(部分厂商也在探索硬件产品敏捷开发的可能性)。持续集成和持续交付的重要特征是自动化和持续构建。下图展示了敏捷开发的主要流程:(来自:https://faun.pub/most-popular-ci-cd-pipelines-and-tools-ccfdce429867)持续集成和持续交付需要快速完成周期计划、编码、测试和发布。持续集成和持续交付并没有画成一个“圆圈”V模型。自动化测试和自动化发布是必不可少的组成部分。并且这个过程应用于每一次提交,也就是说每一次代码提交合并都会经过自动化测试,成为一个新的发布版本。为了保证效率,提交合并和版本发布时可以进行不同程度的测试。重要的是不断获取版本,为进一步验证和最终交付给用户提供强有力的支持。为了实现快速发布,CI/CD本身已经成为一个复杂的软件产品,需要专业的软件团队来维护,编写大量的代码来实现各种任务的调度,集成多个工具链来提高效率的整个过程。这对汽车制造商转变为敏捷软件开发是一个挑战。在转型期,产品开发效率往往因工具链不成熟而受到影响,甚至忽视必要的自动化测试和反馈,导致产品质量出现问题。04在代码分支模型的持续集成和持续交付过程中,需要考虑很多因素,包括但不限于工具链的选择、流程制定、服务器搭建等,以及代码分支模型的选择是持续集成团队和软件开发团队在前期需要定义和遵守的一个规范。下面将讨论持续集成过程中代码分支模型的选择。分支模型是软件开发团队在通过Git等版本控制系统编写、合并和交付代码时使用的策略。一个好的分支模型可以增强软件交付过程中的协作、效率和准确性。它定义了团队如何使用分支来实现和开发。一个好的分支模型往往可以实现以下目标:1.对持续集成的良好支持。2.保证高频集成。3.降低合并冲突和冲突处理的成本(在开发过程中,处理大量的合并冲突是开发者头疼的事情,容易出错)。比较常见的分支模型有:Git-flow、GitHubFlow、GitLabFlow和基于Trunk的开发。使用基于主干的开发是持续集成中常见的选择。下面简单介绍一下各个分支模型的特点。基于主干的开发基于主干的开发(TBD)是基于主干开发的分支模型,所有开发人员每天都将他们的更改直接集成到共享主干(主干或主干)中。理想情况下,主干始终处于可释放状态。下图说明了TBD的基本流程:(来自:https://trunkbaseddevelopment.com/#scaled-trunk-based-development)trunk-based开发的典型策略如下:1.开发基于trunk,没有长期存在的功能分支(featurebranch)。如果需要一个特性分支,它应该是本地的或短期的,并在几天内合并到主干中;2、躯干要保持健康可放的状态;4.修复应首先上传到主干,然后挑选到发布分支(这有助于确保所有修复并避免回退)。TBD非常适合持续集成。持续集成过程可以在主干上运行,验证每次提交,并在代码合并成功后进一步生成可交付成果。发布分支是为了更好的控制产品的质量。因为在实际过程中,主体虽然已经过验证,但缺少冻结过程,新的提交很可能会出现意想不到的问题。发布分支的存在有效地控制了这种影响。release分支checkout后,也可以用trunk做持续集成和交付。使用TBD的主要挑战在于,当有大规模的新特性需要开发时,高频集成会相对困难,开发者需要额外的工作(如使用标志位等)来避免功能不完整的情况产品运行。GitFlowGitFlow模型背后的主要思想是将工作分成不同类型的分支(主分支、开发分支、功能分支、发布分支、修复分支)。trunk分支和development分支都是long-lived的。下图是GitFlow的一个典型流程:(来自:https://docs.gitlab.com/ee/topics/gitlab_flow.html#git-flow-and-its-problems)虽然GitFlow使开发、修复、和发布分支是很清晰的,但是使用GitFlow对工程项目进行持续集成是有难度的。main和develop分支都存在很长时间,随着时间的增长,两者的差异可能会越来越大,难以自动化集成交付闭环。GitHubFlowGitHubFlow改进了GitFlow。开发者使用特性分支并定期将他们的特性分支推送到主干。发布通常直接从主干完成。每个开发人员创建一个新分支,即功能分支。当功能完成时,功能分支会合并到主干中。GitHubFlow对持续集成提供了很好的支持,但是功能分支可能会长期存在,影响软件集成的频率。另外,GitHubFlow的概念中没有发布分支,直接从主干进行发布,这会给软件的质量控制带来更大的挑战。GitLabFlowGitLabFlow在GitHubFlow的基础上增加了发布分支,对持续集成有很好的支持,也可以冻结需要提前发布的产品,更好的进行质量控制。它与TBD的主要区别在于,在模型的理念上,TBD鼓励高频代码的合并和集成。
