正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

needsでジョブをより早く開始する

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

needsキーワードを使用して、ジョブの依存関係をパイプラインで指定します。ジョブは、パイプラインステージに関わらず、その依存関係が完了するとすぐに開始されます。これにより、ジョブを以前より早く実行し、不要な待機を回避できます。

ユースケース:

  • モノレポ: 独立したサービスを並列実行パスでビルドするしてテストします。
  • マルチプラットフォームビルド: すべてのビルドが完了するのを待たずに、異なるプラットフォーム向けにコンパイルします。
  • より高速なフィードバック: テスト結果とエラーを以前より早く取得します。

needs: projectneeds: pipelineキーワードは、ジョブの依存関係を指定するためには使用されません。他のパイプラインからアーティファクトをフェッチするには、needs: projectを使用します。アップストリームパイプラインのステータスをミラーするには、needs: pipelineを使用します。

needsの仕組み

デフォルトでは、ジョブはステージで実行されます。ジョブは、開始する前に、以前のステージ内のすべてのジョブが完了するのを待ちます。

needsを使用すると、どのジョブがどのジョブに依存するかを正確に指定できます。その依存関係が完了するとすぐにジョブが開始されます。これは、以前のステージにある他のジョブがまだ実行中でも同様です。これにより、一種の有向非巡回グラフ (DAG)パイプラインが作成されます。

ステージ化されたジョブとジョブのneeds依存関係を同じパイプライン内で混在させることができます。

さらに、以前のジョブやステージの完了を待たずに、ジョブをすぐに実行するようにneeds: []を使用できます。ソースコードビルド結果に依存しないLintジョブやスキャナーは、すぐに実行できるため、即座に実行することが一般的です。

needsとステージのみを使用するジョブとの比較

needsを使用する利点を示すために、6つのジョブを持つパイプラインを設定する2つの方法を比較できます。

このパイプラインには、ステージに編成された6つのジョブがあります。needsがないと、一部のジョブが独立していても、次のステージが開始する前に、ステージ内のすべてのジョブが完了する必要があります:

stages:
  - build
  - test
  - deploy

build_app_A:
  stage: build
  script: echo "Building A..."

build_app_B:
  stage: build
  script: echo "Building B..."

test_app_A:
  stage: test
  script: echo "Testing A..."

test_app_B:
  stage: test
  script: echo "Testing B..."

deploy_app_A:
  stage: deploy
  script: echo "Deploying A..."

deploy_app_B:
  stage: deploy
  script: echo "Deploying B..."
graph TB
  subgraph build["Build Stage"]
    build_a["build_app_A"]
    build_b["build_app_B"]
  end
  subgraph test["Test Stage"]
    test_a["test_app_A"]
    test_b["test_app_B"]
  end
  subgraph deploy["Deploy Stage"]
    deploy_a["deploy_app_A"]
    deploy_b["deploy_app_B"]
  end

この例では、buildステージ内のすべてのジョブが完了するまで、テストジョブやデプロイジョブは実行されません。Aジョブの実行に時間がかかる場合、Bのテストジョブおよびデプロイジョブは、Aジョブが完了するのを待っている間に遅延する可能性があります。

needsを使用すると、2つの独立した実行パスを定義できます。各ジョブは、実際に必要とするジョブのみに依存するため、2つのパス間で並列実行が可能です:

stages:
  - build
  - test
  - deploy

build_app_A:
  stage: build
  script: echo "Building A..."

build_app_B:
  stage: build
  script: echo "Building B..."

test_app_A:
  stage: test
  needs: ["build_app_A"]
  script: echo "Testing A..."

test_app_B:
  stage: test
  needs: ["build_app_B"]
  script: echo "Testing B..."

deploy_app_A:
  stage: deploy
  needs: ["test_app_A"]
  script: echo "Deploying A..."

deploy_app_B:
  stage: deploy
  needs: ["test_app_B"]
  script: echo "Deploying B..."
graph LR
  subgraph build["Build Stage"]
    build_a["build_app_A"]
    build_b["build_app_B"]
  end
  subgraph test["Test Stage"]
    test_a["test_app_A"]
    test_b["test_app_B"]
  end
  subgraph deploy["Deploy Stage"]
    deploy_a["deploy_app_A"]
    deploy_b["deploy_app_B"]
  end

  build_a --> test_a
  build_b --> test_b
  test_a --> deploy_a
  test_b --> deploy_b

この例では、build_app_Aがまだ実行中であっても、build_app_Bが正常に完了するとすぐにtest_app_Bが実行されます。同様に、build_app_Aが完了する前にdeploy_app_Bが実行され、デプロイされる可能性があります。

