パイプラインの条件
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
この記事では、Azure Pipelines のステージ、ジョブ、またはステップを実行する条件と、さまざまな条件を指定する方法について説明します。 ステージ、ジョブ、およびステップの詳細については、「azure Pipelines の キーの概念を参照してください。
既定では、ジョブまたはステージが他のジョブまたはステージに依存しない場合、またはすべての依存関係が完了して成功した場合に実行されます。 この要件は、直接の依存関係だけでなく、間接的な依存関係にも適用され、再帰的に計算されます。
既定では、ジョブ内の何も失敗せず、その直前のステップが完了した場合、ステップが実行されます。
この動作をオーバーライドまたはカスタマイズするには、前の依存関係が失敗した場合でもステージ、ジョブ、またはステップを強制的に実行するか、カスタム条件を指定します。
Note
この記事では、YAML パイプラインの機能について説明します。 クラシック パイプラインの場合、各タスクの Control Options およびリリース パイプライン内のジョブの 追加オプション でタスクまたはジョブを実行するいくつかの条件を指定できます。
ステージ、ジョブ、またはステップが実行される条件
パイプライン定義 YAML では、ステージ、ジョブ、またはステップを実行する次の条件を指定できます。
同じエージェント プールを持つ以前のすべての直接依存関係と間接依存関係が成功した場合のみ。 エージェント プールが異なる場合、それらのステージまたはジョブは同時に実行されます。 YAML に条件が設定されていない場合、この条件が既定です。
前の依存関係が失敗した場合でも、実行が取り消されない限り。 この条件の YAML では
succeededOrFailed()
を使用します。以前の依存関係が失敗した場合でも、実行が取り消された場合でも。 この条件の YAML では
always()
を使用します。以前の依存関係が失敗した場合のみ。 この条件の YAML では
failed()
を使用します。
- カスタム条件。
既定では、すべての直接的および間接的な依存関係が成功した場合、ステージ、ジョブ、およびステップが実行されます。 この状態は、 condition: succeeded()
を指定する場合と同じです。 詳細については、 状態関数を参照してください。
ステージ、ジョブ、またはステップに condition
プロパティを指定すると、既定の condition: succeeded()
が上書きされます。 独自の条件を指定すると、ビルドがキャンセルされた場合でも、ステージ、ジョブ、またはステップが実行される可能性があります。 作成する条件が、親ステージまたはジョブの状態を考慮に入れるようにしてください。
次の YAML の例は、 always()
と failed()
の条件を示しています。 依存関係が失敗した場合やビルドが取り消された場合でも、最初のジョブのステップが実行されます。 2 番目のジョブは、最初のジョブが失敗した場合にのみ実行されます。
jobs:
- job: Foo
steps:
- script: echo Hello!
condition: always() # this step runs, even if the build is canceled
- job: Bar
dependsOn: Foo
condition: failed() # this job runs only if Foo fails
条件で変数を設定して使用することもできます。 次の例では、 isMain
変数を設定して使用し、 main
を Build.SourceBranch
として指定します。
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)
重要
条件は、ステージ、ジョブ、またはステップを開始するかどうかを決定するために評価されます。 そのため、その作業単位内で実行時に計算されるデータは使用できません。 たとえば、 $[ ]
構文を使用してランタイム式を使用して変数を設定するジョブがある場合、そのジョブのカスタム条件でその変数を使用することはできません。
カスタム条件
組み込みの条件がニーズを満たしていない場合は、 カスタム条件を指定できます。 YAML パイプライン定義では、条件を式として記述します。
エージェントは、最も内側の関数から始まり、外側に進む式を評価します。 最終的な結果は、タスク、ジョブ、またはステージを実行するかどうかを決定するブール値です。 構文の完全なガイドについては、「 Expressions」を参照してください。
いずれかの条件により、ビルドが取り消された後でもタスクを実行できる場合は、ユーザーが実行をキャンセルした後にこれらのタスクが完了するのに十分な時間を確保できるように、 ancel タイムアウト に適切な値を指定します。
ビルドが取り消されたときの条件の結果
ビルドを取り消しても、そのステージ、ジョブ、またはステップがすべて実行を停止するわけではありません。 実行を停止するステージ、ジョブ、またはステップは、指定した条件と、パイプラインの実行のどの時点でビルドをキャンセルしたかによって異なります。 ステージ、ジョブ、またはステップの親がスキップされた場合、タスクは条件に関係なく実行されません。
ステージ、ジョブ、またはステップは、その条件が true
に評価されるたびに実行されます。 条件でタスクの親の状態が考慮されない場合は、親が取り消された場合でもタスクが実行される可能性があります。 ビルドが取り消されたときに条件を持つステージ、ジョブ、またはステップを実行するかどうかを制御するには、条件に ジョブ状態チェック関数 を含めるようにします。
次の例は、ビルドが取り消されたときのステージ、ジョブ、またはステップに設定されたさまざまな条件の結果を示しています。
ステージ例 1
次のパイプラインでは、既定ではstage2
はstage1
に依存しますが、stage2
の状態に関係なく、ソース ブランチがmain
されるたびに実行するcondition
が設定stage1
。
main
ブランチでビルドをキューに入れ、stage1
の実行中に取り消すと、eq(variables['Build.SourceBranch'], 'refs/heads/main')
はtrue
と評価されるため、stage2
は引き続き実行されます。
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
ステージ例 2
次のパイプラインでは、 stage2
は既定で stage1
によって異なります。 stage2
のジョブ B
には、condition
が設定されています。 stage1
の実行中にmain
ブランチでビルドをキューに登録してキャンセルした場合、条件がtrue
と評価されるジョブが含まれている場合でも、stage2
は実行されません。
その理由は、stage2
には既定の condition: succeeded()
があり、stage1
がキャンセルされると、false
と評価されるためです。 したがって、stage2
はスキップされ、そのジョブは実行されません。
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
ステージ例 3
次のパイプラインでは、既定では stage2
は stage1
に依存し、ジョブ B
内のステップには condition
が設定されています。
main
ブランチでビルドをキューに入れて、stage1
の実行中に取り消すと、条件がtrue
に評価されるジョブ B
のステップが含まれている場合でも、stage2
は実行されません。 その理由は、stage1
がキャンセルされたことに応じて stage2
がスキップされるためです。
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')
ジョブの例 1
次の YAML パイプラインでは、ジョブB
は既定でジョブのA
に依存しますが、ジョブ B
には、ソース ブランチがmain
されるたびに実行するcondition
が設定されています。 main
ブランチでビルドをキューに入れ、ジョブ A
の実行中に取り消すと、ジョブB
は引き続き実行されます。これは、eq(variables['Build.SourceBranch'], 'refs/heads/main')
がtrue
に評価されるためです。
jobs:
- job: A
steps:
- script: sleep 30
- job: B
dependsOn: A
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
steps:
- script: echo step 2.1
ジョブ A
が成功し、ビルド ソースが main
ブランチである場合にのみジョブ B
を実行する場合は、condition
をand(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
する必要があります。
ジョブの例 2
次のパイプラインでは、ジョブ B
は既定でジョブ A
によって異なります。 main
ブランチでビルドをキューに登録し、ジョブ A
の実行中に取り消すと、そのステップにtrue
に評価されるcondition
がある場合でも、ジョブ B
は実行されません。
その理由は、ジョブ B
には既定の condition: succeeded()
があり、ジョブ A
がキャンセルされると、false
と評価されるためです。 そのため、ジョブ B
はスキップされ、どのステップも実行されません。
jobs:
- job: A
steps:
- script: sleep 30
- job: B
dependsOn: A
steps:
- script: echo step 2.1
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main', succeeded())
手順の例
ステップに条件を設定することもできます。
次のパイプラインでは、手順 2.3 では、ソース ブランチがmain
されるたびに実行するcondition
が設定されています。 手順 2.1 または 2.2 の実行中に main
ブランチでビルドをキューに登録してキャンセルした場合、手順 2.3 は引き続き実行されます。 eq(variables['Build.SourceBranch'], 'refs/heads/main')
は true
に評価されるためです。
steps:
- script: echo step 2.1
- script: echo step 2.2; sleep 30
- script: echo step 2.3
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
条件の設定
次の表に、さまざまな結果を生成する condition
設定の例を示します。
Note
Release.Artifacts.{artifact-alias}.SourceBranch
は Build.SourceBranch
と等価です。
望ましい結果 | 条件設定の例 |
---|---|
親または前のステージ、ジョブ、またはステップが失敗したか取り消された場合でも、ソース ブランチがメインの場合に実行します。 | 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')) |
プル要求のブランチ ポリシーによってビルドがトリガーされ、親または前のステージ、ジョブ、またはステップが失敗した場合に実行します。 | and(failed(), eq(variables['Build.Reason'], 'PullRequest')) |
親または前のステージ、ジョブ、またはステップが失敗したか取り消された場合でも、スケジュールされたビルドに対して実行します。 | eq(variables['Build.Reason'], 'Schedule') |
親または前のステージ、ジョブ、またはステップが失敗したか取り消された場合でも、変数が true に設定されている場合に実行します。 | eq(variables['System.debug'], true) |
Note
変数が 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 のスクリプトが実行されます。
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), ${{ eq(parameters.doThing, true) }})
前のパイプラインの condition
は、 succeeded()
と eq('${{ parameters.doThing }}', true)
の 2 つの関数を組み合わせています。 succeeded()
関数は、前のステップが成功したかどうかを確認します。 前の手順がないため、 succeeded()
関数は true
を返します。
eq('${{ parameters.doThing }}', true)
関数は、doThing
パラメーターがtrue
と等しいかどうかを確認します。 doThing
の既定値はtrue
であるため、パイプラインで別の値が設定されていない限り、この条件は既定でtrue
を返します。
条件のテンプレート パラメーター
テンプレートにパラメーターを渡す場合は、テンプレートでパラメーターの値を設定するか、templateContext 使用してパラメーターをテンプレートに渡す必要があります。
たとえば、次の parameters.yml ファイルでは、 doThing
パラメーターと既定値が宣言されています。
# 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) }}
パイプライン コードは、 parameters.yml テンプレートを参照します。 パラメーター doThing
が true であるため、パイプラインの出力はI did a thing
されます。
# azure-pipeline.yml
parameters:
- name: doThing
default: true
type: boolean
trigger:
- none
extends:
template: parameters.yml
その他のテンプレート パラメーターの例については、 Template 使用法のリファレンスを参照してください。
後続のジョブ条件で使用されるジョブ出力変数
後続のジョブで変数を使用できるようにし、条件で指定できます。 次のコードのように、isOutput=true
を使用して将来のジョブで使用できる変数を multi-job 出力変数としてマークする必要があります。
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."
後続のステップ条件で使用されるステップで作成された変数
将来の手順で使用できる変数を作成して、条件で指定できます。 ステップから作成された変数は、既定で将来のステップで使用できるため、 multi-job 出力変数としてマークする必要はありません。
ステップから作成される スコープ 変数に関して注意すべき重要な点がいくつかあります。
- ジョブ内のステップで作成された変数のスコープは、同じジョブ内のステップに設定されます。
- ステップで作成された変数は、以降の手順でのみ環境変数として使用できます。
- ステップで作成された変数は、それらを定義するステップでは使用できません。
次の例は、ステップでパイプライン変数を作成し、後続のステップの条件とスクリプトで変数を使用する方法を示しています。
steps:
# This step creates a new pipeline variable: doThing. This variable is available to subsequent steps.
- bash: |
echo "##vso[task.setvariable variable=doThing]Yes"
displayName: Step 1
# This step is able to use doThing, so it uses doThing in its condition
- script: |
# 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 では、ジョブeq(dependencies.A.result,'SucceededWithIssues')
問題A
成功したため、ジョブ B
の実行が許可されます。
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
ビルドをキャンセルしましたが、まだ実行中です。 なぜですか?
ステージで構成された条件に ジョブ状態チェック関数が含まれていない場合は、この問題が発生。 この問題を解決するには、ジョブ状態チェック関数を条件に追加します。
キュー ステージの実行中にジョブを取り消しても実行していない場合は、他のすべてのステージを含め、ジョブ全体が取り消されます。 詳細については、この記事の前半ビルドが取り消されたときの条件の結果を参照してください。