Jenkins Pipeline 語法


pipeline 簡介

pipeline 基本語法

agent

post

stages/stage/steps

environment

options

parameters

tool

when

scripts

triggers

共享庫

pipeline basic steps 插件用法

git plugin 插件用法

publish html report 插件用法

借助 Jenkins 生成 pipeline 代碼

 

 

Pipeline 簡介

Jenkins2.x 的核心是使用 pipeline 來構建項目,也就是流水線,將 Jenkins1.0 版本中基於表單的配置信息比如 JDK/SVN 以及參數的配置都轉變成了代碼,即 pipeline as Code。

傳統的表單方式有以下缺點:

  • 需要大量的 web 表單交互,有時候需要進行很多次的切換,比較繁瑣。
  • 不能進行版本管理。
  • 可重用性差。

而采用 pipeline 的方式,項目的所有流程和配置都寫在 Jenkinsfile 文件中,移植時只要將此文件拷貝即可,無須繁瑣的配置;而且 pipeline 可以很直觀的看到每個階段的構建情況,再結合上 Blue Ocean 可以進行強大的流水線監控,方便、直觀、及時地獲取到構建結果。

在 Jenkins 中,把每一段管道比作是不同的 Job,不同 Job 的鏈接就需要用到 Pipeline 插件。Jenkins 的工作流程可以簡單概括為 build-deploy-test-release,每個流程之間我們都可以用 Pipeline 來連接,大致如下效果圖:

Jenkins pipeline 是基於 Groovy 語言實現的一種 DSL(Domain-Specific Language,領域特定語言),可以理解為適用於 Jenkins 的編程語言。

pipeline 支持兩種語法:腳本式語法(scripted pipeline)和聲明式語法(declarativepipeline)。早期的 pipeline plugin 只支持腳本式語法,聲明式語法是在 pipeline2.5 之后新增加的,相對而言,聲明式語法更簡單,即使沒有 groovy 語言的基礎也能進行基本的操作。Jenkins 社區的動向也是偏向於聲明式語法,所以以聲明式語法為例進行說明。

 

Pipeline 基本結構

pipeline{
    agent any
    stages{
        stage('build'){
            steps{
                echo 'build steps'
            }
        }
    }
}

以上是最最基本的一個 pipeline 結構,具體的含義如下:

  • pipeline:后面用一對 {} 也就是閉包,表示整條流水線,里面是流水線中具體的處理流程。
  • agent:用來指定整個流水線或者某一個階段在哪個機器節點上執行。如果是 any 的話表示該流水線或者階段可以運行在任意一個定義好的節點上。這個指令必須要有,而且一般會放在頂層  pipeline{...} 的下一層,在 stage{...} 中也可以使用 agent,但是一般不這么用。
  • stages:后面跟一對 {},類似於一個容器,封裝了一個或多個 stage,也就是將不同的階段組織在一起;例如 build 是一個 stage, test 是第二個 stage,deploy 是第三個 stage。通過 stage 隔離,讓  Pipeline 代碼讀寫非常直觀。
  • stage:后面跟一對 {},流水線中的某個階段,其中封裝了多個執行步驟,每個階段都需要有個名稱。
  • steps:封裝了在一個階段中的一個或多個具體的執行步驟。在本例中 echo 就是一個步驟。

接下來我們一一介紹上面提到的 pipeline 中包含的最基本的幾個 section,以及另外一些可選的 section。

 

agent

用來指定 pipeline 的執行節點,一般放在頂層的 pipeline 中。agent 部分支持幾種不同的參數以此來適應不同的應用場景。

1)any

作用:表示可以在任意的節點或者代理上執行此 pipeline。

代碼示例:

pipeline {
  agent any
}

2)none

作用:在 pipeline 的頂層應用中使用此參數的話表示不會為整個 pipeline 指定執行的節點,需要在每個 stage 部分用 pipeline 指定執行的節點。

代碼示例:

pipeline {
    agent none
    stages {
        stage('test'){
            agent {
                label '具體的節點名稱'
            }
        }
    }
} 

3)label

作用:在標簽指定的可用代理上執行 pipeline 或 stage,比如 agent {label "label"} 表示流水線或者階段可以運行在任何一個具有 label 標簽的代理節點上。

代碼示例:

pipeline {
    agent {
        label '具體的一個節點 label 名稱'
    }
}

4)自定義工作空間

作用:代理節點的標簽新增了一個特性,允許為流水線或階段指定一個自定義的工作空間,用 customWorkspace 指令來指定。和 label 功能類似。

