Digg4持續部署,程式碼評審和經過測試的提交

元逍發表於2012-02-20

作者:Andrew Bayer

從開發的角度看,Digg4令人興奮的一件事情是持續部署:當開發修復了一個bug或者新增了一個功能的時候,不需要去等待排隊釋出,而是立刻就能將變更上線。這簡直太棒了,因為變更週轉時間極大的縮短了。當然,由於缺少手工測試以及正式簽字通過,這也會使得錯誤的變更出現線上上。如何平衡速度和應需求持續部署的敏捷性以達到足夠的穩定性和可靠性曾經是、並且繼續是一個最主要的挑戰。在過去的幾個月裡,我們實現了一種在不犧牲穩定性或者敏捷性的前提下可以促成這種平衡的流程。

此流程有幾個要點。第一,工具的支援:git原始碼控制,Hudson持續整合和構建管理,Selenium UI測試(由Sauce Labs提供的Sauce OnDemand服務的極為方便的支援),以及puppet伺服器管理。另外,又增加了Gerrit,一個git程式碼評審系統,發源自Google的Android開發團隊。對所有變更程式碼的強制評審感覺會比較痛苦,但是要想發現自動化測試無法發現的設計缺陷,除了由另一個開發來閱讀你的程式碼還能有其它方法嗎?

然而,我們使用Gerrit還有其他的目的。除了程式碼評審以外,Gerrit還提供了一個“已經驗證”標誌,用來記錄相關的變更正確的建立和測試。結合Hudson即可實現預先測試的程式碼提交:除非經過一系列的單元測試,成功的打成Debian包,以及前端程式碼安裝在一臺測試機上並經過Selenium冒煙測試,任何變更都不能進入主幹。這個流程由Gerrit的Hudson Trigger外掛來完成,該外掛是由索尼-愛立信的Robert Sandell及其它Hudson團隊來開發和維護的。

Gerrit Trigger外掛利用了Gerrit的事件流功能來監聽新補丁的建立。每當它看到一個新補丁出現,就檢查是否有被配置來構建補丁所屬Gerrit專案的Hudson專案,如果有的話,就啟動此Hudson專案的構建,並確保該構建包含了待驗證的變更。在所有構建完成以後,Gerrit Trigger監聽器會傳送一條帶結果的訊息到Gerrit。具體的命令、值等是可配置的。在我們的流程裡,我們只是使用“已經驗證”標誌,-1表示構建失敗,+1表示通過。我們還對Gerrit Trigger外掛做了微小的調整以支援補丁在除測試失敗外的構建失敗時能夠重新構建。索尼-愛立信團隊有一個更加正式的解決方案會在將來發布。

為什麼我們在預測試的提交的構建中只執行一部分單元測試和Seleinum測試呢?最主要是時間原因。我們希望預測試的提交過程儘可能快,因為每個變更的每個版本都會經過它。持續部署流程的下一步將會跑的少一些,所以可以花的時間長一些並且更嚴格一些。當一個變更經過了另外一個開發的程式碼評審以及Hudson構建的驗證,就可以合併到主幹了。當一個變更進入主幹時,一個完整的構建被執行,所有單元測試例會被執行。接下來,程式碼被打包、安裝在內部的預發環境裡,然後執行全部Seleinum測試例。如果全部測試例成功通過,我們就會把經過測試的程式碼部署到生產環境。

現在,是不是很完美了?當然沒有。現在,由於部分測試或外部因素的不穩定性,我們必須手工的重新構建更多的事先測試的提交;並且,還有不少部分可以調整,使整個流程更加平滑和可靠。但總體上來看,已經不錯了,因為沒有變更在被另一個開發評審而且經過了特定的測試之前會進入主幹。沒有一個變更會在經過了完整的單元測試之前會從內部進入生產環境,也不會有一個變更會在經過了額外的Selenium測試之前從內部進入生產環境。這是否意味著線上不再出現bug了?當然不是,但這可以使得遺漏的bug儘可能少,並且使得bug修復更容易和更快的上線。

原文:Continuous Deployment, Code Review and Pre-Tested Commits on Digg4

歡迎參加iTran樂譯4期

相關文章