条件の指定
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019 | TFS 2018
各ステージ、ジョブ、ステップを実行する条件を指定できます。 既定では、ジョブまたはステージが他のジョブまたはステージに依存しない場合、または依存するすべてのジョブまたはステージが完了して成功した場合に実行されます。 これには、直接の依存関係だけでなく、再帰的に計算されるそれらの依存関係も含まれます。 既定では、ジョブ内でまだ何も失敗しておらず、その直前のステップが完了した場合に、ステップは実行されます。 この動作をカスタマイズするには、前の依存関係が失敗した場合でも、ステージ、ジョブ、またはステップを強制的に実行するようにするか、カスタム条件を指定します。
注意
Microsoft Team Foundation Server (TFS) 2018 以前のバージョンでは、ビルドとリリースの "パイプライン" は "定義"、"実行" は "ビルド"、"サービス接続" は "サービス エンドポイント"、"ステージ" は "環境"、"ジョブ" は "フェーズ" と呼ばれます。
ステップ、ジョブ、またはステージを実行する条件を指定できます。
同じエージェント プールを持つ以前のすべての直接的および間接的な依存関係が成功した場合のみ。 エージェント プールが異なる場合、それらのステージまたはジョブは同時に実行されます。 これは、YAML に条件が設定されていない場合の既定値です。
実行が取り消された場合を除き、前の依存関係が失敗した場合でも。 この条件の YAML では
succeededOrFailed()
を使用します。実行が取り消された場合も含め、前の依存関係が失敗した場合でも。 この条件の YAML では
always()
を使用します。前の依存関係が失敗したときだけ。 この条件の YAML では
failed()
を使用します。
- カスタム条件
既定では、すべての直接依存関係と間接依存関係が成功した場合、ステップ、ジョブ、およびステージが実行されます。 "condition: succeeded()" ( 成功した状態関数を参照) を指定したかのように表示されます。
jobs:
- job: Foo
steps:
- script: echo Hello!
condition: always() # this step will always run, even if the pipeline is canceled
- job: Bar
dependsOn: Foo
condition: failed() # this job will only run if Foo fails
条件で変数を使用することもできます。
variables:
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
stages:
- stage: A
jobs:
- job: A1
steps:
- script: echo Hello Stage A!
- stage: B
condition: and(succeeded(), eq(variables.isMain, true))
jobs:
- job: B1
steps:
- script: echo Hello Stage B!
- script: echo $(isMain)
条件が評価され、ステージ、ジョブ、またはステップを開始するかどうかが決定されます。
つまり、その作業単位内で実行時に計算されるものは何も使用できなくなります。
たとえば、$[ ]
構文を使用したランタイム式を使用して変数を設定するジョブがある場合、その変数をカスタム条件で使用することはできません。
TFS では YAML はサポートされていません。
注意
ステージ/ジョブ/ステップに独自の condition
プロパティを指定すると、その既定の condition: succeeded()
が上書きされます。 これにより、ビルドがキャンセルされた場合でも、ステージ/ジョブ/ステップが実行される可能性があります。 独自の条件を記述するときは、必ず親ステージ/ジョブの状態を考慮してください。
カスタム条件を有効にする
組み込みの条件がニーズを満たさない場合は、カスタム条件を指定できます。
条件は YAML パイプラインで式として記述されます。 エージェントは、最も内側の関数で始まる式を評価し、その方法を実行します。最終的な結果は、タスク、ジョブ、またはステージを実行するかどうかを決定するブール値になります。 構文の完全なガイドについては、式の記事を参照してください。
ユーザーがビルドを取り消した後でも、いずれかの条件でタスクを実行できますか? その場合は、ユーザーが実行を取り消した後に、そのようなタスクが完了するのに十分な時間を確保できるように、キャンセル タイムアウトに妥当な値を指定します。
ビルドがキャンセルされたときのパイプラインの動作
ビルドがキャンセルされると、すべてのステージ、ジョブ、またはステップの実行が停止するわけではありません。 決定は、指定したステージ、ジョブ、またはステップ conditions
と、パイプライン実行のどの時点でビルドをキャンセルしたかによって異なります。
条件がステージ/ジョブ/ステップの親の状態を考慮していない場合、条件が true
と評価されると、親がキャンセルされた場合でも、ステージ、ジョブ、またはステップが実行されます。 親がスキップされた場合、ステージ、ジョブ、またはステップは実行されません。
いくつかの例を見てみましょう。
このパイプラインでは、既定で、stage2
は stage1
に依存し、stage2
には condition
が設定されています。 stage2
は、ソース ブランチが main
の場合にのみ実行されます。
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
jobs:
- job: B
steps:
- script: echo 2
main
ブランチでビルドをキューに入れ、stage1
の実行中にキャンセルした場合、eq(variables['Build.SourceBranch'], 'refs/heads/main')
は true
と評価されるため、stage2
は引き続き実行されます。
このパイプラインでは、stage2
は stage1
に依存します。 ジョブ B
には、condition
が設定されています。
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
jobs:
- job: B
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
steps:
- script: echo 2
main
ブランチでビルドをキューに入れ、stage1
の実行中にキャンセルすると、条件が true
と評価されるジョブ B
が含まれている場合でも、stage2
は実行されません。 その理由は、stage2
には既定の condition: succeeded()
があり、stage1
がキャンセルされると、false
と評価されるためです。 したがって、stage2
はスキップされ、そのジョブは実行されません。
たとえば、次の YAML パイプラインがあるとします。 既定では、stage2
は stage1
に依存しており、script: echo 2
には condition
が設定されていることに注意してください。
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
jobs:
- job: B
steps:
- script: echo 2
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
main
ブランチでビルドをキューに入れ、stage1
の実行中にキャンセルすると、条件が true
と評価されるジョブ B
にステップが含まれている場合でも、stage2
は実行されません。 その理由は、stage1
がキャンセルされたことに応じて stage2
がスキップされるためです。
ビルドがキャンセルされたときに、conditions
を含むステージ、ジョブ、またはステップが実行されないようにするには、conditions
を記述するときに親の状態を考慮してください。 詳細については、「ジョブの状態関数」を参照してください。
例
メイン ブランチに対して実行する (失敗したり、キャンセルされた場合でも)
eq(variables['Build.SourceBranch'], 'refs/heads/main')
メイン ブランチに対して実行する (成功した場合)
and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
ブランチがメインでない場合は実行する (成功した場合)
and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
ユーザー トピック ブランチに対して実行する (成功した場合)
and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))
継続的インテグレーション (CI) ビルドに対して実行する (成功した場合)
and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))
ビルドが pull request のブランチ ポリシーによって実行された場合に実行する (失敗した場合)
and(failed(), eq(variables['Build.Reason'], 'PullRequest'))
ビルドがスケジュールされている場合に実行する (失敗したり、キャンセルされた場合でも)
eq(variables['Build.Reason'], 'Schedule')
Release.Artifacts.{artifact-alias}.SourceBranch は Build.SourceBranch と同じです。
変数が true に設定されている場合は常に実行する (失敗したり、キャンセルされた場合でも)
eq(variables['System.debug'], true)
変数が null (空の文字列) の場合に実行する
すべての変数は Azure Pipelines で文字列として扱われるので、空の文字列はこのパイプラインの null
と同じです。
variables:
- name: testEmpty
value: ''
jobs:
- job: A
steps:
- script: echo testEmpty is blank
condition: eq(variables.testEmpty, '')
条件の一部としてテンプレート パラメーターを使用する
条件があるのと同じパイプラインでパラメーターを宣言すると、条件が考慮される前にパラメーターの拡張が行われます。 この場合は、条件の中にパラメーターを埋め込むことができます。 parameters.doThing
が true であるため、この YAML ファイル内のスクリプトが実行されます。
パイプラインの condition
は、succeeded()
と eq('${{ parameters.doThing }}', true)
の 2 つの関数を組み合わせています。 succeeded()
関数は、前のステップが成功したかどうかを確認します。 前のステップがないため、succeeded()
関数は true を返します。
eq('${{ parameters.doThing }}', true)
関数は、doThing パラメーターが true
と等しいかどうかをチェックします。 doThing の既定値は true であるため、パイプラインで別の値が設定されていない限り、条件は既定で true を返します。
その他のテンプレート パラメーターの例については、「テンプレートの種類と使用法」を参照してください。
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), eq('${{ parameters.doThing }}', true))
テンプレートにパラメーターを渡す場合は、テンプレートでパラメーターの値を設定するか、 templateContext を使用してテンプレートにプロパティを渡す必要があります。
# parameters.yml
parameters:
- name: doThing
default: true # value passed to the condition
type: boolean
jobs:
- job: B
steps:
- script: echo I did a thing
condition: ${{ eq(parameters.doThing, true) }}
# azure-pipeline.yml
parameters:
- name: doThing
default: true
type: boolean
trigger:
- none
extends:
template: parameters.yml
パラメーター doThing
が true であるため、このパイプラインの出力は I did a thing
になります。
後続のジョブの条件でジョブからの出力変数を使用する
後続のジョブで変数を使用できるようにし、条件で指定できます。 後続のジョブで使用できる変数は、isOutput=true
を使用して複数ジョブ出力変数としてマークする必要があります。
jobs:
- job: Foo
steps:
- bash: |
echo "This is job Foo."
echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #set variable doThing to Yes
name: DetermineResult
- job: Bar
dependsOn: Foo
condition: eq(dependencies.Foo.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check the value
steps:
- script: echo "Job Foo ran and doThing is Yes."
後続のステップの条件でステップから作成されたパイプライン変数を使用する
後続のステップで変数を使用できるようにし、条件で指定できます。 既定では、ステップから作成された変数は後続のステップで使用できるため、isOutput=true
を使用して複数ジョブ出力変数としてマークする必要はありません。
上記のアプローチとスコープに関して、注意すべき重要な点がいくつかあります。
- ジョブ内のステップで作成された変数のスコープは、同じジョブ内のステップに限定されます。
- ステップで作成された変数は、後続のステップでのみ環境変数として使用できます。
- ステップで作成された変数は、それらを定義するステップでは使用できません。
ステップでパイプライン変数を作成し、後続のステップの条件とスクリプトで変数を使用する例を次に示します。
steps:
# This step creates a new pipeline variable: doThing. This variable will be available to subsquent steps.
- bash: |
echo "##vso[task.setvariable variable=doThing]Yes"
displayName: Step 1
# This step is able to use doThing, so it uses it in its condition
- script: |
# You can access the variable from Step 1 as an environment variable.
echo "Value of doThing (as DOTHING env var): $DOTHING."
displayName: Step 2
condition: and(succeeded(), eq(variables['doThing'], 'Yes')) # or and(succeeded(), eq(variables.doThing, 'Yes'))
よく寄せられる質問
以前のジョブがエラーありで成功した場合にジョブをトリガーするにはどうすればよいですか?
以前のジョブの結果を使用できます。 たとえば、この YAML ファイルでは、ジョブ A が問題ありで成功したため、条件 eq(dependencies.A.result,'SucceededWithIssues')
によってジョブの実行が許可されます。
jobs:
- job: A
displayName: Job A
continueOnError: true # next job starts even if this one fails
steps:
- script: echo Job A ran
- script: exit 1
- job: B
dependsOn: A
condition: eq(dependencies.A.result,'SucceededWithIssues') # targets the result of the previous job
displayName: Job B
steps:
- script: echo Job B ran
ビルドをキャンセルしましたが、まだ実行中です。 どうしてでしょうか。
この問題は、ステージで構成されている条件にジョブ状態チェック関数が含まれていない場合に発生します。 この問題を解決するには、ジョブ状態チェック関数を条件に追加します。 キューに入っている間にジョブをキャンセルしたが、実行中ではない場合は、他のすべてのステージを含め、ジョブ全体がキャンセルされます。
詳細については、「ビルドがキャンセルされたときのパイプラインの動作」をご覧ください。