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.rb132
1 files changed, 58 insertions, 74 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index c0dd2eb8584..845e9e83e78 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -33,6 +33,7 @@ class Project < ApplicationRecord
include OptionallySearch
include FromUnion
include IgnorableColumns
+ include Integration
extend Gitlab::Cache::RequestCache
extend Gitlab::ConfigHelper
@@ -95,8 +96,7 @@ class Project < ApplicationRecord
after_create :create_project_feature, unless: :project_feature
after_create :create_ci_cd_settings,
- unless: :ci_cd_settings,
- if: proc { ProjectCiCdSetting.available? }
+ unless: :ci_cd_settings
after_create :create_container_expiration_policy,
unless: :container_expiration_policy
@@ -198,7 +198,7 @@ class Project < ApplicationRecord
has_one :error_tracking_setting, inverse_of: :project, class_name: 'ErrorTracking::ProjectErrorTrackingSetting'
has_one :metrics_setting, inverse_of: :project, class_name: 'ProjectMetricsSetting'
has_one :grafana_integration, inverse_of: :project
- has_one :project_setting, ->(project) { where_or_create_by(project: project) }, inverse_of: :project
+ has_one :project_setting, inverse_of: :project, autosave: true
has_one :alerting_setting, inverse_of: :project, class_name: 'Alerting::ProjectAlertingSetting'
# Merge Requests for target project should be removed with it
@@ -282,7 +282,7 @@ class Project < ApplicationRecord
class_name: 'Ci::Pipeline',
inverse_of: :project
has_many :stages, class_name: 'Ci::Stage', inverse_of: :project
- has_many :ci_refs, class_name: 'Ci::Ref'
+ 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
@@ -291,6 +291,7 @@ class Project < ApplicationRecord
has_many :builds, class_name: 'Ci::Build', inverse_of: :project, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
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'
has_many :runner_projects, class_name: 'Ci::RunnerProject', inverse_of: :project
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
@@ -328,6 +329,9 @@ class Project < ApplicationRecord
has_many :repository_storage_moves, class_name: 'ProjectRepositoryStorageMove'
+ has_many :webide_pipelines, -> { webide_source }, class_name: 'Ci::Pipeline', inverse_of: :project
+ has_many :reviews, inverse_of: :project
+
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
@@ -368,9 +372,11 @@ class Project < ApplicationRecord
delegate :root_ancestor, to: :namespace, allow_nil: true
delegate :last_pipeline, to: :commit, allow_nil: true
delegate :external_dashboard_url, to: :metrics_setting, allow_nil: true, prefix: true
+ delegate :dashboard_timezone, to: :metrics_setting, allow_nil: true, prefix: true
delegate :default_git_depth, :default_git_depth=, to: :ci_cd_settings, prefix: :ci
delegate :forward_deployment_enabled, :forward_deployment_enabled=, :forward_deployment_enabled?, to: :ci_cd_settings
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=, to: :project_setting
# Validations
validates :creator, presence: true, on: :create
@@ -442,7 +448,7 @@ class Project < ApplicationRecord
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).where('events.action = ?', Event::PUSHED) }
+ 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 :inc_routes, -> { includes(:route, namespace: :route) }
scope :with_statistics, -> { includes(:statistics) }
@@ -507,6 +513,11 @@ class Project < ApplicationRecord
.where(project_pages_metadata: { project_id: nil })
end
+ scope :with_api_entity_associations, -> {
+ preload(:project_feature, :route, :tags,
+ group: :ip_restrictions, namespace: [:route, :owner])
+ }
+
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
chronic_duration_attr :build_timeout_human_readable, :build_timeout,
@@ -521,6 +532,10 @@ class Project < ApplicationRecord
# Used by Projects::CleanupService to hold a map of rewritten object IDs
mount_uploader :bfg_object_map, AttachmentUploader
+ def self.with_web_entity_associations
+ preload(:project_feature, :route, :creator, :group, namespace: [:route, :owner])
+ end
+
def self.eager_load_namespace_and_owner
includes(namespace: :owner)
end
@@ -602,8 +617,7 @@ class Project < ApplicationRecord
# Searches for a list of projects based on the query given in `query`.
#
# On PostgreSQL this method uses "ILIKE" to perform a case-insensitive
- # search. On MySQL a regular "LIKE" is used as it's already
- # case-insensitive.
+ # search.
#
# query - The search query as a String.
def search(query, include_namespace: false)
@@ -713,6 +727,10 @@ class Project < ApplicationRecord
super
end
+ def project_setting
+ super.presence || build_project_setting
+ end
+
def all_pipelines
if builds_enabled?
super
@@ -729,6 +747,10 @@ class Project < ApplicationRecord
end
end
+ def active_webide_pipelines(user:)
+ webide_pipelines.running_or_pending.for_user(user)
+ end
+
def autoclose_referenced_issues
return true if super.nil?
@@ -798,10 +820,6 @@ class Project < ApplicationRecord
Feature.enabled?(:context_commits, default_enabled: true)
end
- def jira_issues_import_feature_flag_enabled?
- Feature.enabled?(:jira_issue_import, self, default_enabled: true)
- end
-
# LFS and hashed repository storage are required for using Design Management.
def design_management_enabled?
lfs_enabled? && hashed_storage?(:repository)
@@ -889,18 +907,6 @@ class Project < ApplicationRecord
latest_jira_import&.status || 'initial'
end
- def validate_jira_import_settings!(user: nil)
- raise Projects::ImportService::Error, _('Jira import feature is disabled.') unless jira_issues_import_feature_flag_enabled?
- raise Projects::ImportService::Error, _('Jira integration not configured.') unless jira_service&.active?
-
- if user
- raise Projects::ImportService::Error, _('Cannot import because issues are not available in this project.') unless feature_available?(:issues, user)
- raise Projects::ImportService::Error, _('You do not have permissions to run the import.') unless user.can?(:admin_project, self)
- end
-
- raise Projects::ImportService::Error, _('Unable to connect to the Jira instance. Please check your Jira integration configuration.') unless jira_service.test(nil)[:success]
- end
-
def human_import_status_name
import_state&.human_status_name || 'none'
end
@@ -921,17 +927,15 @@ class Project < ApplicationRecord
job_id
end
- # rubocop:disable Gitlab/RailsLogger
def log_import_activity(job_id, type: :import)
job_type = type.to_s.capitalize
if job_id
- Rails.logger.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}.")
else
- Rails.logger.error("#{job_type} job failed to create for #{full_path}.")
+ Gitlab::AppLogger.error("#{job_type} job failed to create for #{full_path}.")
end
end
- # rubocop:enable Gitlab/RailsLogger
def reset_cache_and_import_attrs
run_after_commit do
@@ -1007,7 +1011,7 @@ class Project < ApplicationRecord
end
def jira_import?
- import_type == 'jira' && latest_jira_import.present? && jira_issues_import_feature_flag_enabled?
+ import_type == 'jira' && latest_jira_import.present?
end
def gitlab_project_import?
@@ -1036,7 +1040,7 @@ class Project < ApplicationRecord
remote_mirrors.stuck.update_all(
update_status: :failed,
last_error: _('The remote mirror took to long to complete.'),
- last_update_at: Time.now
+ last_update_at: Time.current
)
end
@@ -1194,14 +1198,6 @@ class Project < ApplicationRecord
get_issue(issue_id)
end
- def default_issue_tracker
- gitlab_issue_tracker_service || create_gitlab_issue_tracker_service
- end
-
- def issues_tracker
- external_issue_tracker || default_issue_tracker
- end
-
def external_issue_reference_pattern
external_issue_tracker.class.reference_pattern(only_long: issues_enabled?)
end
@@ -1257,7 +1253,7 @@ class Project < ApplicationRecord
available_services_names.map do |service_name|
find_or_initialize_service(service_name)
- end
+ end.sort_by(&:title)
end
def disabled_services
@@ -1267,16 +1263,7 @@ class Project < ApplicationRecord
def find_or_initialize_service(name)
return if disabled_services.include?(name)
- service = find_service(services, name)
- return service if service
-
- template = find_service(services_templates, name)
-
- if template
- Service.build_from_template(id, template)
- else
- public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend
- end
+ find_service(services, name) || build_from_instance_or_template(name) || public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend
end
# rubocop: disable CodeReuse/ServiceClass
@@ -1781,17 +1768,15 @@ class Project < ApplicationRecord
ensure_pages_metadatum.update!(deployed: false)
end
- # rubocop:disable Gitlab/RailsLogger
def write_repository_config(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)
rescue Gitlab::Git::Repository::NoRepository => e
- Rails.logger.error("Error writing to .git/config for project #{full_path} (#{id}): #{e.message}.")
+ Gitlab::AppLogger.error("Error writing to .git/config for project #{full_path} (#{id}): #{e.message}.")
nil
end
- # rubocop:enable Gitlab/RailsLogger
def after_import
repository.expire_content_cache
@@ -1834,17 +1819,15 @@ class Project < ApplicationRecord
@pipeline_status ||= Gitlab::Cache::Ci::ProjectPipelineStatus.load_for_project(self)
end
- # rubocop:disable Gitlab/RailsLogger
def add_export_job(current_user:, after_export_strategy: nil, params: {})
job_id = ProjectExportWorker.perform_async(current_user.id, self.id, after_export_strategy, params)
if job_id
- Rails.logger.info "Export job started for project ID #{self.id} with job ID #{job_id}"
+ Gitlab::AppLogger.info "Export job started for project ID #{self.id} with job ID #{job_id}"
else
- Rails.logger.error "Export job failed to start for project ID #{self.id}"
+ Gitlab::AppLogger.error "Export job failed to start for project ID #{self.id}"
end
end
- # rubocop:enable Gitlab/RailsLogger
def import_export_shared
@import_export_shared ||= Gitlab::ImportExport::Shared.new(self)
@@ -2082,21 +2065,6 @@ class Project < ApplicationRecord
end
end
- def change_repository_storage(new_repository_storage_key)
- return if repository_read_only?
- return if repository_storage == new_repository_storage_key
-
- raise ArgumentError unless ::Gitlab.config.repositories.storages.key?(new_repository_storage_key)
-
- storage_move = repository_storage_moves.create!(
- source_storage_name: repository_storage,
- destination_storage_name: new_repository_storage_key
- )
- storage_move.schedule!
-
- self.repository_read_only = true
- end
-
def pushes_since_gc
Gitlab::Redis::SharedState.with { |redis| redis.get(pushes_since_gc_redis_shared_state_key).to_i }
end
@@ -2438,12 +2406,32 @@ class Project < ApplicationRecord
touch(:last_activity_at, :last_repository_updated_at)
end
+ def metrics_setting
+ super || build_metrics_setting
+ end
+
private
def find_service(services, name)
services.find { |service| service.to_param == name }
end
+ def build_from_instance_or_template(name)
+ instance = find_service(services_instances, name)
+ return Service.build_from_integration(id, instance) if instance
+
+ template = find_service(services_templates, name)
+ return Service.build_from_integration(id, template) if template
+ end
+
+ def services_templates
+ @services_templates ||= Service.templates
+ end
+
+ def services_instances
+ @services_instances ||= Service.instances
+ end
+
def closest_namespace_setting(name)
namespace.closest_setting(name)
end
@@ -2572,10 +2560,6 @@ class Project < ApplicationRecord
end
end
- def services_templates
- @services_templates ||= Service.where(template: true)
- end
-
def ensure_pages_metadatum
pages_metadatum || create_pages_metadatum!
rescue ActiveRecord::RecordNotUnique