Follow-up from "Create downstream pipeline inside same project"
The following discussion from !20930 (merged) should be addressed:
-
@dosuken123 started a discussion: (+5 comments) If we allow to pass
config_content
as an argument, I feel we should passconfig_source
as well. Or should we pass one encapsulated domain object as the argument?
we are assuming that from now on any time
Ci::CreatePipelineService
gets a content passed in as param it's always because of parent/child pipelines.
I'd say config_content
and config_source
params should be always paired. For example,
diff --git a/lib/gitlab/ci/config/content.rb b/lib/gitlab/ci/config/content.rb
new file mode 100644
index 00000000000..63dab28737b
--- /dev/null
+++ b/lib/gitlab/ci/config/content.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ class Content
+ attr_reader :project, :source, :blob
+
+ delegate_missing_to :blob
+
+ def initialize(project)
+ @project = project
+ end
+
+ def generate_for_child_pipeline(bridge:)
+ @blob = @bridge.yaml_in_upstream_for_downstream
+ @source = :parent_pipeline_source
+ end
+
+ def auto_generate(sha:)
+ if @blob = content_from_repo(sha)
+ @source = :repository_source
+ elsif @blob = content_from_auto_devops
+ @source = :auto_devops_source
+ end
+ end
+
+ private
+
+ def content_from_repo(sha)
+ return unless project
+ return unless sha
+ return unless ci_config_path
+
+ project.repository.gitlab_ci_yml_for(sha, ci_config_path)
+ rescue GRPC::NotFound, GRPC::Internal
+ nil
+ end
+
+ def content_from_auto_devops
+ return unless project&.auto_devops_enabled?
+
+ Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps').content
+ end
+
+ def ci_config_path
+ project.ci_config_path.presence || '.gitlab-ci.yml'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/chain/config/content.rb b/lib/gitlab/ci/pipeline/chain/config/content.rb
index a8cd99b8e92..bd2dfceb7b4 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content.rb
@@ -9,18 +9,18 @@ module Gitlab
include Chain::Helpers
def perform!
- return if @command.config_content
-
- if content = content_from_repo
- @command.config_content = content
- @pipeline.config_source = :repository_source
- # TODO: we should persist ci_config_path
- # @pipeline.config_path = ci_config_path
- elsif content = content_from_auto_devops
- @command.config_content = content
- @pipeline.config_source = :auto_devops_source
+ if @command.config_content
+ @pipeline.config_source = @command.config_content.source
+ return
end
+ content = Gitlab::Ci::Config::Content
+ .new(@command.project)
+ .auto_generate(sha: @pipeline.sha)
+
+ @command.config_content = content
+ @pipeline.config_source = content.source
+
unless @command.config_content
return error("Missing #{ci_config_path} file")
end
and then
def create_child_pipeline!
config_content = Gitlab::Ci::Config::Content.generate_for_child_pipeline
::Ci::CreatePipelineService...
.execute(:pipeline, ignore_skip_ci: true, config_content: config_content)
This way, it's very clear how the config blob was generated, which would leave some room for us to extend the architecture.