代碼示例:

pipeline {
    agent {
        node {
            label "xxx-agent-機器"
            customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"
        }
    }
} 

處的 node 可以換成 label,但是為了避免 Docker 代理節點中的 label 用法混淆,一般用 node 表示。這種類型的 agent 在實際工作中的使用場景是最多的

測試代碼

pipeline {
    agent {
        node {
            label "xxx-agent-機器"
            customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"
        }
    } 
    stages {
        stage ("Build") {
            bat "dir"  //執行windows下的bat命令
        } 
        stage ('test') {
            echo ${JAVA_HOME}  //打印JAVA_HOME
        }
    }
}

以將以上代碼段放到 Jenkinsfile 中或者在 Jenkins ui 中去執行。

 

POST

post 部分用來指定 pipeline 或者 stage 執行完畢后的一些操作,比如發送郵件、環境清理等。post 部分在 Jenkins 代碼中是可選的,可以放到頂層,也就是和 agent 同級,也可以放到stage 中。在 post 代碼塊中支持多種指令,比如:always、success、failure、aborted、unstable、changed 等等,我們一一來介紹。

1)always

作用:當 pipeline 執行完畢后一定會執行的操作,不管成功還是還失敗。比如說文件句柄的關閉或者數據庫的清理工作等。

代碼示例:

pipeline {
    agent any
    stages {
        stage ("Build") {
            bat "dir"
        }
    } 
    post {
        always {
            script {
                //寫相關清除/恢復環境等操作代碼
            }
        }
    }
}

2)success

作用:當 pipeline 執行完畢后且構建結果為成功狀態時才會執行的操作。

代碼示例:

pipeline {
    agent any
    stages {
        stage ("Build") {
            bat "dir"
        }
    } 
    post {
        success{
            script {
            //寫相關清除/恢復環境等操作代碼
            }
        }
    }
}

3)failure

作用:當 pipeline 執行完畢后且構建結果為失敗時執行的操作,比如發送錯誤日志給相關人員。

4)changed

作用:當 pipeline 執行完畢后且構建狀態和之前不一致時執行的操作。

5)aborted

作用:當 pipeline 被手動終止時執行的操作。

6)unstable

作用:當 pipeline 構建結果不穩定時執行的操作。

7)以上命令的組合

在 post 部分是可以包含多個條件塊,也就是以上命令的組合,比如:

pipeline {
    agent any
    stages {
        stage ("Build") {
            bat "dir"
        }
    }
    post {
        always {
            script {
                echo "post always "
            }
        } 
        success{
            script {
                echo "post success"
            }
        } 
        failure{
            script {
                echo "post failure"
            }
        }
    }
}

  

stages/stage/steps

  • stagesPipeline 中單個階段的操作封裝到 stages 中,stages 中可以包含多個 stage。
  • stage一個單獨的階段,實際上所有實際工作都將包含在一個或多個 stage 指令中。stage{…} 里面有一個強制的字符串參數,用來描述這個 stage 的作用,這個字符串參數是不支持變量的,只能你自己取名一個描述字段。
  • steps一個 stage 下至少有一個 steps,一般也就是一個 steps。可以在 steps 下寫調用一個或者幾個方法,也就是兩三行代碼。

有以下注意點

  • 在聲明式 pipeline 腳本中,有且只有一個 stages。
  • 一個 stage{…} 必須有且只有一個 steps{…}, 或者 parallel{…} 或者 stages {…},多層嵌套只支持在最后一個 stage{…} 里面。
  • 在聲明式語法中只支持 steps,不支持在 steps {…} 里面嵌套寫 step{…}。

 代碼示例:

pipeline {
    agent any
    stages {
        stage('build') {
            steps { echo 'build' }
        }
        stage ('test') {
            steps { echo "${JAVA_HOME}" }  //打印 JAVA_HOME
        }
    }
}

 

environment

作用:通過鍵值對的方式定義整個 pipeline 或者 stage 中使用的環境變量。

代碼示例:

pipeline {
    agent any
    environment {
        test = true
    } 
    stages {
        stage('build') {
            steps {
                script{
                    if(test == true) {
                    // 一些特定的操作
                        echo 'sucess'
                    }
                }
            }
        }
    }
}

 

options

options 指令在 pipeline 也是可選的。用來指定一些屬性和值,這些預定義的選項可以應用到整個流水線中,可以理解為在 Jenkins web 表單里一個項目的基本配置中定義的事情。

1)retry

作用:表示 Jenkins 中的 job 執行失敗后繼續進行幾次嘗試。可以放到頂層的 pipeline 中也可以放到 stage 中。注意:這個次數是指總次數,包括第 1 次失敗。

pipeline {
    agent any
    options {
        retry(3)
    }
    stages {
        stage('test') {
            steps {
                // 步驟
            }
        }
    }
}

2)buildDiscarder

作用:保留指定數量的流水線執行,包含控制台輸出以及制品。當 pipeline 指定完畢后,會在工作空間中保存制品和執行日志,如果執行次數太多的會話,這些內容會占用很多的存儲空間,使用該參數后會只保留最近指定次數的構建結果,自動清理之前的內容。

代碼示例

pipeline {
    agent any
    options {
        buildDiscarder(logRotator(numToKeepStr:'3'))
    }
    stages {
        stage('test') {
            steps {
                // 步驟
            }
        }
    }
}

明:logRotator 元素並沒有什么作用,主要是歷史原因。

3)checkoutToSubdirectory

作用:指定檢出到工作空間的子目錄中。Jenkins 從代碼管理庫中拉取代碼時默認檢出到工作空間的根目錄,如果想修改的話可以用此參數。

代碼示例

pipeline {
    agent any
    options {
        checkoutToSubdirectory('subdir')
    }
    stages {
        stage('test') {
            steps {
                // 步驟
            }
        }
    }
}

4)disableConcurrentBuilds

作用:阻止 pipeline 同時執行。默認的情況下 pipeline 是可以同時執行多次的,如果為了防止同時訪問共享資源或者防止一個較快的並發執行把較慢的並發執行給碾壓的場景可以使用此參數禁止並發執行。

代碼示例:

pipeline {
    agent any
    options {
        disableConcurrentBuilds()
    }
    stages {
        stage('test') {
            steps {
                // 步驟
            }
        }
    }
}

5)timeout

作用:為流水線的執行設置一個超時時間。如果超過這個值就會把整個流水線終止。時間單位可以是 SECONDS(秒),MINUTES(分鍾),HOURS(小時)。

代碼示例

pipeline {
    agent any
    options {
        timeout(time:10, unit:'HOURS')
    }
    stages {
        stage('test') {
            steps {
                // 步驟
            }
        }
    }
}

6)skipDefaultCheckout

作用:刪除隱式的 checkout scm 語句,因此可以從 Jenkinsfile 定義的流水線中跳過自動的源碼檢出功能。

代碼示例

options {
    skipDefaultCheckout()
}

  

parameters

parameters 用來在 pipeline 中實現參數化構建,也就是根據用戶指定的不同參數執行不同的操作。pipeline 支持很多種類型的參數,有字符串參數,布爾選擇參數,下拉多選參數等。

1)字符串參數

作用:開始構建前需要用戶輸入字符串,比如 ip 或者 url。

代碼示例:

pipeline {
    agent any
    parameters {
        string(name: 'DEPLOY_ENV', defaultValue: 'release', description: '')
    }
}

2)布爾值參數

作用:定義一個布爾類型參數,在執行構建前用戶在 Jenkins UI 上選擇是還是否,選擇是執行這部分代碼,否則會跳過這部分。比如:執行完畢后環境的清理工作。

代碼示例:

pipeline {
    agent any
    parameters {
        booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '')
    }
}

3)文本參數

作用:支持寫很多行的字符串。

代碼示例:

pipeline {
    agent any
    parameters {
        text(name: 'Welcome_text', defaultValue: 'One\nTwo\nThree\n',description: '')
    }
}

4)選擇參數

作用:支持用戶從多個選擇項中選擇一個值用來表示這個變量的值。比如:選擇服務器類型、選擇版本號等。

代碼示例:

pipeline {
    agent any
    parameters {
        choice(name: 'ENV_TYPE', choices: ['test', 'dev', 'product'], description: 'testmeans test env,….')
    }
}

5)文件參數

作用:參數化構建 UI 上提供一個文件路徑的輸入框,Jenkins 會自動去根據用戶提供的網絡路徑去查找並下載。

代碼示例:

pipeline {
    agent any
    parameters {
        name: 'FILE', description: 'Some file to upload')
    }
}

6)密碼參數

作用:密碼(password)參數就是在 Jenkins 參數化構建 UI 提供一個暗文密碼輸入框。

例如,需要登錄到服務器做自動化操作,為了安全起見,就不能用名為的 string 類型參數,而是 password 方式。

代碼示例:

pipeline {
    agent any
    parameters {
        password(name: 'PASSWORD', defaultValue: 'test', description: 'A secret password')
    }
}

測試執行

注意:

保存之后,左側菜仍然單是 Build now,而並不是 Build with Parameters,這個是正常的,需要先點擊 Build now,先完成第一個構建,Jenkins 第二個構建才會顯示代碼中的三個參數。刷新之后,就可以看到參數化構建這個菜單。

  

tool

作用:定義自動安裝和放置工具的路徑。

對於 agent none,這個關鍵字將被忽略,因為沒有任何節點或者代理可以用來安裝工具。此指令主要是為了三大工具(jdk、gradle、maven)提供環境變量服務。一旦配置完成,tools 指令可以讓我們指定的工具需要在我們已經選擇的代理節點上自動安裝在配置路徑下。

代碼示例 1

pipeline {
    agent any
    tools {
        jdk 'jdk1.8'
    }
    stages {
        stage('test') {
            steps {
                sh 'java -version'
            }
        }
    }
}

說明:

tools {
    jdk 'jdk1.8'
}

左側的 jdk 是流水線模型中定義的特殊字符串,目前,在聲明式流水線中可以指定的合法的工具類型如下:ant、git、gradle、jdk、maven、jgit 等。

右側的 jdk8 映射的是全局工具配置中的名稱字段(管理 Jenkins → Global ToolConfiguration 中預配置)。例如,上面代碼我寫了 jdk1.8,那么必須在 Jenkins 管理-->全局工具配置中有別名為 jdk1.8 配置。

一旦這樣設置后,jdk 工具會被自動安裝到指定的路徑下,然后我們可以在流水線步驟中簡單的使用  jdk1.8 字符串替代 JAVA_HOME 路徑,Jenkins 會把它映射到我們系統中安裝的 JDK。

代碼示例 2

pipeline{
    agent any
    parameters {
        string(name: 'gradleTool', defaultValue: 'gradle3', description: 'gradle version')
    }
    tools{
        gradle "${params.gradleTool}"
    }
}

:如果需要輸入一個特定的版本來使用,這個 tools 指令可以使用一個參數的值。

注意:當前生命式語法有一個局限就是當這個流水線第一次運行時,Jenkins 不能識別出該構建需要一個參數,需要先手動構建一次。

 

when

when{…} 是寫在 stage{…} 里面一層條件控制,允許 pipeline 根據給定的條件來決定是否執行某個階段。when 指令必須至少包含一個條件,也可以含多個條件,這與子條件嵌套在一個 allOf 條件中一樣。

更復雜的條件結構可使用嵌套條件建:not,allOf 或 anyOf,嵌套條件可以嵌套到任意深度。下面來看看 when{…} 支持的一些內置條件命令。

1)branch

作用:當正在構建的分支與給出的分支模式匹配時執行。注意,僅適用於多分支 pipeline。

代碼示例:

when { branch 'master' }

2)environment

作用:當指定的環境變量與給定的值相同時執行。

代碼示例:

when { environment name: 'DEPLOY_TO', value: 'production' }

3)expression

作用:當給定的 Groovy 表達式返回 true 時執行。

代碼示例:

when { expression { return params.DEBUG_BUILD } }

4)not

作用:當嵌套條件為 false 時執行,必須包含一個條件。

代碼示例:

when { not { branch 'master' } }

5)allOf

作用:當所有嵌套條件都為真時執行,必須至少包含一個條件。

代碼示例:

when {
    allOf {
    branch 'master';
        environment name: 'DEPLOY_TO',
        value: 'production' 
    }
}

6)anyOf

作用:當至少一個嵌套條件為真時執行,必須至少包含一個條件。

代碼示例:

when { anyOf { branch 'master'; branch 'staging' } }

7)buildingTag

作用:如果 pipeline 所執行的曖昧被打了 tag 則執行。

代碼示例:

when { buildingTag() }

測試代碼

pipeline {
    agent any
    environment {
        quick_test = false
    }
    stages {
        stage('Example Build') {
            steps {
                script {
                    echo 'Hello World'
                }
            }
        }
        stage('Example Deploy') {
            when {
                expression {
                    return (quick_test == "true" )
                }
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}

environment 里面定義了一個鍵值對“quick_test = false”, 第二個 stage('ExampleDeploy') 因為不滿足 when{…}里面的條件就不會執行。

  

script

作用:用來在聲明式流水線中寫非聲明式代碼的地方,允許你定義一定代碼塊/閉包用來囊括非聲明式的語法,其實就是在 script 中寫 Groovy 代碼。比如 if...else 等語句。

代碼示例:

pipeline {agent any
    stages {
    stage('test') {
        steps {
            script{
                def browsers=['chrome','firefox']
                for(int i=0;i<browsers.size();i++){
                    echo "testing the ${browsers[i]} browser"
                    }
                }
            }
        }
    }
}

 

triggers

用來指定使用什么類型的觸發器來自動啟動流水線構建。注意:這些觸發器並不適合用於多分支流水線、github 組織等類型的任務。我們介紹 4 種不同的觸發器:cron、pollSCM、upstream 以 githubPush。

1)cron

作用:按照指定的周期有規律的執行流水線,就是鬧鍾一樣,一到時間點就執行。

代碼示例:

pipeline {
    agent any
    triggers {
        cron ('0 0 * * *')
    } 
    stages {
        stage('test') {
            steps {
                // 步驟
            }
        }
    }
}

說明:

cron 包含 5 個字段,這些字段以空格或者 Tab 鍵分割,用來指定多久去執行一次構建。格式為:

  • MINUTES:一小時內的分鍾,取值范圍(0-59)
  • HOURS:一天內的小時,取值范圍(0-23)
  • DAYMONTH :一個月中的某一天,取值范圍(1-31)
  • MONTH :月份,取值范圍(1-12)
  • DAYWEEK:一周中的星期幾,取值范圍(0-7)。0 和 7 都表示星期日

還可以使用特殊的字符一次指定多個值:

  • *:匹配所有的值
  • N:匹配 M-N 之間的值
  • M-N/<VALUE>或者*/<value>:表示每隔<value>,比如*/5 每隔 5 分鍾
  • A,B,...Z:多個枚舉值
  • H:可以用於任何字段,用來告訴 Jenkins 在一個范圍內使用該項目名的散列值計算出一個唯一的偏移量,這個偏移量於范圍內的最小值相加后定義為實際的執行時間。注意:這個值是項目名的散列值,那么每一個值都與其他項目是不同的,但是同一個項目的值是不變的。

H 符號在實際的項目中是非常推薦使用的,因為在大型的項目中可能存在多個同一時刻需要執行任務,比如(0 0 * * *),都需要在半夜零點啟動,那么使用 H 后,從散列算法獲得的偏移量,就可以錯開執行具有相同 cron 時間的項目。

2)upstream

作用:由上游的任務構建完畢后觸發本任務的執行。比如說需要先執行完編譯打包和發布后才能執行測試腳本。

代碼示例:

triggers {
    upstream threshold: 'UNSTABLE', upstreamProjects: 'jobA,jobB'
}

說明:

upstreamProjects:指定上游任務的名稱,有多個任務時用逗號分隔 。

threshold:指定上游任務的執行結果是什么值時觸發,是枚舉類型 hudson.model.Result 的某一個值,包括:

  • SUCCESS:構建成功;
  • UNSTABLE:存在一些錯誤,但不至於構建失敗;
  • FAILURE:構建失敗。

注意:需要手動觸發一次 pipeline 的執行,讓 Jenkins 加載 pipeline 后,trigger 指令才會生效。

3)pollSCM

作用:輪詢代碼倉庫,也就是定期到代碼倉庫詢問代碼是否有變化,如果有變化就執行。語法和 cron 是一樣的。理論上輪詢的越頻繁越好,但是在一定的構建時間內,如果有多次代碼提交,當構建失敗時無法馬上知道是哪一次的提交導致的,所以這個指令不是很常用,一般是用 webhook,當有代碼提交的時候主動通知到 Jenkins。

代碼示例

pipeline {
    agent any
    triggers {
        pollSCM('h/5 * * * *')
    }
    stages {
        stage('test') {
            steps {
                // 步驟
            }
        }
    }
}

4)Generic Webhook Trigger

需要安裝 Generic Webhook Trigger(簡稱 GWT)插件才能使用,安裝方式見 3.3 節。安裝完之后,Jenkins 會暴露一個 API:http://<Jenkins_URL>/generic-webhook-trigger/invoke,當 GWT 插件接收到 JSON 或者 XML 的 HTTP POST 請求后,根據請求的參數和 Jenkins 中項目的匹配情況來決定執行哪個 Jenkins 項目。注意:項目創建完成后,一定要手動執行一次,這樣 pipeline 的觸發條件才會生效。

4.1 Generic Webhook Trigger 觸發條件的結構

代碼格式:

triggers {
    GenericTrigger
    causeString: 'Generic Cause',
    genericHeaderVariables: [[key: 'header', regexpFilter: '']],
    genericRequestVariables: [[key: 'request', regexpFilter: '']],
    genericVariables: [[defaultValue: '', expressionType: 'XPath', key: 'ref', regexpFilter:'', value: '$.ref']],
    printContributedVariables: true,
    printPostContent: true,
    regexpFilterExpression: '',
    regexpFilterText: '',
    token: 'secret'
}

總結起來可以分為 5 部分:

  • genericVariables/genericHeaderVariables/genericRequestVariables:從 HTTP POST 請求提取參數。
  • token:用於標識待觸發的 Jenkins 項目。
  • regexpFilterExpression/regexpFilterText:根據請求參數判斷是否觸發 Jenkins 項目的執行。
  • printContributedVariables/printPostContent/causeString:日志打印控制。
  • webhook:響應控制。

 4.2 提取請求參數

genericVariables:提取 POST body 中的請求參數。

用法

genericVariables: [[defaultValue: '', expressionType: 'XPath', key: 'ref', regexpFilter: '',value: '$.ref']]

說明

  • expressionType: 可選,'XPath'默認是 JSONPath,采用默認值的話不會有此參數,還可以設置為 XPath。
  • value:JSON 表達式或者 XPath 表達式,取決於 expressionType 的類型。
  • key:一個變量名,用來存儲從 POST body 提取出的值,可以用於 pipeline 其它步驟。
  • defaultValue:可選,當沒有提取到時使用此值返回。
  • regexpFilter:可選,過濾表達式,用來對提取出的值進行過濾。

genericHeaderVariables:從 URL 中提取參數

用法: genericHeaderVariables: [[key: 'header', regexpFilter: '']]

說明

  • key:一個變量名,用來存儲從 URL 提取出的值,可以用於 pipeline 其它步驟。
  • regexpFilter:對提取出的值進行過濾。
  • genericRequestVariables:從 HTTP Header 中提取參數。和 genericHeaderVariables 用法類似。

4.3 token

用法: token: 'secret'

說 明 : 用 來 標 識 一 個 pipeline 在 Jenkins 中 的 唯 一 性 。 當 Jenkins 接 收 到generic-webhook-trigger/invoke 接口的請求時,會將請求傳遞給 GWT 插件,GWT 插

件內部會遍歷 Jenkins 中所有的項目,找到 Generic Webhook Trigger 配置 token 和請求中相同 token 的項目,觸發這些項目的執行。

4.4 觸發請求參數

如果配置了以下 2 項,即使 token 值匹配了,還要繼續判斷以下條件是否滿足,才能真正觸發項目的執行。

  • regexpFilterExpression:正則表達式。
  • regexpFilterText:需要匹配的 key。

4.5 日志打印控制

  • printContributedVariables:布爾類型,打印提取后的變量和變量值。
  • printPostContent:布爾類型,打印 webhook 請求信息。
  • causeString:字符串類型,用來表示 pipeline 被觸發執行的原因,一般引用直接提取的變量。

 

共享庫

當 Jenkins 上建立很多個 pipeline 項目的時候,就會有一些公共的代碼在每個項目中都要去重復的編寫,當這些代碼需要做一些擴展或者修改的時候就需要把所有項目中全部改一遍,維護的成本太高,編寫的效率太低。比如發送郵件的功能是所有項目都需要的,郵件模板都寫在每個 pipeline 項目中的話視覺效果極差。可以使用 pipeline 共享庫(shared library)的技術解決這一問題。

1)共享庫的代碼結構

共享庫有 3 個部分組成:resources 目錄、src 目錄和 vars 目錄。示例如下:

  1. resources 目錄:一般將非 groovy 文件存放在此目錄中,比如 XML 文件或者 JSON文件,可以通過外部庫中的 libraryResource 步驟加載。 
  2. src 目錄:是使用標准 java 目錄結構的 groovy 文件,目錄中的類稱為庫類(Library class),這些類必須實現 Serializable 接口,以此保證在流水線停止或者重新啟動時能正確的恢復。在流水線中使用 src 目錄中的類時,需要注意要使用包名,同時因為是 groovy 代碼,所以還要用 script 命令包起來。
  3. vars 目錄:這個是我們要介紹的重點。此目錄下存放的可以在 pipeline 中直接調用的全局變量,在 pipeline 中使用的函數名就是文件名,當文件中定義了 call 方法時,它可以像常規流水線步驟一樣被調用。這個call方法就相當於這個公共方法的main方法。記住一個原則,一個公共方法,寫一個 groovy 類文件,這個 groovy 文件的名稱就是這個公共方法的函數名稱,在其他 pipeline 項目中調用這個方法就是直接寫這個groovy 類名稱。