ジョブ間の依存関係を表示

ジョブ間の依存関係は、パイプライングラフで確認できます。

この表示を有効にするには、パイプラインの詳細ページから次の手順を実行します:

  • ジョブの依存関係を選択します。
  • オプション。オプション。依存関係を表示を切替て、ジョブがどのようにリンクされているかを表示します。

5つのジョブとその依存関係を示すパイプライングラフ

needsの例

needsを使用して、ジョブ間の依存関係を作成し、ジョブの開始待機時間を短縮します。パターンには、ファンアウト、ファンイン、ダイヤモンド依存関係が含まれます。

ファンアウト

ファンアウトジョブ依存関係グラフを作成するには、複数のジョブが1つのジョブに依存するように設定します。

例:

stages:
  - build
  - test

build:
  stage: build
  script: echo "Building..."

test_unit:
  stage: test
  needs: ["build"]
  script: echo "Unit tests..."

test_integration:
  stage: test
  needs: ["build"]
  script: echo "Integration tests..."

test_performance:
  stage: test
  needs: ["build"]
  script: echo "Performance tests..."
graph LR
  subgraph build["Build Stage"]
    build_job["build"]
  end
  subgraph test["Test Stage"]
    test_unit["test_unit"]
    test_integration["test_integration"]
    test_performance["test_performance"]
  end

  build_job --> test_unit
  build_job --> test_integration
  build_job --> test_performance

ファンイン

ファンイン依存関係グラフを作成するには、1つのジョブが複数のジョブの完了を待機するように設定します。例:

stages:
  - build
  - test
  - deploy

build_frontend:
  stage: build
  script: echo "Building frontend..."

build_backend:
  stage: build
  script: echo "Building backend..."

test_frontend:
  stage: test
  needs: ["build_frontend"]
  script: echo "Testing frontend..."

test_backend:
  stage: test
  needs: ["build_backend"]
  script: echo "Testing backend..."

deploy:
  stage: deploy
  needs: ["test_frontend", "test_backend"]
  script: echo "Deploying..."
graph LR
  subgraph build["Build Stage"]
    build_frontend["build_frontend"]
    build_backend["build_backend"]
  end
  subgraph test["Test Stage"]
    test_frontend["test_frontend"]
    test_backend["test_backend"]
  end
  subgraph deploy["Deploy Stage"]
    deploy_job["deploy"]
  end

  build_frontend --> test_frontend
  build_backend --> test_backend
  test_frontend --> deploy_job
  test_backend --> deploy_job

ダイヤモンド依存関係

ダイヤモンド依存関係グラフを作成するには、ファンアウトとファンインを組み合わせます。1つのジョブが複数のジョブにファンアウトし、それが再び1つのジョブにファンインします。例:

stages:
  - build
  - test
  - deploy

build:
  stage: build
  script: echo "Building..."

test_unit:
  stage: test
  needs: ["build"]
  script: echo "Unit tests..."

test_integration:
  stage: test
  needs: ["build"]
  script: echo "Integration tests..."

test_performance:
  stage: test
  needs: ["build"]
  script: echo "Performance tests..."

deploy:
  stage: deploy
  needs: ["test_unit", "test_integration", "test_performance"]
  script: echo "Deploying..."
graph LR
  subgraph build["Build Stage"]
    build_job["build"]
  end
  subgraph test["Test Stage"]
    test_unit["test_unit"]
    test_integration["test_integration"]
    test_performance["test_performance"]
  end
  subgraph deploy["Deploy Stage"]
    deploy_job["deploy"]
  end

  build_job --> test_unit
  build_job --> test_integration
  build_job --> test_performance
  test_unit --> deploy_job
  test_integration --> deploy_job
  test_performance --> deploy_job

即時開始

needs: []を使用して、パイプラインが作成されたときに、他のジョブやステージを待たずに、ジョブをすぐに開始するように設定します。これは、すぐに実行できるものの、testのように、より後のステージに表示されるべきLintするツールやスキャンツールに使用します。

例:

stages:
  - build
  - test
  - deploy

build_app:
  stage: build
  script: echo "Building app..."

test_app:
  stage: test
  script: echo "Testing app..."

lint_yaml:
  stage: test
  needs: []
  script: echo "Linting YAML..."

lint_code:
  stage: test
  needs: []
  script: echo "Linting code..."

deploy_app:
  stage: deploy
  script: echo "Deploying app..."

パイプラインビューには、ステージごとにグループ化されたジョブが表示されます:

