1 - 持續集成簡介
持續集成(Continuous integration,簡稱CI)是軟件的開發和發布標准流程中最重要的部分。
作為一種開發實踐,在CI中可以通過自動化等手段高頻率地去獲取產品反饋並響應反饋的過程。
簡單來說,就是持續不斷地(一天多次)將代碼合並(集成)到主干源碼倉庫,讓產品可以快速迭代,同時保持高質量。
代碼每次集成到主干之前,必須通過自動化測試,以便快速發現和定位錯誤。
持續集成並不能消除錯誤,而是讓它們非常容易發現和改正。
1.1 適合使用持續集成實現自動化的工作類型
- 應用程序的靜態測試(靜態檢查):不用實際運行應用程序就可以進行的測試,例如語法錯誤和編碼規范等
- 應用程序的構建:驗證依賴關系等問題
- 應用程序的動態測試:單元測試和集成測試等
1.2 持續集成的優點
-
縮減開發周期,快速迭代版本
盡早的持續集成,盡快進入迭代之中,就可以盡早的暴露出問題,提早解決,盡量在規定時間內完成任務。 -
自動化流水線,削減工作成本
CI的精髓在於持續,持續意味着自動化。
自動化驗證代碼變更的過程,可以在軟件開發的早期發現缺陷和與其他代碼和組件的集成問題。 -
隨時可部署
高頻率的集成可以盡可能地保證隨時部署上線,縮短開發復雜軟件的市場交付時間。 -
極大程度避免低級錯誤
減少大塊內容合並到主干分支的情況,避免代碼合並沖突和無法預料的行為。
低級錯誤:編譯錯誤,安裝問題,接口問題,性能問題等。 -
狀態可視化,信息透明化
輕松快捷地確認更改信息、提交過程和測試結果,所有信息公開共享,利於協作
1.3 持續集成的難點
- 遷移遺留代碼到現有CI系統,需要的投入通常在預料之外
- 在文化和組織上如果沒有采用敏捷原則或DevOps的工作方式,那么很可能沒有持續不斷的提交,那么CI的存在意義不大
- 隨着業務增長、工具的更替、技術的演進,CI系統也必然隨之改動,往往會導致階段性的不穩定和人力物力的耗費
- 如果CI的基本設定不到位,開發流程將會增加特別的開銷
1.4 持續集成的注意點
工具
持續集成工具必須能夠定義觸發操作的時機、確認操作的狀態、保存操作的記錄。
代碼倉庫
對於持續集成來說,建議只維護一個源碼倉庫,對於新需求一般采取創建分支的方式,這也可以降低版本管理的復雜度。
CI流程的觸發方式
- 跟蹤觸發式:在每次提交到源碼版本管理系統時觸發
- 計划任務:預配置好的計划,例如一次凌晨的構建
- 手動:無論是通過CI服務器的管理界面還是腳本,用戶可以手工執行CI工作流
代碼審核
- 可在持續集成服務器里使用代碼分析工具(例如Sonar)來執行自動代碼審查
- 自動代碼審查通過后,可發起一個人工代碼審查,揪出那些自動審查無法找出的問題,即驗證業務需求,架構問題,代碼是否可讀,以及是否易於擴展。
- 可靈活配置代碼審核策略,例如:如果某些人沒有審查代碼便阻止對主干分支的任何提交。
- 最常用的工具是Gerrit
1.4 實現持續集成的一些方法與途徑
- 從操作步驟上,將多個處理關聯起來實現自動化
- 通過自動化測試快速執行大量測試,盡量覆蓋所有場景
- 基於時間或者提交進行細顆粒度測試
- 立即通知測試結果,例如直接顯示、郵件通知、關聯即時通訊工具等
- 避免測試等待,優化測試時間,例如分割測試用例、並行測試等
- 重復進行多種測試,為發布做好准備
2 - CI流程
從持續集成的組成部分來理解CI流程,其實就是將應用程序的開發與基礎設施的構建流程合並起來,在一個流程內對二者進行測試。
2.1 典型的CI流程
一個完整的CI系統應該包含3個基本模塊:
- 一個可以自動構建的過程,自動編譯代碼,可以自動分發,部署和測試。
- 一個代碼倉庫,例如Git。
- 一個持續集成的服務器。
2.2 通用的CI流程
-
簽出代碼:
從源碼管理系統里簽出或者克隆最新的代碼到本地開發環境 -
提交(commit):
基於主干分支創建一個新的功能分支,並在此分支編寫代碼,並向倉庫提交代碼 -
測試(第1輪):
代碼倉庫對commit操作配置了鈎子(hook), 每一次提交代碼都會觸發測試
單元測試(針對函數或模塊的測試)和功能測試(集成測試)將會被執行、根據需要設置是否執行端對端測試
一般來說,這些測試也會被打包到代碼里。 -
構建(build):
通過測試(第1輪)后,將源碼轉換為可以運行的實際代碼,比如安裝依賴,配置各種資源等
實現一個CI流程的唯一必要條件便是得有一個自動構建系統。
源代碼一般是自包含構建的,即CI流程所需的構建腳本是放在源碼倉庫里的。 -
測試(第2輪):
以自動化為主的全面測試,包括單元測試和集成測試,必要時做端對端測試,確保新版本的每一個更新點都必須測試到 -
合並:
通過測試(第2輪)后,將代碼更新集成到主干 -
回滾:
如果當前版本發生問題,就回滾到上一個版本的構建結果
一般來說,CI服務器會配置成在遇到故障時發送郵件相關人員,可以快速知曉故障並且盡快采取更正措施。
2.3 實際使用場景中一次提交改動的過程
- 團隊成員提交改動
- Gerrit做代碼審核,提交到GitLab,並通過郵件通知相關人員
- Sonar做代碼掃描,並把結果通知相關人員
- 在GitLab中打tag(通過WebHook觸發Jenkins作業),或者手工觸發Jenkins Job,
- Maven開始下拉代碼進行編譯,然后進行單元測試和打包
- 利用Docker cli構建鏡像,並把鏡像上傳到鏡像倉庫中
- Jenkins作業觸發容器管理工具在測試環境中啟動容器,下拉鏡像,並根據配置啟動容器
- 容器管理工具自動或按規則調度容器運行,並負責容器聲明周期管理(啟動、運行、監控、健康檢查、擴展等)
- 進行自動化測試
- 測試通過后,Jenkins觸發容器管理工具在生產環境中更新測試通過的改動,或者選擇手動發布
3 - CI與TDD結合
Continuous integration (CI) 與test-driven development (TDD)結合,分成了12個步驟: