本節(jié)基于“ 入門(mén)指南”中介紹的信息,并應(yīng)作為參考。有關(guān)如何在實(shí)際示例中使用Pipeline語(yǔ)法的更多信息,請(qǐng)參閱 本章的Jenkinsfile部分。從Pipeline插件2.5版開(kāi)始,Pipeline支持兩種離散語(yǔ)法,詳細(xì)說(shuō)明如下。對(duì)于每個(gè)的利弊,請(qǐng)參閱語(yǔ)法比較(下文中)。
如“ 入門(mén)指南 ”所述,Pipeline最基本的部分是“步驟”?;旧?,步驟告訴Jenkins 要做什么,并且作為Declarative和Scripted Pipeline語(yǔ)法的基本構(gòu)建塊。
有關(guān)可用步驟的概述,請(qǐng)參閱 Pipeline步驟參考(下文中) ,其中包含Pipeline內(nèi)置的完整列表以及插件提供的步驟。
聲明性Pipeline是Jenkins Pipeline 的一個(gè)相對(duì)較新的補(bǔ)充, 它在Pipeline子系統(tǒng)之上提出了一種更為簡(jiǎn)化和有意義的語(yǔ)法。
所有有效的聲明性Pipeline必須包含在一個(gè)pipeline塊內(nèi),例如:
pipeline {
/* insert Declarative Pipeline here */
}
聲明性Pipeline中有效的基本語(yǔ)句和表達(dá)式遵循與Groovy語(yǔ)法相同的規(guī)則 ,但有以下例外:
聲明性Pipeline中的部分通常包含一個(gè)或多個(gè)指令或步驟。
該agent
部分指定整個(gè)Pipeline或特定階段將在Jenkins環(huán)境中執(zhí)行的位置,具體取決于該agent
部分的放置位置。該部分必須在pipeline
塊內(nèi)的頂層定義 ,但階段級(jí)使用是可選的。
需要 | 是 |
---|---|
參數(shù) | 如下面所描述的 |
允許 | 在頂級(jí) |
為了支持作者可能有的各種各樣的pipeline用例, agent
部分支持一些不同類型的參數(shù)。這些參數(shù)應(yīng)用在`pipeline`塊的頂層, 或 stage
指令內(nèi)部。
在任何可用的代理上執(zhí)行Pipeline或stage。例如:agent any
當(dāng)在pipeline
塊的頂層應(yīng)用時(shí),將不會(huì)為整個(gè)Pipeline運(yùn)行分配全局代理,并且每個(gè)stage
部分將需要包含其自己的agent
部分。例如:agent none
使用提供的標(biāo)簽在Jenkins環(huán)境中可用的代理上執(zhí)行Pipeline或階段性執(zhí)行。例如:agent { label 'my-defined-label' }
agent { node { label 'labelName' } }
行為相同 agent { label 'labelName' }
,但node
允許其他選項(xiàng)(如customWorkspace
)。
執(zhí)行Pipeline,或階段執(zhí)行,用給定的容器將被動(dòng)態(tài)地供應(yīng)一個(gè)節(jié)點(diǎn)預(yù)先配置成接受基于Docker-based Pipelines,或匹配的任選定義的節(jié)點(diǎn)上 label
的參數(shù)。 docker
還可以接受一個(gè)args
可能包含直接傳遞給docker run
調(diào)用的參數(shù)的參數(shù)。例如:agent { docker 'maven:3-alpine' }
或
agent {
docker {
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
}
}
使用從Dockerfile
源存儲(chǔ)庫(kù)中包含的容器構(gòu)建容器來(lái)執(zhí)行Pipeline或階段性執(zhí)行 。為了使用此選項(xiàng),Jenkinsfile
必須從多分支Pipeline或“Pipeline從SCM”加載。通常這是Dockerfile
源庫(kù)的根源:agent { dockerfile true }
。如果Dockerfile
在另一個(gè)目錄中建立,請(qǐng)使用以下dir
選項(xiàng):agent { dockerfile { dir 'someSubDir' } }
。您可以docker build ...
使用該additionalBuildArgs
選項(xiàng)將其他參數(shù)傳遞給命令,如agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }
。
這些是可以應(yīng)用兩個(gè)或多個(gè)agent實(shí)現(xiàn)的幾個(gè)選項(xiàng)。除非明確說(shuō)明,否則不需要。
一個(gè)字符串。運(yùn)行Pipeline或個(gè)人的標(biāo)簽stage
。
此選項(xiàng)對(duì)于node
,docker
和dockerfile
,并且是必需的 node
。
一個(gè)字符串。運(yùn)行Pipeline或個(gè)人stage
這agent
是這個(gè)自定義的工作空間內(nèi)的應(yīng)用,而不是默認(rèn)的。它可以是相對(duì)路徑,在這種情況下,自定義工作區(qū)將位于節(jié)點(diǎn)上的工作空間根目錄下,也可以是絕對(duì)路徑。例如:
agent {
node {
label 'my-defined-label'
customWorkspace '/some/other/path'
}
}
此選項(xiàng)是有效的node
,docker
和dockerfile
。
一個(gè)布爾值,默認(rèn)為false。如果為true,則在同一工作空間中,而不是完全在新節(jié)點(diǎn)上運(yùn)行Pipeline頂層指定的節(jié)點(diǎn)上的容器。
此選項(xiàng)適用于docker
和dockerfile
,并且僅在agent
個(gè)人使用時(shí)才有效果stage
。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent { docker 'maven:3-alpine' }
stages {
stage('Example Build') {
steps {
sh 'mvn -B clean verify'
}
}
}
}
:在給定名稱和tag(maven:3-alpine
)的新創(chuàng)建的容器中執(zhí)行此Pipeline中定義的所有步驟。
Stage-level agent
部分
Jenkinsfile (Declarative Pipeline)
pipeline {
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'
}
}
}
}
:agent none
在Pipeline頂層定義確保執(zhí)行者不會(huì)被不必要地分配。使用agent none
也強(qiáng)制每個(gè)stage
部分包含自己的agent
部分
:使用此圖像在新創(chuàng)建的容器中執(zhí)行此階段中的步驟
:在新創(chuàng)建的容器中使用前一個(gè)階段的不同圖像執(zhí)行此階段中的步驟
該post部分定義將在Pipeline運(yùn)行或階段結(jié)束時(shí)運(yùn)行的操作。一些條件后 的塊的內(nèi)支持post:部分 always,changed,failure,success,unstable,和aborted。這些塊允許在Pipeline運(yùn)行或階段結(jié)束時(shí)執(zhí)行步驟,具體取決于Pipeline的狀態(tài)。
需要 | 沒(méi)有 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 在頂級(jí) |
always
運(yùn)行,無(wú)論P(yáng)ipeline運(yùn)行的完成狀態(tài)如何。
changed
只有當(dāng)前Pipeline運(yùn)行的狀態(tài)與先前完成的Pipeline的狀態(tài)不同時(shí),才能運(yùn)行。
failure
僅當(dāng)當(dāng)前Pipeline處于“失敗”狀態(tài)時(shí)才運(yùn)行,通常在Web UI中用紅色指示表示。
success
僅當(dāng)當(dāng)前Pipeline具有“成功”狀態(tài)時(shí)才運(yùn)行,通常在具有藍(lán)色或綠色指示的Web UI中表示。
unstable
只有當(dāng)前Pipeline具有“不穩(wěn)定”狀態(tài),通常由測(cè)試失敗,代碼違例等引起,才能運(yùn)行。通常在具有黃色指示的Web UI中表示。
aborted
只有當(dāng)前Pipeline處于“中止”狀態(tài)時(shí),才會(huì)運(yùn)行,通常是由于Pipeline被手動(dòng)中止。通常在具有灰色指示的Web UI中表示。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post {
always {
echo 'I will always say Hello again!'
}
}
}
:通常,該post
部分應(yīng)放在Pipeline末端
:后條件塊包含的步驟相同的步驟部分
包含一個(gè)或多個(gè)階段指令的序列,該stages部分是Pipeline描述的大部分“工作”的位置。建議stages至少包含至少一個(gè)階段指令,用于連續(xù)交付過(guò)程的每個(gè)離散部分,如構(gòu)建,測(cè)試和部署。
需要 | 是 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 只有一次,在 |
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
:的stages
部分將典型地遵循指令,例如agent
, options
等
該steps部分定義了 在給定指令中執(zhí)行的一系列一個(gè)或多個(gè)步驟stage。
需要 | 是 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 在每個(gè) |
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
:該steps
部分必須包含一個(gè)或多個(gè)步驟
該environment指令指定一系列鍵值對(duì),這些對(duì)值將被定義為所有步驟的環(huán)境變量或階段特定步驟,具體取決于environment指令位于Pipeline中的位置。
該指令支持一種特殊的幫助方法credentials(),可以通過(guò)其在Jenkins環(huán)境中的標(biāo)識(shí)符來(lái)訪問(wèn)預(yù)定義的憑據(jù)。對(duì)于類型為“Secret Text”的憑據(jù),該 credentials()方法將確保指定的環(huán)境變量包含Secret Text內(nèi)容。對(duì)于“標(biāo)準(zhǔn)用戶名和密碼”類型的憑證,指定的環(huán)境變量將被設(shè)置為, username:password并且將自動(dòng)定義兩個(gè)附加的環(huán)境變量:MYVARNAME_USR和MYVARNAME_PSW相應(yīng)的。
需要 | 沒(méi)有 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 在 |
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment {
CC = 'clang'
}
stages {
stage('Example') {
environment {
AN_ACCESS_KEY = credentials('my-prefined-secret-text')
}
steps {
sh 'printenv'
}
}
}
}
:environment
頂級(jí)pipeline
塊中使用的指令將適用于Pipeline中的所有步驟
:在一個(gè)environment
意圖中定義的一個(gè)指令stage
將僅將給定的環(huán)境變量應(yīng)用于該過(guò)程中的步驟stage
:該environment
塊具有一個(gè)幫助方法credentials()
,可用于在Jenkins環(huán)境中通過(guò)其標(biāo)識(shí)符訪問(wèn)預(yù)定義的憑據(jù)
該options指令允許在Pipeline本身內(nèi)配置Pipeline專用選項(xiàng)。Pipeline提供了許多這些選項(xiàng),例如buildDiscarder,但它們也可能由插件提供,例如 timestamps。
需要 | 沒(méi)有 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 只有一次,在 |
持久化工件和控制臺(tái)輸出,用于最近Pipeline運(yùn)行的具體數(shù)量。例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }
不允許并行執(zhí)行Pipeline??捎糜诜乐雇瑫r(shí)訪問(wèn)共享資源等。例如:options { disableConcurrentBuilds() }
在agent
指令中默認(rèn)跳過(guò)來(lái)自源代碼控制的代碼。例如:options { skipDefaultCheckout() }
一旦構(gòu)建狀態(tài)進(jìn)入了“不穩(wěn)定”狀態(tài),就跳過(guò)階段。例如:options { skipStagesAfterUnstable() }
設(shè)置Pipeline運(yùn)行的超時(shí)時(shí)間,之后Jenkins應(yīng)該中止Pipeline。例如:options { timeout(time: 1, unit: 'HOURS') }
失敗后,重試整個(gè)Pipeline指定的次數(shù)。例如:options { retry(3) }
預(yù)處理由Pipeline生成的所有控制臺(tái)輸出運(yùn)行時(shí)間與發(fā)射線的時(shí)間。例如:options { timestamps() }
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
:指定一個(gè)小時(shí)的全局執(zhí)行超時(shí),之后Jenkins將中止Pipeline運(yùn)行。
完整的INFRA-1503完整列表可供選擇
該parameters指令提供用戶在觸發(fā)Pipeline時(shí)應(yīng)提供的參數(shù)列表。這些用戶指定的參數(shù)的值通過(guò)該params對(duì)象可用于Pipeline步驟,具體用法見(jiàn)示例。
需要 | 沒(méi)有 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 只有一次,在 |
string
字符串類型的參數(shù),例如: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
一個(gè)布爾參數(shù),例如: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
parameters {
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
}
stages {
stage('Example') {
steps {
echo "Hello ${params.PERSON}"
}
}
}
}
INFRA-1503的完整列表可供參考 。
該triggers指令定義了Pipeline應(yīng)重新觸發(fā)的自動(dòng)化方式。對(duì)于與源代碼集成的Pipeline,如GitHub或BitBucket,triggers可能不需要基于webhook的集成可能已經(jīng)存在。目前只有兩個(gè)可用的觸發(fā)器是cron和pollSCM。
需要 | 沒(méi)有 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 只有一次,在 |
接受一個(gè)cron風(fēng)格的字符串來(lái)定義Pipeline應(yīng)重新觸發(fā)的常規(guī)間隔,例如: triggers { cron('H 4/* 0 0 1-5') }
接受一個(gè)cron風(fēng)格的字符串來(lái)定義Jenkins應(yīng)該檢查新的源更改的常規(guī)間隔。如果存在新的更改,則Pipeline將被重新觸發(fā)。例如:triggers { pollSCM('H 4/* 0 0 1-5') }
該pollSCM觸發(fā)器僅在Jenkins 2.22或更高版本可用
例如:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
triggers {
cron('H 4/* 0 0 1-5')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
該stage指令在該stages部分中,應(yīng)包含步驟部分,可選agent部分或其他特定于階段的指令。實(shí)際上,Pipeline完成的所有實(shí)際工作都將包含在一個(gè)或多個(gè)stage指令中。
需要 | 最后一個(gè) |
---|---|
參數(shù) | 一個(gè)強(qiáng)制參數(shù),一個(gè)用于舞臺(tái)名稱的字符串。 |
允許 | 在 |
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
定義自動(dòng)安裝和放置工具的部分PATH。如果agent none指定,這將被忽略。
需要 | 沒(méi)有 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 在 |
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
tools {
maven 'apache-maven-3.0.1'
}
stages {
stage('Example') {
steps {
sh 'mvn --version'
}
}
}
}
:工具名稱必須在Jenkins 管理Jenkins → 全局工具配置中預(yù)配置。
該when指令允許Pipeline根據(jù)給定的條件確定是否執(zhí)行該階段。該when指令必須至少包含一個(gè)條件。如果when指令包含多個(gè)條件,則所有子條件必須為舞臺(tái)執(zhí)行返回true。這與子條件嵌套在一個(gè)allOf條件中相同(見(jiàn)下面的例子)。
更復(fù)雜的條件結(jié)構(gòu)可使用嵌套條件建:not,allOf或anyOf。嵌套條件可以嵌套到任意深度。
需要 | 沒(méi)有 |
---|---|
參數(shù) | 沒(méi)有 |
允許 | 在 |
當(dāng)正在構(gòu)建的分支與給出的分支模式匹配時(shí)執(zhí)行stage,例如:when { branch 'master' }
。請(qǐng)注意,這僅適用于多分支Pipeline。
當(dāng)指定的環(huán)境變量設(shè)置為給定值時(shí)執(zhí)行stage,例如: when { environment name: 'DEPLOY_TO', value: 'production' }
當(dāng)指定的Groovy表達(dá)式求值為true時(shí)執(zhí)行stage,例如: when { expression { return params.DEBUG_BUILD } }
當(dāng)嵌套條件為false時(shí)執(zhí)行stage。必須包含一個(gè)條件。例如:when { not { branch 'master' } }
當(dāng)所有嵌套條件都為真時(shí),執(zhí)行stage。必須至少包含一個(gè)條件。例如:when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
當(dāng)至少一個(gè)嵌套條件為真時(shí)執(zhí)行stage。必須至少包含一個(gè)條件。例如:when { anyOf { branch 'master'; branch 'staging' } }
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
allOf {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
expression { BRANCH_NAME ==~ /(production|staging)/ }
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
聲明性Pipeline可以使用“ Pipeline步驟”引用中記錄的所有可用步驟 ,其中包含一個(gè)完整的步驟列表,并附加以下列出的步驟,僅在聲明性PipelinePipeline Pipeline 中支持。
該script步驟需要一個(gè)script Pipeline,并在聲明性Pipeline中執(zhí)行。對(duì)于大多數(shù)用例,script聲明Pipeline中的步驟不是必須的,但它可以提供一個(gè)有用的“escape hatch”。script不平凡的大小和/或復(fù)雜性的塊應(yīng)該轉(zhuǎn)移到共享庫(kù)中。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
script {
def browsers = ['chrome', 'firefox']
for (int i = 0; i < browsers.size(); ++i) {
echo "Testing the ${browsers[i]} browser"
}
}
}
}
}
}
Scripted Pipeline,如聲明式Pipeline,構(gòu)建在底層Pipeline子系統(tǒng)之上。不像聲明,Scripted Pipeline有效地是一個(gè)通用的DSL構(gòu)建與Groovy。由Groovy語(yǔ)言提供的大多數(shù)功能都提供給Scripted Pipeline的用戶,這意味著它可以是一個(gè)非常富有表現(xiàn)力和靈活性的工具,可以通過(guò)這些工具來(lái)創(chuàng)建連續(xù)的傳送Pipeline。
Scripted Pipeline從頂部順序執(zhí)行,與Jenkinsfile Groovy或其他語(yǔ)言中的大多數(shù)傳統(tǒng)Scripted一樣。因此,提供流量控制取決于Groovy表達(dá)式,例如 if/else條件,例如:
Jenkinsfile (Scripted Pipeline)
node {
stage('Example') {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}
可以管理Scripted Pipeline流控制的另一種方式是使用Groovy的異常處理支持。當(dāng)步驟由于任何原因而導(dǎo)致異常時(shí)。處理錯(cuò)誤行為必須使用try/catch/finally
Groovy 中的塊,例如:
Jenkinsfile (Scripted Pipeline)
node {
stage('Example') {
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed, I should sound the klaxons!'
throw
}
}
}
如“ 入門(mén)指南 ”所述,Pipeline最基本的部分是“步驟”。從根本上說(shuō),步驟告訴Jenkins 要做什么,并且作為Declarative和Scripted Pipeline語(yǔ)法的基本構(gòu)建塊。
Scripted Pipeline并沒(méi)有介紹這是專門(mén)針對(duì)它的語(yǔ)法的任何步驟; Pipeline步驟參考 ,其中包含Pipeline和插件提供的完整步驟列表。
為了提供耐久性,這意味著運(yùn)行Pipeline可以在重新啟動(dòng)Jenkins主站后保留,Scripted Pipeline必須將數(shù)據(jù)序列化回主站。由于這個(gè)設(shè)計(jì)要求,一些Groovy成語(yǔ)如collection.each { item -> /* perform operation */ }沒(méi)有完全支持。有關(guān) 更多信息,請(qǐng)參見(jiàn) JENKINS-27421和 JENKINS-26481。
當(dāng)Jenkins Pipeline首次創(chuàng)建時(shí),Groovy被選為基礎(chǔ)。Jenkins長(zhǎng)期運(yùn)用嵌入式Groovy引擎,為管理員和用戶提供高級(jí)腳本功能。此外,Jenkins Pipeline的實(shí)施者發(fā)現(xiàn)Groovy是建立現(xiàn)在稱為“Scripted Pipeline”DSL的堅(jiān)實(shí)基礎(chǔ)。
由于它是一個(gè)功能齊全的編程環(huán)境,Scripted Pipeline為Jenkins用戶提供了極大的靈活性和可擴(kuò)展性。Groovy學(xué)習(xí)曲線通常不適用于給定團(tuán)隊(duì)的所有成員,因此,創(chuàng)建聲明性Pipeline是為了創(chuàng)作Jenkins Pipeline提供一個(gè)更簡(jiǎn)單和更有見(jiàn)解的語(yǔ)法。
兩者基本上是下面相同的Pipeline 子系統(tǒng)。它們都是“Pipeline代碼”的持久實(shí)現(xiàn)。他們都能夠使用Pipeline內(nèi)置的插件或插件提供的步驟。兩者都可以利用共享庫(kù)
不同之處在于語(yǔ)法和靈活性。聲明性限制了用戶具有更嚴(yán)格和預(yù)定義結(jié)構(gòu)的可用性,使其成為更簡(jiǎn)單連續(xù)輸送Pipeline的理想選擇。腳本化提供了極少的限制,因?yàn)镚roovy本身只能對(duì)結(jié)構(gòu)和語(yǔ)法進(jìn)行限制,而不是任何Pipeline專用系統(tǒng),使其成為電力用戶和具有更復(fù)雜要求的用戶的理想選擇。顧名思義,Declarative Pipeline鼓勵(lì)聲明式編程模型。 盡管Scripted Pipeline遵循更命令性的編程模型。
更多建議: