7.Jenkins進階之流水線pipeline語法入門學習(2)


目錄一覽:

  • (2) Declarative Pipeline Syntax

    • 2.1) Sections - 章節

    • 2.2) Directives - 指令

    • 2.3) Sequential Stages - 順序階段

    • 2.4) Parallel - 並行

    • 2.5) Matrix - 模型

    • 語法總結

    • script - 腳本

    • sh - 命令執行

    • agent - 代理

    • stages - 階段

    • steps - 步驟

    • post - 發布

    • environment - 環境

    • options - 選項

    • parameters - 參數

    • triggers - 觸發器

    • stage - 單階段

    • Tools - 工具

    • Input - 輸入

    • when - 執行條件

    • Matrix 單元級指令(可選)

  • 0x03 pipeline 內置支持

    • 3.0) 字符串和標准輸出

    • 3.1) 文件目錄相關步驟

    • 3.2) 制品相關步驟

    • 3.3) 命令相關步驟

    • 3.4) 其他步驟

  • 0x04 Pipeline 片段示例

 


WeiyiGeek Blog - 為了能到遠方,腳下的每一步都不能少。
原文地址: https://mp.weixin.qq.com/s/mqEd6VXzAU8YfumjsXHh1A
Tips : 本文章來源 Blog 站點或者 WeiyiGeek 公眾賬號 (技術交流、友鏈交換請郵我喲)。




(2) Declarative Pipeline Syntax

描述: 前面說過Declarative Pipeline是 Jenkins Pipeline 的一個相對較新的補充, 它在Pipeline子系統之上提出了一種更為簡化和有意義的語法。

Declarative Pipeline 中的基本語句和表達式遵循與Groovy語法相同的規則 ,但有以下例外:

  • 1.Pipeline的頂層必須是塊,即所有有效的Declarative Pipeline必須包含在一個pipeline塊內.

  • 2.沒有分號作為語句分隔符,每個聲明必須在自己的一行。

  • 3.塊只能包含Sections, Directives, Steps或賦值語句。

  • 4.屬性引用語句被視為無參方法調用。(例如: 輸入被視為input)

參考流水線語法: http://jenkins.weiyigeek.top:8080/job/simple-pipeline-demo/pipeline-syntax

 

簡單語法規范示例:

// (1) 所有代碼包裹在 Pipeline 塊之中
pipeline {
// (2) 定義任務在那台主機上運行可以是any、none(可以實現分布式的構建)等
agent any
// (3) 定義的環境變量比如PATH路徑
environment {
hostname='Jenkins Pipeline'
}
// (4) 其類似一個大項目任務的集合主要包含所有stage子項目
stages {
// (5) 其類似一個項目中的單個任務主要來包含所有stage子任務
stage ('clone') {
// (6) 用來實現具體的執行的動作
steps {
// (7) 內置命令執行(信息打印)
echo "git Clone Stage!"
}
}
stage ('build') {
steps {
// (8) shell 命令執行 (Shell Script)
sh "echo $hostname"
}
}
}
// (9) 消息通知
post {
always {
echo "構建成功"
}
}
}

語法格式說明:
pipeline:代表整條流水線,包含整條流水線的邏輯。

  • agent 部分:指定流水線的執行位置(Jenkins agent)。流水線中的每個階段都必須在某個地方(物理機、虛擬機或Docker容器)執行。

  • stage 部分:階段,代表流水線的階段。每個階段都必須有名稱。本例中,build就是此階段的名稱。

    • steps 部分:代表階段中的一個或多個具體步驟(step)的容器。steps部分至少包含一個步驟。

    • stages 部分:流水線中多個stage的容器。stages部分至少包含一個stage。

  • post 部分:包含的是在整個pipeline或階段完成后一些附加的步驟 (可選)

 

2.1) Sections - 章節

描述: 聲明性 Pipeline中的節通常包含一個或多個指令或步驟(Steps)。

agent - 代理

描述: 指定整個Pipeline或特定階段將在Jenkins環境中執行的位置,具體取決於該agent 部分的放置位置;

語法參數:

必須: YES
參數:any / none / label / node / docker / dockerfile / kubernetes
- 1.在任何可用的 agent 上執行Pipeline或stage
- 2.在pipeline塊的頂層應用時,不會為整個 Pipeline運行分配全局代理,並且每個stage部分都需要包含自己的agent部分。
- 3.使用提供的標簽在Jenkins環境中可用的代理上執行 Pipeline或階段, 注意標簽條件也可以使用。
- 4.node使用與lable類似
- 5.執行Pipeline或stage時會動態供應一個docker節點去接受Docker-based的Pipelines。
- 6.使用從Dockerfile源存儲庫中包含的容器構建的容器執行 Pipeline或階段,Jenkinsfile 必須從多分支 Pipeline或 SCM Pipeline加載。
- 7.在Kubernetes集群上部署的Pod內執行 Pipeline或階段,同樣Jenkinsfile 必須從多分支 Pipeline或 SCM Pipeline加載,Pod模板在kubernetes {} 塊內定義。
允許:在頂層pipeline塊和每個stage塊中。

語法示例:

