Skip to content

Ignore invalid project CI with pipeline execution policy using the `override_project_ci` strategy

Summary

With a pipeline execution policy using the override_project_ci strategy, the project CI should be ignored. However if the project has an invalid CI/CD configuration, it is not possible to start a pipeline.

Steps to reproduce

  1. Create a group
  2. Create a project in the group
  3. Add a simple CI file to the project.
    # polici-ci.yml
    build1:
      stage: .pipeline-policy-pre
      script:
        - echo "Do your build here"
  4. Go back to the group.
  5. On the projects left sidebar, select Security & Compliance and Policies.
  6. Select New Policy
  7. Select Pipeline execution policy
  8. Choose a name for the policy
  9. In the Actions section choose Override and select the project and polici-ci.yml file you created in step 2. and 3.
  10. Select Update via Merge Request.
  11. Merge the MR.
  12. Go back to the group.
  13. Create a new project
  14. Add an invalid .gitlab-ci.yml file to the project. For example:
    test1:
      stage: non-existing-stage
      script:
        - echo "Do a test here"
  15. Go to Build and Pipelines.
  16. There should be a failed pipeline with the yaml invalid label

Implementation plan

This implementation plan is based on !159124 (merged).

We can pass a flag to sources that indicates if there are any overriding pipeline execution policies. If this is the case, we can ignore project CI/CD configs.

diff --git a/lib/gitlab/ci/pipeline/chain/config/content.rb b/lib/gitlab/ci/pipeline/chain/config/content.rb
index 0f5f72e449ba..ec0fdca00c74 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content.rb
@@ -34,10 +34,17 @@ def pipeline_config
                   pipeline_source: @command.source, pipeline_source_bridge: @command.bridge,
                   triggered_for_branch: @pipeline.branch?,
                   ref: @pipeline.ref,
-                  has_pipeline_execution_policies: @command.pipeline_execution_policies.present?
+                  has_pipeline_execution_policies: @command.pipeline_execution_policies.present?,
+                  has_overriding_pep: has_overriding_pep?
                 )
               end
             end
+
+            def has_overriding_pep?
+              return unless @command.pipeline_execution_policies.present?
+
+              !!@command.pipeline_execution_policies.any?(&:strategy_override_project_ci?)
+            end
           end
         end
       end
diff --git a/lib/gitlab/ci/project_config.rb b/lib/gitlab/ci/project_config.rb
index dd00c2b25424..ac03bb969a05 100644
--- a/lib/gitlab/ci/project_config.rb
+++ b/lib/gitlab/ci/project_config.rb
@@ -29,7 +29,7 @@ class ProjectConfig
 
       def initialize(
         project:, sha:, custom_content: nil, pipeline_source: nil, pipeline_source_bridge: nil,
-        triggered_for_branch: nil, ref: nil, has_pipeline_execution_policies: nil)
+        triggered_for_branch: nil, ref: nil, has_pipeline_execution_policies: nil, has_overriding_pep: nil)
         @config = nil
 
         sources.each do |source|
@@ -40,7 +40,9 @@ def initialize(
             pipeline_source_bridge: pipeline_source_bridge,
             triggered_for_branch: triggered_for_branch,
             ref: ref,
-            has_pipeline_execution_policies: has_pipeline_execution_policies)
+            has_pipeline_execution_policies: has_pipeline_execution_policies,
+            has_overriding_pep: has_overriding_pep
+          )
 
           if source_config.exists?
             @config = source_config
diff --git a/lib/gitlab/ci/project_config/repository.rb b/lib/gitlab/ci/project_config/repository.rb
index 0b250abb9e03..c83288d9954c 100644
--- a/lib/gitlab/ci/project_config/repository.rb
+++ b/lib/gitlab/ci/project_config/repository.rb
@@ -7,6 +7,8 @@ class Repository < Source
         extend ::Gitlab::Utils::Override
 
         def content
+          return if @has_overriding_pep
+
           strong_memoize(:content) do
             next unless file_in_repository?
 
diff --git a/lib/gitlab/ci/project_config/source.rb b/lib/gitlab/ci/project_config/source.rb
index 1b3c565d47f4..f12e2872ffbc 100644
--- a/lib/gitlab/ci/project_config/source.rb
+++ b/lib/gitlab/ci/project_config/source.rb
@@ -8,7 +8,7 @@ class Source
 
         def initialize(
           project:, sha:, custom_content: nil, pipeline_source: nil, pipeline_source_bridge: nil,
-          triggered_for_branch: false, ref: nil, has_pipeline_execution_policies: nil)
+          triggered_for_branch: false, ref: nil, has_pipeline_execution_policies: nil, has_overriding_pep: nil)
           @project = project
           @sha = sha
           @custom_content = custom_content
@@ -17,6 +17,7 @@ def initialize(
           @triggered_for_branch = triggered_for_branch
           @ref = ref
           @has_pipeline_execution_policies = has_pipeline_execution_policies
+          @has_overriding_pep = has_overriding_pep
         end
 
         def exists?
Edited by Andy Schoenen