diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md index 6d34a3034f71fa1047feeaa83d3d6cea2599ebd6..252cef0aa97772e54744b651ab711274986e6962 100644 --- a/doc/ci/yaml/includes.md +++ b/doc/ci/yaml/includes.md @@ -405,7 +405,8 @@ see this [CI/CD variable demo](https://youtu.be/4XR8gw3Pkos). > - Introduced in GitLab 14.2 [with a flag](../../administration/feature_flags.md) named `ci_include_rules`. Disabled by default. > - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3. > - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.4. Feature flag `ci_include_rules` removed. -> - [Support for `exists` keyword added](https://gitlab.com/gitlab-org/gitlab/-/issues/341511) in GitLab 14.5. +> - Support for `exists` keyword [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/341511) in GitLab 14.5. +> - Support for `needs` job dependency [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345377) in GitLab 15.11. You can use [`rules`](index.md#rules) with `include` to conditionally include other configuration files. @@ -415,11 +416,6 @@ these keywords: - [`rules:if`](index.md#rulesif). - [`rules:exists`](index.md#rulesexists). -You cannot use [`needs:`](index.md#needs) to create a job dependency that points to -a job added with `include:local:rules`. When the configuration is validated, -GitLab returns `undefined need: `. [Issue 345377](https://gitlab.com/gitlab-org/gitlab/-/issues/345377) -proposes improving this behavior. - ### `include` with `rules:if` Use [`rules:if`](index.md#rulesif) to conditionally include other configuration files diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index 01173f43c2e71efca1750ea85c46a1a55c2232b7..82d333b8136fe83d90d97798303313ab5f8cec53 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -2556,11 +2556,10 @@ can use that variable in `needs:pipeline` to download artifacts from the parent To need a job that sometimes does not exist in the pipeline, add `optional: true` to the `needs` configuration. If not defined, `optional: false` is the default. -Jobs that use [`rules`](#rules), [`only`, or `except`](#only--except) might not always -be added to a pipeline. GitLab checks the `needs` relationships before starting a -pipeline: +Jobs that use [`rules`](#rules), [`only`, or `except`](#only--except) and that are added with [`include`](#include) +might not always be added to a pipeline. GitLab checks the `needs` relationships before starting a pipeline: -- If the needs entry has `optional: true` and the needed job is present in the pipeline, +- If the `needs` entry has `optional: true` and the needed job is present in the pipeline, the job waits for it to complete before starting. - If the needed job is not present, the job can start when all other needs requirements are met. - If the `needs` section contains only optional jobs, and none are added to the pipeline, diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb index 59acfa802589d2fdab4df6afce0c858ec1999202..255bb4dc0dc5e4555ae69ec02eb9c4a08e0de070 100644 --- a/lib/gitlab/ci/yaml_processor.rb +++ b/lib/gitlab/ci/yaml_processor.rb @@ -99,7 +99,7 @@ def validate_job_needs!(name, job) validate_duplicate_needs!(name, needs) needs.each do |need| - validate_job_dependency!(name, need[:name], 'need') + validate_job_dependency!(name, need[:name], 'need', optional: need[:optional]) end end @@ -109,8 +109,11 @@ def validate_duplicate_needs!(name, needs) end end - def validate_job_dependency!(name, dependency, dependency_type = 'dependency') + def validate_job_dependency!(name, dependency, dependency_type = 'dependency', optional: false) unless @jobs[dependency.to_sym] + # Here, we ignore the optional needed job if it is not included in the result YAML. + return if optional + error!("#{name} job: undefined #{dependency_type}: #{dependency}") end diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb index b00d9b46bc7f2938b58719093b7c92a6bdbeb14e..d7dcfe64c748d1cee41eecf88c847fd802c7f0e5 100644 --- a/spec/lib/gitlab/ci/yaml_processor_spec.rb +++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb @@ -2395,10 +2395,16 @@ module Ci end end - context 'undefined need' do + context 'when need is an undefined job' do let(:needs) { ['undefined'] } it_behaves_like 'returns errors', 'test1 job: undefined need: undefined' + + context 'when need is optional' do + let(:needs) { [{ job: 'undefined', optional: true }] } + + it { is_expected.to be_valid } + end end context 'needs to deploy' do