summaryrefslogtreecommitdiff
path: root/app/models/project.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/project.rb')
-rw-r--r--app/models/project.rb68
1 files changed, 60 insertions, 8 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index 155ebe88d33..f7182d1645c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -37,6 +37,7 @@ class Project < ApplicationRecord
include EachBatch
include GitlabRoutingHelper
include BulkMemberAccessLoad
+ include BulkUsersByEmailLoad
include RunnerTokenExpirationInterval
include BlocksUnsafeSerialization
@@ -382,7 +383,7 @@ class Project < ApplicationRecord
has_many :source_pipelines, class_name: 'Ci::Sources::Pipeline', foreign_key: :project_id
has_many :import_failures, inverse_of: :project
- has_many :jira_imports, -> { order 'jira_imports.created_at' }, class_name: 'JiraImportState', inverse_of: :project
+ has_many :jira_imports, -> { order(JiraImportState.arel_table[:created_at].asc) }, class_name: 'JiraImportState', inverse_of: :project
has_many :daily_build_group_report_results, class_name: 'Ci::DailyBuildGroupReportResult'
has_many :ci_feature_usages, class_name: 'Projects::CiFeatureUsage'
@@ -545,8 +546,8 @@ class Project < ApplicationRecord
.or(arel_table[:storage_version].eq(nil)))
end
- # last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push
- scope :sorted_by_activity, -> { reorder(Arel.sql("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC")) }
+ scope :sorted_by_updated_asc, -> { reorder(self.arel_table['updated_at'].asc) }
+ scope :sorted_by_updated_desc, -> { reorder(self.arel_table['updated_at'].desc) }
scope :sorted_by_stars_desc, -> { reorder(self.arel_table['star_count'].desc) }
scope :sorted_by_stars_asc, -> { reorder(self.arel_table['star_count'].asc) }
# Sometimes queries (e.g. using CTEs) require explicit disambiguation with table name
@@ -655,7 +656,9 @@ class Project < ApplicationRecord
preload(:project_feature, :route, namespace: [:route, :owner])
}
+ scope :created_by, -> (user) { where(creator: user) }
scope :imported_from, -> (type) { where(import_type: type) }
+ scope :imported, -> { where.not(import_type: nil) }
scope :with_tracing_enabled, -> { joins(:tracing_setting) }
scope :with_enabled_error_tracking, -> { joins(:error_tracking_setting).where(project_error_tracking_settings: { enabled: true }) }
@@ -780,9 +783,9 @@ class Project < ApplicationRecord
# pass a string to avoid AR adding the table name
reorder('project_statistics.storage_size DESC, projects.id DESC')
when 'latest_activity_desc'
- reorder(self.arel_table['last_activity_at'].desc)
+ sorted_by_updated_desc
when 'latest_activity_asc'
- reorder(self.arel_table['last_activity_at'].asc)
+ sorted_by_updated_asc
when 'stars_desc'
sorted_by_stars_desc
when 'stars_asc'
@@ -896,6 +899,18 @@ class Project < ApplicationRecord
association(:namespace).loaded?
end
+ def personal_namespace_holder?(user)
+ return false unless personal?
+ return false unless user
+
+ # We do not want to use a check like `project.team.owner?(user)`
+ # here because that would depend upon the state of the `project_authorizations` cache,
+ # and also perform the check across multiple `owners` of the project, but our intention
+ # is to check if the user is the "holder" of the personal namespace, so need to make this
+ # check against only a single user (ie, namespace.owner).
+ namespace.owner == user
+ end
+
def project_setting
super.presence || build_project_setting
end
@@ -1048,6 +1063,17 @@ class Project < ApplicationRecord
end
end
+ def container_repositories_size
+ strong_memoize(:container_repositories_size) do
+ next unless Gitlab.com?
+ next 0 if container_repositories.empty?
+ next unless container_repositories.all_migrated?
+ next unless ContainerRegistry::GitlabApiClient.supports_gitlab_api?
+
+ ContainerRegistry::GitlabApiClient.deduplicated_size(full_path)
+ end
+ end
+
def has_container_registry_tags?
return @images if defined?(@images)
@@ -1401,7 +1427,7 @@ class Project < ApplicationRecord
end
def last_activity_date
- [last_activity_at, last_repository_updated_at, updated_at].compact.max
+ updated_at
end
def project_id
@@ -1469,7 +1495,7 @@ class Project < ApplicationRecord
end
def find_or_initialize_integration(name)
- return if disabled_integrations.include?(name)
+ return if disabled_integrations.include?(name) || Integration.available_integration_names.exclude?(name)
find_integration(integrations, name) || build_from_instance(name) || build_integration(name)
end
@@ -1920,6 +1946,10 @@ class Project < ApplicationRecord
Gitlab.config.pages.enabled
end
+ def pages_show_onboarding?
+ !(pages_metadatum&.onboarding_complete || pages_metadatum&.deployed)
+ end
+
def remove_private_deploy_keys
exclude_keys_linked_to_other_projects = <<-SQL
NOT EXISTS (
@@ -1935,6 +1965,10 @@ class Project < ApplicationRecord
.delete_all
end
+ def mark_pages_onboarding_complete
+ ensure_pages_metadatum.update!(onboarding_complete: true)
+ end
+
def mark_pages_as_deployed
ensure_pages_metadatum.update!(deployed: true)
end
@@ -1974,13 +2008,15 @@ class Project < ApplicationRecord
ProjectCacheWorker.perform_async(self.id, [], [:repository_size])
AuthorizedProjectUpdate::ProjectRecalculateWorker.perform_async(id)
+ enqueue_record_project_target_platforms
+
# 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.
# Those records are going to be recreated with the next normal creation
# of a model instance (e.g. an Issue).
InternalId.flush_records!(project: self)
- import_state.finish
+ import_state&.finish
update_project_counter_caches
after_create_default_branch
join_pool_repository
@@ -2829,6 +2865,22 @@ class Project < ApplicationRecord
pending_delete? || hidden?
end
+ def work_items_feature_flag_enabled?
+ group&.work_items_feature_flag_enabled? || Feature.enabled?(:work_items, self, default_enabled: :yaml)
+ end
+
+ def enqueue_record_project_target_platforms
+ return unless Gitlab.com?
+ return unless Feature.enabled?(:record_projects_target_platforms, self, default_enabled: :yaml)
+
+ Projects::RecordTargetPlatformsWorker.perform_async(id)
+ end
+
+ def inactive?
+ (statistics || build_statistics).storage_size > ::Gitlab::CurrentSettings.inactive_projects_min_size_mb.megabytes &&
+ last_activity_at < ::Gitlab::CurrentSettings.inactive_projects_send_warning_email_after_months.months.ago
+ end
+
private
# overridden in EE