次の方法で共有


パイプラインにジョブを指定する

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

パイプラインをジョブに整理することができます。 すべてのパイプラインには、少なくとも 1 つのジョブがあります。 "ジョブ" とは、1 つの単位として順番に実行される一連のステップです。 つまり、ジョブは、実行をスケジュールできる最小の作業単位です。

パイプラインを構成する主要な概念とコンポーネントについては、新しい Azure Pipelines ユーザーの主要な概念に関するページを参照してください。

Azure Pipelines では、YAML パイプラインのジョブ優先度はサポートされていません。 ジョブの実行タイミングを制御するには、条件依存関係を指定します。

1 つのジョブを定義する

最もシンプルなケースでは、パイプラインに 1 つのジョブがあります。 この場合、jobを使っている場合を除き、 キーワードを明示的に使う必要はありません。 YAML ファイルでステップを直接指定できます。

この YAML ファイルには、Microsoft ホステッド エージェントで実行され、Hello world を出力するジョブがあります。

pool:
  vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello world"

そのジョブにさらに多くのプロパティを指定することもできます。 その場合は、job キーワードを使用できます。

jobs:
- job: myJob
  timeoutInMinutes: 10
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - bash: echo "Hello world"

パイプラインには複数のジョブが含まれる場合があります。 その場合は、jobs キーワードを使います。

jobs:
- job: A
  steps:
  - bash: echo "A"

- job: B
  steps:
  - bash: echo "B"

パイプラインには複数のステージを含めることができます。それぞれに複数のジョブがあります。 その場合は、stages キーワードを使います。

stages:
- stage: A
  jobs:
  - job: A1
  - job: A2

- stage: B
  jobs:
  - job: B1
  - job: B2

ジョブを指定する完全な構文:

- job: string  # name of the job, A-Z, a-z, 0-9, and underscore
  displayName: string  # friendly name to display in the UI
  dependsOn: string | [ string ]
  condition: string
  strategy:
    parallel: # parallel strategy
    matrix: # matrix strategy
    maxParallel: number # maximum number simultaneous matrix legs to run
    # note: `parallel` and `matrix` are mutually exclusive
    # you may specify one or the other; including both is an error
    # `maxParallel` is only valid with `matrix`
  continueOnError: boolean  # 'true' if future jobs should run even if this job fails; defaults to 'false'
  pool: pool # agent pool
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs
  container: containerReference # container to run this job inside
  timeoutInMinutes: number # how long to run the job before automatically cancelling
  cancelTimeoutInMinutes: number # how much time to give 'run always even if cancelled tasks' before killing them
  variables: { string: string } | [ variable | variableReference ] 
  steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
  services: { string: string | container } # container resources to run as a service container

ジョブを指定する完全な構文:

- job: string  # name of the job, A-Z, a-z, 0-9, and underscore
  displayName: string  # friendly name to display in the UI
  dependsOn: string | [ string ]
  condition: string
  strategy:
    parallel: # parallel strategy
    matrix: # matrix strategy
    maxParallel: number # maximum number simultaneous matrix legs to run
    # note: `parallel` and `matrix` are mutually exclusive
    # you may specify one or the other; including both is an error
    # `maxParallel` is only valid with `matrix`
  continueOnError: boolean  # 'true' if future jobs should run even if this job fails; defaults to 'false'
  pool: pool # agent pool
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs
  container: containerReference # container to run this job inside
  timeoutInMinutes: number # how long to run the job before automatically cancelling
  cancelTimeoutInMinutes: number # how much time to give 'run always even if cancelled tasks' before killing them
  variables: { string: string } | [ variable | variableReference ] 
  steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
  services: { string: string | container } # container resources to run as a service container
  uses: # Any resources (repos or pools) required by this job that are not already referenced
    repositories: [ string ] # Repository references to Azure Git repositories
    pools: [ string ] # Pool names, typically when using a matrix strategy for the job

ジョブの主な目的が (アプリのビルドまたはテストとは異なり) アプリの配置である場合、配置ジョブという特殊なジョブを使用できます。

