運算式
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
重要
選取對應至您平臺和版本的本文版本。 版本選取器位於目錄上方。 查閱您的 Azure DevOps 平臺和版本。
表達式可用於撰寫管線時需要指定字串、布爾值或數位值的許多位置。 當表達式傳回陣列時,會套用一般索引規則,而索引會以 0
開頭。
# Expressions are used to define conditions for a step, job, or stage
steps:
- task: ...
condition: <expression>
表達式的另一個常見用法是定義變數。
表達式可以在編譯時間或運行時間進行評估。
編譯時間表達式可以在任何地方使用;運行時間表達式可用於變數和條件。 運行時間表達式的目的是用來計算變數和狀態的內容(例如: condition
)。
# Two examples of expressions used to define variables
# The first one, a, is evaluated when the YAML file is compiled into a plan.
# The second one, b, is evaluated at runtime.
# Note the syntax ${{}} for compile time and $[] for runtime expressions.
variables:
a: ${{ <expression> }}
b: $[ <expression> ]
運行時間和編譯時間表達式語法之間的差異主要是可用的內容。
在編譯時期表示式中,${{ <expression> }}
您可以存取 parameters
和 靜態定義 variables
。
在運行時間表示式 ($[ <expression> ]
) 中,您可以存取更多 variables
參數,但無法存取任何參數。
在此範例中,運行時間表達式會設定 的值 $(isMain)
。 編譯表達式中的靜態變數會設定的值 $(compileVar)
。
variables:
staticVar: 'my value' # static variable
compileVar: ${{ variables.staticVar }} # compile time expression
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] # runtime expression
steps:
- script: |
echo ${{variables.staticVar}} # outputs my value
echo $(compileVar) # outputs my value
echo $(isMain) # outputs True
表達式可以是常值、變數的參考、相依性、函式的參考,或這些表達式的有效巢狀組合。
常值
在表達式中,您可以使用布爾值、Null、數位、字串或版本常值。
# Examples
variables:
someBoolean: ${{ true }} # case insensitive, so True or TRUE also works
someNumber: ${{ -1.2 }}
someString: ${{ 'a b c' }}
someVersion: ${{ 1.2.3 }}
布林值
True
和 False
是布爾常值表達式。
Null
Null 是從字典遺漏傳回的特殊常值表達式,例如 (variables['noSuch']
)。 Null 可以是表達式的輸出,但無法直接在表達式內呼叫。
數字
從 '-'、'.' 或 '0' 到 '9' 開始。
String
必須是單引號。 例如: 'this is a string'
。
若要表示常值單引號,請使用單引號逸出它。
例如: 'It''s OK if they''re using contractions.'
。
您可以將管道字元 (|
) 用於多行字串。
myKey: |
one
two
three
版本
版本號碼,最多四個區段。
必須以數字開頭,且包含兩或三個句號(.
) 字元。
例如: 1.2.3.4
。
變數
在表達式中,您可以使用兩種語法之一來存取變數:
- 索引語法:
variables['MyVar']
- 屬性取值語法:
variables.MyVar
若要使用屬性取值語法,屬性名稱必須:
a-Z
從或開始_
- 後面接著
a-Z
0-9
或_
視執行內容而定,可以使用不同的變數。
變數一律為字串。 如果您想要使用具類型的值,您應該改用 參數 。
注意
透過變數索引標籤 UI 設定這類變數時,使用具有傳統和 YAML 管線表達式的變數有一項限制。 定義為表達式的變數不應相依於值表達式的另一個變數,因為它 不保證 會正確評估這兩個表達式。 例如,我們有變數,其值$[ <expression> ]
會當做變數 a
b
值的一部分使用。 因為處理變數的順序不保證變數 b
在評估之後可能會有不正確的變數 a
值。
只有在透過 YAML 管線中的 variables 關鍵詞設定變數時,才允許描述的建構。 在處理之後,必須依應處理變數的順序放置變數,以取得正確的值。
函式
下列內建函式可用於表達式中。
及
- 評估為
True
是否為所有參數True
- 最小參數:2。 最大參數:N
- 將參數轉換成布爾值以進行評估
- 第一次之後的短線
False
- 範例:
and(eq(variables.letters, 'ABC'), eq(variables.numbers, 123))
coalesce
- 依序評估參數(由左至右),並傳回不等於 null 或空字串的第一個值。
- 如果參數值全部為 Null 或空字串,則不會傳回任何值。
- 最小參數:2。 最大參數:N
- 範例:
coalesce(variables.couldBeNull, variables.couldAlsoBeNull, 'literal so it always works')
contains
True
評估左參數 String 是否包含右參數- 最小參數:2。 最大參數:2
- 將參數轉換成 String 以進行評估
- 執行序數忽略大小寫比較
- 範例:
contains('ABCDE', 'BCD')
(傳回 True)
containsValue
True
評估左參數是否為陣列,且任何專案都等於右參數。 此外,也會True
評估左參數是否為物件,而任何屬性的值是否等於右參數。- 最小參數:2。 最大參數:2
- 如果左參數是陣列,請轉換每個專案以符合右邊參數的類型。 如果左參數是物件,請轉換每個屬性的值,以符合右邊參數的類型。 如果轉換失敗,則每個特定專案的相等比較會
False
評估。 - 字串的序數忽略大小寫比較
- 第一場比賽后的短線
注意
YAML 管線中沒有指定數位的常值語法。 此函式在一般管線中使用有限。 它適用於管線裝飾項目內容,並搭配系統提供的陣列,例如步驟清單。
您可以使用 containsValue
表示式來尋找物件中的相符值。 以下範例示範在來源分支清單中尋找 是否有相符專案 Build.SourceBranch
。
parameters:
- name: branchOptions
displayName: Source branch options
type: object
default:
- refs/heads/main
- refs/heads/test
jobs:
- job: A1
steps:
- ${{ each value in parameters.branchOptions }}:
- script: echo ${{ value }}
- job: B1
condition: ${{ containsValue(parameters.branchOptions, variables['Build.SourceBranch']) }}
steps:
- script: echo "Matching branch found"
convertToJson
- 採用複雜的物件,並將它輸出為 JSON。
- 最小參數:1。 最大參數:1。
parameters:
- name: listOfValues
type: object
default:
this_is:
a_complex: object
with:
- one
- two
steps:
- script: |
echo "${MY_JSON}"
env:
MY_JSON: ${{ convertToJson(parameters.listOfValues) }}
文稿輸出:
{
"this_is": {
"a_complex": "object",
"with": [
"one",
"two"
]
}
}
計數器
- 此函式只能在定義變數的表達式中使用。 它不能當做步驟、作業或階段條件的一部分使用。
- 評估每次執行管線時遞增的數位。
- 參數:2。
prefix
和seed
。 - 前置詞是字串表達式。 計數器的個別值會針對前置詞的每個唯一值進行追蹤。 應該
prefix
使用UTF-16個字元。 - Seed 是計數器的起始值
您可以建立一個計數器,在管線的每個執行中自動遞增一個計數器。 當您定義計數器時,您會提供 prefix
和 seed
。 以下是示範此範例的範例。
variables:
major: 1
# define minor as a counter with the prefix as variable major, and seed as 100.
minor: $[counter(variables['major'], 100)]
steps:
- bash: echo $(minor)
上述範例中管線第一次執行中的 值 minor
是 100。 在第二次執行中,它是 101,前提是 的值 major
仍然為 1。
如果您編輯 YAML 檔案,並將變數 major
的值更新為 2,則在下一次管線執行時,的值 minor
會是 100。 後續執行會將計數器遞增至 101、102、103...
稍後,如果您編輯 YAML 檔案,並將 值 major
設定回 1,則計數器的值會繼續該前置詞的離開位置。 在此範例中,它會繼續於 102。
以下是將變數設定為做為計數器的另一個範例,從 100 開始、每次執行都會遞增 1,並且每天重設為 100。
注意
pipeline.startTime
在表達式之外無法使用。 pipeline.startTime
格式化 system.pipelineStartTime
為日期和時間物件,以便使用表達式。
的預設時區 pipeline.startTime
為UTC。 您可以 變更組織的時區 。
jobs:
- job:
variables:
a: $[counter(format('{0:yyyyMMdd}', pipeline.startTime), 100)]
steps:
- bash: echo $(a)
以下是一個計數器,可維護PR和 CI 執行個別值的範例。
variables:
patch: $[counter(variables['build.reason'], 0)]
計數器的範圍設定為管線。 換句話說,其值會針對該管線的每個執行遞增。 沒有專案範圍的計數器。
endsWith
True
評估左參數 String 是否以右參數結尾- 最小參數:2。 最大參數:2
- 將參數轉換成 String 以進行評估
- 執行序數忽略大小寫比較
- 範例:
endsWith('ABCDE', 'DE')
(傳回 True)
eq
True
評估參數是否相等- 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 如果轉換失敗,則傳
False
回 。 - 字串的序數忽略大小寫比較
- 範例:
eq(variables.letters, 'ABC')
format
- 評估尾端參數,並將其插入前置參數位符串
- 最小參數:1。 最大參數:N
- 範例:
format('Hello {0} {1}', 'John', 'Doe')
- 使用 .NET 自訂日期和時間格式規範進行日期格式設定(
yyyy
、、、d
dd
M
yy
MM
、HH
H
、 )m
mm
ss
s
f
ff
ffff
K
- 範例:
format('{0:yyyyMMdd}', pipeline.startTime)
。 在此情況下pipeline.startTime
是特殊的日期時間物件變數。 - 藉由翻倍的大括號逃脫。 例如:
format('literal left brace {{ and literal right brace }}')
ge
True
評估 left 參數是否大於或等於右邊參數- 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 轉換失敗時發生錯誤。
- 字串的序數忽略大小寫比較
- 範例:
ge(5, 5)
(傳回 True)
gt
True
評估 left 參數是否大於右參數- 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 轉換失敗時發生錯誤。
- 字串的序數忽略大小寫比較
- 範例:
gt(5, 2)
(傳回 True)
in
True
評估 left 參數是否等於任何右邊參數- 最小參數:1。 最大參數:N
- 將右參數轉換為符合左參數的類型。 相等比較會
False
評估轉換是否失敗。 - 字串的序數忽略大小寫比較
- 第一場比賽后的短線
- 範例:
in('B', 'A', 'B', 'C')
(傳回 True)
join
- 串連右參數陣列中的所有專案,並以左參數位符串分隔。
- 最小參數:2。 最大參數:2
- 陣列中的每個項目都會轉換成字串。 複雜物件會轉換成空字串。
- 如果右參數不是陣列,結果就是轉換成字串的正確參數。
在此範例中,會在陣列中的每個項目之間加入分號。 參數類型是物件。
parameters:
- name: myArray
type: object
default:
- FOO
- BAR
- ZOO
variables:
A: ${{ join(';',parameters.myArray) }}
steps:
- script: echo $A # outputs FOO;BAR;ZOO
le
True
評估左參數是否小於或等於右邊參數- 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 轉換失敗時發生錯誤。
- 字串的序數忽略大小寫比較
- 範例:
le(2, 2)
(傳回 True)
length
- 傳回字串或陣列的長度,可能是來自系統或來自參數的陣列。
- 最小參數:1。 最大參數 1
- 範例:
length('fabrikam')
傳回 8
lower
- 將字串或變數值轉換為所有小寫字元
- 最小參數:1。 最大參數 1
- 傳回字串的對等小寫
- 範例:
lower('FOO')
傳回foo
lt
True
評估 left 參數是否小於右邊參數- 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 轉換失敗時發生錯誤。
- 字串的序數忽略大小寫比較
- 範例:
lt(2, 5)
(傳回 True)
ne
True
評估參數是否不相等- 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 如果轉換失敗,則傳
True
回 。 - 字串的序數忽略大小寫比較
- 範例:
ne(1, 2)
(傳回 True)
not
True
評估參數是否為False
- 最小參數:1。 最大參數:1
- 將值轉換為布爾值以進行評估
- 範例:
not(eq(1, 2))
(傳回 True)
notIn
True
評估 left 參數是否不等於任何右邊參數- 最小參數:1。 最大參數:N
- 將右參數轉換為符合左參數的類型。 相等比較會
False
評估轉換是否失敗。 - 字串的序數忽略大小寫比較
- 第一場比賽后的短線
- 範例:
notIn('D', 'A', 'B', 'C')
(傳回 True)
或
True
評估是否有任何參數為True
- 最小參數:2。 最大參數:N
- 將參數轉換成布爾值以進行評估
- 第一次之後的短線
True
- 範例:
or(eq(1, 1), eq(2, 3))
(傳回 True、短線路)
replace
- 傳回新字串,其中目前實例中字串的所有實例都會以另一個字串取代
- 最小參數:3。 最大參數:3
replace(a, b, c)
:傳回 ,且 b 的所有實例都由 c 取代- 範例:
replace('https://www.tinfoilsecurity.com/saml/consume','https://www.tinfoilsecurity.com','http://server')
(傳回http://server/saml/consume
)
split
- 根據指定的分隔字元,將字串分割成子字串
- 最小參數:2。 最大參數:2
- 第一個參數是要分割的字串
- 第二個參數是分隔字元
- 傳回子字串的陣列。 當分隔字元連續出現或在字串結尾出現時,陣列會包含空字串
- 範例:
variables: - name: environments value: prod1,prod2 steps: - ${{ each env in split(variables.environments, ',')}}: - script: ./deploy.sh --environment ${{ env }}
- 使用 split() 搭配 replace():
parameters: - name: resourceIds type: object default: - /subscriptions/mysubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/loadBalancers/kubernetes-internal - /subscriptions/mysubscription02/resourceGroups/myResourceGroup02/providers/Microsoft.Network/loadBalancers/kubernetes - name: environments type: object default: - prod1 - prod2 trigger: - main steps: - ${{ each env in parameters.environments }}: - ${{ each resourceId in parameters.resourceIds }}: - script: echo ${{ replace(split(resourceId, '/')[8], '-', '_') }}_${{ env }}
startsWith
True
評估左參數位符串是否以右參數開頭- 最小參數:2。 最大參數:2
- 將參數轉換成 String 以進行評估
- 執行序數忽略大小寫比較
- 範例:
startsWith('ABCDE', 'AB')
(傳回 True)
upper
- 將字串或變數值轉換為所有大寫字元
- 最小參數:1。 最大參數 1
- 傳回字串的大寫對等專案
- 範例:
upper('bah')
傳回BAH
xor
True
評估是否只有一個參數True
- 最小參數:2。 最大參數:2
- 將參數轉換成布爾值以進行評估
- 範例:
xor(True, False)
(傳回 True)
作業狀態檢查函式
您可以使用下列狀態檢查函式作為條件中的運算式,但在變數定義中則無法使用。
always
- 一律評估為
True
(即使取消也一樣)。 注意:重大失敗可能仍會防止工作執行。 例如,如果取得來源失敗。
取消
- 評估為
True
是否已取消管線。
失敗
- 對於步驟,相當於
eq(variables['Agent.JobStatus'], 'Failed')
。 - 針對作業:
- 如果沒有自變數,只有在相依性圖形中的任何先前作業失敗時,才會評估為
True
。 - 使用工作名稱做為自變數時,只有在其中任何作業失敗時,才會評估
True
為 。
- 如果沒有自變數,只有在相依性圖形中的任何先前作業失敗時,才會評估為
succeeded
- 針對步驟,相當於
in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')
- 在處理作業時使用 ,
dependsOn
而且您想要評估先前的作業是否成功。 作業的設計目的是在階段循序執行時以平行方式執行。 - 針對作業:
- 如果沒有自變數,只有在相依性圖形中的所有先前作業都成功或部分成功時,才會評估
True
為 。 - 使用作業名稱做為自變數,評估為
True
,如果所有作業都成功或部分成功。 - 評估是否
False
取消管線。
- 如果沒有自變數,只有在相依性圖形中的所有先前作業都成功或部分成功時,才會評估
succeededOrFailed
針對步驟,相當於
in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues', 'Failed')
針對作業:
- 沒有任何自變數,不論相依性圖表中的任何作業都成功或失敗,都會評估
True
為 。 - 使用作業名稱做為自變數,評估
True
這些作業是否成功或失敗。 - 當相依性圖表中有先前略過的作業時,您可能會想要改用
not(canceled())
。
這就像
always()
,不同之處在於它會在取消管線時進行評估False
。- 沒有任何自變數,不論相依性圖表中的任何作業都成功或失敗,都會評估
條件式插入
您可以使用 if
、 elseif
和 else
子句,有條件地指派變數值或設定工作的輸入。 您也可以有條件地在符合條件時執行步驟。
您可以使用 來 if
有條件地指派變數值或設定工作的輸入。 您也可以有條件地在符合條件時執行步驟。
elseif
和 else
子句可從 Azure DevOps 2022 開始提供,不適用於 Azure DevOps Server 2020 和舊版 Azure DevOps。
條件只能在使用範本語法時運作。 深入瞭解 變數語法。
針對範本,您可以在新增序列或對應時使用條件式插入。 深入了解 範本中的條件式插入。
有條件地指派變數
variables:
${{ if eq(variables['Build.SourceBranchName'], 'main') }}: # only works if you have a main branch
stageName: prod
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo ${{variables.stageName}}
有條件地設定工作輸入
pool:
vmImage: 'ubuntu-latest'
steps:
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Pipeline.Workspace)'
${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
artifact: 'prod'
${{ else }}:
artifact: 'dev'
publishLocation: 'pipeline'
有條件地執行步驟
如果沒有設定變數,或的值 foo
不符合 if
條件,語句就會 else
執行。 在這裡,條件中的 elseif
值foo
會傳回 true。
variables:
- name: foo
value: contoso # triggers elseif condition
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo "start"
- ${{ if eq(variables.foo, 'adaptum') }}:
- script: echo "this is adaptum"
- ${{ elseif eq(variables.foo, 'contoso') }}: # true
- script: echo "this is contoso"
- ${{ else }}:
- script: echo "the value is not adaptum or contoso"
Each 關鍵字
您可以使用 each
關鍵詞來循環處理具有物件類型的參數。
parameters:
- name: listOfStrings
type: object
default:
- one
- two
steps:
- ${{ each value in parameters.listOfStrings }}:
- script: echo ${{ value }}
此外,您可以逐一查看 物件內的巢狀專案。
parameters:
- name: listOfFruits
type: object
default:
- fruitName: 'apple'
colors: ['red','green']
- fruitName: 'lemon'
colors: ['yellow']
steps:
- ${{ each fruit in parameters.listOfFruits }} :
- ${{ each fruitColor in fruit.colors}} :
- script: echo ${{ fruit.fruitName}} ${{ fruitColor }}
相依性
表達式可以使用相依性內容來參考先前的作業或階段。 您可以使用相依性來:
- 參考上一個作業的作業狀態
- 參考上一個階段的階段狀態
- 參考相同階段上一個作業中的輸出變數
- 參考階段中上一個階段的輸出變數
- 在上一個階段中參考作業中的輸出變數
內容會針對作業和階段進行呼叫 dependencies
,而且運作方式非常類似變數。
如果您在另一個階段中參考作業的輸出變數,則內容稱為 stageDependencies
。
如果您在輸出變數中遇到引號字元 ('
或 "
) 的問題,請參閱 此疑難解答指南。
相依性語法概觀
參考具有相依性之輸出變數的語法會根據情況而有所不同。 以下是最常見案例的概觀。 有時替代語法也有效。
類型
說明
階段到階段相依性 (不同階段)
參考 中條件中不同階段中作業中上一個階段的 stages
輸出變數。
- 語法:
and(succeeded(), eq(stageDependencies.<stage-name>.outputs['<job-name>.<step-name>.<variable-name>'], 'true'))
- 範例:
and(succeeded(), eq(stageDependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
作業對作業相依性 (相同階段)
參考 相同階段中不同作業中的 stages
輸出變數。
- 語法:
and(succeeded(), eq(dependencies.<job-name>.outputs['<step-name>.<variable-name>'], 'true'))
- 範例:
and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))
作業對階段相依性 (不同階段)
參考 中不同階段的 job
輸出變數。
- 語法:
eq(stageDependencies.<stage-name>.<job-name>.outputs['<step-name>.<variable-name>'], 'true')
- 範例:
eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
階段至暫存相依性 (部署作業)
在不同的階段中參考部署作業中的 stages
輸出變數。
- 語法:
eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<deployment-job-name>.<step-name>.<variable-name>'], 'true')
- 範例:
eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')
階段至暫存相依性 (含資源的部署作業)
參考部署作業中的輸出變數,其中包含 中不同階段中的 stages
資源。
- 語法:
eq(dependencies.<stage-name>.outputs['<deployment-job-name>.<Deploy_resource-name>.<step-name>.<variable-name>'], 'true')
- 範例:
eq(dependencies.build.outputs['build_job.Deploy_winVM.setRunTests.runTests'], 'true')
根據部署策略,部署作業中的輸出變數也有不同的語法。 如需詳細資訊,請參閱 部署作業。
階段至階段相依性
在結構上, dependencies
對像是 作業和階段名稱與 results
和 outputs
的對應。
以 JSON 表示,看起來會像這樣:
"dependencies": {
"<STAGE_NAME>" : {
"result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
"outputs": {
"jobName.stepName.variableName": "value"
}
},
"...": {
// another stage
}
}
注意
下列範例使用標準管線語法。 如果您使用部署管線,變數和條件變數語法將會有所不同。 如需要使用的特定語法資訊,請參閱 部署作業。
使用此形式的 dependencies
來對應變數或階段層級的檢查條件。
在此範例中,有兩個階段:A 和 B。階段 A 有 條件 false
,因此永遠不會執行。 如果階段 A 的結果為 Succeeded
、 SucceededWithIssues
或 Skipped
,則執行階段 B。 階段 B 會執行,因為已略過階段 A。
stages:
- stage: A
condition: false
jobs:
- job: A1
steps:
- script: echo Job A1
- stage: B
condition: in(dependencies.A.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
jobs:
- job: B1
steps:
- script: echo Job B1
階段也可以使用另一個階段的輸出變數。
在此範例中,也有兩個階段。 階段 A 包含將輸出變數 shouldrun
設定為 true
的作業 A1。 當 為 true
時shouldrun
,會執行階段 B。 因為 shouldrun
是 true
,因此會執行階段 B。
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- stage: B
condition: and(succeeded(), eq(dependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
dependsOn: A
jobs:
- job: B1
steps:
- script: echo hello from Stage B
注意
根據預設,管線中的每個階段都會相依於 YAML 檔案中的階段。
如果您需要參考目前階段之前的階段,您可以將區段新增 dependsOn
至階段,以覆寫此自動預設值。
一個階段內的作業對作業相依性
在單一階段內的作業層級, dependencies
數據不包含階段層級資訊。
"dependencies": {
"<JOB_NAME>": {
"result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
"outputs": {
"stepName.variableName": "value1"
}
},
"...": {
// another job
}
}
在此範例中,有三個作業(a、b 和 c)。 作業 a 一律會因為 而 condition: false
略過。
作業 b 會執行,因為沒有任何相關聯的條件。
作業 c 會執行,因為其所有相依性都成功 (作業 b) 或已略過 (作業 a)。
jobs:
- job: a
condition: false
steps:
- script: echo Job a
- job: b
steps:
- script: echo Job b
- job: c
dependsOn:
- a
- b
condition: |
and
(
in(dependencies.a.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
in(dependencies.b.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
)
steps:
- script: echo Job c
在此範例中,作業 B 相依於作業 A 的輸出變數。
jobs:
- job: A
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- job: B
condition: and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))
dependsOn: A
steps:
- script: echo hello from B
跨階段的工作對作業相依性
在作業層級,您也可以參考上一個階段中作業的輸出。
這需要使用 stageDependencies
內容。
"stageDependencies": {
"<STAGE_NAME>" : {
"<JOB_NAME>": {
"result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
"outputs": {
"stepName.variableName": "value"
}
},
"...": {
// another job
}
},
"...": {
// another stage
}
}
在此範例中,如果略過作業 A1,作業 B1 就會執行。 作業 B2 會檢查作業 A1 輸出變數的值,以判斷它是否應該執行。
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- stage: B
dependsOn: A
jobs:
- job: B1
condition: in(stageDependencies.A.A1.result, 'Skipped') # change condition to `Succeeded and stage will be skipped`
steps:
- script: echo hello from Job B1
- job: B2
condition: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
steps:
- script: echo hello from Job B2
如果作業相依於部署作業在不同的階段所定義的變數,則語法會不同。 在下列範例中,如果部署作業設定runTests
為 true
,則作業run_tests
會build_job
執行。 請注意,用於字典的 outputs
索引鍵是 build_job.setRunTests.runTests
。
stages:
- stage: build
jobs:
- deployment: build_job
environment:
name: Production
strategy:
runOnce:
deploy:
steps:
- task: PowerShell@2
name: setRunTests
inputs:
targetType: inline
pwsh: true
script: |
$runTests = "true"
echo "setting runTests: $runTests"
echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"
- stage: test
dependsOn:
- 'build'
jobs:
- job: run_tests
condition: eq(stageDependencies.build.build_job.outputs['build_job.setRunTests.runTests'], 'true')
steps:
...
部署作業輸出變數
如果階段相依於部署作業在不同階段中定義的變數,則語法會不同。 在下列範例中,階段test
取決於的true
部署build_job
設定shouldTest
。 請注意,在 condition
階段的 test
中, build_job
會出現兩次。
stages:
- stage: build
jobs:
- deployment: build_job
environment:
name: Production
strategy:
runOnce:
deploy:
steps:
- task: PowerShell@2
name: setRunTests
inputs:
targetType: inline
pwsh: true
script: |
$runTests = "true"
echo "setting runTests: $runTests"
echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"
- stage: test
dependsOn:
- 'build'
condition: eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')
jobs:
- job: A
steps:
- script: echo Hello from job A
在上述範例中,條件會參考環境,而不是環境資源。 若要參考環境資源,您必須將環境資源名稱新增至相依性條件。 在下列範例中,條件會參考名為 vmtest
的環境虛擬機資源。
stages:
- stage: build
jobs:
- deployment: build_job
environment:
name: vmtest
resourceName: winVM2
resourceType: VirtualMachine
strategy:
runOnce:
deploy:
steps:
- task: PowerShell@2
name: setRunTests
inputs:
targetType: inline
pwsh: true
script: |
$runTests = "true"
echo "setting runTests: $runTests"
echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"
- stage: test
dependsOn:
- 'build'
condition: eq(dependencies.build.outputs['build_job.Deploy_winVM2.setRunTests.runTests'], 'true')
jobs:
- job: A
steps:
- script: echo Hello from job A
篩選的陣列
在專案的集合上作業時,您可以使用 *
語法來套用篩選的陣列。 篩選的陣列會傳回所有物件/專案,而不論其名稱為何。
例如,請考慮名為 foo
的物件陣列。 我們想要取得數位中每個物件中屬性值的 id
陣列。
[
{ "id": 1, "a": "avalue1"},
{ "id": 2, "a": "avalue2"},
{ "id": 3, "a": "avalue3"}
]
我們可以執行下列動作:
foo.*.id
這會告訴系統以篩選陣列的形式運作 foo
,然後選取 id
屬性。
這會傳回:
[ 1, 2, 3 ]
類型轉型
表達式中的值可能會從某個類型轉換成另一個類型,因為表達式會進行評估。 評估表達式時,參數會聯合至相關的數據類型,然後重新轉換成字串。
例如,在此 YAML 中,值True
和 False
會轉換成 ,並在0
評估表示式時轉換為 1
和 。
lt()
當左參數小於右邊參數時,函式會True
傳回 。
variables:
firstEval: $[lt(False, True)] # 0 vs. 1, True
secondEval: $[lt(True, False)] # 1 vs. 0, False
steps:
- script: echo $(firstEval)
- script: echo $(secondEval)
當您使用eq()
表達式來評估等價時,值會隱含地轉換成數位(false
對 0
和 true
)。1
variables:
trueAsNumber: $[eq('true', true)] # 1 vs. 1, True
falseAsNumber: $[eq('false', true)] # 0 vs. 1, False
steps:
- script: echo $(trueAsNumber)
- script: echo $(falseAsNumber)
在下一個範例中,值 variables.emptyString
和空字串都會評估為空字串。
函式 coalesce()
會依序評估參數,並傳回不等於 null 或空字串的第一個值。
variables:
coalesceLiteral: $[coalesce(variables.emptyString, '', 'literal value')]
steps:
- script: echo $(coalesceLiteral) # outputs literal value
下面會進一步列出詳細的轉換規則。
From / To | 布林值 | Null | 數字 | String | 版本 |
---|---|---|---|---|---|
布林值 | - | - | Yes | Yes | - |
Null | Yes | - | .是 | Yes | - |
Number | Yes | - | - | Yes | Partial |
String | Yes | Partial | Partial | - | Partial |
版本 | Yes | - | - | Yes | - |
布林值
要編號:
False
→0
True
→1
字串:
False
→'False'
True
→'True'
Null
- 至布爾值:
False
- 要編號:
0
- 到字串:
''
(空字串)
數字
- 對布爾值:
0
→False
,任何其他數位→True
- 若要版本:必須大於零,而且必須包含非零十進位。 必須小於 Int32.MaxValue (十進位元件也)。
- 至字串:將數字轉換成沒有千位分隔符和無小數分隔符的字串。
String
- 對布爾值:
''
(空字串)→False
,任何其他字串→True
- 若要 null:
''
(空字串)→Null
,任何其他字串都無法轉換 - 若要編號:
''
(空字串)→ 0,否則會使用 InvariantCulture 執行 C#Int32.TryParse
,並遵循下列規則:AllowDecimalPoint |AllowLeadingSign |AllowLeadingWhite |AllowThousands |AllowTrailingWhite。 如果TryParse
失敗,則無法轉換。 - 若要版本:執行 C# 的
Version.TryParse
。 至少必須包含主要和次要元件。 如果TryParse
失敗,則無法轉換。
版本
- 至布爾值:
True
- 若要字串:Major.Minor 或 Major.Minor.Build 或 Major.Minor.Build.Revision。
常見問題集
我想執行表達式不支持的動作。 我有哪些擴充管線功能的選項?
您可以使用包含表示式的文稿來自定義管線。 例如,此代碼段會採用 BUILD_BUILDNUMBER
變數,並使用Bash加以分割。 此文稿會針對主要和次要執行數位輸出兩個新的變數 $MAJOR_RUN
和 $MINOR_RUN
。
接著會使用這兩個變數來建立兩個管線變數, $major
並使用 $minor
task.setvariable。 這些變數可供下游步驟使用。 若要跨管線共用變數,請參閱 變數群組。
steps:
- bash: |
MAJOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f1)
echo "This is the major run number: $MAJOR_RUN"
echo "##vso[task.setvariable variable=major]$MAJOR_RUN"
MINOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f2)
echo "This is the minor run number: $MINOR_RUN"
echo "##vso[task.setvariable variable=minor]$MINOR_RUN"
- bash: echo "My pipeline variable for major run is $(major)"
- bash: echo "My pipeline variable for minor run is $(minor)"