pipeline {
agent any

agent none

agent {
label 'my-label1 && my-label2'
}

agent { node { label 'labelName' } } // 等同於 agent { label 'labelName' }

// docker 還可以接受一個args直接傳遞給`docker run`調用以及一個 alwaysPull 選項
// registryUrl和registryCredentialsId參數 有助於指定要使用的Docker注冊表及其憑據
agent {
docker {
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
registryUrl 'https://myregistry.com/'
registryCredentialsId 'myPredefinedCredentialsInJenkins'
}
}

// dockerfile
agent {
// 等同於 to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/
dockerfile {
filename 'Dockerfile.build'
// 如果要Dockerfile在另一個目錄中構建,請使用以下dir選項
dir 'build'
label 'my-defined-label'
additionalBuildArgs '--build-arg version=1.0.2'
args '-v /tmp:/tmp'
// 同樣也接受registryUrl和registryCredentialsId參數
registryUrl 'https://myregistry.com/'
registryCredentialsId 'myPredefinedCredentialsInJenkins'
}
}

// kubernetes: 例如如果要在其中裝有Kaniko容器的容器
agent {
kubernetes {
label podlabel
yaml """
kind: Pod
metadata:
name: jenkins-agent
spec:
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
imagePullPolicy: Always
command:
- /busybox/cat
tty: true
volumeMounts:
- name: aws-secret
mountPath: /root/.aws/
- name: docker-registry-config
mountPath: /kaniko/.docker
restartPolicy: Never
volumes:
- name: aws-secret
secret:
secretName: aws-secret
- name: docker-registry-config
configMap:
name: docker-registry-config
"""
}
}

常用選項:
描述: 下面可以應用於兩個或者多個agent實現的選項即label、customWorkspace、reuseNode;

  • 1.label (參數:字符串): 運行 Pipeline或單個 Pipeline的標簽或標簽條件stage。 【此選項對node,docker和有效對dockerfile必需 node。】

  • 2.customWorkspace (參數: 字符串) : 運行 Pipeline或個人 stage 這 agent 是這個自定義的工作空間內的應用,而不是默認的, 它可以是相對路徑(在這種情況下自定義工作空間將位於節點上的工作空間根目錄下),也可以是絕對路徑。【此選項是有效的node,docker和dockerfile。】

  • 3.reuseNode(參數: 布爾值-false): 如果為true在同一工作空間中在 Pipeline頂級指定的節點上運行容器,而不是在整個新節點上運行

  • 4.args (參數: 字符串): 要傳遞給的運行時參數docker run,此選項對docker和有效dockerfile。

// 示例1. Docker代理,聲明性 Pipeline
pipeline {
// V.在具有給定名稱和標簽(maven:3-alpine)的新創建容器中執行此 Pipeline中定義的所有步驟。
agent { docker 'maven:3-alpine' }
stages {
stage('Example Build') {
steps {
sh 'mvn -B clean verify'
}
}
}
}

// 例子2.階段級代理部分
pipeline {
/* agent none在 Pipeline的頂層進行定義可確保 不會不必要地分配執行程序。使用agent none還會強制每個stage部分包含其自己的agent部分。 */
agent none
stages {
stage('Example Build') {
/* 使用此映像在新創建的容器中執行此階段中的步驟。*/
agent { docker 'maven:3-alpine' }
steps {
echo 'Hello, Maven'
sh 'mvn --version'
}
}
stage('Example Test') {
/* 使用與上一階段不同的圖像在新創建的容器中執行此階段中的步驟。 */
agent { docker 'openjdk:8-jre' }
steps {
echo 'Hello, JDK'
sh 'java -version'
}
}
}
}

 

stages - 階段

描述: Stages 是 Pipeline描述的大部分“工作”所在的位置, 該部分包含一個或多個階段指令的序列。對於連續交付過程的每個離散部分,建議stages至少包含一個階段指令,例如Build,Test和Deploy。

位置&參數:

必須: YES
參數:NONE
允許:pipeline塊內只有一次

例子.階段聲明性 Pipeline

pipeline {
agent any
// stages部分將典型地遵循指令,例如agent, options等
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}

Tips : 該部分必須在pipeline塊內的頂層定義,但stage級使用是可選的。
Tips : 頂級代理和階段代理之間的細微差別,而在options應用指令時會有所不同。

 

steps - 步驟

描述: 該階段包含在給定指令中執行的一系列一個或多個步驟 stage 之中

位置&參數:

必須: YES
參數:None
允許:每個Stage塊之中
script - 腳本

描述: 前面我們說過我們可在Declarative Pipeline 中 采用script指令來執行Scripted Pipeline中的一些腳本;

例子.單步式聲明式 && Script Block in Declarative Pipeline

pipeline {
agent any
stages {
stage('Example') {
// 步驟部分必須包含一個或多個步驟。
steps {
echo 'Hello World'
// 執行 Scripted Pipeline (實際上就是直接執行並采用Groovy原生語法)
script {
def browsers = ['chrome', 'firefox']
for (int i = 0; i < browsers.size(); ++i) {
echo "Testing the ${browsers[i]} browser"
}
}
}
}
}
}
sh - 命令執行

描述: pipeline中獲取shell命令的輸出以及狀態,注意其必須在steps 塊以及 script 塊之中

  • (0) 最簡單的方式最簡單的方式

sh ''
  • (1) 獲取標准輸出

//第一種
result = sh returnStdout: true ,script: ""
result = result.trim()
//第二種
result = sh(script: "", returnStdout: true).trim()
//第三種
sh " > commandResult"
result = readFile('commandResult').trim()
  • (2) 獲取執行狀態

//第一種
result = sh returnStatus: true ,script: ""
result = result.trim()

//第二種
result = sh(script: "", returnStatus: true).trim()

//第三種
sh '; echo $? > status'
def r = readFile('status').trim() //值得學習

//第四種
sh label: 'release', returnStdout: true, script:"""
sudo apk add jq && \
if ( \$(curl -s --header 'PRIVATE-TOKEN: ${private_token}' ${GITLAB_REL} | jq .[].tag_name | grep -c '${params.RELEASE_VERSION}') != 0 );then echo -n 1 > result.txt;else echo -n 0 > result.txt;fi
"""
def r = readFile('result.txt').trim() //值得學習

// 注意使用'但引號也可以解析變量
sh(returnStatus: true, script: "sudo apk add jq && curl -s --header 'PRIVATE-TOKEN: ${private_token}' ${GITLAB_REL} | jq .[].tag_name | grep -c '${params.RELEASE_VERSION}'")

實際案例:

// # (1) 命令拼接
sh ' $SonarScannerHome/bin/sonar-scanner ' +
'-Dsonar.sources=src/main ' +
'-Dsonar.projectKey="test" ' +
'-Dsonar.projectName="test" '

// # (2) 值傳遞到參數
stage ("測試") {
steps {
timeout(time: 1, unit: 'MINUTES') {
script {
def RELEASE=sh returnStdout: true, script: 'git tag -l --column' // # git show --oneline --ignore-all-space --text | head -n 1
env.DEPLOY_ENV = input message: "選擇部署的環境的版本", ok: 'deploy',
parameters: [string(name: 'DEPLOY_ENV',defaultValue: "${RELEASE}",description: "可選項選擇的版本 ${RELEASE}")]
}
}
}
}

// # (3) 多行命令執行(值得注意在sh中得 $符號 需要采用 \$ 進行轉義)
stage ("測試") {
steps {
timeout(time: 1, unit: 'MINUTES') {
script {
def RELEASE=sh returnStdout: true, script: 'git tag -l --column'
def RELE=sh returnStdout: true, script: """\
git tag -l --column | tr -d ' ' > tag ;
export a="\$(sed "s#v#,'v#g" tag)'";
echo [\${a#,*}];
"""
// env.DEPLOY_ENV = input message: "選擇部署的環境的版本1", ok: 'deploy',
// parameters: [string(name: 'DEPLOY_ENV',defaultValue: "${RELEASE}",description: "可選項選擇的版本 ${RELEASE}")]
// }
println RELE // ['v1.1,'v1.10,'v1.11,'v1.2,'v1.3,'v1.6,'v1.7,'v1.8,'v1.9']
// 選擇部署的環境的版本 ['v1.1,'v1.10,'v1.11,'v1.2,'v1.3,'v1.6,'v1.7,'v1.8,'v1.9']
env.DEPLOY_RELEASE = input message: "選擇部署的環境的版本 ${RELE}", ok: 'deploy',
parameters: [choice(name: 'PREJECT_OPERATION', choices: ["ss","s"], description: 'Message: 選擇項目版本? ${RELE}')]
}
}
}

Tips : 注意傳遞變量得生存周期以及范圍,在pipeline全局中則全局有效,而stage塊中則該塊中有效,其他stage引用則報No such property: 變量名稱 for class: groovy.lang.Binding錯誤

 

post - 發布

描述: 本post部分定義了在 Pipeline或階段的運行完成后運行的一個或多個其他步驟(取決於該post部分在 Pipeline中的位置),即定義Pipeline或stage運行結束時的操作, 通常將清理工作空間以及構建狀態的消息通知(Email/釘釘、企業微信或者其他WebHook);
post可以支持任何以下的后置條件塊:always, changed,fixed,regression,aborted,failure,success, unstable,unsuccessful,和cleanup, 條件塊允許根據 Pipeline或階段的完成狀態在每個條件內執行步驟。

位置&參數:

必須: NO

參數:`always,changed,fixed,regression,aborted,failure,success, unstable,unsuccessful,和cleanup`
- always :post不管 Pipeline運行或階段運行的完成狀態如何,都運行本節中的步驟。
- changed :僅post當當前 Pipeline或階段的運行與之前的運行具有不同的完成狀態時,才運行步驟。
- fixed :僅post在當前 Pipeline或階段的運行成功並且前一運行失敗或不穩定的情況下運行步驟。
- regression :僅post當當前 Pipeline或階段的運行狀態為失敗,不穩定或中止並且上一次運行成功時,才運行步驟。
- aborted :僅post在當前 Pipeline或階段的運行狀態為“中止”時才運行步驟,通常是由於手動中止了 Pipeline。通常在網絡用戶界面中用灰色表示。
- failure :僅post當當前 Pipeline或階段的運行具有“失敗”狀態時才運行這些步驟,通常在Web UI中用紅色表示。
- success :僅post當當前 Pipeline或階段的運行具有“成功”狀態時才運行步驟,通常在Web UI中用藍色或綠色表示。
- unstable :僅post在當前 Pipeline或階段的運行狀態為“不穩定”(通常由測試失敗,代碼沖突等引起)的情況下,才運行步驟。通常在Web UI中以黃色表示。
- unsuccessful :僅post當當前 Pipeline或階段的運行狀態不是“成功”時才運行步驟。這通常根據前面提到的狀態在Web UI中表示。
- cleanup : 在評估post所有其他條件之后post,無論 Pipeline或階段的狀態如何,都在此條件下運行步驟。

允許位置:在頂層pipeline塊和每個stage塊中。

示例.Post 部分示例:

pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post {
always {
echo 'I will always say Hello again!'
}
}
}

2.2) Directives - 指令

描述: 顯然基本結構滿足不了現實多變的需求。所以Jenkins pipeline通過各種指令(directive)來豐富自己。指令可以被理解為對Jenkins pipeline基本結構的補充。

Jenkins pipeline支持的指令有:

  • environment:用於設置環境變量,可定義在stage或pipeline部分。

  • tools:可定義在pipeline或stage部分。它會自動下載並安裝我們指定的工具,並將其加入PATH變量中。

  • input:定義在stage部分,會暫停pipeline,提示你輸入內容。

  • options:用於配置Jenkins pipeline本身的選項,比如options {retry(3)}指當pipeline失敗時再重試2次。options指令可定義在stage或pipeline部分。

  • parallel:並行執行多個step。在pipeline插件1.2版本后,parallel開始支持對多個階段進行並行執行。

  • parameters:與input不同,parameters是執行pipeline前傳入的一些參數。

  • triggers:用於定義執行pipeline的觸發器。

  • when:當滿足when定義的條件時,階段才執行。

Tips: 在使用指令時需要注意的是每個指令都有自己的“作用域”。如果指令使用的位置不正確Jenkins將會報錯。

 

environment - 環境

描述: 該指定了一系列鍵值對,這些鍵值對將被定義為所有步驟或特定於階段的步驟的環境變量,具體取決於該environment指令在 Pipeline中的位置。

