l

2012年6月25日 星期一

當Branch遇到持續整合(1):Develop on Mainline

June 25 10:49~12:33

螢幕快照 2012-06-25 上午10.58.27

 

上週Teddy提到最近讀了《Continuous Delivery》這本書,書中介紹了四種很有用的「分支/合併模式」(branch/merge pattern),並且討論這四種pattern與持續整合之間的關係。接下來就分幾天把這四個pattern介紹一下,哪四個?

  1. 在主幹上開發(Develop on Mainline)
  2. 為了釋出而分支(Branch for Release)
  3. 依功能而分支(Branch by Feature)
  4. 依團隊而分支(Branch by Team)

Develop on Mainline

第一種模式叫做「在主幹上開發」,顧名思義就是說:開發人員主要的開發活動都在主幹上進行,沒事不要使用分支(插花說明一下,這裡的主幹指的是版本控制系統,像是CVS或SVN上面的Trunk,又稱作Mainline)。這種方法聽起來有點怪怪的,很多介紹版本控制系統的書不是都鼓勵開發人員要使用分支,為什麼這個模式反而建議大家沒事不要使用分支?

要回答這個問題之前,要先說明一下版本控制系統的使用情境,基本上可以從兩個角度來探討:

  • 程式開發:從程式開發的角度來看版本控制系統,為了避免提交到trunk裡面的程式碼有問題,導致軟體專案無法成功建構,產生所謂的broken build,因此有些實務做法會建議開發人員頻繁地使用分支(branch)功能。這種想法的出發點是:開發人員在分支上開發新的功能,一旦新的功能通過測試確定都沒有問題之後,才可以把分支中的程式合併(merge)回trunk,這樣子便可常保trunk上的軟體永遠都保持在可以隨時釋出的狀態。聽起來很好,但是頻繁使用branch有兩個主要的缺點:
    • 版本控制系統中的專案結構變得比較複雜,因此增加merge的成本。
    • 降低持續整合系統的功效。開發人員可能花費好幾天的時間在branch上開發程式,之後才把完成的程式merge回trunk,此時才會觸發持續整合系統執行一次建構。換句話說,持續整合系統就變得不是那麼的「持續」了(好幾天才建構一次,就不能說自己有在實施持續整合了)。
  • 持續整合:為了建構,每一個存在於持續整合系統中的專案上都必須要指定一個版本控制系統來源位置(code repository)。因此,從持續整合的角度來看版本控制系統,如果所有的開發活動都在trunk上進行,那麼持續整合系統中便只需要指定到trunk便可建構一個專案。假設有一個專案同時在trunk與branch上開發,而團隊又想要實施持續整合,那麼至少需要在持續整合系統上為此專案設定兩個持續整合專案。

看完上面的分析之後,鄉民們應該知道Develop on Mainline這個模式的用意了。開發團隊如果要採用這個模式,需要搭配幾點配合措施方可成功:

  • 頻繁地簽入(check-in or commit)程式碼到版本控制系統中:每次有程式碼被簽入至版本控制系統中便會驅動持續整合系統執行一次建構。因此,如果開發團隊採用Develop on Mainline,便需要經常性地將手邊的程式碼送交到版本控制系統中,否則就無法達到持續整合的目的。至於何謂「頻繁」?理想上完成一小段程式碼,例如寫完一個method與該method的單元測試便可送交程式碼。如果一開始無法做到這麼極端,最低限度一天至少也要送交一次(通常是下班前)。
  • 允許trunk上存在短暫的broken build:由於開發人員直接將程式碼送交到trunk上,因此難免有時候送交進去的程式碼可能會造成建構失敗,此時trunk裡面的程式碼就是「不健康的程式碼」。如果有其他開發人員在這個時候不小心checkout或是update了trunk上的程式碼,那麼這位倒楣的開發人員就拿到一套有問題的程式碼。如果該開發人員沒有注意到這個問題繼續開發程式,最糟的情況可能導致做白工,或是要花很多時間才可以把自己個程式碼merge回trunk。看到這邊鄉民們一定會想:「這樣不是很危險?」是啊,當發生broken build而沒有人發現是一件很危險的事。Develop on Mainline這個模式的出發點是:由於開發人員非常頻繁地送交程式碼,所以專案也會非常頻繁地被建構與整合。如果送交的程式碼不幸引起broken build,至少能夠被持續整合系統給發現,這也正是實施持續整合的目的:早期發現,早期治療。只要團隊成員可以清楚地從持續整合系統中知道目前專案的健康狀態,那麼短暫的broken build也就沒有那麼的可怕。
  • 指派專人關照專案健康狀態:有時候造成broken build的原因不明,或是開發人員沒有意識至自己送交的程式碼已經造成了broken build。長此以往如果都沒有人負責去關注broken build發生的原因並追蹤修復的進度,則持續整合的效果有做等於沒做一樣。因此,團隊需要指派專人來關注是否有broken build發生。此人不是要負責去修復broken build,而是要通知團隊目前發生了broken build,並找到或是協調相關開發人員立即在最短的時間內修復broken build。

***

看到這這邊鄉民們可能會問:難道Develop on Mainline就完全不能用branch嗎?也不是說不能用,只是說「沒事不要用」。好,沒事不要用,那什麼才叫做有事可以用哩?

  • 釋出軟體的時候:這一點等Teddy寫到Branch for Release之後再見分曉。
  • 做實驗的時候:有時候鄉民們想要對專案做一些實驗,例如換掉某個元件,或是嘗試一些新的功能,但是又怕實驗風險太大而把trunk搞亂了。此時便可產生一個branch然後在branch上做實驗。

在Develop on Mainline的情境下所產生的branch有一特點,就是基本上branch是不會被merge回trunk的,這樣才符合「所有的開發活動都在trunk進行」的宗旨。

***

最後還有一點要補充的,開發什麼樣的專案適合採用Develop on Mainline呢?答案很簡單:

  • 所開發的軟體還沒有釋出之前。
  • 如果同一時間提供給客戶的軟體版本只會有一個,那麼就很適合使用。例如,公司內部的資訊管理系統,或是網站系統。
  • 團隊人數不是很多的時候,例如9人以內。

***

友藏內心獨白:開車要走大馬路,不要走小徑。

沒有留言:

張貼留言