Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/ci/catalog/resources/versions/create_service.rb')
-rw-r--r--app/services/ci/catalog/resources/versions/create_service.rb111
1 files changed, 111 insertions, 0 deletions
diff --git a/app/services/ci/catalog/resources/versions/create_service.rb b/app/services/ci/catalog/resources/versions/create_service.rb
new file mode 100644
index 00000000000..863bad43271
--- /dev/null
+++ b/app/services/ci/catalog/resources/versions/create_service.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+module Ci
+ module Catalog
+ module Resources
+ module Versions
+ class CreateService
+ def initialize(release)
+ @project = release.project
+ @release = release
+ @errors = []
+ @version = nil
+ @components_project = Ci::Catalog::ComponentsProject.new(project)
+ end
+
+ def execute
+ build_catalog_resource_version
+ fetch_and_build_components if Feature.enabled?(:ci_catalog_create_metadata, project)
+ publish_catalog_resource!
+
+ if errors.empty?
+ ServiceResponse.success
+ else
+ ServiceResponse.error(message: errors.flatten.first(10).join(', '))
+ end
+ end
+
+ private
+
+ attr_reader :project, :errors, :release, :components_project
+
+ def build_catalog_resource_version
+ return error('Project is not a catalog resource') unless project.catalog_resource
+
+ @version = Ci::Catalog::Resources::Version.new(
+ release: release,
+ catalog_resource: project.catalog_resource,
+ project: project
+ )
+ end
+
+ def fetch_and_build_components
+ return if errors.present?
+
+ max_components = Ci::Catalog::ComponentsProject::COMPONENTS_LIMIT
+ component_paths = components_project.fetch_component_paths(release.sha, limit: max_components + 1)
+
+ if component_paths.size > max_components
+ return error("Release cannot contain more than #{max_components} components")
+ end
+
+ build_components(component_paths)
+ end
+
+ def build_components(component_paths)
+ paths_with_oids = component_paths.map { |path| [release.sha, path] }
+ blobs = project.repository.blobs_at(paths_with_oids)
+
+ blobs.each do |blob|
+ metadata = extract_metadata(blob)
+ build_catalog_resource_component(metadata)
+ end
+ rescue ::Gitlab::Config::Loader::FormatError => e
+ error(e)
+ end
+
+ def extract_metadata(blob)
+ {
+ name: components_project.extract_component_name(blob.path),
+ inputs: components_project.extract_inputs(blob.data),
+ path: blob.path
+ }
+ end
+
+ def build_catalog_resource_component(metadata)
+ return if errors.present?
+
+ component = @version.components.build(
+ name: metadata[:name],
+ project: @version.project,
+ inputs: metadata[:inputs],
+ catalog_resource: @version.catalog_resource,
+ path: metadata[:path],
+ created_at: Time.current
+ )
+
+ return if component.valid?
+
+ error("Build component error: #{component.errors.full_messages.join(', ')}")
+ end
+
+ def publish_catalog_resource!
+ return if errors.present?
+
+ ::Ci::Catalog::Resources::Version.transaction do
+ BulkInsertableAssociations.with_bulk_insert do
+ @version.save!
+ end
+
+ project.catalog_resource.publish!
+ end
+ end
+
+ def error(message)
+ errors << message
+ end
+ end
+ end
+ end
+ end
+end