汽車軟件敏捷開發(fā)和分支管理
?經(jīng)過十多年的發(fā)展,敏捷軟件開發(fā)已經(jīng)從一種前衛(wèi)的開發(fā)方式轉(zhuǎn)變成為在各大軟件公司中被廣泛應(yīng)用的主流技術(shù),變成了互聯(lián)網(wǎng)行業(yè)的一種潮流。隨著軟件定義汽車等概念的興起,軟件在一輛汽車中的價(jià)值正在不斷增加。電動(dòng)化、網(wǎng)聯(lián)化、智能化、共享化的背后都需要強(qiáng)大的軟件能力作為支撐,而軟件能力不僅體現(xiàn)在構(gòu)建出高質(zhì)量的軟件產(chǎn)品上,同時(shí)還體現(xiàn)在軟件產(chǎn)品的快速迭代以滿足快速變化的市場(chǎng)需求的能力之上。這樣的變化無疑給汽車軟件開發(fā)帶來了新的挑戰(zhàn),同時(shí)也帶來了巨大的機(jī)遇。新玩家紛紛入場(chǎng),期望在軟件和用戶體驗(yàn)上贏得市場(chǎng),而傳統(tǒng)的汽車制造商則正重新審視組織架構(gòu)、人才、流程、職責(zé)等方方面面以期適應(yīng)新的變化,成為軟件驅(qū)動(dòng)的公司。
持續(xù)集成/持續(xù)發(fā)布(Continuous Integration andContinuous Delivery)是敏捷軟件開發(fā)中的核心過程,本文將從持續(xù)集成/持續(xù)發(fā)布角度探討汽車軟件開發(fā)過程中的代碼管理和發(fā)布流程。
01 傳統(tǒng)汽車軟件的開發(fā)流程
傳統(tǒng)汽車軟件開發(fā)大量依賴于供應(yīng)商,汽車制造商提出需求,由供應(yīng)商負(fù)責(zé)軟件編寫和實(shí)現(xiàn)。在過去十幾年的時(shí)間里,汽車電子器件的數(shù)量增長(zhǎng)迅速,車內(nèi)電子控制單元(ECU)從十幾個(gè)增長(zhǎng)到了上百個(gè),帶來的是軟件復(fù)雜度的快速增加。除了汽車功能繁多所帶來的軟件復(fù)雜度,汽車電子類產(chǎn)品在軟硬上往往對(duì)設(shè)備的高可靠性、穩(wěn)定性有著嚴(yán)格的要求。這些要求在消費(fèi)電子類,甚至是醫(yī)療電子類和工業(yè)控制類產(chǎn)品上是沒有的。因此,為了滿足功能安全等要求,汽車的軟硬件往往需要做額外設(shè)計(jì)。面對(duì)這樣的復(fù)雜系統(tǒng),汽車行業(yè)制定了許多標(biāo)準(zhǔn)及方法論以規(guī)范開發(fā)過程,而在軟件開發(fā)過程中,最有名的是ASPICE(Automotive Software Process Improvement and CapabilitydEtermination)。
Automotive SPICE簡(jiǎn)稱ASPICE,是ISO/IEC 15504(SPICE)國際標(biāo)準(zhǔn)在車用領(lǐng)域下的修改版本。其目的是為了評(píng)估汽車產(chǎn)業(yè)中,電子控制器供應(yīng)商開發(fā)的流程。
ASPICE 建立在 V 模型之上,它需要與每個(gè)開發(fā)階段相對(duì)應(yīng)的測(cè)試階段。這是一個(gè)嚴(yán)格的模型,需要嚴(yán)格評(píng)估以確保持續(xù)的評(píng)估和發(fā)展。下圖是ASPICE中定義的典型開發(fā)流程:
From: https://www.automotivespice.com
V 模型的左側(cè)包括需求分析、系統(tǒng)設(shè)計(jì)、架構(gòu)設(shè)計(jì)、模塊設(shè)計(jì)、編碼;
V 模型的右側(cè)包括單元測(cè)試、集成測(cè)試、系統(tǒng)測(cè)試、驗(yàn)收測(cè)試。
從上面可以看出,V模型是一種類似于瀑布式的開發(fā)模型,開發(fā)模型是線性的,制造商只有等到整個(gè)過程的末期才能見到開發(fā)成果。盡管在實(shí)際過程中,可以進(jìn)一步分解成更小的任務(wù)進(jìn)行驗(yàn)證,但階段的劃分依然比較固定,階段之間會(huì)要求大量的文檔。
02 敏捷開發(fā)的理念
傳統(tǒng)裝載在汽車上的軟件往往一旦賣出,就不會(huì)再變更,升級(jí)需要去線下4S店完成。在這樣的情況下,基于V模型進(jìn)行軟件開發(fā)有利于需求和過程管理,明確范圍和進(jìn)度。不過,這樣的情況正在發(fā)生變化,一方面,消費(fèi)者對(duì)新技術(shù)越來越感興趣,特別是與用戶有直接交互的信息娛樂系統(tǒng)或者是智能駕駛功能,用戶希望功能不斷完善,獲取新的技術(shù)不用換一臺(tái)新車;另一方面,隨著車內(nèi)固件升級(jí)(FOTA)和應(yīng)用軟件升級(jí)(SOTA)技術(shù)的成熟,汽車制造商已經(jīng)有可能在遠(yuǎn)程完成軟件的更新。軟件和硬件的開發(fā)過程正在逐步解耦,軟件需要實(shí)現(xiàn)小步快跑,不斷迭代。這個(gè)時(shí)候,汽車軟件的新老從業(yè)者們開始思考如何改變,是否能在汽車行業(yè)中應(yīng)用敏捷開發(fā)的理念或者是將敏捷開發(fā)與傳統(tǒng)的開發(fā)模型進(jìn)行結(jié)合。目標(biāo)是獲得效率和質(zhì)量的平衡。
與傳統(tǒng)計(jì)劃驅(qū)動(dòng)的開發(fā)相比,敏捷開發(fā)有兩個(gè)核心理念:
1. 自適應(yīng)而不是預(yù)測(cè);
2. 以人為本而不是流程為導(dǎo)向的。
計(jì)劃驅(qū)動(dòng)的工程期望在開發(fā)之前提出一個(gè)預(yù)測(cè)計(jì)劃。該計(jì)劃列出了整個(gè)項(xiàng)目的人員、資源和進(jìn)度。軟件設(shè)計(jì)也是預(yù)先完成的,預(yù)計(jì)實(shí)現(xiàn)與此設(shè)計(jì)一致。成功的衡量標(biāo)準(zhǔn)是這個(gè)計(jì)劃的遵循程度。
敏捷計(jì)劃是用來幫助控制變更的基線。敏捷團(tuán)隊(duì)的計(jì)劃與傳統(tǒng)團(tuán)隊(duì)一樣仔細(xì),但計(jì)劃會(huì)不斷修改以反映在項(xiàng)目中學(xué)到的東西。成功取決于軟件提供的價(jià)值。
計(jì)劃驅(qū)動(dòng)的工程尋求一種結(jié)構(gòu)以將個(gè)體差異減少到最低。這樣的工業(yè)流程更具可預(yù)測(cè)性,在人員轉(zhuǎn)移時(shí)能夠更好地應(yīng)對(duì),并且更容易定義技能。
敏捷工程將軟件開發(fā)視為人類活動(dòng),其中涉及的人員以及他們?nèi)绾螀f(xié)作是成功背后的主要驅(qū)動(dòng)力。
03 持續(xù)集成
在敏捷開發(fā)的理念之下,持續(xù)集成和持續(xù)交付(CI/CD)軟件產(chǎn)品(有的制造商也同樣在探索硬件產(chǎn)品敏捷開發(fā)的可能性)。持續(xù)集成和持續(xù)交付的重要特點(diǎn)是自動(dòng)化、不斷構(gòu)建,下圖是敏捷開發(fā)的主要過程:
(From:https://faun.pub/most-popular-ci-cd-pipelines-and-tools-ccfdce429867)
持續(xù)集成和持續(xù)交付需要快速完成計(jì)劃、編碼、測(cè)試、發(fā)布的循環(huán),持續(xù)集成和持續(xù)交付并不是畫成“圓”的V模型,自動(dòng)化的測(cè)試和自動(dòng)化的發(fā)布是不可或缺的組成部分。而這一過程應(yīng)用于每一次提交,意味著每一次代碼的提交、合并都會(huì)經(jīng)過自動(dòng)化測(cè)試,成為一個(gè)新的發(fā)布版本。為了保障效率,可在提交合并和版本發(fā)布時(shí),進(jìn)行不同程度的測(cè)試。重要的是持續(xù)獲得版本,為進(jìn)一步驗(yàn)證和最終交付給用戶提供有力支持。
為了完成快速發(fā)布,CI/CD本身也成為了一個(gè)復(fù)雜的軟件產(chǎn)品,需要專業(yè)的軟件團(tuán)隊(duì)進(jìn)行維護(hù),編寫大量代碼以實(shí)現(xiàn)各個(gè)任務(wù)的調(diào)度,集成多個(gè)工具鏈以提高整個(gè)過程的效率。而這也是汽車制造商實(shí)現(xiàn)敏捷軟件開發(fā)轉(zhuǎn)型的一個(gè)挑戰(zhàn)。在過渡期間,往往會(huì)因?yàn)楣ぞ哝湹牟怀墒於绊懏a(chǎn)品的開發(fā)效率,甚至于忽略必要的自動(dòng)化測(cè)試和反饋,使產(chǎn)品的質(zhì)量出現(xiàn)問題。
04 代碼分支模型
持續(xù)集成和持續(xù)交付的落地過程中,需要考量不少因素,包括但不限于工具鏈的選擇、流程的制定、服務(wù)器的搭建等等,而代碼分支模型的選擇是持續(xù)集成團(tuán)隊(duì)和軟件開發(fā)團(tuán)隊(duì)需要在早期進(jìn)行定義并共同遵守的一項(xiàng)規(guī)范,下面將對(duì)持續(xù)集成過程中代碼分支模型的選擇進(jìn)行探討。
分支模型是軟件開發(fā)團(tuán)隊(duì)通過Git 等版本控制系統(tǒng)編寫、合并和交付代碼時(shí)采用的策略。好的分支模型增強(qiáng)了軟件交付過程中的協(xié)作、效率和準(zhǔn)確性。它定義了團(tuán)隊(duì)如何使用分支來實(shí)現(xiàn)并開發(fā)。
良好的分支模型往往可以達(dá)到以下目標(biāo):
1. 對(duì)持續(xù)集成的良好支持。
2. 確保高頻率的集成。
3. 減少合并沖突和處理沖突的成本(在開發(fā)過程中,處理大量合并沖突是開發(fā)人員非常頭痛的問題,并且很容易發(fā)生錯(cuò)誤)。
比較常見的分支模型有:Git-flow、GitHub Flow、GitLab Flow和Trunk-based development。
使用Trunk-baseddevelopment是持續(xù)集成中常見的選擇,下面簡(jiǎn)單介紹一下各個(gè)分支模型的特點(diǎn)。
Trunk-based development
Trunk-based development (TBD) 是基于主干開發(fā)的一種分支模型,所有開發(fā)人員每天都將他們的更改直接集成到共享主干(trunk或master)中。理想情況下,主干始終處于可發(fā)布狀態(tài)。
下圖說明了 TBD 的基本流程:
(From:https://trunkbaseddevelopment.com/#scaled-trunk-based-development)
基于主干開發(fā)的典型策略如下:
1. 開發(fā)基于主干,沒有長(zhǎng)期存在的功能分支(feature branch)。如果需要功能分支,它應(yīng)該是本地的或短期的,并在幾天內(nèi)合并到主干;
2. 主干應(yīng)保持健康且可發(fā)布的狀態(tài);
3. 發(fā)布分支(release branch)從主干中“即時(shí)”檢出(checkout)(例如發(fā)布前 2 周)并在發(fā)布之前凍結(jié)(例如發(fā)布前 1 周);
4. 修復(fù)應(yīng)該首先上傳到主干,然后cherry-pick到發(fā)布分支(這有助于確保主干中包含所有修復(fù)并避免回退)。
TBD非常適合持續(xù)集成,持續(xù)集成的流程可以在主干上運(yùn)行,對(duì)每次提交進(jìn)行驗(yàn)證,在代碼成功合并后進(jìn)一步生成交付物。發(fā)布分支是為了更好管控產(chǎn)品的質(zhì)量。因?yàn)閷?shí)際過程中,盡管主干經(jīng)過驗(yàn)證,但缺少凍結(jié)過程,新的提交容易造成意想不到的問題,發(fā)布分支的存在有效控制了這一影響。在發(fā)布分支檢出后,同樣可以與主干一起進(jìn)行持續(xù)集成和交付。
使用TBD的主要挑戰(zhàn)是當(dāng)有體量較大的新特性需要開發(fā)時(shí),高頻集成會(huì)相對(duì)較難,開發(fā)人員需要額外的工作(如使用標(biāo)志位等方式),避免不完整的功能在產(chǎn)品中運(yùn)行。
Git Flow
Git Flow模型背后的主要思想是將工作隔離到不同類型的分支(main, develop, feature, release, hotfix)。主干分支和開發(fā)分支都是長(zhǎng)期存在的。下圖是Git Flow的典型流程:
(From:https://docs.gitlab.com/ee/topics/gitlab_flow.html#git-flow-and-its-problems)
雖然Git Flow使開發(fā)、修復(fù)、發(fā)布分支很清晰,但很難在采用Git Flow的工程項(xiàng)目上進(jìn)行持續(xù)集成,main和develop分支都是長(zhǎng)期存在的,且隨著時(shí)間的增加,兩者可能會(huì)有越來越大的差異,難以形成自動(dòng)化的集成交付閉環(huán)。
GitHub Flow
GitHub Flow 對(duì)Git Flow進(jìn)行了改進(jìn)。開發(fā)人員使用功能分支(feature branch)并定期將其功能分支推送到主干。發(fā)布通常是直接從主干完成的。每個(gè)開發(fā)人員都會(huì)創(chuàng)建一個(gè)新分支,即功能分支。功能分支在功能完成后合并到主干。
GitHub Flow對(duì)持續(xù)集成提供良好支持,但功能分支可能會(huì)存在較長(zhǎng)的時(shí)間,從而影響軟件集成的頻度。
另外,GitHub Flow的概念中并沒有發(fā)布分支,發(fā)布直接從主干進(jìn)行,會(huì)對(duì)軟件的質(zhì)量的管控帶來更大的挑戰(zhàn)。
GitLab Flow
GitLab Flow在GitHub Flow的基礎(chǔ)上增加了發(fā)布分支(release branch),對(duì)持續(xù)集成有良好的支持,也可以對(duì)需要發(fā)布的產(chǎn)品提前進(jìn)行凍結(jié)以便對(duì)質(zhì)量進(jìn)行更好的管控。它和TBD的主要區(qū)別是在模型的理念上,TBD更加鼓勵(lì)高頻率的代碼合并和集成。?