1. 程式人生 > >CICD | Jenkins & Gitlab整合:WebHook觸發構建

CICD | Jenkins & Gitlab整合:WebHook觸發構建

在上一篇部落格中,我們學習了`Jenkins`的搭建和外掛+流水線的基本使用方法,`Jenkins`極大地提升了部署效率。 最近想學習一下如何整合`GitLab webhook`,實現進一步解放雙手,目標: - 推送(`git push`)觸發構建 - 推送到指定分支觸發構建 - 根據`commit`的檔案,結合`mvn -pl `指令,實現部分增量構建,並記錄`commit`資訊 推送事件也可以換成`Tag push events`、`Merge request events`等其他觸發條件,根據需要自由選擇。 # 基礎實現 使用`Gitlab Hook Plugin`,並在Jenkins和GitLab中分別配置。 ## 下載並配置外掛 ![下載安裝Gitlab Hook Plugin](https://upload-images.jianshu.io/upload_images/6810620-353e4f10f540fc3d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![在Jenkins Job中配置](https://upload-images.jianshu.io/upload_images/6810620-21930db92cde720b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 在`GitLab`中配置 ![在Gitlab中配置](https://upload-images.jianshu.io/upload_images/6810620-bc5e8ec09a7459d2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![在Jenkins配置中配置允許訪問](https://upload-images.jianshu.io/upload_images/6810620-10732c3e00bda044.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![配置完畢後,點選測試](https://upload-images.jianshu.io/upload_images/6810620-9db94d3d3098de57.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![出現如圖所示提醒,配置成功!](https://upload-images.jianshu.io/upload_images/6810620-d400edd412fb4be1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) **至此,目標中的前兩條,推送構建和推送到指定分支構建實現!** # 進階實現 從上述過程,我們也可以看出,`WebHook`的本質就是從`GitLab`發了一條請求,`Jenkins`配置了一個終端地址(`endpoint`)來接收,從而實現了兩個步驟的串聯。 這個請求實質上就是一條`HTTP POST`請求。 相信接觸過服務互相呼叫的小夥伴們都不陌生。有了請求體,我們自然可以拿到自己想要的東西,進行進一步的處理了。 ![請求體內容](https://upload-images.jianshu.io/upload_images/6810620-7b23ad48bbff1267.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## Jenkins外掛:Generic WebHook Trigger Pugin ![下載並配置Generic WebHook Trigger Pugin](https://upload-images.jianshu.io/upload_images/6810620-65d7e5edac5a9bd2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 從外掛簡介來看,支援接收任何一個`HTTP`請求,當然也包括接收`GitLab`傳送的請求。 ### 在`Jenkins Job`中配置接收地址 ![構建觸發器配置](https://upload-images.jianshu.io/upload_images/6810620-fe7b4a0fb5ac3344.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 配置鑑權token ![在Jenkins使用者管理中配置鑑權token](https://upload-images.jianshu.io/upload_images/6810620-0809e85c027cc4f6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 我直接使用`admin`帳號建立,在傳送請求時需要攜帶此token。 ### GitLab配置 在Gitlab中的配置與上文相同,格式為: `http://admin:${token}@${JENKINS_IP}:${PORT}/generic-webhook-trigger/invoke` 填上剛剛配置生成的`token`和自己的`Jenkins`地址和埠即可。 同樣可以使用自帶的測試來測試連線,返回200成功。 - 如果返回`404`,看配置的地址是否有誤 - 返回`403`,檢視許可權配置是否有誤 **至此,連線建立成功!** # 編寫流水線指令碼 關於如何使用宣告式流水線,上一次的部落格已有所介紹。這裡主要說明如何加入觸發器語法。 ## 流水線觸發器語法 ![從JSONPath中獲取引數](https://upload-images.jianshu.io/upload_images/6810620-891b7014d1847d7d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 要從請求體中拿到所需要的引數,可以通過配置獲取JSONPath引數實現。 在流水線中加入下列語句,**即可當作變數在流水線指令碼中使用。** ``` triggers { GenericTrigger( genericVariables: [ [key: 'branch', value: '$.ref'], [key:'commitText', value:'$.commits'] ], causeString: 'Triggered on $branch' , printContributedVariables: false, printPostContent: false ) } ``` - 序列化JSON 要想在pipeline指令碼中將字串反序列化成JSON物件,可以引入 `Pipeline Utility Step`外掛,該外掛提供了一些工具方法。 ![Pipeline Utility Step](https://upload-images.jianshu.io/upload_images/6810620-b29c6b728ba3cbd2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ``` def commits = readJSON text: commitText ``` > 流水線指令碼使用`Groovy`語言,該語言基於`Java`編寫,也集成了一些有趣的特性。在IDEA中編寫只需要配置`Groovy Library`即可。 ## 核心方法 - 根據commits,定義patternMap,匹配到指定正則檔案格式,構建指定元件。 ``` def modifiedFile = []; for (commit in commits) { modifiedFile.addAll(commit.getAt("added").findAll()) modifiedFile.addAll(commit.getAt("modified").findAll()) modifiedFile.addAll(commit.getAt("removed").findAll()) } def buildComponents = new HashSet(); def patternMap = ['mark-engine-manager/.*': 'manager', 'mark-tools/.*': 'web','mark-engine-dm/.*':'dm','mark-engine-web/.*':'web', 'mark-engine-uc/.*':'uc','mark-engine-gateway/.*':'gateway']; //遍歷所有修改了的檔案 for (file in modifiedFile) { for(entry in patternMap.entrySet()){ if (file ==~ entry.key) { buildComponents << entry.value; } } } ``` - 根據需要構建的元件,拼接`maven`構建指令。 ``` String mvnCmd = 'mvn clean install -Dmaven.test.skip=true' for(component in buildComponents){ mvnCmd = mvnCmd + ' -pl mark-engine-'+component+','; } ``` **經過除錯和測試push,三個目標全部完成。** # 總結 **一切都是程式碼**,CICD當然也可以使用程式碼實現。經過實踐我們可以探索出Jenkins更多有趣的