位置&參數:

必須: No
參數:Yes
允許:在pipeline塊內,或在stage指令內。

Tips : 非常注意該塊中的變量將寫入到Linux環境變量之中作為全局變量,在shell可通過變量名訪問,而在script pipeline腳本中通過env.變量名稱訪問.

支持的憑證類型:Supported Credentials Type

  • Secret Text :設置為加密文本字符串內容

  • Secret File : 設置為臨時創建的文件文件的位置, 並自動定義變量存儲該文件內容。

  • Username and password : 將設置為username:password並且兩個其他環境變量將自動定義為MYVARNAME_USR 和MYVARNAME_PSW

  • SSH with Private Key : 設置為臨時創建的SSH密鑰文件的位置,並且可能會自動定義兩個其他環境變量:MYVARNAME_USR和MYVARNAME_PSW(保留密碼)。

 

示例1:秘密文本憑證,聲明性 Pipeline

pipeline {
agent any
// (1) 由於在pipeline下一層,則使用的指令將應用於 Pipeline中的所有步驟。
environment {
CC = 'clang'
}
stages {
stage('Example') {
// (2) 在 stage 中定義的 environment指令只會將給定的環境變量應用於Example內的步驟。
environment {
// 在environment塊中credentials('憑據名稱')定義的幫助程序方法通過其在Jenkins環境中的標識符來訪問預定義的憑據
AN_ACCESS_KEY = credentials('my-predefined-secret-text')
}
steps {
sh 'printenv'
echo "${env.AN_ACCESS_KEY}"
echo "${env.CC}"
}
}
}
}

 

示例2.用戶名和密碼憑證

pipeline {
agent any
stages {
stage('Example Username/Password') {
environment {
// 變量 = 將用戶密碼憑證賦予變量
SERVICE_CREDS = credentials('my-predefined-username-password')
}
steps {
// 注意點: defined: MYVARNAME_USR and MYVARNAME_PSW respectively.
sh 'echo "Service user is $SERVICE_CREDS_USR"'
sh 'echo "Service password is $SERVICE_CREDS_PSW"'
sh 'curl -u $SERVICE_CREDS https://myservice.example.com'
}
}
stage('Example SSH Username with private key') {
environment {
// 變量 = 將 `ssh private` 公密鑰進行賦予變量
SSH_CREDS = credentials('my-predefined-ssh-creds')
}
steps {
// 注意點: defined: MYVARNAME_USR and MYVARNAME_PSW (holding the passphrase).
sh 'echo "SSH private key is located at $SSH_CREDS"'
sh 'echo "SSH user is $SSH_CREDS_USR"'
sh 'echo "SSH passphrase is $SSH_CREDS_PSW"'

// 調用內置變量 (如果變量不存在則輸出null) - 值得學習注意。
echo "${JOB_NAME}"
echo env.'JOB_NAME'
println(env.'JOB_NAME')

// 自定義全局變量方式(寫入文件中再讀取)
script {
def projectProduct = sh returnStdout: true, script: "find ${APP_NAME}"
if ( projectProduct != '' ){
echo "${projectProduct}"
writeFile file: 'abc.sh', text: "${projectProduct}"
change_id = readFile 'abc.sh'
print(change_id)
} else {
error "[-Error] : projectProduct 不能為空!"
}
}

}
}
}
}

Tips : 該指令支持特殊的幫助程序方法credentials(),該方法可用於在Jenkins環境中通過其標識符訪問預定義的憑據。

Tips : 如有不支持的憑據類型導致 Pipeline失敗,並顯示以下消息:org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: No suitable binding handler could be found for type .

 

options - 選項

描述: options 指令 允許在 Pipeline 本身內配置 Pipeline 專用選項, 例如 buildDiscarder 它們也可能由插件提供;

位置&參數:

必須: No
參數:None
允許:pipeline塊內只有一次。

可用選項:

  • 1.buildDiscarder : 保存最近歷史構建記錄的數量。設置此選項后會自動清理pipeline 的構建歷史。

options { buildDiscarder(logRotator(numToKeepStr: '1')) }
  • 2.disableConcurrentBuilds : 禁止並發執行 Pipeline 對於防止同時訪問共享資源等很有用

options { disableConcurrentBuilds() }
  • 3.checkoutToSubdirectory : Jenkins從版本控制庫拉取源碼時,默認檢出到工作空間的根目錄中,此選項可以指定檢出到工作空間的子目錄中。

options { checkoutToSubdirectory('foo') }
  • 4.newContainerPerStage : 當agent為docker或dockerfile時,指定在同一個Jenkins節點上,每個stage都分別運行在一個新的容器中,而不是所有stage都運行在同一個容器中。

  • 5.disableResume : 如果控制器重新啟動則不允許 Pipeline恢復

options { disableResume() }
  • 6.overrideIndexTriggers : 允許重寫分支索引觸發器的默認處理,如果在多分支或組織標簽處禁用了分支索引觸發器。

# 僅為該作業啟用分支索引觸發器
options { overrideIndexTriggers(true) }

# 僅為此作業禁用分支索引觸發器
options { overrideIndexTriggers(false) }
  • 7.preserveStashes: 保留已完成構建中的隱藏項,以用於階段重新啟動。

# 保存構建
options { preserveStashes() }

# 保存最近5次構建
options { preserveStashes(buildCount: 5) }
  • 8.quietPeriod:設置 Pipeline的靜默時間段(以秒為單位),以覆蓋全局默認值

options { quietPeriod(30) }
  • 9.retry:如果失敗重試整個 Pipeline指定次數。該次數是指總次數包括第1次失敗。

options { retry(3) }
  • 10.skipDefaultCheckout : 默認跳過來自源代碼控制的代碼(代理指令)。

options { skipDefaultCheckout() }
  • 11.skipStagesAfterUnstable : 一旦構建狀態變得不穩定就跳過各個階段;

options { skipStagesAfterUnstable() }
  • 12.timestamps : 預定義由Pipeline生成的所有控制台輸出時間

options { timestamps() }
  • 13.parallelsAlwaysFailFast :將 Pipeline中所有后續並行階段的failfast設置為true。

options { parallelsAlwaysFailFast() }
  • 14.timeout(常用) : 設置 Pipeline運行的超時時間在此之后Jenkins 應中止 Pipeline(運行的超時時間)。

# 操守時間一個小時(HOURS/Minute)
options { timeout(time: 1, unit: 'HOURS') }

# Global Timeout, Declarative Pipeline
pipeline {
agent any
options {
// 將全局執行超時指定為一小時,然后Jenkins將中止 Pipeline運行。
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}

Tips: 在 stage 塊中支持的 options 要少於 pipeline 塊中,只能采用skipDefaultCheckout,timeout,retry,timestamps 等選項;

例如:

pipeline {
agent any
stages {
stage('Example') {
// 關鍵單
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
echo 'Hello World'
}
}
}
}

 

parameters - 參數

描述: 該指令提供了一個用戶在觸發 Pipeline時應該提供的參數列表。這些用戶指定參數的值通過params對象提供給 Pipeline步驟,請參閱參數,聲明式 Pipeline的具體用法。

目前可用參數有string , text, booleanParam, choice, password等參數,其他高級參數化類型還需等待社區支持。

位置&參數:

必須: No
參數: None
允許: 在`Pipeline`塊內僅一次。

Tips : 非常注意全局參數, 在shell可通過變量名訪問,而在script pipeline腳本中通過params.參數名稱訪問.

 

示例: Parameters, Declarative Pipeline

Parameters, Declarative Pipeline
pipeline {
agent any

// Jenkins -> 原生 Build With Parameters 支持
parameters {
gitParameter name: 'RELEASE_VERSION',
type: 'PT_BRANCH_TAG',
branchFilter: 'origin/(.*)',
defaultValue: 'master',
selectedValue: 'DEFAULT',
sortMode: 'DESCENDING_SMART',
description: 'Message: 請選擇部署的Tags版本?'
choice(name: 'SONARQUBE', choices: ['False','True'], description: 'Message: 是否進行代碼質量檢測?')

// Jenkins -> 原生 Build With Parameters 支持 和 BlueOcean 都支持
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')

text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')

booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')

choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')

password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
}
stages {
stage('Example') {
steps {
// 調用
echo "Hello ${params.PERSON}"

echo "Biography: ${params.BIOGRAPHY}"

echo "Toggle: ${params.TOGGLE}"

echo "Choice: ${params.CHOICE}"

echo "Password: ${params.PASSWORD}"
}
}
}
}

 

triggers - 觸發器

描述: 該指令定義了Pipeline自動化觸發的方式,對於與GitHub或BitBucket等源集成的 Pipeline可能不需要觸發器,因為基於webhook的集成可能已經存在了。

位置&參數:

必須: No
參數: None
允許: 在Pipeline塊內