共享庫的定義和使用一般分為以下 4 步:

  1. 根據工作實際需要編寫共享庫的源代碼;
  2. 將源代碼放到代碼管理倉庫中;
  3. 在 Jenkins 全局配置中定義共享庫;
  4. 在 pipeline 項目或中 Jenkinsfile 中通過@Library 引用共享庫。

2)編寫共享庫文件

注意:庫文件中包含中文的話一定要保存為 ANSI 格式,否則可能會出現亂碼的情況。

我們主要將常用的一些功能封裝到 vars 目錄來演示,其它高級的用法可以根據實際的需要進一步研究。在 vars 目錄下創建 2 個文件,分別名為 command.groovy 的文件,如下:

 再創建名為 say.groovy 的文件,內容如下:

3)Jenkins 中配置共享庫

 

 

4)通過@Library 注解使用共享庫

在 pipeline 的上方使用@Library 引入共享庫。

語法:@Library('<libname>[@<version>]')_ [<import statement>]

說明:

  • libname:表示庫名,必須要有。
  • version:版本號以@開頭,可以是代碼倉庫的標簽、分支名或者其他規范。
  • _:下划線,表示一次性靜態加載 src 目錄下所有的代碼到 classpath 中,如果沒有后面的 import 語句,就必須有此下划線。
  • import:可以沒有,表示導入指定的方法,如果沒有指定表示導入共享庫中所有的方法。

使用示例:

//加載一個庫的默認版本
@Library('share-lib')_

//加載一個庫的指定版本
@Library('share-lib@2.0')_

//加載多個庫
@Library(['share-lib@release1.0','myLib'])_

//帶導入語句
@Library('share-lib@2.0') import static org.demo.Utils.*

Pipeline Basic Steps 插件用法

pipeline basic steps 是 pipeline 最基礎的一個插件,在安裝 pipeline 的時候默認會自動安裝,可以在 Jenkins 環境,插件管理下的 installed 下面找到這個插件。

1)readFile

作用:讀取指定文件的內容,以字符串的形式返回。

參數說明

  • file:相對於當前工作空間的文件路徑,也可以用絕對路徑表示;
  • encoding:讀取文件時的編碼方式,默認是根據你當前平台的編碼去解析。如果讀取的是二進制文件,會采用 Base64 轉碼的字符串輸出。
import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages{
        stage("init") {
            steps{
                script {
                    file = "../../jobs/test_pipeline_demo/demo.txt"
                    file_contents = readFile file
                    println file_contents
                }
            }
        }
    }
}

明:將 jobs/test_pipeline_demo 目錄下的 demo.txt 文件內容讀出並打印。

2)writeFile

作用:writeFile 和 readFile 類似,是簡單的文本文件進行寫操作。如果明確知道是 json 或其他類型文件,那么就可以用其他插件的 readJson 來讀取。

參數說明

  • file相對於當前工作空間的文件路徑,也可以用絕對路徑表示,路徑不存在會創建。
  • text:要寫入的文件內容。
  • encoding:寫入文件時的編碼方式,默認使用的是當前平台的編碼。

3)deleteDir() 方法

作用:默認遞歸刪除 WORKSPACE 下的文件和文件夾,這個方法是沒有參數,一般與 dir 一起使用。當執行完每一個 stage 里面的代碼,需要在 post{...}里面寫一些 clean up 操作,如果這個操作是清空 WORKSPACE 的話,就可以使用 deleteDir()。特別是生產環境,需要節約 Jenkins 服務器的磁盤空間,清空 WORKSPACE 是很有必要的操作。

用法:deleteDir()

4)mail

郵件功能在 Jenkins 中是非常有用的,當構建完成后無論成功還是失敗都需要將構建結果通知到相關人員,郵件是最常見的選擇。在 pipeline 中發送郵件之前,需要先按照 3.3.7 部分配置完畢。我們可以借助片段生成器查看該插件支持的參數:

需要注意的是 Body MIME Type 這個選項默認就是 text/plain,可以指定為 text/html。

5)dir

作用:切換操作目錄。

代碼示例:

import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages{
        stage("dir") {
            steps{
                println env.WORKSPACE
                dir(".."){
                    echo "pwd"
                }
            }
        }
    }
}

