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.rb79
1 files changed, 46 insertions, 33 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index f89e616a5ca..155ebe88d33 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -38,7 +38,7 @@ class Project < ApplicationRecord
include GitlabRoutingHelper
include BulkMemberAccessLoad
include RunnerTokenExpirationInterval
- include RunnersTokenPrefixable
+ include BlocksUnsafeSerialization
extend Gitlab::Cache::RequestCache
extend Gitlab::Utils::Override
@@ -196,6 +196,7 @@ class Project < ApplicationRecord
has_one :external_wiki_integration, class_name: 'Integrations::ExternalWiki'
has_one :flowdock_integration, class_name: 'Integrations::Flowdock'
has_one :hangouts_chat_integration, class_name: 'Integrations::HangoutsChat'
+ has_one :harbor_integration, class_name: 'Integrations::Harbor'
has_one :irker_integration, class_name: 'Integrations::Irker'
has_one :jenkins_integration, class_name: 'Integrations::Jenkins'
has_one :jira_integration, class_name: 'Integrations::Jira'
@@ -344,22 +345,18 @@ class Project < ApplicationRecord
has_many :stages, class_name: 'Ci::Stage', inverse_of: :project
has_many :ci_refs, class_name: 'Ci::Ref', inverse_of: :project
- # Ci::Build objects store data on the file system such as artifact files and
- # build traces. Currently there's no efficient way of removing this data in
- # bulk that doesn't involve loading the rows into memory. As a result we're
- # still using `dependent: :destroy` here.
has_many :pending_builds, class_name: 'Ci::PendingBuild'
- has_many :builds, class_name: 'Ci::Build', inverse_of: :project, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ has_many :builds, class_name: 'Ci::Build', inverse_of: :project
has_many :processables, class_name: 'Ci::Processable', inverse_of: :project
- has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
+ has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks, dependent: :restrict_with_error
has_many :build_report_results, class_name: 'Ci::BuildReportResult', inverse_of: :project
- has_many :job_artifacts, class_name: 'Ci::JobArtifact'
- has_many :pipeline_artifacts, class_name: 'Ci::PipelineArtifact', inverse_of: :project
+ has_many :job_artifacts, class_name: 'Ci::JobArtifact', dependent: :restrict_with_error
+ has_many :pipeline_artifacts, class_name: 'Ci::PipelineArtifact', inverse_of: :project, dependent: :restrict_with_error
has_many :runner_projects, class_name: 'Ci::RunnerProject', inverse_of: :project
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
has_many :variables, class_name: 'Ci::Variable'
has_many :triggers, class_name: 'Ci::Trigger'
- has_many :secure_files, class_name: 'Ci::SecureFile'
+ has_many :secure_files, class_name: 'Ci::SecureFile', dependent: :restrict_with_error
has_many :environments
has_many :environments_for_dashboard, -> { from(with_rank.unfoldered.available, :environments).where('rank <= 3') }, class_name: 'Environment'
has_many :deployments
@@ -462,7 +459,7 @@ class Project < ApplicationRecord
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
delegate :add_user, :add_users, to: :team
- delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_role, to: :team
+ delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_owner, :add_role, to: :team
delegate :group_runners_enabled, :group_runners_enabled=, to: :ci_cd_settings, allow_nil: true
delegate :root_ancestor, to: :namespace, allow_nil: true
delegate :last_pipeline, to: :commit, allow_nil: true
@@ -501,11 +498,15 @@ class Project < ApplicationRecord
presence: true,
project_path: true,
length: { maximum: 255 }
+ validates :path,
+ format: { with: Gitlab::Regex.oci_repository_path_regex,
+ message: Gitlab::Regex.oci_repository_path_regex_message },
+ if: :path_changed?
validates :project_feature, presence: true
validates :namespace, presence: true
- validates :project_namespace, presence: true, on: :create, if: -> { self.namespace && self.root_namespace.project_namespace_creation_enabled? }
+ validates :project_namespace, presence: true, on: :create, if: -> { self.namespace }
validates :project_namespace, presence: true, on: :update, if: -> { self.project_namespace_id_changed?(to: nil) }
validates :name, uniqueness: { scope: :namespace_id }
validates :import_url, public_url: { schemes: ->(project) { project.persisted? ? VALID_MIRROR_PROTOCOLS : VALID_IMPORT_PROTOCOLS },
@@ -529,6 +530,7 @@ class Project < ApplicationRecord
# Scopes
scope :pending_delete, -> { where(pending_delete: true) }
scope :without_deleted, -> { where(pending_delete: false) }
+ scope :not_hidden, -> { where(hidden: false) }
scope :not_aimed_for_deletion, -> { where(marked_for_deletion_at: nil).without_deleted }
scope :with_storage_feature, ->(feature) do
@@ -1006,10 +1008,6 @@ class Project < ApplicationRecord
Feature.enabled?(:unlink_fork_network_upon_visibility_decrease, self, default_enabled: true)
end
- def context_commits_enabled?
- Feature.enabled?(:context_commits, self.group, default_enabled: :yaml)
- end
-
# LFS and hashed repository storage are required for using Design Management.
def design_management_enabled?
lfs_enabled? && hashed_storage?(:repository)
@@ -1565,14 +1563,17 @@ class Project < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def execute_hooks(data, hooks_scope = :push_hooks)
run_after_commit_or_now do
- hooks.hooks_for(hooks_scope).select_active(hooks_scope, data).each do |hook|
- hook.async_execute(data, hooks_scope.to_s)
- end
+ triggered_hooks(hooks_scope, data).execute
SystemHooksService.new.execute_hooks(data, hooks_scope)
end
end
# rubocop: enable CodeReuse/ServiceClass
+ def triggered_hooks(hooks_scope, data)
+ triggered = ::Projects::TriggeredHooks.new(hooks_scope, data)
+ triggered.add_hooks(hooks)
+ end
+
def execute_integrations(data, hooks_scope = :push_hooks)
# Call only service hooks that are active for this scope
run_after_commit_or_now do
@@ -1876,13 +1877,9 @@ class Project < ApplicationRecord
ensure_runners_token!
end
- def runners_token_prefix
- RUNNERS_TOKEN_PREFIX
- end
-
override :format_runners_token
def format_runners_token(token)
- "#{runners_token_prefix}#{token}"
+ "#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}#{token}"
end
def pages_deployed?
@@ -1938,12 +1935,12 @@ class Project < ApplicationRecord
.delete_all
end
- def mark_pages_as_deployed(artifacts_archive: nil)
- ensure_pages_metadatum.update!(deployed: true, artifacts_archive: artifacts_archive)
+ def mark_pages_as_deployed
+ ensure_pages_metadatum.update!(deployed: true)
end
def mark_pages_as_not_deployed
- ensure_pages_metadatum.update!(deployed: false, artifacts_archive: nil, pages_deployment: nil)
+ ensure_pages_metadatum.update!(deployed: false)
end
def update_pages_deployment!(deployment)
@@ -2521,7 +2518,18 @@ class Project < ApplicationRecord
end
def access_request_approvers_to_be_notified
- members.maintainers.connected_to_user.order_recent_sign_in.limit(Member::ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT)
+ # For a personal project:
+ # The creator is added as a member with `Owner` access level, starting from GitLab 14.8
+ # The creator was added as a member with `Maintainer` access level, before GitLab 14.8
+ # So, to make sure access requests for all personal projects work as expected,
+ # we need to filter members with the scope `owners_and_maintainers`.
+ access_request_approvers = if personal?
+ members.owners_and_maintainers
+ else
+ members.maintainers
+ end
+
+ access_request_approvers.connected_to_user.order_recent_sign_in.limit(Member::ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT)
end
def pages_lookup_path(trim_prefix: nil, domain: nil)
@@ -2817,6 +2825,10 @@ class Project < ApplicationRecord
end
end
+ def pending_delete_or_hidden?
+ pending_delete? || hidden?
+ end
+
private
# overridden in EE
@@ -2838,7 +2850,9 @@ class Project < ApplicationRecord
if @topic_list != self.topic_list
self.topics.delete_all
- self.topics = @topic_list.map { |topic| Projects::Topic.find_or_create_by(name: topic) }
+ self.topics = @topic_list.map do |topic|
+ Projects::Topic.where('lower(name) = ?', topic.downcase).order(total_projects_count: :desc).first_or_create(name: topic)
+ end
end
@topic_list = nil
@@ -3010,16 +3024,15 @@ class Project < ApplicationRecord
end
def ensure_project_namespace_in_sync
- # create project_namespace when project is created if create_project_namespace_on_project_create FF is enabled
+ # create project_namespace when project is created
build_project_namespace if project_namespace_creation_enabled?
- # regardless of create_project_namespace_on_project_create FF we need
- # to keep project and project namespace in sync if there is one
+ # we need to keep project and project namespace in sync if there is one
sync_attributes(project_namespace) if sync_project_namespace?
end
def project_namespace_creation_enabled?
- new_record? && !project_namespace && self.namespace && self.root_namespace.project_namespace_creation_enabled?
+ new_record? && !project_namespace && self.namespace
end
def sync_project_namespace?