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