次の方法で共有


パイプラインの条件

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 変数を設定して使用し、 mainBuild.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

次のパイプラインでは、既定ではstage2stage1に依存しますが、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

次のパイプラインでは、既定では stage2stage1に依存し、ジョブ 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を実行する場合は、conditionand(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')
      

手順の例

ステップに条件を設定することもできます。

次のパイプラインでは、手順 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}.SourceBranchBuild.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: ${{ 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

ビルドをキャンセルしましたが、まだ実行中です。 なぜですか?

ステージで構成された条件に ジョブ状態チェック関数が含まれていない場合は、この問題が発生。 この問題を解決するには、ジョブ状態チェック関数を条件に追加します。

キュー ステージの実行中にジョブを取り消しても実行していない場合は、他のすべてのステージを含め、ジョブ全体が取り消されます。 詳細については、この記事の前半ビルドが取り消されたときの条件の結果を参照してください。