Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020
この記事では、Azure Pipelines のステージ、ジョブ、またはステップを実行できるさまざまな条件と、YAML パイプライン定義でこれらの条件を設定する方法について説明します。
メモ
この記事では、YAML パイプラインの機能について説明します。 クラシック パイプラインでは、各タスクの [コントロール オプション] 、およびリリース パイプラインのジョブの [追加オプション でタスクまたはジョブを実行する条件を指定できます。
ステージ、ジョブ、またはステップの実行条件
既定では、パイプライン ジョブまたはステージは、他のジョブまたはステージに依存しない場合、またはすべての依存関係が完了して 成功した場合に実行されます。 依存関係の要件は、直接の依存関係とその間接的な依存関係に適用され、再帰的に計算されます。
既定では、ジョブ内でまだ何も失敗しておらず、その直前のステップが完了した場合に、ステップは実行されます。 ステージ、ジョブ、およびステップの詳細については、「Azure Pipelines の主要な概念」を参照してください。
これらの既定の動作をオーバーライドまたはカスタマイズするには、前の依存関係が失敗した場合や別の結果が発生した場合にのみ、実行するステージ、ジョブ、またはステップを設定します。
カスタム条件を定義することもできます。 YAML パイプライン定義では、 condition プロパティを使用して、ステージ、ジョブ、またはステップを実行できる条件を指定します。
メモ
条件は、同じエージェント プールを持つ以前のすべての直接依存関係と間接依存関係に適用されます。 異なるエージェント プール内のステージまたはジョブは同時に実行されます。
以前の依存関係の状態に基づく条件は次のとおりです。
-
成功: 以前のすべての依存関係が成功した場合にのみ実行します。 この動作は、YAML に条件が設定されていない場合の既定値です。 この条件を適用するには、
condition: succeeded()を指定します。 -
成功または失敗: 実行が取り消されない限り、以前の依存関係が失敗した場合でも実行します。 この条件を適用するには、
condition: succeededOrFailed()を指定します。 -
常に: 実行が取り消された場合でも、以前の依存関係が失敗した場合でも実行します。 この条件を適用するには、
condition: always()を指定します。 -
失敗: 以前の依存関係が失敗した場合にのみ実行されます。 この条件を適用するには、
condition: failed()を指定します。
重要
ステージ、ジョブ、またはステップに condition プロパティを指定すると、既定の条件が上書きされます。 ビルドが取り消された場合でも、ステージ、ジョブ、またはステップが実行される場合があります。 条件が親ステージまたはジョブの状態を考慮に入れる必要があります。
条件の例
次の YAML の例は、 always() 条件と failed() 条件を示しています。 ジョブ 1 の最初のスクリプト タスクには always 条件があるため、依存関係が失敗した場合やビルドが取り消された場合でも実行されます。 2 番目のスクリプト タスクでは、exit job1job1 ジョブが強制的に失敗します。
パイプライン ステージは既定で順番に実行されますが、ジョブは並列で実行できます。
dependsOn プロパティを使用して、ステージまたはジョブ間の依存関係を明示的に定義できます。
別のジョブの結果に依存するジョブの条件を設定するには、 dependsOn を使用して依存関係を定義します。 次の例では、 job2 は job1 に依存し、 job1 が失敗するため実行されます。
jobs:
- job: job1
steps:
- script: echo Hello!
condition: always() # this step runs even if the build is canceled
- script: |
echo "This task will fail."
exit job1
- job: job2
dependsOn: job1
condition: failed() # this job runs only if job1 fails
メモ
また、Azure Pipelines UI を使用して、親ステージが失敗したときに依存ステージを手動で実行することもできます。 詳細については、「 親ステージが失敗したときに子ステージを実行する」を参照してください。
カスタム条件
組み込み条件がニーズを満たしていない場合は、YAML パイプライン定義で 式 としてカスタム条件を指定できます。
エージェントは、最も内側の関数から始まり、外側に向かって式を評価します。 最終的な結果は、ステージ、ジョブ、またはステップを実行するかどうかを決定するブール値です。 構文の完全なガイドについては、「式」を参照してください。
重要
条件が評価され、ステージ、ジョブ、またはステップを開始するかどうかが決定されます。 そのため、ステージ、ジョブ、またはステップの実行時に、同じステージ、ジョブ、またはステップ内で使用できる計算は何もありません。 たとえば、 $[ ] 構文を持つランタイム式を使用してジョブに変数を設定した場合、そのジョブ内の条件でその変数を使用することはできません。
条件内の変数
パイプライン変数を設定し、条件で使用できます。 次のパイプラインでは、 isMain 変数を設定し、ビルド ソース ブランチが mainされている場合にのみステージ B を実行する条件で使用します。
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)
変数が null または空の文字列の場合に実行する条件を設定できます。 すべての変数は Azure Pipelines で文字列として扱われるので、空の文字列は次のパイプラインの null と同じです。
variables:
- name: testEmpty
value: ''
jobs:
- job: A
steps:
- script: echo testEmpty is blank
condition: eq(variables.testEmpty, '')
他のジョブ条件で使用されるジョブ出力変数
同じステージ内の他のジョブが条件で指定できる変数をジョブに作成できます。 依存ジョブで使用できる変数は、次のコードのように、を使用してisOutput=trueとしてマークする必要があります。
jobs:
- job: A
steps:
- bash: |
echo "This is job A."
echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #set variable doThing to Yes
name: DetermineResult
- job: B
dependsOn: A
condition: eq(dependencies.A.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check the value
steps:
- script: echo "Job A ran and doThing is Yes."
後続のステップ条件で使用されるステップ変数
同じジョブ内の将来のステップで条件で指定できる変数をステップで作成できます。 ステップから作成された変数は、既定でジョブの将来のステップで使用でき、マルチジョブ出力変数としてマークする必要はありません。
ジョブのステップで作成される変数には、次の制限があります。
次の例では、ステップでパイプライン変数を作成し、後の手順のスクリプト条件で変数を使用します。
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 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'))
さまざまな結果の条件設定
次の表は、さまざまな目的の結果を生成するための condition 設定を示しています。
| 希望する結果 | 条件設定の例 |
|---|---|
親または前のステージ、ジョブ、またはステップが失敗したか取り消された場合でも、ソース ブランチが mainされている場合に実行します。 |
eq(variables['Build.SourceBranch'], 'refs/heads/main') |
ソース ブランチが main され、親または前のステージ、ジョブ、またはステップが成功した場合に実行します。 |
and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) |
ソース ブランチが mainされておらず、親または前のステージ、ジョブ、またはステップが成功した場合に実行します。 |
and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main')) |
親または前のステージ、ジョブ、またはステップが成功した場合は、 user ブランチに対して実行します。 |
and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/')) |
| 親または前のステージ、ジョブまたはステップが成功した場合、continuous integration (CI) ビルドに対して実行されます。 | and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI')) |
| プル要求によってビルドがトリガーされ、親または前のステージ、ジョブ、またはステップが失敗した場合に実行します。 | and(failed(), eq(variables['Build.Reason'], 'PullRequest')) |
| 親または前のステージ、ジョブまたはステップが失敗またはキャンセルされた場合でも、スケジュールされたビルドに対して実行されます。 | eq(variables['Build.Reason'], 'Schedule') |
親または前のステージ、ジョブ、またはステップが失敗したか取り消された場合でも、 System.debug 変数が trueに設定されている場合に実行します。 |
eq(variables['System.debug'], true) |
メモ
Release.Artifacts.{artifact-alias}.SourceBranch は Build.SourceBranch と等価です。
ビルドがキャンセルされたときの条件の結果
ビルドを取り消しても、そのステージ、ジョブ、およびステップがすべて実行を停止するわけではありません。 実行を停止するジョブ、ステージ、またはステップは、指定した条件と、パイプラインの実行のどの時点でビルドをキャンセルしたかによって異なります。 ステージ、ジョブ、またはステップの親がスキップされた場合、ステージ、ジョブ、またはステップは、その条件に関係なく実行されません。
ステージ、ジョブ、またはステップは、その条件が true と評価されるたびに実行されます。 条件がタスクの親の状態を考慮しない場合、その親が取り消された場合でもタスクが実行される可能性があります。 ビルドが取り消されたときにジョブ、ステージ、またはステップを実行するかどうかを制御するには、条件に ジョブ状態チェック関数 を含めます。
キュー ステージの実行中にビルドを取り消しても、まだ実行されていない場合は、他のすべてのステージを含め、実行全体が取り消されます。
メモ
いずれかの条件により、ビルドが取り消された後でもタスクを実行できる場合は、 キャンセル タイムアウト の値を指定します。この値を指定すると、実行が取り消された後にタスクが完了するのに十分な時間が確保されます。
ステージ条件の結果の例
次の例は、ビルドが取り消されたときにステージに設定されたさまざまな条件の結果を示しています。
ステージ例 1
次のパイプラインでは、既定では、 stage2 は正常に完了 stage1 によって異なります。 ただし、stage2には、状態に関係なく、ソース ブランチがconditionされるたびに実行するmainが設定stage1。
main ブランチでビルドをキューし、stage1 の実行中にそれをキャンセルした場合、stage2 が eq(variables['Build.SourceBranch'], 'refs/heads/main') と評価されるため、true も引き続き実行されます。
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 によって異なります。
Bのジョブ stage2には、ソース ブランチがconditionされるたびに実行するmainが設定されています。
mainブランチでビルドをキューに入れ、stage1の実行中にそれをキャンセルすると、ステージに条件がstage2評価されるジョブが含まれている場合でも、trueとそのジョブはまったく実行されません。
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内のジョブ stage2内のステップには、ソース ブランチがconditionされるたびに実行するmainが設定されています。
main ブランチでビルドをキューに登録し、stage1の実行中にキャンセルすると、ジョブ stage2に条件がBと評価されるステップが含まれている場合でも、Bとジョブtrueはまったく実行されません。
Stage2 は、 stage1 が取り消されたため、完全にスキップされます。
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には、ソース ブランチがconditionされるたびに実行するmainが設定されています。
main ブランチでビルドをキューし、ジョブ A の実行中にそれをキャンセルした場合、B が condition: 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
ジョブ Bが成功し、ビルド ソースがA場合にのみジョブ mainを実行する場合は、conditionを and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) に設定する必要があります。
ジョブ例 2
次の YAML パイプラインでは、ジョブの B はジョブ A 成功に依存します。 ジョブ Bには、ジョブ conditionが成功し、ビルド ソース ブランチがAされるたびに実行するmainが設定されています。
main ブランチでビルドをキューに入れ、ジョブ Aの実行中に取り消すと、ジョブ Bは実行されません。ただし、conditionと評価されるtrueが 1 つあっても、ジョブは実行されません。 ジョブBの条件は、ジョブfalseが成功しなかったため、Aに評価されます。 そのため、ジョブ B とそのステップはスキップされます。
jobs:
- job: A
steps:
- script: sleep 30
- job: B
dependsOn: A
steps:
- script: echo step 2.1
condition: and(eq(variables['Build.SourceBranch'], 'refs/heads/main'), succeeded())
ステップ条件の結果の例
ステップに条件を設定することもできます。 次のパイプラインでは、ステップ 2.3 で、ソース ブランチが condition の場合に main が実行されるように設定されています。
main ブランチでビルドをキューし、ステップ 2.1 または 2.2 の実行中にそれをキャンセルした場合、eq(variables['Build.SourceBranch'], 'refs/heads/main') が true と評価されているため、ステップ 2.3 は引き続き実行されます。
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 は、 succeeded() と ${{ eq(parameters.doThing, true) }}の 2 つの関数を組み合わせています。
succeeded() 関数は、前のステップが成功したかどうかを確認します。 この関数は、前の手順がない場合も true を返します。
${{ eq(parameters.doThing, true) }} 関数は、doThing パラメータが true に等しいかどうかを確認します。 次の例のスクリプト ステップは、前の手順がなく、 parameters.doThing が既定で true されているために実行されます。
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), ${{ eq(parameters.doThing, true) }})
条件の Template パラメータ
パイプライン テンプレートにパラメーターを渡すときは、テンプレート ファイルでパラメーターの値を設定するか、 templateContext を使用してパラメーターをテンプレートに渡すことができます。
次のparameters.ymlテンプレート ファイルでは、既定値の doThing で true パラメーターを宣言し、ジョブ条件でパラメーターを使用します。
# parameters.yml
parameters:
- name: doThing
default: true
type: boolean
jobs:
- job: B
steps:
- script: echo I did a thing
condition: ${{ eq(parameters.doThing, true) }}
次 のazure-pipelines.yml パイプライン定義は、 parameters.yml テンプレート ファイル内のジョブを参照します。 パラメーター I did a thingが既定で true であるため、パイプラインの出力はdoThingされます。
# azure-pipelines.yml
extends:
template: parameters.yml
Template パラメータ例の詳細については、「テンプレートの利用参照」を参照してください。
FAQ
以前のジョブがエラーありで成功した場合にジョブをトリガーするにはどうすればよいですか?
前のジョブの結果を条件で使用できます。 次の YAML では、ジョブeq(dependencies.A.result,'SucceededWithIssues')問題B成功した後に実行するジョブ Aを設定する条件です。
jobs:
- job: A
steps:
- script: echo Job A ran
- job: B
dependsOn: A
condition: eq(dependencies.A.result,'SucceededWithIssues') # targets the result of the previous job
steps:
- script: echo Job A had issues
キャンセルした後もビルドがまだ実行されているのはなぜですか?
この問題は、ステージで構成した条件に、job status check 関数が含まれていないために発生します。 この問題を解決するには、ジョブ状態チェック関数を条件に追加します。 詳細については、「 ビルドが取り消されたときの条件の結果」を参照してください。