diff options
Diffstat (limited to 'app/models/project.rb')
-rw-r--r-- | app/models/project.rb | 78 |
1 files changed, 59 insertions, 19 deletions
diff --git a/app/models/project.rb b/app/models/project.rb index b66ec28b659..dca47911d20 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -121,6 +121,8 @@ class Project < ApplicationRecord before_save :ensure_runners_token before_validation :ensure_project_namespace_in_sync + before_validation :set_package_registry_access_level, if: :packages_enabled_changed? + after_save :update_project_statistics, if: :saved_change_to_namespace_id? after_save :schedule_sync_event_worker, if: -> { saved_change_to_id? || saved_change_to_namespace_id? } @@ -418,6 +420,8 @@ class Project < ApplicationRecord has_one :ci_project_mirror, class_name: 'Ci::ProjectMirror' has_many :sync_events, class_name: 'Projects::SyncEvent' + has_one :build_artifacts_size_refresh, class_name: 'Projects::BuildArtifactsSizeRefresh' + accepts_nested_attributes_for :variables, allow_destroy: true accepts_nested_attributes_for :project_feature, update_only: true accepts_nested_attributes_for :project_setting, update_only: true @@ -443,7 +447,7 @@ class Project < ApplicationRecord :pages_enabled?, :analytics_enabled?, :snippets_enabled?, :public_pages?, :private_pages?, :merge_requests_access_level, :forking_access_level, :issues_access_level, :wiki_access_level, :snippets_access_level, :builds_access_level, - :repository_access_level, :pages_access_level, :metrics_dashboard_access_level, :analytics_access_level, + :repository_access_level, :package_registry_access_level, :pages_access_level, :metrics_dashboard_access_level, :analytics_access_level, :operations_enabled?, :operations_access_level, :security_and_compliance_access_level, :container_registry_access_level, :container_registry_enabled?, to: :project_feature, allow_nil: true @@ -598,6 +602,7 @@ class Project < ApplicationRecord scope :inc_routes, -> { includes(:route, namespace: :route) } scope :with_statistics, -> { includes(:statistics) } scope :with_namespace, -> { includes(:namespace) } + scope :with_group, -> { includes(:group) } scope :with_import_state, -> { includes(:import_state) } scope :include_project_feature, -> { includes(:project_feature) } scope :include_integration, -> (integration_association_name) { includes(integration_association_name) } @@ -1167,7 +1172,7 @@ class Project < ApplicationRecord job_type = type.to_s.capitalize if job_id - Gitlab::AppLogger.info("#{job_type} job scheduled for #{full_path} with job ID #{job_id}.") + Gitlab::AppLogger.info("#{job_type} job scheduled for #{full_path} with job ID #{job_id} (primary: #{::Gitlab::Database::LoadBalancing::Session.current.use_primary?}).") else Gitlab::AppLogger.error("#{job_type} job failed to create for #{full_path}.") end @@ -2161,6 +2166,7 @@ class Project < ApplicationRecord .append(key: 'CI_PROJECT_ID', value: id.to_s) .append(key: 'CI_PROJECT_NAME', value: path) .append(key: 'CI_PROJECT_TITLE', value: title) + .append(key: 'CI_PROJECT_DESCRIPTION', value: description) .append(key: 'CI_PROJECT_PATH', value: full_path) .append(key: 'CI_PROJECT_PATH_SLUG', value: full_path_slug) .append(key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path) @@ -2504,7 +2510,13 @@ class Project < ApplicationRecord end def gitlab_deploy_token - @gitlab_deploy_token ||= deploy_tokens.gitlab_deploy_token + strong_memoize(:gitlab_deploy_token) do + if Feature.enabled?(:ci_variable_for_group_gitlab_deploy_token, self) + deploy_tokens.gitlab_deploy_token || group&.gitlab_deploy_token + else + deploy_tokens.gitlab_deploy_token + end + end end def any_lfs_file_locks? @@ -2573,16 +2585,7 @@ class Project < ApplicationRecord end def access_request_approvers_to_be_notified - # 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 = members.owners_and_maintainers access_request_approvers.connected_to_user.order_recent_sign_in.limit(Member::ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT) end @@ -2900,6 +2903,14 @@ class Project < ApplicationRecord last_activity_at < ::Gitlab::CurrentSettings.inactive_projects_send_warning_email_after_months.months.ago end + def refreshing_build_artifacts_size? + build_artifacts_size_refresh&.started? + end + + def security_training_available? + licensed_feature_available?(:security_training) + end + private # overridden in EE @@ -3098,7 +3109,6 @@ class Project < ApplicationRecord # create project_namespace when project is created build_project_namespace if project_namespace_creation_enabled? - # we need to keep project and project namespace in sync if there is one sync_attributes(project_namespace) if sync_project_namespace? end @@ -3111,11 +3121,24 @@ class Project < ApplicationRecord end def sync_attributes(project_namespace) - project_namespace.name = name - project_namespace.path = path - project_namespace.parent = namespace - project_namespace.shared_runners_enabled = shared_runners_enabled - project_namespace.visibility_level = visibility_level + attributes_to_sync = changes.slice(*%w(name path namespace_id namespace visibility_level shared_runners_enabled)) + .transform_values { |val| val[1] } + + # if visibility_level is not set explicitly for project, it defaults to 0, + # but for namespace visibility_level defaults to 20, + # so it gets out of sync right away if we do not set it explicitly when creating the project namespace + attributes_to_sync['visibility_level'] ||= visibility_level if new_record? + + # when a project is associated with a group while the group is created we need to ensure we associate the new + # group with the project namespace as well. + # E.g. + # project = create(:project) <- project is saved + # create(:group, projects: [project]) <- associate project with a group that is not yet created. + if attributes_to_sync.has_key?('namespace_id') && attributes_to_sync['namespace_id'].blank? && namespace.present? + attributes_to_sync['parent'] = namespace + end + + project_namespace.assign_attributes(attributes_to_sync) end # SyncEvents are created by PG triggers (with the function `insert_projects_sync_event`) @@ -3132,6 +3155,23 @@ class Project < ApplicationRecord raise ExportLimitExceeded, _('The project size exceeds the export limit.') end end + + def set_package_registry_access_level + return if !project_feature || project_feature.package_registry_access_level_changed? + + self.project_feature.package_registry_access_level = packages_enabled ? enabled_package_registry_access_level_by_project_visibility : ProjectFeature::DISABLED + end + + def enabled_package_registry_access_level_by_project_visibility + case visibility_level + when PUBLIC + ProjectFeature::PUBLIC + when INTERNAL + ProjectFeature::ENABLED + else + ProjectFeature::PRIVATE + end + end end Project.prepend_mod_with('Project') |