条件の指定

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

各ステージ、ジョブ、ステップを実行する条件を指定できます。 既定では、ジョブまたはステージが他のジョブまたはステージに依存しない場合、または依存するすべてのジョブまたはステージが完了して成功した場合に実行されます。 これには、直接の依存関係だけでなく、再帰的に計算されるそれらの依存関係も含まれます。 既定では、ジョブ内でまだ何も失敗しておらず、その直前のステップが完了した場合に、ステップは実行されます。 この動作をカスタマイズするには、前の依存関係が失敗した場合でも、ステージ、ジョブ、またはステップを強制的に実行するようにするか、カスタム条件を指定します。

ステップ、ジョブ、またはステージを実行する条件を指定できます。

  • 同じエージェント プールを持つ以前のすべての直接的および間接的な依存関係が成功した場合のみ。 エージェント プールが異なる場合、それらのステージまたはジョブは同時に実行されます。 これは、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 と評価されると、親がキャンセルされた場合でも、ステージ、ジョブ、またはステップが実行されます。 親がスキップされた場合、ステージ、ジョブ、またはステップは実行されません。

いくつかの例を見てみましょう。

このパイプラインでは、既定で、stage2stage1 に依存し、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 は引き続き実行されます。

このパイプラインでは、stage2stage1 に依存します。 ジョブ 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 パイプラインがあるとします。 既定では、stage2stage1 に依存しており、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}.SourceBranchBuild.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: ${{ 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

ビルドをキャンセルしましたが、まだ実行中です。 どうしてでしょうか。

この問題は、ステージで構成されている条件にジョブ状態チェック関数が含まれていない場合に発生します。 この問題を解決するには、ジョブ状態チェック関数を条件に追加します。 キューに入っている間にジョブをキャンセルしたが、実行中ではない場合は、他のすべてのステージを含め、ジョブ全体がキャンセルされます。

詳細については、「ビルドがキャンセルされたときのパイプラインの動作」をご覧ください。