l

2012年6月27日 星期三

當Branch遇到持續整合(3):Branch by Feature

June 25 16:17~17:50

螢幕快照 2012-06-25 下午4.11.40

 

這一集為各位介紹Branch by Feature(依功能而分支)這個模式。這個模式的目的很簡單,就是希望trunk上面的程式碼永遠保持著可以被釋出的品質。為了達到這個目的,開發人員就必須要:

  • 開發任何一個新功能的時候,就必須產生一個新的branch。假設鄉民們採用Scrum,在這個sprint裡面有五個story要完成。當開發人員要開始針對某一個story開始施工的時候,就必須先產生一個branch,然後在這個branch上面做開發
  • Branch上的程式必須被驗證後才可merge到trunk中。當開發人員在branch上面完成某一個功能之後,該功能必須要先通過測試人員的驗證,之後才可以merge到trunk中

Branch by Feature的概念就這麼簡單。但是要運作的好,還有幾件事情要留意的:

  • Trunk上面的異動每天必須要被merge到每一個branch中:看到這一點鄉民們可能覺得怪怪的,不是說所有的開發活動都必須在branch上面進行嗎,那為什麼trunk上面還會有程式異動需要merge到branch中呢?有,當某一個branch開發完成且merge回trunk之後,此時trunk的異動便需要merge回其他branch之中。以上圖為例,專案一開始同時間有Story 1與Story 2這兩個branch。當Story 1開發完成並且merge回trunk之後,trunk上的程式碼便需要儘快merge到Story 2 中。這個要求鄉民們應該已經清楚了,但是為什麼呢?每個story所代表的branch不是各自獨立開發嗎,那為什麼某個branch送交回trunk的結果要儘快merge到其他尚在開發中的branch呢?答案很簡單,為了避免之後其他branch送交回trunk造成broken build
  • Branch不可以活太久:如果開發團隊採用為期兩周的Scrum,每一個branch的生命週期才能才幾天而已。也就是說幾天之內就必須要完成一個story。如果一個branch活太久,例如超過一個月,就代表某個功能橫跨了兩個sprint才完成。這通常是story太大,必須要再細分的跡象。此外,branch活得太長,表示某項功能要很久之後才會被整合一次(假設持續整合系統只針對trunk上的程式進行整合)。當然看到這邊鄉民們可能會說,為什麼不幫每一個branch在持續整合系統上都設定一個建構專案?因為branch的生命週期很短,如果持續整合系統要針對每一個開發功能的branch都設定一個「短命專案」,那麼持續整合的工作量將會大大的增加,不見得每一個團隊都願意如此做。
  • 最大同時進行開發活動的branch數量不可大於每一個開發週期預計完成的story數量:簡單的說,同時進行開發的branch數量不可大於團隊所約定的最大WIP(Work in Progress)的數量,否則將會產生一大堆開發中但是都沒有被做完的工作,也就是Teddy經常說的半成品
  • Refactorying要小心:如果開發人員產生branch的目的是為了refactoring,那麼refactoring的結果要盡早merge回trunk,以避免產生merge衝突。
  • 配置守門員:如果可能的話,每次merge回trunk的程式碼都需要經過專案技術經理或是technical lead的檢視與批准。

***

基本上對於Branch的使用可以分成兩大類,第一類是覺得merge很麻煩,所以儘量不使用branch,這就造成了主要開發工作都在trunk上的Develop on Mainline。另一類可以看成有「潔癖」,認為trunk上的程式碼必須隨時保持可釋出的狀態。所以,所有的開發活動都必須要在branch上進行。近年來很流行的分散式版本控制系統(distributed version control system),像是Git,用branch的頻率簡直就跟喝開水一樣,非常適合用來支援Branch by Feature模式。

***

Branch by Feature讓trunk維持隨時都可以釋出的狀態,所有的開發都在branch上面進行,開發人員可以毫無後顧之憂地修改程式碼而不用怕一不小心就弄壞了trunk。看起來很棒,也很酷(不曉得為什麼使用很多branch的開發團隊感覺起來就比較酷一點XD)。但是從持續整合的角度來看,Branch by Feature是比較不好的一種方法。為什麼?原因Teddy剛剛已經說過了,什麼,沒看到…哇哩勒!請再看一次:

Branch如果活得太長,表示某項功能要很久之後才會被整合一次(假設持續整合系統只針對trunk上的程式進行整合)。那為什麼不幫每一個branch在持續整合系統上都設定一個建構專案?因為branch的生命週期很短,如果持續整合系統要針對每一個開發功能的branch都設定一個「短命專案」,那麼持續整合的工作量將會大大的增加,不見得每一個團隊都願意如此做。

看到這邊鄉民們應該只剩下最後一個疑問:哪種專案適合採用Branch by Feature?

Branch by Feature很適合使用於開放原始碼開發專案,此類專案的開發人員通常散布於全世界各地,而且不是任何阿貓阿狗都可以直接把程式碼貢獻到trunk中。通常開放原始碼專案會有一個人或是一個小團隊,負責審核「義工」所貢獻進來的程式碼(可能以patch的方式遞交給專案負責人),通過審核之後才會進到專案的trunk之中。而這些「義工」在開發某項功能,或是解決某個bug的時候,可以先在自己的本地端產生一份專案的branch,然後在此branch上面開發。

除了開放原始碼專案外,有些採用Kanban(看板)系統的團隊也會使用Branch by Feature。由於Kanban沒有像Scrum有開發週期(sprint)的概念,採行Kanban系統的團隊,可以更有彈性的決定釋出軟體的時間(這一點跟開放原始碼專案還挺像的)。因此保持trunk上的程式碼隨時都處於可釋出的狀態就顯得非常重要。在Scrum中,只要sprint結束時有一個潛在可釋出的軟體便可。從這個角度來看,採行Scrum的團隊並不需要嚴格要求「trunk上的程式碼隨時隨地都處於可釋出狀態」。換句話說,如果是小型的Scrum團隊,採用Develop on Mainline就挺合適的。什麼,你問那大型的Scrum團隊要採用哪種模式?等下一集你就知道了。

等一下,故事還沒結束。看了上一段不要以為採用Kanban的團隊就一定要使用Branch by Feature。根據Teddy讀了《Continuous Delivery》的感覺,除了使用在開放原始碼專案外,這本書的作者似乎不是很欣賞Branch by Feature這種模式,因為採用這種模式和持續整合的精神有所衝突。至於要不採用這種模式,就請鄉民們自行判斷一下吧。

***

友藏內心獨白:不是每種branch模式都是對持續整合很友善滴。

沒有留言:

張貼留言