運算式
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
表達式可以是常值、變數的參考、相依性、函式的參考,或這些表達式的有效巢狀組合。
常值
在表達式中,您可以使用布爾值、空值、數值、字串或版本常值。
# 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' 開始。
字串
必須是單引號。 例如: '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 管線表達式的變數有一項限制。 定義為表達式的變數不應相依於值表達式的另一個變數,因為它 不保證 會正確評估這兩個表達式。 例如,我們有變數,其值a
會當做變數 $[ <expression> ]
b
值的一部分使用。 因為處理變數的順序不保證變數 b
在評估之後可能會有不正確的變數 a
值。
只有透過 YAML 管線中的variables關鍵詞設定變數時,才允許描述的建構。 在處理之後,必須依應處理變數的順序放置變數,以取得正確的值。
功能
下列內建函式可用於表達式中。
及
- 當所有參數為
True
時,評估結果為True
。 - 最小參數:2。 最大參數:N
- 將參數轉換成布爾值以進行評估
- 第一次
False
之後的短路 - 範例:
and(eq(variables.letters, 'ABC'), eq(variables.numbers, 123))
合併
- 依序評估參數(由左至右),並傳回不等於 null 或空字串的第一個值。
- 如果參數值全部為 Null 或空字串,則不會傳回任何值。
- 最小參數:2。 最大參數:N
- 範例:
coalesce(variables.couldBeNull, variables.couldAlsoBeNull, 'literal so it always works')
包含
-
True
評估左參數 String 是否包含右參數 - 最小參數:2。 最大參數:2
- 將參數轉換成 String 以進行評估
- 進行忽略大小寫的序數比較
- 範例:
contains('ABCDE', 'BCD')
(傳回 True)
包含值
- 評估
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)]
計數器的範圍設定為管線。 換句話說,其值會隨著每次管線的執行而遞增。 沒有專案範圍的計數器。
結尾是
-
True
評估左參數 String 是否以右參數結尾 - 最小參數:2。 最大參數:2
- 將參數轉換成 String 以進行評估
- 執行不分大小寫的序數比較
- 範例:
endsWith('ABCDE', 'DE')
(傳回 True)
eq
-
True
檢查並評估參數是否相等 - 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 如果轉換失敗,則傳
False
回 。 - 字串的序數忽略大小寫比較
- 範例:
eq(variables.letters, 'ABC')
格式
- 評估尾端參數,並將其插入前置參數位符串
- 最小參數:1。 最大參數:N
- 範例:
format('Hello {0} {1}', 'John', 'Doe')
- 使用 .NET 自訂日期和時間格式規範進行日期格式設定(
yyyy
,yy
,MM
,M
,dd
,d
,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
是否左側參數大於或等於右側參數 - 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 轉換失敗時的錯誤。
- 字串的序數忽略大小寫比較
- 範例:
ge(5, 5)
(傳回 True)
gt
-
True
評估左參數是否大於右參數 - 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 若轉換失敗則會發生錯誤。
- 依序而不分大小寫的字串比較
- 範例:
gt(5, 2)
(傳回 True)
在
- 評估
True
是否左參數等於任何右參數 - 最小參數:1。 最大參數:N
- 將右參數轉換為符合左參數的類型。 相等比較會檢查
False
是否在轉換時失敗。 - 字符串中进行不區分大小寫的序數比較
- 第一場比賽后的短路
- 範例:
in('B', 'A', 'B', 'C')
(傳回 True)
iif
- 如果第一個參數評估為
True
,而第三個參數 otherwize,則傳回第二個參數 - 最小參數:1。 最大參數:3
- 第一個參數必須是條件
- 範例:當管線執行回應PR時,
iif(eq(variables['Build.Reason'], 'PullRequest'), 'ManagedDevOpsPool', 'Azure Pipelines')
會傳回 'ManagedDevOpsPool'。
加入
- 串連右側參數陣列中的所有元素,並以左側參數字串分隔。
- 最小參數: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)
長度
- 傳回字串或陣列的長度,該字串或陣列可以來自系統或參數。
- 最小參數:1。 最大參數 1
- 範例:
length('fabrikam')
傳回 8
降低
- 將字串或變數值轉換為所有小寫字元
- 最小參數:1。 最大參數 1
- 將字串轉為小寫字母
- 範例:
lower('FOO')
傳回foo
The translation remains as "lt" unless additional context is provided to clarify its meaning.
- 評估
True
左參數是否小於右參數 - 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 轉換失敗時發生錯誤。
- 字串的序數忽略大小寫比較
- 範例:
lt(2, 5)
(傳回 True)
ne
-
True
評估參數是否不相等 - 最小參數:2。 最大參數:2
- 將右參數轉換為符合左參數的類型。 如果轉換失敗,則傳
True
回 。 - 字串忽略大小寫的序列比較
- 範例:
ne(1, 2)
(傳回 True)
不是
-
True
評估參數是否為False
- 最小參數:1。 最大參數:1
- 將值轉換為布爾值以進行評估
- 範例:
not(eq(1, 2))
(傳回 True)
notIn
- 判斷
True
左邊的參數是否不等於任何右邊的參數 - 最小參數:1。 最大參數:N
- 將右參數轉換為符合左參數的類型。 當轉換失敗時,進行相等比較以評估
False
。 - 字串的順序忽略大小寫比較
- 第一場比賽后的短線
- 範例:
notIn('D', 'A', 'B', 'C')
(傳回 True)
或
- 評估
True
是否存在任何參數True
- 最小參數:2。 最大參數:N
- 將參數轉換成布爾值以進行評估
- 第一次之後的電路短路
True
- 範例:
or(eq(1, 1), eq(2, 3))
(傳回 True,短路)
替換
- 傳回新字串,其中目前實例中字串的所有實例都會以另一個字串取代
- 最小參數:3。 最大參數:3
-
replace(a, b, c)
:傳回 a,將所有 b 的元素替換為 c - 範例:
replace('https://www.tinfoilsecurity.com/saml/consume','https://www.tinfoilsecurity.com','http://server')
(傳回http://server/saml/consume
)
分開
- 根據指定的分隔字元,將字串分割成子字串
- 最小參數: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 }}
以...開始
-
True
評估左參數位符串是否以右參數開頭 - 最小參數:2。 最大參數:2
- 將參數轉換成 String 以進行評估
- 執行不區分大小寫的排序比較
- 範例:
startsWith('ABCDE', 'AB')
(傳回 True)
修剪
- 傳回參數,不含開頭和尾端空格符
- 最小參數:1。 最大參數:1
- 範例:
trim(' variable ')
傳回 'variable'
上部
- 將字串或變數值轉換為所有大寫字元
- 最小參數:1。 最大參數 1
- 傳回字串的大寫版本
- 範例:
upper('bah')
傳回BAH
xor
-
True
評估是否只有一個參數True
- 最小參數:2。 最大參數:2
- 將參數轉換成布爾值以進行評估
- 範例:
xor(True, False)
(傳回 True)
作業狀態檢查函式
您可以使用下列狀態檢查函式作為條件中的運算式,但在變數定義中則無法使用。
總是
- 一律評估為
True
(即使取消也一樣)。 注意:重大失敗可能仍會防止工作執行。 例如,如果取得來源失敗。
取消
- 管線被取消時評估為
True
。
失敗
- 對於步驟,相當於
eq(variables['Agent.JobStatus'], 'Failed')
。 - 針對工作:
- 如果沒有自變數,只有在相依性圖形中的任何先前作業失敗時,才會評估為
True
。 - 使用工作名稱作為參數時,只有在其中任何一個作業失敗時,才會評估為
True
。
- 如果沒有自變數,只有在相依性圖形中的任何先前作業失敗時,才會評估為
成功了
- 每一步驟,相當於
in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')
- 在處理作業時,若要評估先前的作業是否成功,請搭配
dependsOn
使用。 作業被設計成以平行方式執行,而階段則是依序執行。 - 針對工作:
- 如果沒有參數,只有在相依性圖形中的所有先前作業都成功或部分成功時,才會評估結果為
True
。 - 使用作業名稱做為自變數,評估為
True
,如果所有作業都成功或部分成功。 - 如果管線被取消,評估結果為
False
。
- 如果沒有參數,只有在相依性圖形中的所有先前作業都成功或部分成功時,才會評估結果為
成功或失敗
這類步驟等於
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
語句。 在這裡,foo
的值在elseif
條件中會傳回 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
關鍵詞來循環處理具有物件類型的參數。
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。 當shouldrun
為true
時,會執行階段 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
如果作業相依於部署作業在不同的階段所定義的變數,則語法會不同。 在下列範例中,作業run_tests
會執行,如果部署作業將runTests
設定為true
。 請注意,用於字典的 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
取決於部署設定 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
會在表示式被評估時轉換為 1
和 0
。
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
下面會進一步列出詳細的轉換規則。
從 / 到 | 布林值 | Null | 數字 | 字串 | 版本 |
---|---|---|---|---|---|
布林值 | - | - | Yes | Yes | - |
Null | Yes | - | Yes | Yes | - |
Number | Yes | - | - | Yes | 部分 |
String | Yes | 部分的 | 部分的 | - | 部分 |
版本 | Yes | - | - | Yes | - |
布林值
要編號:
-
False
→0
-
True
→1
轉換為字串:
-
False
→'False'
-
True
→'True'
Null
- 至布爾值:
False
- 要編號:
0
- 到字串:
''
(空字串)
數字
- 對布爾值:
0
→False
,任何其他數位→True
- 要設置版本號:必須大於零,且必須包含非零小數點。 必須小於 Int32.MaxValue (十進位元件也)。
- 至字串:將數字轉換成沒有千位分隔符和無小數分隔符的字串。
字串
- 對布爾值:
''
(空字串)→False
,任何其他字串→True
- 若要變為 null:
''
(空字串)→Null
,任何其他字串都無法轉換成為 null - 若要編號:
''
(空字串)→ 0,否則會使用 InvariantCulture 的Int32.TryParse
執行 C#,並遵循下列規則: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)"