Tips : 當前可用的觸發器是cron、pollSCM和upstream

  • 1.cron : 以Linux中Cron風格的字符串,以定義應該重新觸發 Pipeline的定期間隔

triggers { cron('H */4 * * 1-5') }
  • 2.pollSCM : 接受cron樣式的字符串以定義Jenkins應檢查新源更改的定期間隔。如果存在新的更改則將重新觸發 Pipeline。

triggers { pollSCM('H */4 * * 1-5') }
  • Tips : pollSCM觸發器僅在Jenkins 2.22或更高版本中可用。

  • 3.upstream : 接受以逗號分隔的作業字符串和閾值。當字符串中的任何作業以最小閾值結束時 Pipeline將被重新觸發

triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }

 

cron語法
描述: Jenkins cron語法遵循cron實用程序的語法(略有不同)。具體來說每行包含5個由TAB或空格分隔的字段:

* * * * * 
MINUTE - Minutes within the hour (0–59)

HOUR - The hour of the day (0–23)

DAY - The day of the month (1–31)

MONTH - The month (1–12)

WEEK - The day of the week (0–7) where 0 and 7 are Sunday.

如果要為一個字段指定多個值,可以使用以下操作符。按照優先順序,

*   specifies all valid values  (指定所有有效值)

M-N specifies a range of values (指定值范圍)

M-N/X or */X steps by intervals of X through the specified range or whole valid range (在指定范圍或整個有效范圍內按X的間隔步進)

A,B,…,Z enumerates multiple values (枚舉多個值)

Tips : 在 Cron 中使用 H 字符為了使定期計划的任務在系統上產生均勻的負載,H符號可以被認為是在一定范圍內的隨機值。
例如使用0 0 * * *一打日常工作將導致午夜時分大幅增加。相反使用H H * * *仍會每天執行一次每個作業,但不是同時執行所有作業,更好地使用有限的資源

Tips : 此外@yearly,@annually,@monthly, @weekly,@daily,@midnight,並且@hourly也支持方便的別名。這些使用哈希系統進行自動平衡。
例如 @hourly與相同,H * * * *並且可能表示該小時中的任何時間, @midnight實際上是指在12:00 AM和2:59 AM之間的某個時間。

 

示例.Triggers, Declarative Pipeline:

// (1) Jenkins cron語法示例
// 每十五分鍾執行觸發
triggers{ cron('H/15 * * * *') }

// 每小時(1~30分鍾)內每十分鍾一次
triggers{ cron('H(0-29)/10 * * * *') }

// 每隔一個小時的45分鍾,每兩小時一次,從上午9:45開始,到每個工作日的下午3:45結束。
triggers{ cron('45 9-16/2 * * 1-5') }

// 每個工作日的上午9點至下午5點之間每兩小時一次
triggers{ cron('H H(9-16)/2 * * 1-5') }

// 每月12月1日和15日每天一次
triggers{ cron('H H 1,15 1-11 *') }

//(2) Declarative Pipeline
pipeline {
agent any
triggers {
cron('H */4 * * 1-5')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}

 

stage - 單階段

描述: 該 stage 指令位於stages中並且應包含Step 節,可選 agent 節或其他特定於階段的指令, 實際上管道完成的所有實際工作都將包含在一個或多個stage指令中。

位置&參數:

必須: YES
參數: 步驟名稱(字符串、必填)
允許: 在 Pipeline塊 -> stages部分 內

示例.stage , Declarative Pipeline

// Declarative 
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}

 

Tools - 工具

描述: 定義自定義安裝的Tools工具路徑,並放置環境變量到PATH。如果agent none 這將被忽略
Supported Tools(Global Tool Configuration) : maven / jdk / gradle / Sonarqube

位置&參數:

必須: No
參數: None
允許: 在 Pipeline 塊 或者 stage 部分 內

示例.Tools ,聲明性管道

pipeline {
agent any
tools {
// 工具名稱必須在Jenkins中的 Manage Jenkins → Global Tool Configuration 下預先配置。
maven 'apache-maven-3.0.1'
}
stages {
stage('Example') {
steps {
sh 'mvn --version'
script {
// 無指定名稱時可用采用tool指定設置的全局工具名稱,這里這個tool是直接根據名稱,獲取自動安裝的插件的路徑
def scannerHome = tool 'sonarqubescanner'
}
withSonarQubeEnv('SonarQube') {
sh "${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=YourProjectKey -Dsonar.sources=."
}
}
}
}
}

 

Input - 輸入

描述: input指令允許您使用輸入步驟提示輸入。在應用了任何選項之后,在進入該階段的代理塊或評估該階段的when條件之前,該階段將暫停。如果輸入被批准,該階段將繼續。作為輸入提交的一部分提供的任何參數都將在該階段的其余部分的環境中可用。

位置&參數:

必須: No
參數: message 、id 、ok、submitter、submitterParameter、parameters
允許: 在 Pipeline塊 -> stages 塊內 (注意不是在stage中)

配置選項

  • message : 必須的前台輸入時提示用戶的信息;

  • id : 此輸入的可選標識符。默認為階段名稱。

  • ok : 輸入表單上“確定”按鈕的可選文本。

  • Parameter : 提示提交者提供的可選參數列表。請參閱參數以獲取更多信息。

  • submitter : 可選的用逗號分隔的用戶或允許輸入此輸入的外部組名的列表,默認為允許任何用戶。

  • submitterParameter : 可以使用提交者名稱設置的環境變量的可選名稱(如果存在)。

基礎示例:

pipeline {
agent any
stages {
stage('Example') {
// 方式1.此種方式只能該塊有效
input {
message "Title : 個人信息輸入"
ok "完成提交"
submitter "alice,bob"
parameters {
string(name: 'INPUT_PERSON', defaultValue: 'WeiyiGeek', description: 'Message: 請輸入您的姓名?')
string(name: 'INPUT_AGE', defaultValue: 'WeiyiGeek', description: 'Message: 請輸入您的年齡?')
choice(name: 'INPUT_SEX', choices: ['Male','Female'], description: 'Message: 請選擇你的性別?')
booleanParam(name: 'INPUT_AGREE', defaultValue: true, description: 'Message: 是否確定協議?')
}
}

steps {
// 方式2: 注意script必須包含在 steps 塊之中(此種方式可以全局傳遞參數)
script {
env.git_version=input message: 'Titel: 版本', ok: '通過',parameters: [string ( name: 'git_version', trim: true, description: 'Message : 請選擇要操作的應用版本?')];

env.deploy_option = input message: 'Titel: 操作', ok: 'deploy', parameters: [choice(name: 'deploy_option', choices: ['deploy', 'rollback', 'redeploy'], description: 'Message : 請選擇操作流程?')];
}

// 12.input 輸出示例
echo "局部可用 輸出示例1: 姓名:${INPUT_PERSON}, 年齡:${INPUT_AGE}, 性別:${INPUT_SEX}, 是否同意協議: ${INPUT_AGREE}"

echo "全局可用 輸出示例(script) -> 版本 : ${env.git_version}"
echo "全局可用 輸出示例(script) -> 版本 : ${env.deploy_option}"
}
}

// 采用script塊中定義input可以調用不同stage中得參數值
stage ('調用') {
steps {
echo "調用1 : ${env.git_version}"
echo "調用2 : ${env.deploy_option}"
}
}

}


 

when - 執行條件

描述: 該指令允許管道根據給定條件確定是否應執行該階段,when指令必須至少包含一個條件,如果when指令包含多個條件,則所有子條件必須返回true才能執行該階段;

使用嵌套條件構建更復雜的條件結構:not,allOf或anyOf,嵌套條件可以嵌套到任意深度。

  • 1.如果使用allOf條件,則表示所有條件為真才繼續執行。

  • 2.如果使用anyOf條件,請注意一旦找到第一個“真”條件,該條件將跳過其余測試。

  • 3.使用使用not條件是,則當條件為false是為真才進行執行

// 1.不匹配分支
when { not { branch 'master' } }

// 2.分別滿足分支為master並且DEPLOY_TO環境變量值為production是繼續執行
when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }

// 3.滿足分支為master或者分支為staging都可以繼續執行.
when { anyOf { branch 'master'; branch 'staging' } }

位置&參數:

必須: No
參數: Express
允許: 在 Pipeline塊 -> stage 塊內

內置條件:

  • branch : 當正在構建的分支與給出的分支模式匹配時執行,請注意這僅適用於多分支管道;

when { branch 'master' }
  • environment : 當指定的環境變量設置為給定值時執行,

when { expression { return params.DEBUG_BUILD } }
  • equals : 當期望值等於實際值時執行階段,

when { equals expected: 2, actual: currentBuild.number }
  • expression : 在指定的Groovy表達式計算為true時執行階段, 注意當從表達式返回字符串時,它們必須被轉換為布爾值,或者返回null來計算為false。簡單地返回"0"或"false"仍然會計算為"true"

when { expression { return params.DEBUG_BUILD } } 
  • Tag : 如果TAG_NAME變量匹配給定的模式則執行該階段, 注意如果提供了一個空模式,那么階段將在TAG_NAME變量存在時執行(與buildingTag()相同)。

when { tag "release-*" }
  • buildingTag : 執行構建構建標簽的階段.

when { buildingTag() }
  • changelog : 如果構建的SCM更改日志包含給定的正則表達式模式則執行階段;

when { changelog '.*^\\[DEPENDENCY\\] .+$' }
  • changeset : 如果構建的SCM變更集包含一個或多個與給定模式匹配的文件,則執行階段。

when { changeset "**/*.js" }
when { changeset pattern: ".TEST\\.java", comparator: "REGEXP" } // 正則表達式匹配
when { changeset pattern: "*/*TEST.java", caseSensitive: true } // 區分大小寫ANT樣式路徑
  • changeRequest : 如果當前構建是針對“變更請求”的,則執行階段(也稱為GitHub和Bitbucket上的Pull Request,GitLab上的Merge Request,Gerrit變更等)。如果未傳遞任何參數,則階段將在每個更改請求上運行

when { changeRequest() }.
// # Possible attributes are `id, target, branch, fork, url, title, author, authorDisplayName, and authorEmail`

// 每一個都對應一個CHANGE_*環境變量,
when { changeRequest target: 'master' }.

// comparator 參數后指導屬性,以指定匹配時如何計算任何模式:
// * EQUALS用於簡單的字符串比較(默認值),
// * GLOB用於ANT風格的路徑GLOB(與例如changeset相同),
// * REGEXP用於正則表達式匹配
when { changeRequest authorEmail: "[\\w_-.]+@example.com", comparator: 'REGEXP' }
  • triggeredBy : 在給定的參數觸發當前構建時執行該階段。

when { triggeredBy 'SCMTrigger' }

when { triggeredBy 'TimerTrigger' }

when { triggeredBy 'UpstreamCause' }

when { triggeredBy cause: "UserIdCause", detail: "vlinde" }

優先級說明

  • 1.when在input指令前評估 : 默認情況下,如果定義了階段則在輸入之前不會評估階段的when條件。但是可以通過beforeInput在when塊中指定選項來更改此設置。如果beforeInput設置為true,則將首先評估when條件並且僅當when條件評估為true時才輸入

pipeline {
agent none
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
beforeInput true // 關鍵點
branch 'production'
}
input {
message "Deploy to production?"
id "simple-input"
}
steps {
echo 'Deploying'
}
}
}
}
  • 2.when在options指令前評估 : 默認情況下,when一個條件stage會進入之后進行評價options為stage,如果任何限定。但是可以通過beforeOptions在when 塊中指定選項來更改此設置。如果beforeOptions將設置為true,when則將首先評估條件,並且options僅在 when 條件評估為true時才輸入

pipeline {
agent none
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
beforeOptions true // 關鍵點
branch 'testing'
}
options {
lock label: 'testing-deploy-envs', quantity: 1, variable: 'deployEnv'
}
steps {
echo "Deploying to ${deployEnv}"
}
}
}
}
  • 3.when在stage進入agent前評估 : 默認情況下,如果定義了一個階段的when條件,那么將在進入該階段的代理之后計算。但是,這可以通過在when塊中指定beforeAgent選項來更改。如果beforeAgent被設置為true,那么將首先計算when條件,只有當when條件計算為true時才會輸入agent

pipeline {
agent none
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
agent {
label "some-label"
}
when {
beforeAgent true
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}

示例.Condition When

pipeline {
agent none // beforeAgent
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
// Single Condition - 單一條件
when {
branch 'production'
}

// Multiple Condition - 多重條件
when {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}

// Nested condition - 嵌套條件
when {
allOf {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
}

// Multiple condition and nested condition - 注意點
when {
branch 'production'
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}

// Expression condition and nested condition - 表達式條件和嵌套條件
when {
expression { BRANCH_NAME ==~ /(production|staging)/ }
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}

// triggeredBy
when {
triggeredBy "TimerTrigger" // 當前Job設置的觸發器名稱進行監控
}

// 當前面的when都滿足時采用執行該階段步驟,否則丟棄
steps {
echo 'Deploying'
}
}
}
}

Tips : GLOB(對於默認)對於不區分大小寫的ANT樣式路徑所以可以使用caseSensitive參數將其關閉;

 

2.3) Sequential Stages - 順序階段

描述: 聲明式管道中的階段可能有一個包含要按順序運行的嵌套階段列表的stage節。注意,一個階段必須有且只有一個步驟、階段、並行或 Matrix。如果stage指令嵌套在一個並行塊或 Matrix 塊本身中, 則不可能在stage指令中嵌套一個並行塊或 Matrix 塊。然而一個並行或 Matrix 塊中的stage指令可以使用stage的所有其他功能,包括代理、工具、when等。

示例:Sequential Stages, Declarative Pipeline

pipeline {
agent none
stages {
// 非時序的階段
stage('Non-Sequential Stage') {
agent {
label 'for-non-sequential'
}
steps {
echo "On Non-Sequential Stage"
}
}
// 順序階段
stage('Sequential Stage') {
agent {
label 'for-sequential'
}
environment {
FOR_SEQUENTIAL = "some-value"
}
// 注意點1:
stages {
stage('In Sequential 1') {
steps {
echo "In Sequential 1"
}
}
stage('In Sequential 2') {
steps {
echo "In Sequential 2"
}
}
// 注意點2:可以使用stage的所有其他功能,包括代理、工具、when等
stage('Parallel In Sequential') {
// 並行執行上面已講述
parallel {
stage('In Parallel 1') {
steps {
echo "In Parallel 1"
}
}
stage('In Parallel 2') {
steps {
echo "In Parallel 2"
}
}
}
}
}
}
}
}

 

2.4) Parallel - 並行

描述:聲明式管道中的階段可能有一個包含要並行運行的嵌套階段列表的並行部分。注意,一個階段必須有且只有一個步驟、階段、並行或 Matrix 。如果stage指令嵌套在一個並行塊或 Matrix 塊本身中,則不可能在stage指令中嵌套一個並行塊或 Matrix 塊。然而,一個並行或 Matrix 塊中的stage指令可以使用stage的所有其他功能,包括代理、工具、when等。

Tips : 此外,通過在包含並行的階段中添加failFast true,可以在任何一個階段失敗時強制終止所有並行階段。添加failfast 的另一個選項是在管道定義中添加一個option{ parallelsAlwaysFailFast() }

示例:Parallel Stages, Declarative Pipeline

pipeline {
agent any
//方式1.parallelsAlwaysFailFast
options {
parallelsAlwaysFailFast()
}
stages {
stage('Non-Parallel Stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('Parallel Stage') {
when {
branch 'master'
}
// 方式2.在任何一個階段失敗時強制終止所有並行階段
failFast true
// 並行構建值得學習
parallel {
stage('Branch A') {
agent {
label "for-branch-a"
}
steps {
echo "On Branch A"
}
}
stage('Branch B') {
agent {
label "for-branch-b"
}
steps {
echo "On Branch B"
}
}
stage('Branch C') {
agent {
label "for-branch-c"
}
stages {
stage('Nested 1') {
steps {
echo "In stage Nested 1 within Branch C"
}
}
stage('Nested 2') {
steps {
echo "In stage Nested 2 within Branch C"
}
}
}
}
}
}
}
}

 

2.5) Matrix - 模型

描述: 聲明式管道(Declarative pipeline)中的階段可能有一個 Matrix 節,定義要並行運行的名稱-值組合的多維 Matrix 。我們將把這些組合稱為 Matrix 中的“細胞”。 Matrix 中的每個單元可以包括一個或多個階段,使用該單元的配置按順序運行。注意一個階段必須有且只有一個步驟、階段、並行或 Matrix 。如果stage指令嵌套在一個並行塊或 Matrix 塊本身中,則不可能在stage指令中嵌套一個並行塊或 Matrix 塊。然而,一個並行或 Matrix 塊中的stage指令可以使用stage的所有其他功能,包括代理、工具、when等。

此外,通過在包含 Matrix 的階段同樣也可添加 failFast true,您可以強制您的 Matrix 單元在其中任何一個失敗時全部終止。添加failfast的另一個選項是在管道定義中添加一個option { parallelsAlwaysFailFast() } Matrix 部分必須包括一個軸部分和一個級部分。

  • axis部分定義了 Matrix 中每個軸的值。

  • stage部分定義了要在每個單元格中按順序運行的階段列表。

Tips : 同時Matrix 可以有一個exclude節來移除無效的單元格, 舞台上可用的許多指令,包括代理、工具、何時等,也可以添加到matrix中來控制每個單元格的行為。

 

axis
描述: axes(軸線)部分指定了一個或多個axis指令。每個軸由一個名稱和一個值列表組成。每個軸上的所有值都與其他軸上的值組合起來生成單元格。

 

stages
描述: 該階段部分指定每個單元中要順序執行的一個或多個階段, 此部分與前面任何stages是相同的;

示例: Matrix

// One-axis with 3 cells, each cell runs three stages - "build", "test", and "deploy"
matrix {
axes {
axis {
name 'PLATFORM'
values 'linux', 'mac', 'windows'
}
}
stages {
stage('build') {
// ...
}
stage('test') {
// ...
}
stage('deploy') {
// ...
}
}
}


// Three-axis matrix with 24 cells (three by four by two)
// 即 24 種組合方式: 例如 linux -> 32-bit -> chrome , mac -> 32-bit -> chrome
matrix {
axes {
axis {
name 'PLATFORM'
values 'linux', 'mac', 'windows'
}
axis {
name 'BROWSER'
values 'chrome', 'edge', 'firefox', 'safari'
}
axis {
name 'ARCHITECTURE'
values '32-bit', '64-bit'
}
}
// ...
}

 

excludes (optional) - 排出
描述: 可選的exclude部分允許作者指定一個或多個exclude filter表達式,這些表達式選擇要從擴展的矩陣單元格集合中排除的單元格(aka, sparsening)。過濾器是使用一個或多個帶有名稱和值列表的排除軸指令的基本指令結構來構造的。
exclude中的axis指令生成一組組合(類似於生成矩陣單元格)。匹配排除組合中所有值的矩陣單元格從矩陣中移除。如果提供了多個exclude指令,則每個指令將分別計算以刪除單元格。

當處理一長串要排除的值時 exclude axis指令可以使用 notValues 代替 values.這將排除與傳遞給notValues的值之一不匹配的單元格。

示例.具有24個單元的三軸矩陣,不包括“ 32位,mac”(不包括4個單元)

matrix {
axes {
axis {
name 'PLATFORM'
values 'linux', 'mac', 'windows'
}
axis {
name 'BROWSER'
values 'chrome', 'edge', 'firefox', 'safari'
}
axis {
name 'ARCHITECTURE'
values '32-bit', '64-bit'
}
}
excludes {
exclude {
axis {
name 'PLATFORM'
values 'mac'
}
axis {
name 'ARCHITECTURE'
values '32-bit'
}
}

//排除linux和safari組合,並排除使用edge瀏覽器的任何非windows平台。
exclude {
// 2 cells
axis {
name 'PLATFORM'
values 'linux'
}
axis {
name 'BROWSER'
values 'safari'
}
}
exclude {
// 3 more cells and '32-bit, mac' (already excluded)
axis {
name 'PLATFORM'
notValues 'windows' // 注意點 norValues
}
axis {
name 'BROWSER'
values 'edge'
}
}
}
// ...
}

 

Matrix 單元級指令(可選)

描述: 通過在Matrix本身下添加階段級指令,用戶可以有效地為每個單元配置整體環境。這些指令的行為與它們在舞台上的行為相同,但它們也可以接受矩陣為每個單元格提供的值。

注意 axis和exclude指令定義了組成矩陣的靜態單元格集, 這組組合是在管道運行開始之前生成的。另一方面“per-cell”指令在運行時進行計算。

directives include:

  • agent

  • environment

  • input

  • options

  • post

  • tools

  • when

 

Example.完整的矩陣示例,聲明性管道

pipeline {
// 參數選擇
parameters {
choice(name: 'PLATFORM_FILTER', choices: ['all', 'linux', 'windows', 'mac'], description: 'Run on specific platform')
}
agent none
stages {
stage('BuildAndTest') {
matrix {
agent {
label "${PLATFORM}-agent"
}
when { anyOf {
// 參數選擇不為空時繼續執行
expression { params.PLATFORM_FILTER == 'all' }
expression { params.PLATFORM_FILTER == env.PLATFORM }
} }
// 2 軸 (3 x 4) 十二格組合方式
axes {
axis {
name 'PLATFORM'
values 'linux', 'windows', 'mac'
}
axis {
name 'BROWSER'
values 'firefox', 'chrome', 'safari', 'edge'
}
}
// 排除指定Matrix矩陣中的值 (排除linux和safari組合,並排除使用edge瀏覽器的任何非windows平台。)
// 即 排除 (linux,safari) , (linux,edge) , (mac,edge) 三種情況
excludes {
exclude {
axis {
name 'PLATFORM'
values 'linux'
}
axis {
name 'BROWSER'
values 'safari'
}
}
exclude {
axis {
name 'PLATFORM'
notValues 'windows'
}
axis {
name 'BROWSER'
values 'edge'
}
}
}
stages {
stage('Build') {
steps {
echo "Do Build for ${PLATFORM} - ${BROWSER}"
}
}
stage('Test') {
steps {
echo "Do Test for ${PLATFORM} - ${BROWSER}"
}
}
}
}
}
}
}

 

語法總結

// Declarative Pipeline Syntax Composite sample
pipeline {
// 1.由於此處沒有其它jenkins slave 分布式機器則采用any進行替代
agent any
// 7.全局環境變量
environment {
global_env = 'Jenkins global environment'
global_when = 'true'
}
// 8.全局選項
options {
// 如果失敗重試整個 Pipeline指定次數
retry(3)
// 在任何一個階段失敗時強制終止所有並行階段
parallelsAlwaysFailFast()

}
// 9.全局參數
parameters {
// 參數聲明定義
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')
text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')
choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')
password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
}

// 11.觸發器 (每兩分鍾執行一次)
triggers{ cron('H/2 * * * *') }

// 12.工具路徑並放置環境變量到PATH
// Dashboard -> 全局工具配置
tools {
maven 'maven_env'
jdk 'jdk_1.8.0_211'
}
// 2.多階段唯一入口
stages {
// 3.指定的單階段(init-初始化階段)
stage ('init') {
// 4.單階段中的只有一個步驟steps
steps {
// 5.內置指令例如 echo 、println進行輸出
echo "init - steps one - built-in functions echo"
println "init - steps one - built-in functions println "

// 6.采用script指令來執行Scripted Pipeline中的一些腳本
script {
def browsers = ['chrome', 'firefox', 'edge']
for (int i = 0; i < browsers.size(); ++i) {
echo "Testing the ${browsers[i]} browser"
}
}
}
}

stage ('one-stage') {
// 7.局部環境變量
environment {
// 變量定義
local_env = "Jenkins local environment"
// 將在Jenkins中設置的用戶密碼憑證賦予local_creds變量, 注意括號中為憑據名稱
// Dashboard -> 憑據 -> 系統 -> 全局憑據 (unrestricted) -> 添加憑據
// Username with password : 43287e62-ce5b-489a-9c11-cedf38e16e92 weiyigeek/****** (Pipeline 測試 credentials 讀取) Username with password Pipeline 測試 credentials 讀取
Local_userpass_creds = credentials('43287e62-ce5b-489a-9c11-cedf38e16e92')
// SSH Username with private key : b4c8b4e9-2777-44a1-a1ed-e9dc21d37f4f weiyigeek (myself-gitlab-weiyigeek) SSH Username with private key myself-gitlab-weiyigeek
Local_ssh_creds = credentials('b4c8b4e9-2777-44a1-a1ed-e9dc21d37f4f')
}

steps {
println "全局變量: " + global_env +", 局部變量: " + local_env
/* == 全局變量: Jenkins global environment, 局部變量: Jenkins local environment*/
// 注意點: defined: MYVARNAME_USR and MYVARNAME_PSW respectively. (輸出的字符串已經經過轉義)
sh 'echo "user is $Local_userpass_creds_USR"' /* = user is **** */
sh 'echo "password is $Local_userpass_creds_PSW"' /* = password is **** */
// 注意點: defined: MYVARNAME_USR and MYVARNAME_PSW (holding the passphrase).
sh 'echo "SSH private key is located at $Local_ssh_creds"'
sh 'echo "SSH user is $Local_ssh_creds_USR"'

// 12.額外第三方工具插件路徑調用方式
script {
scannerHome = tool 'sonarqubescanner'
//這里這個tool是直接根據名稱,獲取自動安裝的插件的路徑
}
// withSonarQubeEnv('SonarQube') {
// sh "${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=YourProjectKey -Dsonar.sources=."
// }
}


}

stage ('two-stage') {
// 13.當任一滿足以下條件時執行
when {
beforeInput true
anyOf { branch 'master'; environment name: 'global_when', value: 'true' }
}

// 8.局部選項
options {
// 可設置全局(局部階段)執行超時指定為一分鍾,然后Jenkins將中止 Pipeline運行。
timeout(time: 5, unit: 'MINUTES')
}

// 12.Input指令輸入參數到變量中
// 方式1
input {
message "Title : 個人信息輸入"
ok "完成提交"
submitter "alice,bob"
parameters {
string(name: 'INPUT_PERSON', defaultValue: 'WeiyiGeek', description: 'Message: 請輸入您的姓名?')
text(name: 'INPUT_AGE', defaultValue: 'WeiyiGeek', description: 'Message: 請輸入您的年齡?')
choice(name: 'INPUT_SEX', choices: ['Male','Female'], description: 'Message: 請選擇你的性別?')
password(name: 'INPUT_PASSWORD', defaultValue: 'SECRET', description: 'Message: 請輸入您注冊密碼?')
booleanParam(name: 'INPUT_AGREE', defaultValue: true, description: 'Message: 是否確定協議?')
}
}

steps {
// 方式2:注意script必須包含在 steps 塊之中
script {
env.git_version=input message: 'Titel: 版本', ok: '通過',parameters: [string ( name: 'git_version', trim: true, description: 'Message : 請選擇要操作的應用版本?')];
env.deploy_option = input message: 'Titel: 操作', ok: 'deploy', parameters: [choice(name: 'deploy_option', choices: ['deploy', 'rollback', 'redeploy'], description: 'Message : 請選擇操作流程?')];
}

// 10.Parameters 參數調用
echo "全局 - Hello ${params.PERSON}"
echo "全局 - Toggle: ${params.TOGGLE}"
echo "全局 - Choice: ${params.CHOICE}"
echo "全局 - Password: ${params.PASSWORD}"
echo "全局 - Biography: ${params.BIOGRAPHY}"

// 12.input 輸出示例
echo "input 輸出示例1: 姓名:${INPUT_PERSON}, 年齡:${INPUT_AGE}, 性別:${INPUT_SEX}, 是否同意協議: ${INPUT_AGREE}"
echo "input 輸出示例(script) -> 版本 : ${env.git_version}"
echo "input 輸出示例(script) -> 版本 : ${env.deploy_option}"
}
}

stage ('three-stage') {
// 14.Parallel Stages 並行執行
// 方式2.failFast true 在任何一個階段失敗時強制終止所有並行階段
parallel {
stage('parallel-Branch A') {
steps {
echo "On Branch A"
}
}
stage('parallel-Branch B') {
steps {
echo "On Branch B"
}
}
stage('parallel-Branch C') {
stages {
stage('嵌套Nested 1') {
steps {
echo "In stage Nested 1 within Branch C"
}
}
stage('嵌套Nested 2') {
steps {
echo "In stage Nested 2 within Branch C"
}
}
}
}
}
}

// 15.Matrix 矩陣模型實踐
stage ('four-stage') {
input {
message "Title : 部署平台"
ok "完成提交"
submitter "alice,bob"
parameters {
choice(name: 'PLATFORM_FILTER', choices: ['all', 'linux', 'windows', 'mac'], description: 'Run on specific platform')
}
}
matrix {
when { anyOf {
// 參數選擇不為空時繼續執行
expression { params.PLATFORM_FILTER == 'all' }
expression { params.PLATFORM_FILTER == env.PLATFORM }
}
}
// 16.2 軸 (3 x 2) 6種組合方式的模型
axes {
axis {
name 'PLATFORM'
values 'linux', 'windows', 'mac'
}
axis {
name 'ARCHITECTURE'
values '32-bit','64-bit'
}
}
// 17.排除指定模型例如非64-bit的在windows平台的將被剔除
excludes {
exclude {
axis {
name 'PLATFORM'
values 'windows'
}
axis {
name 'ARCHITECTURE'
notValues '64-bit'
}
}
}
// 18.還有5種情況依次進行構建
stages {
stage('Build') {
steps {
echo "matrix - Do Build for ${PLATFORM} - ${BROWSER}"
}
}
}
}
}
}

// 6.消息通知
post {
// # 總是執行的步驟
always {
echo 'I will always say Hello again!' /* == I will always say Hello again!— Print Message */
}
}
}

輸出結果:

## init - stage
maven_env— Use a tool from a predefined Tool Installation <1s
# Fetches the environment variables for a given tool in a list of 'FOO=bar' strings suitable for the withEnv step.<1s
jdk_k1.8.0_211— Use a tool from a predefined Tool Installation <1s
# Fetches the environment variables for a given tool in a list of 'FOO=bar' strings suitable for the withEnv step.<1s
maven_env— Use a tool from a predefined Tool Installation <1s
# Fetches the environment variables for a given tool in a list of 'FOO=bar' strings suitable for the withEnv step.<1s
jdk_k1.8.0_211— Use a tool from a predefined Tool Installation <1s
# Fetches the environment variables for a given tool in a list of 'FOO=bar' strings suitable for the withEnv step.<1s
init - steps one - built-in functions echo— Print Message <1s
init - steps one - built-in functions println — Print Message <1s
Testing the chrome browser— Print Messag e<1s
Testing the firefox browser— Print Message 1s
Testing the edge browser— Print Message <1s


## one - stage
全局變量: Jenkins global environment, 局部變量: Jenkins local environment
+ echo user is ****
user is ****
+ echo **** is ****
**** is ****
+ echo SSH private key is located at ****
SSH private key is located at ****
+ echo SSH user is ****
SSH user is ****


## two-stage
全局 - Hello Mr Jenkins— Print Message<1s
全局 - Toggle: true— Print Message<1s
全局 - Choice: One— Print Message<1s
全局 - Password: SECRET— Print Message<1s
全局 - Biography: — Print Message<1s
input 輸出示例1: 姓名:WeiyiGeek, 年齡:185, 性別:Male, 是否同意協議: true— Print Message<1s
input 輸出示例(script) -> 版本 : v1.2— Print Message<1s
input 輸出示例(script) -> 版本 : deploy— Print Message

## three-stage
On Branch A— Print Message
On Branch B— Print Message
In stage Nested 1 within Branch C
In stage Nested 2 within Branch C

## four-stage
I will always say Hello again!— Print Message<1s


0x03 pipeline 內置支持

3.0) 字符串和標准輸出

  • echo: Print Message

  • println: Print Message

echo "Hello"
println "World!"

 

3.1) 文件目錄相關步驟

  • isUnix: 如果封閉節點運行在類unix系統(如Linux或Mac OS X)上,則返回true,如果Windows。

  • pwd:確認當前目錄

  • dir: 默認pipeline工作在工作空間目錄下,dir步驟可以讓我們切換到其他目錄。

  • deleteDir:是一個無參步驟刪除的是當前工作目錄。通常它與dir步驟一起使用,用於刪除指定目錄下的內容。

dir("./delete_dir")
deleteDir()
  • fileExists:檢查給定的文件(作為當前目錄的相對路徑)是否存在。參數file返回 true | false 。

# 工作空間中文件的相對(/分隔)路徑,以驗證文件是否存在。
fileExists file: "./pom.xml"
  • writeFile:將內容寫入指定文件中; 參數為:file, text, encoding

  • readFile:讀取文件內容; 參數為:file, encoding

writeFile encoding: 'utf-8', file: 'file', text: '測試寫入'

 

3.2) 制品相關步驟

  • stash : 步驟可以將一些文件保存起來以便被同一次構建的其他步驟或階段使用。

name
Name of a stash. Should be a simple identifier akin to a job name.
Type: String

allowEmpty (optional)
Type: boolean

excludes (optional)
Optional set of Ant-style exclude patterns.
Use a comma separated list to add more than one expression.
If blank, no files will be excluded.
Type: String

includes (optional)
Optional set of Ant-style include patterns.
Use a comma separated list to add more than one expression.
If blank, treated like **: all files.
The current working directory is the base directory for the saved files, which will later be restored in the same relative locations, so if you want to use a subdirectory wrap this in dir.
Type: String

useDefaultExcludes (optional)
If selected, use the default excludes from Ant - see here for the list.
Type: boolean
  • unstash:恢復以前存儲在當前工作區中的一組文件。

# name: 以前保存的倉庫的名稱。
unstash 'repo'
  • wrap: 一般構建包裝,它是特殊的步驟允許調用構建包裝器(在freestyle或類似項目中也稱為“環境配置”)

wrap([$class: 'AnsiColorBuildWrapper']). 
  • archive: Archive artifacts-歸檔的工件

  • unarchive: Copy archived artifacts into the workspace-將存檔工件復制到工作區中

  • archiveArtifacts: 存檔構建的成品 (重點)