配置ジョブの構文は次のとおりです。

- deployment: string        # instead of job keyword, use deployment keyword
  pool:
    name: string
    demands: string | [ string ]
  environment: string
  strategy:
    runOnce:
      deploy:
        steps:
        - script: echo Hi!

job に配置タスクの手順を追加することもできますが、代わりに配置ジョブを使うことをお勧めします。 配置ジョブにはいくつかのベネフィットがあります。 たとえば、環境にデプロイできます。これには、デプロイした内容の履歴を表示できるなどの利点が含まれます。

ジョブの種類

ジョブは、実行する場所によってさまざまな種類があります。

  • エージェント プール ジョブはエージェント プール内のエージェント上で実行されます。
  • サーバー ジョブは、Azure DevOps Server で実行されます。
  • コンテナー ジョブ は、エージェント プール内のエージェント上のコンテナーで実行されます。 コンテナーの選択の詳細については、「コンテナー ジョブを定義する」を参照してください。
  • エージェント プール ジョブはエージェント プール内のエージェント上で実行されます。
  • サーバー ジョブは、Azure DevOps Server で実行されます。

エージェント プール ジョブ

エージェント プール OB は最も一般的なジョブです。 これらのジョブは、エージェント プール内のエージェントで実行されます。 ジョブを実行するプールを指定できます。また、要求を指定して、エージェントがジョブを実行するために必要な機能を指定することもできます。 エージェントは、Microsoft でホストすることも、セルフホステッドにすることもできます。 詳細については、Azure Pipelines エージェントに関するページを参照してください。

  • Microsoft でホストされるエージェントを使用している場合、パイプライン内の各ジョブは新しいエージェントを取得します。
  • セルフホステッド エージェントを使用している場合は、要求 を使用して、エージェントがジョブを実行するために必要な機能を指定できます。 パイプラインの要求に一致するエージェント プールに複数のエージェントがあるかどうかに応じて、連続するジョブに対して同じエージェントを取得できます。 パイプラインの要求に一致するエージェントがプール内に 1 つしかない場合、このエージェントが使用可能になるまでパイプラインは待機します。

Note

要求と機能はセルフホステッド エージェントで使うように設計されているので、ジョブをジョブの要件を満たすエージェントと対応付けることができます。 Microsoft でホストされるエージェントを使用する場合は、ジョブの要件に一致するエージェントのイメージを選択します。 Microsoft でホストされるエージェントに機能を追加することはできますが、Microsoft がホストするエージェントで機能を使用する必要はありません。

pool:
  name: myPrivateAgents    # your job runs on an agent in this pool
  demands: agent.os -equals Windows_NT    # the agent must have this capability to run the job
steps:
- script: echo hello world

または複数の要求:

pool:
  name: myPrivateAgents
  demands:
  - agent.os -equals Darwin
  - anotherCapability -equals somethingElse
steps:
- script: echo hello world

詳細については、エージェント機能に関する記事を参照してください。

サーバー ジョブ

サーバーは、サーバー ジョブ内のタスクを調整して実行します。 サーバー ジョブにエージェントまたはターゲット コンピューターは必要ありません。 現在、サーバー ジョブでサポートされているタスクはごくわずかです。 サーバー ジョブの最大時間は 30 日です。

エージェントレス ジョブでサポートされるタスク

現在、既定のエージェントレス ジョブでは、次のタスクのみがサポートされています。

タスクは拡張機能可能であるため、拡張機能を使ってエージェントレス タスクをさらに追加できます。 エージェントレス ジョブの既定のタイムアウトは 60 分です。

サーバー ジョブを指定する完全な構文:

jobs:
- job: string
  timeoutInMinutes: number
  cancelTimeoutInMinutes: number
  strategy:
    maxParallel: number
    matrix: { string: { string: string } }

  pool: server # note: the value 'server' is a reserved keyword which indicates this is an agentless job

また、簡略化された構文も使用できます。

jobs:
- job: string
  pool: server # note: the value 'server' is a reserved keyword which indicates this is an agentless job

依存関係

1 つのステージで複数のジョブを定義する場合、それらの間の依存関係を指定できます。 パイプラインには、依存関係のないジョブを少なくとも 1 つ含める必要があります。 既定では、dependsOn 値が設定されている場合を除き、Azure DevOps YAML パイプライン ジョブは並列で実行されます。

Note

各エージェントは、一度に 1 つのジョブのみを実行できます。 複数のジョブを並列で実行するには、複数のエージェントを構成する必要があります。 また、十分な数の並列ジョブも必要です。

複数のジョブとその依存関係を定義するための構文は次のとおりです。

jobs:
- job: string
  dependsOn: string
  condition: string

順番にビルドされるジョブの例:

jobs:
- job: Debug
  steps:
  - script: echo hello from the Debug build
- job: Release
  dependsOn: Debug
  steps:
  - script: echo hello from the Release build

並列でビルドされるジョブの例 (依存関係なし):

jobs:
- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - script: echo hello from Windows
- job: macOS
  pool:
    vmImage: 'macOS-latest'
  steps:
  - script: echo hello from macOS
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - script: echo hello from Linux

ファンアウトの例:

jobs:
- job: InitialJob
  steps:
  - script: echo hello from initial job
- job: SubsequentA
  dependsOn: InitialJob
  steps:
  - script: echo hello from subsequent A
- job: SubsequentB
  dependsOn: InitialJob
  steps:
  - script: echo hello from subsequent B

ファンインの例:

jobs:
- job: InitialA
  steps:
  - script: echo hello from initial A
- job: InitialB
  steps:
  - script: echo hello from initial B
- job: Subsequent
  dependsOn:
  - InitialA
  - InitialB
  steps:
  - script: echo hello from subsequent

条件

各ジョブを実行する条件を指定できます。 既定では、他のジョブに依存しない場合、または依存しているすべてのジョブが正常に完了した場合、ジョブが実行されます。 この動作をカスタマイズするには、前のジョブが失敗した場合でもジョブを強制的に実行するか、カスタム条件を指定します。

前のジョブの実行状態に基づいてジョブを実行する例:

jobs:
- job: A
  steps:
  - script: exit 1

- job: B
  dependsOn: A
  condition: failed()
  steps:
  - script: echo this will run when A fails

- job: C
  dependsOn:
  - A
  - B
  condition: succeeded('B')
  steps:
  - script: echo this will run when B runs and succeeds

カスタム条件の使用例:

jobs:
- job: A
  steps:
  - script: echo hello

- job: B
  dependsOn: A
  condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/main'))
  steps:
  - script: echo this only runs for master

前のジョブで設定した出力変数の値に基づいて、ジョブの実行を指定できます。 この場合、直接依存するジョブで設定された変数のみを使用できます。

jobs:
- job: A
  steps:
  - script: "echo '##vso[task.setvariable variable=skipsubsequent;isOutput=true]false'"
    name: printvar

- job: B
  condition: and(succeeded(), ne(dependencies.A.outputs['printvar.skipsubsequent'], 'true'))
  dependsOn: A
  steps:
  - script: echo hello from B

Timeouts

ジョブが応答しない場合や待ち時間が長すぎるときにリソースを占有しないようにするには、ジョブの実行時間に制限を設定できます。 ジョブのタイムアウト設定を使って、ジョブの実行に関する制限を分単位で指定します。 値をゼロに設定した場合、ジョブを実行できる期間は次のとおりです。

  • セルフホステッド エージェントの場合は永続的
  • パブリック プロジェクトとパブリック リポジトリを使う Microsoft ホステッド エージェントの場合は 360 分 (6 時間)
  • Microsoft がホストするエージェントのプライベート プロジェクトまたはプライベート リポジトリで、最大60分間 (追加の容量 に対する の支払いが行われた場合を除く)

タイムアウト期間は、ジョブの実行が開始されたときに開始されます。 これには、ジョブがキューに入っている時間やエージェントを待機している時間は含まれません。

timeoutInMinutes を使うと、ジョブの実行時間に制限を設定できます。 指定しない場合、既定値は 60 分です。 0 を指定すると、上限が使用されます。

配置タスクで前のタスクが失敗した場合に実行を継続するように設定している場合、cancelTimeoutInMinutes を使うと、ジョブのキャンセル時間に制限を設定できます。 指定しない場合、既定値は 5 分です。 この値の範囲は 1 分から 35,790 分です。

jobs:
- job: Test
  timeoutInMinutes: 10 # how long to run the job before automatically cancelling
  cancelTimeoutInMinutes: 2 # how much time to give 'run always even if cancelled tasks' before stopping them

タイムアウトには、次のレベルの優先順位があります。

  1. Microsoft ホステッド エージェントでは、ジョブの実行時間は、プロジェクトの種類と、有料の並列ジョブを使用して実行されるかどうかに基づいて制限されます。 Microsoft がホストするジョブのタイムアウト間隔が経過すると、ジョブは終了します。 Microsoft ホステッド エージェントでは、ジョブで指定されたジョブ レベルのタイムアウトに関係なく、ジョブをこの間隔より長く実行することはできません。
  2. ジョブ レベルで構成されたタイムアウトは、ジョブの実行の最大期間を指定します。 ジョブ レベルのタイムアウト間隔が経過すると、ジョブは終了します。 Microsoft ホストエージェントでジョブを実行する場合、ジョブレベルのタイムアウトを、Microsoft ホスト型ジョブの組み込みタイムアウトよりも大きく設定しても、 影響はありません。
  3. 各タスクのタイムアウトを個別に設定することもできます。「タスク制御オプション」をご覧ください。 タスクが完了する前にジョブ レベルのタイムアウト間隔が経過すると、タスクのタイムアウト間隔が長く構成されている場合でも、実行中のジョブは終了します。

複数ジョブの構成

作成した 1 つのジョブから、複数のエージェントで複数のジョブを並列で実行することができます。 次に例をいくつか示します。

  • 複数構成のビルド: 複数の構成を並列でビルドできます。 たとえば、debugrelease の両方のプラットフォーム上で x86x64 の両方の構成向けに Visual C++ アプリをビルドできます。 詳細については、「 Visual Studio Build - 複数のプラットフォームの複数の構成を参照してください。

  • 複数構成の配置: 複数の配置を、たとえば異なる地域に対して並列で実行できます。

  • 複数構成のテスト: テスト用の複数の構成を並列で実行できます。

  • 複数構成変数が空の場合でも、複数構成では常に少なくとも 1 つのジョブが生成されます。

matrix 戦略を使うと、異なる変数セットを使ってジョブを複数回ディスパッチできます。 maxParallel タグを使うと、並列処理の量を制限できます。 Location と Browser に設定した値のとおり、次のジョブは 3 回ディスパッチされます。 ただし、同時に実行されるのは 2 つのジョブのみです。

jobs:
- job: Test
  strategy:
    maxParallel: 2
    matrix: 
      US_IE:
        Location: US
        Browser: IE
      US_Chrome:
        Location: US
        Browser: Chrome
      Europe_Chrome:
        Location: Europe
        Browser: Chrome

Note

マトリックス構成名 (例の US_IE など) には、基本的なラテンアルファベット (A - Z、a - z)、数字、アンダースコア (_) のみを含める必要があります。 列名の先頭は文字である必要があります。 また、100 文字以下にする必要があります

また、出力変数を使ってマトリックスを生成することもできます。 このメソッドは、スクリプトを使用してマトリックスを生成する必要がある場合に便利です。

matrix は、文字列化された JSON オブジェクトを含むランタイム式を受け入れます。 この JSON オブジェクトは、展開したときに、マトリックス構文と一致する必要があります。 次の例では、JSON 文字列をハードコーディングしましたが、スクリプト言語またはコマンド ライン プログラムを使用して生成できます。

jobs:
- job: generator
  steps:
  - bash: echo "##vso[task.setVariable variable=legs;isOutput=true]{'a':{'myvar':'A'}, 'b':{'myvar':'B'}}"
    name: mtrx
  # This expands to the matrix
  #   a:
  #     myvar: A
  #   b:
  #     myvar: B
- job: runner
  dependsOn: generator
  strategy:
    matrix: $[ dependencies.generator.outputs['mtrx.legs'] ]
  steps:
  - script: echo $(myvar) # echos A or B depending on which leg is running

スライス

エージェント ジョブを使うと、一連のテストを並列して実行できます。 たとえば、1 つのエージェントで 1,000 個の大規模なテストスイートを実行できます。 また、2 つのエージェントを使って、それぞれに対して 500 個のテストを並列して実行できます。

スライスを適用するには、ジョブ内のタスクに、その属するスライスを理解できる高い機能が必要です。

Visual Studio Test タスクは、そのようなテスト スライスをサポートするタスクの 1 つです。 複数のエージェントをインストールした場合、これらのエージェント上で Visual Studio Test タスクを並列で実行する方法を指定できます。

parallel 戦略を使うと、ジョブを何度も複製できます。 変数 System.JobPositionInPhaseSystem.TotalJobsInPhase が各ジョブに追加されます。 この変数をスクリプト内で使うことで、作業を複数のジョブに分割できます。 エージェント ジョブを使った並列および複数の実行に関する記事を参照してください。

次のジョブは 5 回ディスパッチされます。その際に System.JobPositionInPhaseSystem.TotalJobsInPhase の値は適切に設定されます。

jobs:
- job: Test
  strategy:
    parallel: 5

ジョブ変数

YAML を使っている場合、ジョブに対して変数を指定できます。 これらの変数は、マクロ構文 $(variableName) を使ってタスク入力に渡すことや、スクリプト内でステージ変数を使ってアクセスすることができます。

ジョブで変数を定義し、タスク内で使う例を次に示します。

variables:
  mySimpleVar: simple var value
  "my.dotted.var": dotted var value
  "my var with spaces": var with spaces value

steps:
- script: echo Input macro = $(mySimpleVar). Env var = %MYSIMPLEVAR%
  condition: eq(variables['agent.os'], 'Windows_NT')
- script: echo Input macro = $(mySimpleVar). Env var = $MYSIMPLEVAR
  condition: in(variables['agent.os'], 'Darwin', 'Linux')
- bash: echo Input macro = $(my.dotted.var). Env var = $MY_DOTTED_VAR
- powershell: Write-Host "Input macro = $(my var with spaces). Env var = $env:MY_VAR_WITH_SPACES"

condition の使用については、「条件の指定」を参照してください。

ワークスペース

エージェント プール ジョブを実行すると、エージェント上にワークスペースが作成されます。 ワークスペースとは、ソースをダウンロードし、ステップを実行し、出力を生成するディレクトリです。 ワークスペース ディレクトリは、ジョブ内で Pipeline.Workspace 変数を使って参照できます。 この下に、さまざまなサブディレクトリが作成されます。

  • Build.SourcesDirectory は、タスクがアプリケーションのソース コードをダウンロードする場所です。
  • Build.ArtifactStagingDirectory は、タスクがパイプラインに必要な成果物をダウンロードしたり、発行前の成果物をアップロードしたりする場所です。
  • Build.BinariesDirectory は、タスクが出力を書き込む場所です。
  • Common.TestResultsDirectory は、タスクがテスト結果をアップロードする場所です。

$(Build.ArtifactStagingDirectory)$(Common.TestResultsDirectory) は常に削除され、ビルドの前に再作成されます。

セルフホステッド エージェント上でパイプラインを実行する場合、既定で、$(Build.ArtifactStagingDirectory)$(Common.TestResultsDirectory) 以外のサブディレクトリは、2 つの連続した実行の間にクリーンされません。 その結果、インクリメンタルなビルドとデプロイを活用するようにタスクが実装されている場合、それらを実行できます。 この動作は、ジョブの workspace 設定を使ってオーバーライドできます。

重要

ワークスペースのクリーン オプションは、セルフホステッド エージェントにのみ適用されます。 Microsoft ホステッド エージェントを使用して、ジョブは常に新しいエージェント上で実行されます。

- job: myJob
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs

clean オプションのいずれかを指定すると、次のように解釈されます。

  • outputs: 新しいジョブを実行する前に Build.BinariesDirectory を削除します。
  • resources: 新しいジョブを実行する前に Build.SourcesDirectory を削除します。
  • all: 新しいジョブを実行する前に Pipeline.Workspace ディレクトリ全体を削除します。
  jobs:
  - deployment: MyDeploy
    pool:
      vmImage: 'ubuntu-latest'
    workspace:
      clean: all
    environment: staging

Note

エージェントの機能とパイプラインの要求に応じて、各ジョブをセルフホステッド プール内の異なるエージェントにルーティングできます。 その結果、後続のパイプライン実行 (または同じパイプライン内のステージまたはジョブ) 用に新しいエージェントを取得できるため、クリーニングしないことが、後続の実行、ジョブ、またはステージで以前の実行、ジョブ、またはステージからの出力にアクセスできるという保証にはなりません。 エージェントの機能とパイプラインの要求を構成して、パイプライン ジョブの実行に使用するエージェントを指定できます。 ただし、要求を満たすエージェントがプール内に 1 つしかない場合を除き、後続のジョブで以前のジョブと同じエージェントが使用される保証はありません。 詳細については、「要求の指定」を参照してください。

ワークスペースのクリーンに加えて、パイプライン設定 UI で [クリーン] 設定を構成することでクリーンを構成することもできます。 [クリーン] 設定が true (既定値) の場合、パイプラインのclean: true ステップごとに を指定することと同じです。 clean: trueを指定すると、git フェッチの前 git clean -ffdxgit reset --hard HEAD が実行されます。 [クリーン] 設定を構成するには:

  1. パイプラインを編集し、[...] を選び、[トリガー] を選びます。

    トリガーを編集する。

  2. [YAML][ソースの取得] を選び、任意の [クリーン] 設定を構成します。 既定値は trueです。

    [クリーン] 設定。

成果物のダウンロード

この例の YAML ファイルでは、成果物 WebSite を発行し、$(Pipeline.Workspace) に成果物をダウンロードします。 配置ジョブは、ビルド ジョブが成功した場合にのみ実行されます。

# test and upload my code as an artifact named WebSite
jobs:
- job: Build
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - script: npm test
  - task: PublishBuildArtifacts@1
    inputs:
      pathtoPublish: '$(System.DefaultWorkingDirectory)'
      artifactName: WebSite

# download the artifact and deploy it only if the build job succeeded
- job: Deploy
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - checkout: none #skip checking out the default repository resource
  - task: DownloadBuildArtifacts@0
    displayName: 'Download Build Artifacts'
    inputs:
      artifactName: WebSite
      downloadPath: $(Pipeline.Workspace)

  dependsOn: Build
  condition: succeeded()

dependsOncondition の使用については、「条件の指定」を参照してください。

OAuth トークンにアクセスする

ジョブで実行されているスクリプトが現在の Azure Pipelines OAuth セキュリティ トークンにアクセスすることを許可できます。 このトークンは、Azure Pipelines REST API に対する認証に使用できます。

OAuth トークンは、YAML パイプラインで常に使用できます。 env を使ってタスクまたはステップに明示的にマップする必要があります。 次に例を示します。

steps:
- powershell: |
    $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$($env:SYSTEM_DEFINITIONID)?api-version=4.1-preview"
    Write-Host "URL: $url"
    $pipeline = Invoke-RestMethod -Uri $url -Headers @{
      Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
    }
    Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
  env:
    SYSTEM_ACCESSTOKEN: $(system.accesstoken)

次の内容