標籤:
1 概述
持續整合(Continuous Integration)是一種軟體開發實踐。在本系列文章的前一章節已經對其背景及理論體系進行了介紹。本小節則承接前面提出的理論構想進行具體的技術實現。
《Google軟體測試之道》:
"每天,Google都要測試和發布數百萬個源檔案,億萬行代碼。數以億計的構建動作會觸發幾百萬次的自動化測試,並在好幾十萬個瀏覽器執行個體上執行。面對這些看似不可能完成的任務,Google是如何測試的呢?"
希望看完此文章的人,能夠自己找到自己的答案。
2 主要環境及工具
- Git代碼管理系統(如:GitOSC)
- Linux作業系統(Ubuntu)
- Jenkins系統軟體安裝包
- Jenkins的Python語言的SDK
- Python及 Tornado Web 架構
以上的技術選型,都是盡量使用 開源 且 主流 的系統,這樣的好處如下:
- 節省軟體購置成本
- 有豐富的參考資料
- 有能力的企業或者個人可以按照需求做自訂擴充
3 原理分析
在上一篇文章裡面,對持續整合繪製過一個基本的結構圖,如下:
基本流程如下:
開發人員推送代碼到Git
Git通知Jenkins
Jenkins開啟構建
-
-
構建完成開啟後續任務
-
Jenkins通知自動化發布系統
發布系統持續後續的任務……
這裡面涉及的系統有:
- 代碼版本管理系統
- 自動化構建系統
- 自動化測試系統
- 自動化發布系統
關於 自動化發布系統 這個基本上屬於營運方面的內容,在互連網產品領域情形和技術需求比較複雜,暫時不列入本部分的內容。但是Jenkins 能夠有介面去通知相應的發布系統,以達到 事件資訊流的連續性
本文則主要從技術角度來將這些系統聯合起來。
4 Jenkins安裝及配置4.1 下載和安裝
關於 Jenkins 的下載及安裝,可以參考其官網。
https://jenkins-ci.org/
直接下載Ubuntu/Debian版本,在Ubuntu伺服器上安裝即可。
由於過程比較簡單,網上相關教程很多,此處也不再贅述。但是一般Jenkins安裝完畢後,最初的許可權配置會比較繁瑣,所以本文重點從相應的使用情境出發,實現一個完整的帶許可權配置的解決方案。
5 內網持續整合系統
對於只是在 內網 使用持續整合的團隊來說,許可權的配置就相對簡單一些。因為只是在內網,所以可以將許可權的要求放鬆,只要保證公司網路之外的人無法訪問到 Jenkins 服務即可。
注意:如果要和git服務的webhook形成完整的事件流,則git服務也需要在內網,否則 構建事件 無法被 程式碼推送事件 給觸發。
5.1 許可權配置
對 Jenkins 進行如下操作:
[系統管理]->[Configure Global Security]->[存取控制]->[授權策略]->[項目矩陣授權策略]
對 匿名使用者 進行如下配置:
- Overall: Read -> Enabled
- Job: Read -> Enabled
具體配置介面如下:
注意:如果不這樣配置,則後面提到的基於git的構建觸發器將無法通過調用指定的url介面來觸發構建。因為webhook只能構造 單次 簡單的http請求,無法構造由多個請求組成的會話,故而無法調用需要身份授權的介面。
5.2 構建觸發器
一般情況下,構建都是以代碼的發布作為起始事件點,所以需要和git伺服器建立事件關聯,在Jenkins具體的項目的配置介面中,對 構建觸發器 進行配置。
目前網路上一般都是介紹的這種方式,具體的細節,此處就不再贅述,感興趣的同學可以自行在網路上搜尋。
基本原理圖如下:
5.3 最終效果
可以達到如下效果:
- 開發人員向內網的git伺服器推送代碼
- git服務的webhook向內網jenkins發送訊息並 觸發構建
- Jenkins執行構建相關命令
以上的內網方案的特點如下:
-
-
優點:
-
-
-
缺點
-
- 無法限制匿名使用者的許可權
- 出於安全考慮,只能在內網使用
當然,對於 開發資源相對匱乏 的小團隊而言,推薦通過以上方法 快速搭建 自己的內部的持續整合系統,畢竟先快速生產自己的特色產品才是最重要的事情。
6 公網持續整合系統
對於前面的 內網持續整合系統 的優點和缺點都介紹之後,作為一個以 開放為主要精神 的互連網團隊來說,肯定是無法滿足這樣一個 封閉的內部網路 系統的,所以下面就要隆重介紹 公網持續整合系統 。
對於 內網系統 在配置上進行了 偷懶 ,但是實際上卻在其它地方付出了 巨大的代價 ,這些代價包括:
- 無法使用市場上已經成熟的公網git服務(包括但不限於:bitbucket,github,[email protected])
- 團隊成員的工作地點將受到限制,必須局限於同一個內網環境中
所以,如果配置人員擁有一定的系統設計能力和開發能力,還是建議搭建 公網持續整合系統 。
公網方案具有如下特點:
6.1 許可權配置
公網持續構建系統對許可權控制有如下要求:
- 未登入的匿名使用者無法查看任何項目資訊
- 登入使用者可以配置不同的許可權
對 Jenkins 進行如下操作:
[系統管理]->[Configure Global Security]->[存取控制]->[授權策略]->[項目矩陣授權策略]
可以建立三類使用者並進行許可權配置:
-
-
普通使用者
-
登入後,可以查看相應的項目的名稱及構建的狀態(主要是基本的查看功能)
-
-
管理使用者
-
登入後,可以進行構建操作,對任務進行增加及刪除等等進階操作(主要是專案管理功能)
-
-
匿名使用者
-
未登入使用者,不具備任何許可權,只呈現登入介面
有了這樣的登入授權機制,就不用再使用網路進行隔離了,此系統就可以放心地放到公網伺服器上了。
前面提到的內網系統的解決方案,主要原因是:
- 基於git的webhook無法對需要認證的 構建觸發器 介面請求發起有效構建請求
- 將 構建觸發器 介面設定為不需要認證,會導致匿名使用者的許可權過大
如果部署到公網,則需要解決如上的矛盾之處。一個比較好的思路就是:
- 按照要求配置好相應的使用者權限(見公網許可權配置方案)
- 開發中介軟體來完成 構建API 的使用者登入認證
6.2 構建觸發器
在兼顧Git的webhook的特點和Jenkins構建特性的情況下,可以提出如下所描述的解決方案:
使用web服務作為中介軟體,來類比使用者登入:將本來需要多個請求組成的會話變成單一的Http請求(可以在單次請求的url裡面加入授權的token),這樣就可以被Git的webhook所調用。
基本原理圖如下:
主要的通訊過程為:
- Git Server 接收代碼並向 Web Server 發起單次Http請求(參數帶上token)
- Web Server 先向 Jenkins Server 發起認證授權請求
- Web Server 再向 Jenkins Server 發起構建請求,觸發構建
當然,由於 Jenkins 提供了Pyhon語言的SDK,所以以上 步驟2和3其實可以簡化為對其SDK的調用了。
安裝方法:
pip install python-jenkins
最簡單的使用樣本如下:
# coding:utf-8"""jenkins相關的工具函數及配置"""from dtlib.dtlog import dlogimport jenkins__author__ = ‘harmo‘jenkins_url = ‘http://jenkins.xxxx.com‘jenkins_user = ‘jenkins_user‘jenkins_passwd = ‘jenkins_user_password‘def build_job(project_name): """ 構建項目 :param project_name: 項目名稱 :return: """ jen = jenkins.Jenkins(jenkins_url, username=jenkins_user, password=jenkins_passwd) jen.build_job(project_name) print("build %s succeed" % project_name)if __name__ == ‘__main__‘: build_job("your-project-name")
開發人員只需要在自己的web程式裡面整合此SDK,並進行參數化,即可完成webhook和jenkins的中介軟體。
6.3 最終效果
可以達到如下效果:
- 接收git服務的webhook請求
- 解析請求中代碼提供資訊,包括但不限於:提交時間,提交人,分支,備忘,項目名稱等等
- 進行條件過濾,並觸發 Jenkins 進行自動構建(例如:本文是對release分支進行監控,來觸發構建)
使用中介軟體的好處是,對構建的事件有很好的訂製性,包括分支監控,提交人許可權等等。當然,也可以只使用最簡單的功能:只要有人向 release 分支提交了代碼,那麼就會觸發自動構建流程,這樣就完成了整個流程了。
當然,構建成功之後到發布還有一些後續的流程,比如:
開發人員完成代碼,自測完畢後,推送代碼到 release 分支
觸發自動構建,構建成功,並產生構建產物
將構建產物發布到 測試伺服器
-
-
觸發自動化測試指令碼
-
- 如果測試不通過,發送訊息給相關人員,終止後續流程
- 如果測試通過,通知 自動化發布系統
由 自動化發布系統 完成構建產物向生產伺服器發布的過程
6.4 其它說明
在得知Jenkins有Python語言的SDK之前,其實還有個其它方法也能夠完成登入授權並調用構建介面。直接通過介面來類比使用者登入行為(因為Jenkins登入處不需要驗證碼),然後擷取登入成功的sessionid ,以此作為授權token來調用構建的介面。
具體的技術實現的代碼細節不在本文的討論內容中出現,只要瞭解登入的原理,很容易就開發出來。
此處做一些說明的目的是,其實只要瞭解原理,即使官方沒有提供一些工具,仍然也是有辦法完成想要的功能的。
7 持續整合的應用情境
持續整合的平台搭建完畢後,關於其可應用的項目也進行一些簡單的介紹。
基本上任何的軟體項目,從生產到最終發布都可以劃分為如下幾個過程:
- 代碼開發
- 構建產生發布產物
- 發布上線
不同類型項目,無非就是構建過程不同而已,本文也簡單的列舉一下幾類項目的應用方式的流程,關於具體的技術手段就由各人根據各自的項目去做相應的訂製開發了。
7.1 指令碼類服務端項目
主要的代表有:Php,Python等等。
它們的構建產物就本身的原始碼,所以整個持續整合的過程如下:
- 開發人員發布代碼到Git倉庫
- Jenkins同步代碼到本地(做好發布產物的備份,方便復原)
- 部署好測試伺服器
- 執行自動化測試指令碼
- 發布到生產伺服器或者駁回
7.2 需要編譯的服務端項目
主要的代表有:Java等。
過程如下:
- 開發人員發布代碼到Git倉庫
- Jenkins同步代碼到本地,並使用構建工具(如:Ant等)產生位元組碼的構建產物
- 將構建產物統一備份到相應目錄,做好發布產物的備份,方便復原
- 部署測試伺服器
- 測試……
- 發布……
7.3 Web前端項目
主要代表有:Javascript,css等。
過程如下:
- 開發人員發布代碼到Git倉庫
- Jenkins同步代碼到本地,並使用前端構建工具(如:Grunt等)產生構建產物
- 將構建產物統一備份到相應目錄,做好發布產物的備份,方便復原
- 部署測試伺服器
- 測試……
- 發布……
7.4 移動端App項目
主要代表有:Android等。
過程如下:
開發人員發布代碼到Git倉庫
Jenkins同步代碼到本地,並使用構建工具產生構建產物Apk
將構建產物統一備份到相應目錄,做好發布產物的備份,方便復原
安裝到裝置,執行測試
-
-
測試
-
- 如果測試通過,發布到各大應用市場
- 如果測試未通過,發現bug後駁回
8 運行效果
Jenkins系統運行介面:
Jenkins本身可以實現如下功能:
- 完成項目持續整合及持續發布
- 對構建過程進行記錄
- 構建完畢後可以發郵件或者通知相應的人員,形成良好的反饋機制
再通過文章前半部分提到的系統,團隊就可以達到 持續傳遞 和 持續部署 的目的,從而實現項目的 快速迭代 。
持續傳遞:
持續部署:
當然,還有後續的更多的擴充功能,就需要測試開發人員去實現了。
9 小結
此文作為 持續整合 系列文章的具體技術實現部分,介紹了一個通用的技術架構的解決方案。剩下的就是各種針對自己的工程特性是編寫各種指令碼和安裝各種環境了。這樣 理論加實踐,就構成了能夠提供生產力的 持續整合 系統,大家Enjoy it吧。
目前以 Google 為代表的大型的互連網公司,基本上都是保持著這樣的開發節奏。《Google軟體測試之道》裡面提到了這樣的生產方式,但是沒有給出具體的技術解決方案,本文則將這種構想進行技術落地,並發布此方案,希望能夠給後來者一些協助吧。
(如果大家有興趣,後面可以針對某個具體的項目,來一個完整的持續整合樣本,包括構建代碼的編寫,及過程的等等。但是如果反響不大,就不再浪費時間了)
作者: |
Harmo哈莫 |
作者介紹: |
https://zhengwh.github.io |
技術部落格: |
http://www.cnblogs.com/beer |
Email: |
[email protected] |
QQ: |
1295351490 |
時間: |
2016-02 |
著作權聲明: |
歡迎以學習交流為目的讀者隨意轉載,但是請 【註明出處】 |
支援本文: |
如果文章對您有啟發,可以點擊部落格右下角的按鈕進行 【推薦】 |
CI-持續整合(2)-軟體工業“流水線”技術實現