# 參數: String includes, optional: excludes 
archive
# 參數: Type: java.util.Map<java.lang.String, java.lang.String> mapping
unarchive
# 參數:
# artifacts: 用於存檔的文件(支持通配符)
# excludes: 不包含的文件(支持通配符)
# allowEmptyArchive: 歸檔為空時不引起構建失敗
# onlyIfSuccessful: 只有構建成功時歸檔
# fingerprint: 記錄所有歸檔成品的指紋
# Follow symbolic links: 通過禁用此選項,工作空間中找到的所有符號鏈接都將被忽略。
archiveArtifacts artifacts: './target/*.jar', excludes: './target/test/*', fingerprint: true, onlyIfSuccessful: true, allowEmptyArchive: true

 

3.3) 命令相關步驟

描述: 與命令相關的步驟其實是 Pipeline:Nodes and Processes 插件提供的步驟。由於它是 Pipeline 插件的一個組件,所以基本不需要單獨安裝

withEnv: 設置環境變量
描述: 在塊中設置一個或多個環境變量, 這些可用於該范圍內生成的任何外部流程。例如:

node {
withEnv(['MYTOOL_HOME=/usr/local/mytool']) {
sh '$MYTOOL_HOME/bin/start'
}
}

Tips: 注意這里我們在Groovy中使用了單引號,所以變量展開是由Bourne shell完成的而不是Jenkins;

 

sh:執行shell命令
該步驟支持的參數有:

  • script:將要執行的shell腳本,通常在類UNIX系統上可以是多行腳本。

  • encoding:腳本執行后輸出日志的編碼,默認值為腳本運行所在系統的編碼。

  • returnStatus:布爾類型,默認腳本返回的是狀態碼,如果是一個非零的狀態碼,則會引發pipeline執行失敗。如果 returnStatus 參數為true,則不論狀態碼是什么,pipeline的執行都不會受影響。

  • returnStdout:布爾類型,如果為true,則任務的標准輸出將作為步驟的返回值,而不是打印到構建日志中(如果有錯誤,則依然會打印到日志中)。除了script參數,其他參數都是可選的。

Tips: returnStatus與returnStdout參數一般不會同時使用,因為返回值只能有一個。如果同時使用則只有returnStatus參數生效。

Tips : 注意采用sh執行echo 1 > 1.txt命令時然后采用readFile讀取時帶有換行符,解決辦法:

# 方式1.采用 $? 判斷命令執行成功與否。
# 方式2.采用echo命令輸出到文件時加上 -n 選項。

bat、powershell步驟

  • bat步驟執行的是Windows的批處理命令。

  • powershell步驟執行的是PowerShell腳本,支持3+版本。

Tips: 步驟支持的參數與sh步驟的一樣就不重復介紹了。

 

3.4) 其他步驟

異常終止
try-catch-finally : 異常捕獲和拋出
error:主動報錯中止當前 pipeline 並且避免打印堆棧跟蹤信息。

// 簡單示例
try {
sh 'might fail && whoami'
echo 'Succeeded!'
} catch (err) {
echo "Failed: ${err} - " + err.toString()
error "[-Error] : 項目部署失敗 \n[-Msg] : ${err.getMessage()} "
} finally {
sh './tear-down.sh'
}

catchError: 捕獲錯誤並將構建結果設置為失敗

catchError {
sh 'might fail'
}

unstable: 設置階段結果為不穩定, 將一條消息打印到日志中並將整個構建結果和階段結果設置為不穩定。消息還將與階段結果相關聯並可能以可視化方式顯示。

unstable '階段結果為不穩定'
unstable {
echo "階段結果為不穩定"
}

電子郵件

  • mail: Simple step for sending email.

subject
Email subject line.
Type: String
body
Email body.
Type: String
bcc (optional)
BCC email address list. Comma separated list of email addresses.
Type: String
cc (optional)
CC email address list. Comma separated list of email addresses.
Type: String
charset (optional)
Email body character encoding. Defaults to UTF-8
Type: String
from (optional)
From email address. Defaults to the admin address globally configured for the Jenkins instance.
Type: String
mimeType (optional)
Email body MIME type. Defaults to text/plain.
Type: String
replyTo (optional)
Reploy-To email address. Defaults to the admin address globally configured for the Jenkins instance.
Type: String
to (optional)
To email address list. Comma separated list of email addresses.
Type: String

 

重試休眠和超時

  • retry:重試正文最多N次, 如果在塊體執行過程中發生任何異常,請重試該塊(最多N次)。如果在最后一次嘗試時發生異常,那么它將導致中止構建(除非以某種方式捕獲並處理它),不會捕獲生成的用戶中止。

  • sleep:讓pipeline休眠指定的一段時間 , 只需暫停管道構建直到給定的時間已經過期相當於(在Unix上)sh 'sleep…'

  • timeout:以確定的超時限制執行塊內的代碼。

  • waitUntil:反復運行它的主體直至條件滿足。

# 參數: int count
retry(count: 5) # 重試5次

# 參數: int time, optional unit ( Values: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS)
sleep(time: 60,unit: SECONDS # 休眠60s

# 參數: int time, optional activity, optional unit
# Values: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS
timeout(time: 10,unit: MINUTES) # 超時10分鍾

# 參數: optional initialRecurrencePeriod, optional quiet
# initialRecurrencePeriod: 設置重試之間的初始等待周期(以毫秒為單位)默認為250 ms。每次失敗都將降低嘗試之間的延遲最多可達15秒。
# quiet: 如果為true,則該步驟不會在每次檢查條件時記錄消息。默認值為false。
waitUntil(initialRecurrencePeriod: 250, quiet: false){
sh "./monitor.sh"
}

tool:使用預定義的工具,在Global Tool Configuration(全局工具配置)中配置了工具。

tool name: 'Sonar-Scanner', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
tool name: 'docker', type: 'dockerTool'

getContext: 從內部api獲取上下文對象
withContext: 在塊中使用內部api中的上下文對象

# 參數: 用於受信任的代碼,如全局庫,它可以操作內部Jenkins api。
# Type: java.lang.Class<?>
# 例子:接受單個類型參數
getContext hudson.FilePath

# 例子:接受一個context參數和一個block。
# 在ConsoleLogFilter、LauncherDecorator和EnvironmentExpander的情況下,自動將其參數與上下文對象合並。
withContext(new MyConsoleLogFilter()) {
sh 'process'
}

Tips : 不要試圖傳遞在Groovy中定義的對象;只支持java定義的對象。實際上你應該避免使用this和getContext而只是在插件中定義一個步驟。

參考地址: https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/


0x04 Pipeline 片段示例

(1) 超時設置與部署參數switch語句選擇

timeout(time: 1, unit: 'MINUTES') {
script {
env.deploy_option = input message: '選擇操作', ok: 'deploy',
parameters: [choice(name: 'deploy_option', choices: ['deploy', 'rollback', 'redeploy'], description: '選擇部署環境')]
switch("${env.deploy_option}"){
case 'deploy':
println('1.deploy prd env')
break;
case 'rollback':
println('2.rollback env')
break;
case 'redeploy':
println('3.redeploy env')
break;
default:
println('error env')
}
}
}

 

(1)代碼倉庫拉取之checkout SCM

checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'b4c8b4e9-2777-44a1-a1ed-e9dc21d37f4f', url: 'git@gitlab.weiyigeek.top:ci-cd/java-maven.git']]])

 

(2) 代碼質量檢測之shell Script

/usr/local/bin/sonar-scanner -Dsonar.projectName=${JOB_NAME} -Dsonar.projectKey=Hello-World -Dsonar.sources=.

// # 生成的流水線
sh label: 'sonar', returnStatus: true, script: '''/usr/local/bin/sonar-scanner -Dsonar.projectName=${JOB_NAME} -Dsonar.projectKey=Hello-World -Dsonar.sources=.'''

 

(3) Kubernetes 動態節點 Pod 模板的選擇

// # Scripted Pipeline
podTemplate(label: 'jenkins-jnlp-slave', cloud: 'k8s_115') {
node ('jenkins-jnlp-slave') {
stage ('dynamic-checkout') {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], userRemoteConfigs: [[credentialsId: '69c0dbf0-f786-4aa0-975a-76528f10de8b', url: 'http://127.0.0.1/xxx/devops_test.git']]])
}
}
}

 

WeiyiGeek Blog - 為了能到遠方,腳下的每一步都不能少。

Tips : 本文章來源 Blog 站點或者 WeiyiGeek 公眾賬號 (友鏈交換請郵我喲):

  • 微信公眾號-WeiyiGeek` # 精華文章發布地址

  • https://weiyigeek.top # 采用cloudflare CDN 國內有時訪問較慢

  • https://weiyigeek.gitee.io # 國內訪問快可能會有更新不及時得情況

  • 個人知乎-WeiyiGeek

Tips: 更多學習筆記文章請關注 WeiyiGeek 公眾賬號
【微信公眾號關注(點擊)】
【郵箱聯系: Master#weiyigeek.top】




免責聲明!

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



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