Jenkins2 學習系列28 — 優化多分支流水線任務

  • 2019 年 10 月 5 日
  • 筆記

Multibranch Pipeline Job 應該是最常見的了。非常適用於一個項目中,不同分支對於不同構建任務。

之前的做法:項目程式碼的每個分支有維護單獨的Jenkinsfile,這樣不但麻煩而且冗餘。

我們知道pipeline流水線由若干個stage階段組成,其實stage中支援寫when指令,即根據條件執行這個stage。

when 支援的條件有 branch, environment, express, not, anyOf, allOf 具體使用可參見官方文檔

下面是個使用when選項優化後的Jenkinsfile,所有分支使用一份Jenkinsfile即可:

有幾點細節說下:

  1. changset 是提交中的變更的文件列表,這裡項目中即包含後台PHP程式碼也包含前端的 JS 和 CSS文件,只有當提交中包含了JS或CSS文件才觸發npm run build,加速構建,因為如果提交了 PHP 文件,沒有必要構建前端資源
 when {     anyOf {        // 是 ant 路徑寫法        changeset "**/*.js"        changeset "**/*.css"      }   }
  1. 如果兩次push程式碼間隔很短,有可能造成同時出現多個的npm run build,為避免這種情況加上了disableConcurrentBuilds()
  2. 通過使用when, 只有往master分支提交程式碼才觸發郵件step,post指令也可以寫在stage中
  3. 默認情況下,stage內的所有程式碼都將在指定的Jenkins agent上執行,when指令提供 beforeAgent選項,當他的值為true時,只有符合when條件時才會進入該Jenkins agent,這樣就避免的沒有必要的工作空間的分配
// https://jenkins.io/zh/doc/book/pipeline/syntax    pipeline {      agent {          // 在Docker容器里跑Job,跑完Jenkins會自動刪除容器          docker {              image 'node:8.15.0-alpine'          }      }      // 避免 npm install 報許可權問題      environment {          HOME = '.'          _EMAIL_TO='[email protected]'      }      options {          // 不允許同時執行流水線, 防止同時訪問共享資源等          disableConcurrentBuilds()          // 顯示具體的構建流程時間戳          timestamps()      }      stages {          // 只有修改 JS 或 CSS 資源文件才觸發 Build 步驟          stage('Build') {              when {                  anyOf {                      changeset "**/*.js"                      changeset "**/*.css"                  }              }              steps {                  sh 'npm install'                  sh 'npm run build'              }          }          // 只有觸發 Master 分支才發郵件          stage('Master') {              when {                  beforeAgent true                  branch 'master'              }              steps {                  echo 'master branch'              }              post {                  always {                      configFileProvider([configFile(fileId: 'email-groovy-template-cn', targetLocation: 'email.html', variable: 'content')]) {                         script {                             template = readFile encoding: 'UTF-8', file: "${content}"                             emailext(                                 to: "${env._EMAIL_TO}",                                 subject: "Job [${env.JOB_NAME}] - Status: ${currentBuild.result?: 'success'}",                                 body: """${template}"""                             )                         }                      }                  }              }          }          stage('Staging') {              when {                  beforeAgent true                  branch 'staging'              }              steps {                  echo 'This is staging branch'              }          }          stage('Develop') {              when {                  beforeAgent true                  branch 'develop'              }              steps {                  echo 'This is develop branch'              }          }      }  }