CICD | Jenkins & Gitlab集成:WebHook觸發構建

在上一篇博客中,咱們學習了Jenkins的搭建和插件+流水線的基本使用方法,Jenkins極大地提高了部署效率。
最近想學習一下如何集成GitLab webhook,實現進一步解放雙手,目標:git

  • 推送(git push)觸發構建
  • 推送到指定分支觸發構建
  • 根據commit的文件,結合mvn -pl 指令,實現部分增量構建,並記錄commit信息

推送事件也能夠換成Tag push eventsMerge request events等其餘觸發條件,根據須要自由選擇。web

基礎實現

使用Gitlab Hook Plugin,並在Jenkins和GitLab中分別配置。maven

下載並配置插件

下載安裝Gitlab Hook Plugin

在Jenkins Job中配置

GitLab中配置

在Gitlab中配置

在Jenkins配置中配置容許訪問

配置完畢後,點擊測試

出現如圖所示提醒,配置成功!

至此,目標中的前兩條,推送構建和推送到指定分支構建實現!工具

進階實現

從上述過程,咱們也能夠看出,WebHook的本質就是從GitLab發了一條請求,Jenkins配置了一個終端地址(endpoint)來接收,從而實現了兩個步驟的串聯。
這個請求實質上就是一條HTTP POST請求。
相信接觸過服務互相調用的小夥伴們都不陌生。有了請求體,咱們天然能夠拿到本身想要的東西,進行進一步的處理了。
請求體內容gitlab

Jenkins插件:Generic WebHook Trigger Pugin

下載並配置Generic WebHook Trigger Pugin
從插件簡介來看,支持接收任何一個HTTP請求,固然也包括接收GitLab發送的請求。學習

Jenkins Job中配置接收地址

構建觸發器配置

配置鑑權token

在Jenkins用戶管理中配置鑑權token

我直接使用admin賬號建立,在發送請求時須要攜帶此token。測試

GitLab配置

在Gitlab中的配置與上文相同,格式爲:
http://admin:${token}@${JENKINS_IP}:${PORT}/generic-webhook-trigger/invoke
填上剛剛配置生成的token和本身的Jenkins地址和端口便可。
一樣可使用自帶的測試來測試鏈接,返回200成功。ui

  • 若是返回404,看配置的地址是否有誤
  • 返回403,查看權限配置是否有誤
    至此,鏈接創建成功!

編寫流水線腳本

關於如何使用聲明式流水線,上一次的博客已有所介紹。這裏主要說明如何加入觸發器語法。插件

流水線觸發器語法

從JSONPath中獲取參數
要從請求體中拿到所須要的參數,能夠經過配置獲取JSONPath參數實現。3d

在流水線中加入下列語句,便可看成變量在流水線腳本中使用。

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
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更多有趣的玩法。

相關文章
相關標籤/搜索