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/models/project.rb')
-rw-r--r--app/models/project.rb90
1 files changed, 46 insertions, 44 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index c5522737b87..81b04e1316c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -43,8 +43,13 @@ class Project < ApplicationRecord
extend Gitlab::ConfigHelper
+ ignore_columns :container_registry_enabled, remove_after: '2021-09-22', remove_with: '14.4'
+
BoardLimitExceeded = Class.new(StandardError)
+ ignore_columns :mirror_last_update_at, :mirror_last_successful_update_at, remove_after: '2021-09-22', remove_with: '14.4'
+ ignore_columns :pull_mirror_branch_prefix, remove_after: '2021-09-22', remove_with: '14.4'
+
STATISTICS_ATTRIBUTE = 'repositories_count'
UNKNOWN_IMPORT_URL = 'http://unknown.git'
# Hashed Storage versions handle rolling out new storage to project and dependents models:
@@ -73,7 +78,6 @@ class Project < ApplicationRecord
default_value_for :packages_enabled, true
default_value_for :archived, false
default_value_for :resolve_outdated_diff_discussions, false
- default_value_for :container_registry_enabled, gitlab_config_features.container_registry
default_value_for(:repository_storage) do
Repository.pick_storage_shard
end
@@ -95,9 +99,6 @@ class Project < ApplicationRecord
before_save :ensure_runners_token
- # https://api.rubyonrails.org/v6.0.3.4/classes/ActiveRecord/AttributeMethods/Dirty.html#method-i-will_save_change_to_attribute-3F
- before_update :set_container_registry_access_level, if: :will_save_change_to_container_registry_enabled?
-
after_save :update_project_statistics, if: :saved_change_to_namespace_id?
after_save :create_import_state, if: ->(project) { project.import? && project.import_state.nil? }
@@ -318,7 +319,6 @@ class Project < ApplicationRecord
# still using `dependent: :destroy` here.
has_many :builds, class_name: 'Ci::Build', inverse_of: :project, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :processables, class_name: 'Ci::Processable', inverse_of: :project
- has_many :build_trace_section_names, class_name: 'Ci::BuildTraceSectionName'
has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
has_many :build_report_results, class_name: 'Ci::BuildReportResult', inverse_of: :project
has_many :job_artifacts, class_name: 'Ci::JobArtifact'
@@ -378,6 +378,7 @@ class Project < ApplicationRecord
has_many :operations_feature_flags_user_lists, class_name: 'Operations::FeatureFlags::UserList'
has_many :error_tracking_errors, inverse_of: :project, class_name: 'ErrorTracking::Error'
+ has_many :error_tracking_client_keys, inverse_of: :project, class_name: 'ErrorTracking::ClientKey'
has_many :timelogs
@@ -436,7 +437,7 @@ class Project < ApplicationRecord
delegate :restrict_user_defined_variables, :restrict_user_defined_variables=, to: :ci_cd_settings, allow_nil: true
delegate :actual_limits, :actual_plan_name, to: :namespace, allow_nil: true
delegate :allow_merge_on_skipped_pipeline, :allow_merge_on_skipped_pipeline?,
- :allow_merge_on_skipped_pipeline=, :has_confluence?, :allow_editing_commit_messages?,
+ :allow_merge_on_skipped_pipeline=, :has_confluence?,
to: :project_setting
delegate :active?, to: :prometheus_integration, allow_nil: true, prefix: true
@@ -538,10 +539,8 @@ class Project < ApplicationRecord
scope :visible_to_user_and_access_level, ->(user, access_level) { where(id: user.authorized_projects.where('project_authorizations.access_level >= ?', access_level).select(:id).reorder(nil)) }
scope :archived, -> { where(archived: true) }
scope :non_archived, -> { where(archived: false) }
- scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct }
scope :with_push, -> { joins(:events).merge(Event.pushed_action) }
scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') }
- scope :with_active_jira_integrations, -> { joins(:integrations).merge(::Integrations::Jira.active) }
scope :with_jira_dvcs_cloud, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: true)) }
scope :with_jira_dvcs_server, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) }
scope :inc_routes, -> { includes(:route, namespace: :route) }
@@ -549,7 +548,9 @@ class Project < ApplicationRecord
scope :with_namespace, -> { includes(:namespace) }
scope :with_import_state, -> { includes(:import_state) }
scope :include_project_feature, -> { includes(:project_feature) }
- scope :with_integration, ->(integration) { joins(integration).eager_load(integration) }
+ scope :include_integration, -> (integration_association_name) { includes(integration_association_name) }
+ scope :with_integration, -> (integration_class) { joins(:integrations).merge(integration_class.all) }
+ scope :with_active_integration, -> (integration_class) { with_integration(integration_class).merge(integration_class.active) }
scope :with_shared_runners, -> { where(shared_runners_enabled: true) }
scope :inside_path, ->(path) do
# We need routes alias rs for JOIN so it does not conflict with
@@ -913,7 +914,13 @@ class Project < ApplicationRecord
.base_and_ancestors(upto: top, hierarchy_order: hierarchy_order)
end
- alias_method :ancestors, :ancestors_upto
+ def ancestors(hierarchy_order: nil)
+ if Feature.enabled?(:linear_project_ancestors, self, default_enabled: :yaml)
+ group&.self_and_ancestors(hierarchy_order: hierarchy_order) || Group.none
+ else
+ ancestors_upto(hierarchy_order: hierarchy_order)
+ end
+ end
def ancestors_upto_ids(...)
ancestors_upto(...).pluck(:id)
@@ -1180,6 +1187,15 @@ class Project < ApplicationRecord
import_type == 'gitea'
end
+ def github_import?
+ import_type == 'github'
+ end
+
+ def github_enterprise_import?
+ github_import? &&
+ URI.parse(import_url).host != URI.parse(Octokit::Default::API_ENDPOINT).host
+ end
+
def has_remote_mirror?
remote_mirror_available? && remote_mirrors.enabled.exists?
end
@@ -1411,14 +1427,13 @@ class Project < ApplicationRecord
def find_or_initialize_integration(name)
return if disabled_integrations.include?(name)
- find_integration(integrations, name) || build_from_instance_or_template(name) || build_integration(name)
+ find_integration(integrations, name) || build_from_instance(name) || build_integration(name)
end
# rubocop: disable CodeReuse/ServiceClass
def create_labels
Label.templates.each do |label|
- # TODO: remove_on_close exception can be removed after the column is dropped from all envs
- params = label.attributes.except('id', 'template', 'created_at', 'updated_at', 'type', 'remove_on_close')
+ params = label.attributes.except('id', 'template', 'created_at', 'updated_at', 'type')
Labels::FindOrCreateService.new(nil, self, params).execute(skip_authorization: true)
end
end
@@ -1876,11 +1891,11 @@ class Project < ApplicationRecord
.update_all(deployed: deployment.present?, pages_deployment_id: deployment&.id)
end
- def write_repository_config(gl_full_path: full_path)
+ def set_full_path(gl_full_path: full_path)
# We'd need to keep track of project full path otherwise directory tree
# created with hashed storage enabled cannot be usefully imported using
# the import rake task.
- repository.raw_repository.write_config(full_path: gl_full_path)
+ repository.raw_repository.set_full_path(full_path: gl_full_path)
rescue Gitlab::Git::Repository::NoRepository => e
Gitlab::AppLogger.error("Error writing to .git/config for project #{full_path} (#{id}): #{e.message}.")
nil
@@ -1892,6 +1907,7 @@ class Project < ApplicationRecord
DetectRepositoryLanguagesWorker.perform_async(id)
ProjectCacheWorker.perform_async(self.id, [], [:repository_size])
+ AuthorizedProjectUpdate::ProjectRecalculateWorker.perform_async(id)
# The import assigns iid values on its own, e.g. by re-using GitHub ids.
# Flush existing InternalId records for this project for consistency reasons.
@@ -1904,7 +1920,7 @@ class Project < ApplicationRecord
after_create_default_branch
join_pool_repository
refresh_markdown_cache!
- write_repository_config
+ set_full_path
end
def update_project_counter_caches
@@ -2030,6 +2046,7 @@ class Project < ApplicationRecord
.append(key: 'CI_PROJECT_URL', value: web_url)
.append(key: 'CI_PROJECT_VISIBILITY', value: Gitlab::VisibilityLevel.string_level(visibility_level))
.append(key: 'CI_PROJECT_REPOSITORY_LANGUAGES', value: repository_languages.map(&:name).join(',').downcase)
+ .append(key: 'CI_PROJECT_CLASSIFICATION_LABEL', value: external_authorization_classification_label)
.append(key: 'CI_DEFAULT_BRANCH', value: default_branch)
.append(key: 'CI_CONFIG_PATH', value: ci_config_path_or_default)
end
@@ -2557,12 +2574,15 @@ class Project < ApplicationRecord
[project&.id, root_group&.id]
end
- def package_already_taken?(package_name)
- namespace.root_ancestor.all_projects
- .joins(:packages)
- .where.not(id: id)
- .merge(Packages::Package.default_scoped.with_name(package_name))
- .exists?
+ def package_already_taken?(package_name, package_version, package_type:)
+ Packages::Package.with_name(package_name)
+ .with_version(package_version)
+ .with_package_type(package_type)
+ .for_projects(
+ root_ancestor.all_projects
+ .id_not_in(id)
+ .select(:id)
+ ).exists?
end
def default_branch_or_main
@@ -2651,40 +2671,22 @@ class Project < ApplicationRecord
private
- def set_container_registry_access_level
- # changes_to_save = { 'container_registry_enabled' => [value_before_update, value_after_update] }
- value = changes_to_save['container_registry_enabled'][1]
-
- access_level =
- if value
- ProjectFeature::ENABLED
- else
- ProjectFeature::DISABLED
- end
-
- project_feature.update!(container_registry_access_level: access_level)
- end
-
def find_integration(integrations, name)
integrations.find { _1.to_param == name }
end
- def build_from_instance_or_template(name)
+ def build_from_instance(name)
instance = find_integration(integration_instances, name)
- return Integration.build_from_integration(instance, project_id: id) if instance
- template = find_integration(integration_templates, name)
- return Integration.build_from_integration(template, project_id: id) if template
+ return unless instance
+
+ Integration.build_from_integration(instance, project_id: id)
end
def build_integration(name)
Integration.integration_name_to_model(name).new(project_id: id)
end
- def integration_templates
- @integration_templates ||= Integration.for_template
- end
-
def integration_instances
@integration_instances ||= Integration.for_instance
end