6. echo("message")和 error("error_message")

作用:echo和 groovy 中的 println 沒有任何區別。一般來說使用 echo 就是打印 info debug級別的日志輸出用,如果遇到錯誤,就可以使用 error(“error message”),如果出現執行到 error 方法,Jenkins job 會退出並顯示失敗效果。

7)fileExists

作用:判斷一個文件是否存在,返回值是布爾類型,true 就表示文件存在,false 表示文件存在。

8. isUnix()

作用:判斷當前運行的 Jenkins node 環境是 linux 還是 windows,如果返回是 true 表示是 linux/mac 系統,如果返回是 false,表示當前 Jenkins job 運行在 windows 的系統上。

import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages {
        stage("isUnix") {
            steps{
                script {
                    if(isUnix() == true) {
                        echo("this Jenkins job running on a linux-like system")
                    }else {
                        error("the Jenkins job running on a windows system")
                    }
                }
            }
        }
    }
}

9)pwd()

作用:返回當前所在的目錄。由於 Jenkins 支持 windows 和 linux,但是 linux 是 pwd,windows 上是 dir。所以這個插件就干脆支持一個方法,統稱為 pwd()。

 

git plugin 插件用法

作用:使用 git 命令 checkout 出項目的代碼,在 pipeline 代碼中,很常見在不同 stage 中使用不同 git 倉庫地址的代碼,所以 git SCM 操作,可以寫在不同 stage 中。

import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages{
        stage("test") {
            steps{
                script {
                    println "test"
                }
            }
        }
        stage("git checkout") {
            steps{
                script {
                    checkout([$class: 'GitSCM',
                    branches: [[name: '*/master']],
                    doGenerateSubmoduleConfigurations: false,
                    userRemoteConfigs: [[credentialsId: 'gtihub', url:
                    'https://github.com/kongsh8778/pipelinetest']]])
                }
            }
        }
    }
}

 

publish html report 插件用法

作用:將測試完成后生成的 html 格式的測試報告展示在 Jenkins 中,無需再切換到目錄用瀏覽器打開。

import hudson.model.*;

pipeline{
    agent any
    parameters {
        string(name: 'BROWSER_TYPE', defaultValue: 'chrome', description: 'Type a
        browser type, should be chrome/firefox')
        string(name: 'TEST_SERVER_URL', defaultValue: '', description: 'Type the
        test server url')
        string(name: 'NODE', defaultValue: 'win-anthony-demo', description:
        'Please choose a windows node to execute this job.')
    }
    stages{
        stage("test"){
            steps{
                script{
                    browser_type = BROWSER_TYPE?.trim()
                    test_url = TEST_SERVER_URL?.trim()
                    win_node = NODE?.trim()
                    echo 'test'
                }
            }
        }
    }
    post {
        always{
            script{
                publishHTML (target: [
                    allowMissing: false,
                    alwaysLinkToLastBuild: false,
                    keepAll: true,
                    reportDir: '../../jobs/test_pipeline_demo/report',
                    reportFiles: '接口測試報告.html',
                    reportName: "接口測試報告"
                ])
            }
        }
    }
}

件參數說明

  • reportDir:項目中保存 html 文件的地方,這里寫的是一個相對路徑寫法,相對於當前工作目錄的路徑,不寫的話默認是項目根目錄。
  • reportFiles:需要展示的 html 文件名,也可以同時寫多個 html 文件,逗號隔開。
  • reportName:這個參數指定的字符串會在 Jenkins 構建 Job 頁面顯示的菜單名稱,后面會看到這個名稱,這個名稱可以隨意修改。

構建結果

手動構建后,在項目首頁左側的導航欄可以看到上一步 reportName 值指定的菜單名:

單擊接口測試報告,可以看到如下展示結果:

 

借助 Jenkins 生成 pipeline 代碼

通過之前的介紹我們對 pipeline 常用的語法有了初步的印象,但是如果完全記住所有的指令還有第 3 方插件的指令也是不太現實的事情。其實 Jenkins 為我們提供了流水線語法在線生成的功能,我們基於表單的格式填好后,會 Jenkins 會幫助我們生成 pipeline 的代碼。

1)進入任意一個 pipeline 項目,單擊配置選項:

 

2)進入流水線選項卡,單擊左下角的流水線語法:

3)選擇“片段生成器”,可以查看所有內置的和已安裝插件支持的命令

以 dir 為例:

選擇“Declarative Pipeline directive”,可以查看聲明式 pipeline 的語法

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM