From 5cbf24858edb03505b16474e3b7b41a49b677ff6 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 17 Oct 2023 18:10:11 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- app/models/ci/catalog/components_project.rb | 94 +++++++++++++++++++++++++++++ app/models/integrations/pushover.rb | 4 ++ app/models/ml/model.rb | 5 ++ app/models/project.rb | 1 + 4 files changed, 104 insertions(+) create mode 100644 app/models/ci/catalog/components_project.rb (limited to 'app/models') diff --git a/app/models/ci/catalog/components_project.rb b/app/models/ci/catalog/components_project.rb new file mode 100644 index 00000000000..2bc33a6f050 --- /dev/null +++ b/app/models/ci/catalog/components_project.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module Ci + module Catalog + class ComponentsProject + # ComponentsProject is a type of Catalog Resource which contains one or more + # CI/CD components. + # It is responsible for retrieving the data of a component file, including the content, name, and file path. + + TEMPLATE_FILE = 'template.yml' + TEMPLATES_DIR = 'templates' + TEMPLATE_PATH_REGEX = '^templates\/\w+\-?\w+(?:\/template)?\.yml$' + + ComponentData = Struct.new(:content, :path, keyword_init: true) + + def initialize(project, sha = project&.default_branch) + @project = project + @sha = sha + end + + def fetch_component_paths(sha) + project.repository.search_files_by_regexp(TEMPLATE_PATH_REGEX, sha) + end + + def extract_component_name(path) + return unless path.match?(TEMPLATE_PATH_REGEX) + + dirname = File.dirname(path) + filename = File.basename(path, '.*') + + if dirname == TEMPLATES_DIR + filename + else + File.basename(dirname) + end + end + + def extract_inputs(blob) + result = Gitlab::Ci::Config::Yaml::Loader.new(blob).load_uninterpolated_yaml + + raise result.error_class, result.error unless result.valid? + + result.inputs + end + + def fetch_component(component_name) + path = simple_template_path(component_name) + content = fetch_content(path) + + if content.nil? + path = complex_template_path(component_name) + content = fetch_content(path) + end + + if content.nil? + path = legacy_template_path(component_name) + content = fetch_content(path) + end + + ComponentData.new(content: content, path: path) + end + + private + + attr_reader :project, :sha + + def fetch_content(component_path) + project.repository.blob_data_at(sha, component_path) + end + + # A simple template consists of a single file + def simple_template_path(component_name) + # TODO: Extract this line and move to fetch_content once we remove legacy fetching + return unless component_name.index('/').nil? + + File.join(TEMPLATES_DIR, "#{component_name}.yml") + end + + # A complex template is directory-based and may consist of multiple files. + # Given a path like "my-org/sub-group/the-project/templates/component" + # returns the entry point path: "templates/component/template.yml". + def complex_template_path(component_name) + # TODO: Extract this line and move to fetch_content once we remove legacy fetching + return unless component_name.index('/').nil? + + File.join(TEMPLATES_DIR, component_name, TEMPLATE_FILE) + end + + def legacy_template_path(component_name) + File.join(component_name, TEMPLATE_FILE).delete_prefix('/') + end + end + end +end diff --git a/app/models/integrations/pushover.rb b/app/models/integrations/pushover.rb index e97c7e5e738..2feae29f627 100644 --- a/app/models/integrations/pushover.rb +++ b/app/models/integrations/pushover.rb @@ -125,5 +125,9 @@ module Integrations Gitlab::HTTP.post('/messages.json', base_uri: BASE_URI, body: pushover_data) end + + def avatar_url + ActionController::Base.helpers.image_path('illustrations/third-party-logos/integrations-logos/pushover.svg') + end end end diff --git a/app/models/ml/model.rb b/app/models/ml/model.rb index 0680bb0d381..27f03ed5857 100644 --- a/app/models/ml/model.rb +++ b/app/models/ml/model.rb @@ -19,6 +19,11 @@ module Ml has_one :latest_version, -> { latest_by_model }, class_name: 'Ml::ModelVersion', inverse_of: :model scope :including_latest_version, -> { includes(:latest_version) } + scope :with_version_count, -> { + left_outer_joins(:versions) + .select("ml_models.*, count(ml_model_versions.id) as version_count") + .group(:id) + } scope :by_project, ->(project) { where(project_id: project.id) } def valid_default_experiment? diff --git a/app/models/project.rb b/app/models/project.rb index 6c12c85d45d..fd226d23e77 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -753,6 +753,7 @@ class Project < ApplicationRecord scope :service_desk_enabled, -> { where(service_desk_enabled: true) } scope :with_builds_enabled, -> { with_feature_enabled(:builds) } scope :with_issues_enabled, -> { with_feature_enabled(:issues) } + scope :with_package_registry_enabled, -> { with_feature_enabled(:package_registry) } scope :with_issues_available_for_user, ->(current_user) { with_feature_available_for_user(:issues, current_user) } scope :with_merge_requests_available_for_user, ->(current_user) { with_feature_available_for_user(:merge_requests, current_user) } scope :with_issues_or_mrs_available_for_user, -> (user) do -- cgit v1.2.3