graph LR
  subgraph build["Build Stage"]
    build_app["build_app"]
  end
  subgraph test["Test Stage"]
    test_app["test_app"]
    lint_yaml["lint_yaml"]
    lint_code["lint_code"]
  end
  subgraph deploy["Deploy Stage"]
    deploy_app["deploy_app"]
  end

  build_app --> test_app
  test_app --> deploy_app

ジョブは可能な限り早く実行を開始します:

graph LR
  start["Pipeline Start"]

  start --> build_app["build_app"]
  start --> lint_yaml["lint_yaml"]
  start --> lint_code["lint_code"]

  build_app --> test_app["test_app"]
  test_app --> deploy_app["deploy_app"]

この例では、lint_yamllint_codeneeds: []を使用してすぐに開始し、build_apptestステージの完了を待ちません。deploy_appneedsを使用しないため、開始する前に以前のステージにあるすべてのジョブが完了するのを待ちます。

ステージなしのパイプライン

stageおよびstagesキーワードを省略し、needsのみを使用してジョブの順序を定義できます。stageキーワードがないすべてのジョブは、デフォルトのtestステージで実行されます:

compile:
  script: echo "Compiling..."

unit_tests:
  needs: ["compile"]
  script: echo "Running unit tests..."

integration_tests:
  needs: ["compile"]
  script: echo "Running integration tests..."

package:
  needs: ["unit_tests", "integration_tests"]
  script: echo "Packaging..."

このパイプラインの構造を表示するには、パイプラインの詳細ページからジョブの依存関係を選択します。デフォルトビューを使用する場合、すべてのジョブはtestステージにまとめられます。

オプションの依存関係

needsoptional: trueを使用すると、パイプライン内にジョブが存在する場合にのみジョブに依存できます。このオプションを使用して、needsrulesを組み合わせたときに実行される場合とされない場合があるジョブを処理します。

例:

stages:
  - build
  - test
  - deploy

build:
  stage: build
  script: echo "Building..."

test:
  stage: test
  needs: ["build"]
  script: echo "Testing..."

test_optional:
  stage: test
  rules:
    - if: $RUN_OPTIONAL_TESTS == "true"
  script: echo "Optional tests..."

deploy:
  stage: deploy
  needs:
    - job: "test"
    - job: "test_optional"
      optional: true
  script: echo "Deploying..."

この例では:

  • deployは以下に依存します:
    • test。パイプライン内に常に存在します。
    • test_optionalRUN_OPTIONAL_TESTStrueの場合にのみパイプライン内に存在します。
  • RUN_OPTIONAL_TESTSが次のとき:
    • trueの場合、test_optionalはパイプラインに存在せず、testが完了した後にdeployが実行されます。
    • falseの場合、test_optionalはパイプラインに存在し、deploytesttest_optionalの両方が完了するのを待ちます。

optional: trueがないと、deployジョブがtest_optionalを期待しているにもかかわらず、それがパイプラインに存在しないため、パイプラインの作成が失敗します。

needsparallel:matrixの組み合わせ

needsキーワードはparallel:matrixと連携して、並列化されたジョブを指す依存関係を定義します

トラブルシューティング

エラー: 'job' does not exist in the pipeline

needsrulesを組み合わせると、パイプラインの作成が失敗し、次のエラーが表示されることがあります:

'unit_tests' job needs 'compile' job, but 'compile' does not exist in the pipeline.
This might be because of the only, except, or rules keywords. To need a job that
sometimes does not exist in the pipeline, use needs:optional.

このエラーは、needsがパイプラインに存在しない別のジョブに設定されている1つのジョブによって引き起こされます。この問題を修正するには、次のいずれかを実行する必要があります:

  • optional: trueをジョブの依存関係に追加して、必要なジョブがパイプラインに存在しない場合に無視されるようにします。
  • rules設定を更新して、必要なジョブが常に実行されるようにします。

例:

# Method 1: Job with rules that may not exist
compile:
  stage: build
  rules:
    - if: $COMPILE == "true"
  script: echo "Compiling..."

unit_tests:
  stage: test
  needs:
    - job: "compile"        # If $COMPILE == "false", the `compile` job is not added
      optional: true        # to the pipeline and this needs is ignored.
  script: echo "Running unit tests..."

# Method 2: Job with rules that always matches the dependent job
build:
  stage: build
  rules:
    - if: $BUILD == "true"
  script: echo "Building..."

test:
  stage: test
  rules:                    # Both jobs have identical `rules`, and will always exist
    - if: $BUILD == "true"  # in the pipeline together.
  needs: ["build"]
  script: echo "Testing..."