summaryrefslogtreecommitdiff
path: root/app/services
diff options
context:
space:
mode:
Diffstat (limited to 'app/services')
-rw-r--r--app/services/ci/archive_trace_service.rb28
-rw-r--r--app/services/ci/play_build_service.rb4
-rw-r--r--app/services/ci/process_pipeline_service.rb4
-rw-r--r--app/services/clusters/refresh_service.rb40
-rw-r--r--app/services/cohorts_service.rb6
-rw-r--r--app/services/commits/create_service.rb18
-rw-r--r--app/services/files/multi_service.rb1
-rw-r--r--app/services/groups/nested_create_service.rb4
-rw-r--r--app/services/groups/transfer_service.rb1
-rw-r--r--app/services/issuable/clone/attributes_rewriter.rb2
-rw-r--r--app/services/members/destroy_service.rb2
-rw-r--r--app/services/merge_requests/build_service.rb28
-rw-r--r--app/services/merge_requests/push_options_handler_service.rb37
-rw-r--r--app/services/metrics/dashboard/base_service.rb70
-rw-r--r--app/services/metrics/dashboard/default_embed_service.rb63
-rw-r--r--app/services/metrics/dashboard/project_dashboard_service.rb48
-rw-r--r--app/services/metrics/dashboard/system_dashboard_service.rb47
-rw-r--r--app/services/notes/create_service.rb4
-rw-r--r--app/services/notification_service.rb6
-rw-r--r--app/services/projects/base_move_relations_service.rb12
-rw-r--r--app/services/projects/fetch_statistics_increment_service.rb7
-rw-r--r--app/services/projects/move_deploy_keys_projects_service.rb3
-rw-r--r--app/services/projects/move_lfs_objects_projects_service.rb3
-rw-r--r--app/services/projects/move_notification_settings_service.rb3
-rw-r--r--app/services/projects/move_project_authorizations_service.rb3
-rw-r--r--app/services/projects/move_project_group_links_service.rb3
-rw-r--r--app/services/projects/move_project_members_service.rb2
-rw-r--r--app/services/quick_actions/interpret_service.rb31
-rw-r--r--app/services/users/refresh_authorized_projects_service.rb8
-rw-r--r--app/services/wiki_pages/base_service.rb6
30 files changed, 365 insertions, 129 deletions
diff --git a/app/services/ci/archive_trace_service.rb b/app/services/ci/archive_trace_service.rb
index b5cfa1d019c..700d78361a4 100644
--- a/app/services/ci/archive_trace_service.rb
+++ b/app/services/ci/archive_trace_service.rb
@@ -2,8 +2,25 @@
module Ci
class ArchiveTraceService
- def execute(job)
+ def execute(job, worker_name:)
+ # TODO: Remove this logging once we confirmed new live trace architecture is functional.
+ # See https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/4667.
+ unless job.has_live_trace?
+ Sidekiq.logger.warn(class: worker_name,
+ message: 'The job does not have live trace but going to be archived.',
+ job_id: job.id)
+ return
+ end
+
job.trace.archive!
+
+ # TODO: Remove this logging once we confirmed new live trace architecture is functional.
+ # See https://gitlab.com/gitlab-com/gl-infra/infrastructure/issues/4667.
+ unless job.has_archived_trace?
+ Sidekiq.logger.warn(class: worker_name,
+ message: 'The job does not have archived trace after archiving.',
+ job_id: job.id)
+ end
rescue ::Gitlab::Ci::Trace::AlreadyArchivedError
# It's already archived, thus we can safely ignore this exception.
rescue => e
@@ -11,7 +28,7 @@ module Ci
# If `archive!` keeps failing for over a week, that could incur data loss.
# (See more https://docs.gitlab.com/ee/administration/job_traces.html#new-live-trace-architecture)
# In order to avoid interrupting the system, we do not raise an exception here.
- archive_error(e, job)
+ archive_error(e, job, worker_name)
end
private
@@ -22,9 +39,12 @@ module Ci
"Counter of failed attempts of trace archiving")
end
- def archive_error(error, job)
+ def archive_error(error, job, worker_name)
failed_archive_counter.increment
- Rails.logger.error "Failed to archive trace. id: #{job.id} message: #{error.message}" # rubocop:disable Gitlab/RailsLogger
+
+ Sidekiq.logger.warn(class: worker_name,
+ message: "Failed to archive trace. message: #{error.message}.",
+ job_id: job.id)
Gitlab::Sentry
.track_exception(error,
diff --git a/app/services/ci/play_build_service.rb b/app/services/ci/play_build_service.rb
index eb0b070657d..9f922ffde81 100644
--- a/app/services/ci/play_build_service.rb
+++ b/app/services/ci/play_build_service.rb
@@ -2,7 +2,7 @@
module Ci
class PlayBuildService < ::BaseService
- def execute(build)
+ def execute(build, job_variables_attributes = nil)
unless can?(current_user, :update_build, build)
raise Gitlab::Access::AccessDeniedError
end
@@ -10,7 +10,7 @@ module Ci
# Try to enqueue the build, otherwise create a duplicate.
#
if build.enqueue
- build.tap { |action| action.update(user: current_user) }
+ build.tap { |action| action.update(user: current_user, job_variables_attributes: job_variables_attributes || []) }
else
Ci::Build.retry(build, current_user)
end
diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb
index aaf56048b5c..207cc5017d0 100644
--- a/app/services/ci/process_pipeline_service.rb
+++ b/app/services/ci/process_pipeline_service.rb
@@ -10,13 +10,13 @@ module Ci
update_retried
new_builds =
- stage_indexes_of_created_processables.map do |index|
+ stage_indexes_of_created_processables.flat_map do |index|
process_stage(index)
end
@pipeline.update_status
- new_builds.flatten.any?
+ new_builds.any?
end
private
diff --git a/app/services/clusters/refresh_service.rb b/app/services/clusters/refresh_service.rb
deleted file mode 100644
index 3752a306793..00000000000
--- a/app/services/clusters/refresh_service.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- class RefreshService
- def self.create_or_update_namespaces_for_cluster(cluster)
- projects_with_missing_kubernetes_namespaces_for_cluster(cluster).each do |project|
- create_or_update_namespace(cluster, project)
- end
- end
-
- def self.create_or_update_namespaces_for_project(project)
- clusters_with_missing_kubernetes_namespaces_for_project(project).each do |cluster|
- create_or_update_namespace(cluster, project)
- end
- end
-
- def self.projects_with_missing_kubernetes_namespaces_for_cluster(cluster)
- cluster.all_projects.missing_kubernetes_namespace(cluster.kubernetes_namespaces)
- end
-
- private_class_method :projects_with_missing_kubernetes_namespaces_for_cluster
-
- def self.clusters_with_missing_kubernetes_namespaces_for_project(project)
- project.clusters.managed.missing_kubernetes_namespace(project.kubernetes_namespaces)
- end
-
- private_class_method :clusters_with_missing_kubernetes_namespaces_for_project
-
- def self.create_or_update_namespace(cluster, project)
- kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace_for_project(project)
-
- ::Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
- cluster: cluster,
- kubernetes_namespace: kubernetes_namespace
- ).execute
- end
-
- private_class_method :create_or_update_namespace
- end
-end
diff --git a/app/services/cohorts_service.rb b/app/services/cohorts_service.rb
index 6d466c2fc9c..97fbb70f350 100644
--- a/app/services/cohorts_service.rb
+++ b/app/services/cohorts_service.rb
@@ -95,10 +95,6 @@ class CohortsService
# rubocop: enable CodeReuse/ActiveRecord
def column_to_date(column)
- if Gitlab::Database.postgresql?
- "CAST(DATE_TRUNC('month', #{column}) AS date)"
- else
- "STR_TO_DATE(DATE_FORMAT(#{column}, '%Y-%m-01'), '%Y-%m-%d')"
- end
+ "CAST(DATE_TRUNC('month', #{column}) AS date)"
end
end
diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb
index bb34a3d3352..f3be68f9602 100644
--- a/app/services/commits/create_service.rb
+++ b/app/services/commits/create_service.rb
@@ -10,6 +10,7 @@ module Commits
@start_project = params[:start_project] || @project
@start_branch = params[:start_branch]
+ @start_sha = params[:start_sha]
@branch_name = params[:branch_name]
@force = params[:force] || false
end
@@ -40,7 +41,7 @@ module Commits
end
def different_branch?
- @start_branch != @branch_name || @start_project != @project
+ @start_project != @project || @start_branch != @branch_name || @start_sha.present?
end
def force?
@@ -49,6 +50,7 @@ module Commits
def validate!
validate_permissions!
+ validate_start_sha!
validate_on_branch!
validate_branch_existence!
@@ -63,7 +65,21 @@ module Commits
end
end
+ def validate_start_sha!
+ return unless @start_sha
+
+ if @start_branch
+ raise_error("You can't pass both start_branch and start_sha")
+ elsif !Gitlab::Git.commit_id?(@start_sha)
+ raise_error("Invalid start_sha '#{@start_sha}'")
+ elsif !@start_project.repository.commit(@start_sha)
+ raise_error("Cannot find start_sha '#{@start_sha}'")
+ end
+ end
+
def validate_on_branch!
+ return unless @start_branch
+
if !@start_project.empty_repo? && !@start_project.repository.branch_exists?(@start_branch)
raise_error('You can only create or edit files when you are on a branch')
end
diff --git a/app/services/files/multi_service.rb b/app/services/files/multi_service.rb
index d8c4e5bc5e8..65af4dd5a28 100644
--- a/app/services/files/multi_service.rb
+++ b/app/services/files/multi_service.rb
@@ -47,6 +47,7 @@ module Files
author_name: @author_name,
start_project: @start_project,
start_branch_name: @start_branch,
+ start_sha: @start_sha,
force: force?
)
rescue ArgumentError => e
diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb
index 01bd685712b..a51ac9aa593 100644
--- a/app/services/groups/nested_create_service.rb
+++ b/app/services/groups/nested_create_service.rb
@@ -18,10 +18,6 @@ module Groups
return namespace
end
- if group_path.include?('/') && !Group.supports_nested_objects?
- raise 'Nested groups are not supported on MySQL'
- end
-
create_group_path
end
diff --git a/app/services/groups/transfer_service.rb b/app/services/groups/transfer_service.rb
index 98e7c311572..fe7e07ef9f0 100644
--- a/app/services/groups/transfer_service.rb
+++ b/app/services/groups/transfer_service.rb
@@ -43,7 +43,6 @@ module Groups
def ensure_allowed_transfer
raise_transfer_error(:group_is_already_root) if group_is_already_root?
- raise_transfer_error(:database_not_supported) unless Group.supports_nested_objects?
raise_transfer_error(:same_parent_as_current) if same_parent?
raise_transfer_error(:invalid_policies) unless valid_policies?
raise_transfer_error(:namespace_with_same_path) if namespace_with_same_path?
diff --git a/app/services/issuable/clone/attributes_rewriter.rb b/app/services/issuable/clone/attributes_rewriter.rb
index 0300cc0d8d3..3c061d35558 100644
--- a/app/services/issuable/clone/attributes_rewriter.rb
+++ b/app/services/issuable/clone/attributes_rewriter.rb
@@ -17,6 +17,8 @@ module Issuable
private
def cloneable_milestone
+ return unless new_entity.supports_milestone?
+
title = original_entity.milestone&.title
return unless title
diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb
index c8d5e563cd8..0164760920f 100644
--- a/app/services/members/destroy_service.rb
+++ b/app/services/members/destroy_service.rb
@@ -31,7 +31,7 @@ module Members
return unless member.is_a?(GroupMember) && member.user && member.group
delete_project_members(member)
- delete_subgroup_members(member) if Group.supports_nested_objects?
+ delete_subgroup_members(member)
end
def delete_project_members(member)
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index 109c964e577..b28f80939ae 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -11,15 +11,18 @@ module MergeRequests
# https://gitlab.com/gitlab-org/gitlab-ce/issues/53658
merge_quick_actions_into_params!(merge_request, only: [:target_branch])
merge_request.merge_params['force_remove_source_branch'] = params.delete(:force_remove_source_branch) if params.has_key?(:force_remove_source_branch)
- merge_request.assign_attributes(params)
+ # Assign the projects first so we can use policies for `filter_params`
merge_request.author = current_user
+ merge_request.source_project = find_source_project
+ merge_request.target_project = find_target_project
+
+ filter_params(merge_request)
+ merge_request.assign_attributes(params.to_h.compact)
+
merge_request.compare_commits = []
- merge_request.source_project = find_source_project
- merge_request.target_project = find_target_project
- merge_request.target_branch = find_target_branch
- merge_request.can_be_created = projects_and_branches_valid?
- ensure_milestone_available(merge_request)
+ merge_request.target_branch = find_target_branch
+ merge_request.can_be_created = projects_and_branches_valid?
# compare branches only if branches are valid, otherwise
# compare_branches may raise an error
@@ -50,12 +53,14 @@ module MergeRequests
to: :merge_request
def find_source_project
+ source_project = project_from_params(:source_project)
return source_project if source_project.present? && can?(current_user, :create_merge_request_from, source_project)
project
end
def find_target_project
+ target_project = project_from_params(:target_project)
return target_project if target_project.present? && can?(current_user, :create_merge_request_in, target_project)
target_project = project.default_merge_request_target
@@ -65,6 +70,17 @@ module MergeRequests
project
end
+ def project_from_params(param_name)
+ project_from_params = params.delete(param_name)
+
+ id_param_name = :"#{param_name}_id"
+ if project_from_params.nil? && params[id_param_name]
+ project_from_params = Project.find_by_id(params.delete(id_param_name))
+ end
+
+ project_from_params
+ end
+
def find_target_branch
target_branch || target_project.default_branch
end
diff --git a/app/services/merge_requests/push_options_handler_service.rb b/app/services/merge_requests/push_options_handler_service.rb
index a24163331e8..b210004e6e1 100644
--- a/app/services/merge_requests/push_options_handler_service.rb
+++ b/app/services/merge_requests/push_options_handler_service.rb
@@ -117,15 +117,16 @@ module MergeRequests
collect_errors_from_merge_request(merge_request) unless merge_request.valid?
end
- def create_params(branch)
+ def base_params
params = {
- assignees: [current_user],
- source_branch: branch,
- source_project: project,
- target_branch: push_options[:target] || target_project.default_branch,
- target_project: target_project
+ title: push_options[:title],
+ description: push_options[:description],
+ target_branch: push_options[:target],
+ force_remove_source_branch: push_options[:remove_source_branch]
}
+ params.compact!
+
if push_options.key?(:merge_when_pipeline_succeeds)
params.merge!(
merge_when_pipeline_succeeds: push_options[:merge_when_pipeline_succeeds],
@@ -136,23 +137,25 @@ module MergeRequests
params
end
- def update_params
- params = {}
+ def create_params(branch)
+ params = base_params
- if push_options.key?(:merge_when_pipeline_succeeds)
- params.merge!(
- merge_when_pipeline_succeeds: push_options[:merge_when_pipeline_succeeds],
- merge_user: current_user
- )
- end
+ params.merge!(
+ assignees: [current_user],
+ source_branch: branch,
+ source_project: project,
+ target_project: target_project
+ )
- if push_options.key?(:target)
- params[:target_branch] = push_options[:target]
- end
+ params[:target_branch] ||= target_project.default_branch
params
end
+ def update_params
+ base_params
+ end
+
def collect_errors_from_merge_request(merge_request)
merge_request.errors.full_messages.each do |error|
errors << error
diff --git a/app/services/metrics/dashboard/base_service.rb b/app/services/metrics/dashboard/base_service.rb
new file mode 100644
index 00000000000..b331bf51874
--- /dev/null
+++ b/app/services/metrics/dashboard/base_service.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+# Searches a projects repository for a metrics dashboard and formats the output.
+# Expects any custom dashboards will be located in `.gitlab/dashboards`
+module Metrics
+ module Dashboard
+ class BaseService < ::BaseService
+ PROCESSING_ERROR = Gitlab::Metrics::Dashboard::Stages::BaseStage::DashboardProcessingError
+ NOT_FOUND_ERROR = Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError
+
+ def get_dashboard
+ return error('Insufficient permissions.', :unauthorized) unless allowed?
+
+ success(dashboard: process_dashboard)
+ rescue NOT_FOUND_ERROR
+ error("#{dashboard_path} could not be found.", :not_found)
+ rescue PROCESSING_ERROR => e
+ error(e.message, :unprocessable_entity)
+ end
+
+ # Summary of all known dashboards for the service.
+ # @return [Array<Hash>] ex) [{ path: String, default: Boolean }]
+ def self.all_dashboard_paths(_project)
+ raise NotImplementedError
+ end
+
+ # Returns an un-processed dashboard from the cache.
+ def raw_dashboard
+ Gitlab::Metrics::Dashboard::Cache.fetch(cache_key) { get_raw_dashboard }
+ end
+
+ private
+
+ # Determines whether users should be able to view
+ # dashboards at all.
+ def allowed?
+ Ability.allowed?(current_user, :read_environment, project)
+ end
+
+ # Returns a new dashboard Hash, supplemented with DB info
+ def process_dashboard
+ Gitlab::Metrics::Dashboard::Processor
+ .new(project, params[:environment], raw_dashboard)
+ .process(insert_project_metrics: insert_project_metrics?)
+ end
+
+ # @return [String] Relative filepath of the dashboard yml
+ def dashboard_path
+ params[:dashboard_path]
+ end
+
+ # @return [Hash] an unmodified dashboard
+ def get_raw_dashboard
+ raise NotImplementedError
+ end
+
+ # @return [String]
+ def cache_key
+ raise NotImplementedError
+ end
+
+ # Determines whether custom metrics should be included
+ # in the processed output.
+ # @return [Boolean]
+ def insert_project_metrics?
+ false
+ end
+ end
+ end
+end
diff --git a/app/services/metrics/dashboard/default_embed_service.rb b/app/services/metrics/dashboard/default_embed_service.rb
new file mode 100644
index 00000000000..0967c5bcfeb
--- /dev/null
+++ b/app/services/metrics/dashboard/default_embed_service.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+# Responsible for returning a filtered system dashboard
+# containing only the default embedded metrics. In future,
+# this class may be updated to support filtering to
+# alternate metrics/panels.
+#
+# Why isn't this filtering in a processing stage? By filtering
+# here, we ensure the dynamically-determined dashboard is cached.
+#
+# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards.
+module Metrics
+ module Dashboard
+ class DefaultEmbedService < ::Metrics::Dashboard::BaseService
+ # For the default filtering for embedded metrics,
+ # uses the 'id' key in dashboard-yml definition for
+ # identification.
+ DEFAULT_EMBEDDED_METRICS_IDENTIFIERS = %w(
+ system_metrics_kubernetes_container_memory_total
+ system_metrics_kubernetes_container_cores_total
+ ).freeze
+
+ # Returns a new dashboard with only the matching
+ # metrics from the system dashboard, stripped of groups.
+ # @return [Hash]
+ def raw_dashboard
+ panels = panel_groups.each_with_object([]) do |group, panels|
+ matched_panels = group['panels'].select { |panel| matching_panel?(panel) }
+
+ panels.concat(matched_panels)
+ end
+
+ { 'panel_groups' => [{ 'panels' => panels }] }
+ end
+
+ def cache_key
+ "dynamic_metrics_dashboard_#{metric_identifiers.join('_')}"
+ end
+
+ private
+
+ # Returns an array of the panels groups on the
+ # system dashboard
+ def panel_groups
+ ::Metrics::Dashboard::SystemDashboardService
+ .new(project, nil)
+ .raw_dashboard['panel_groups']
+ end
+
+ # Identifies a panel as "matching" if any metric ids in
+ # the panel is in the list of identifiers to collect.
+ def matching_panel?(panel)
+ panel['metrics'].any? do |metric|
+ metric_identifiers.include?(metric['id'])
+ end
+ end
+
+ def metric_identifiers
+ DEFAULT_EMBEDDED_METRICS_IDENTIFIERS
+ end
+ end
+ end
+end
diff --git a/app/services/metrics/dashboard/project_dashboard_service.rb b/app/services/metrics/dashboard/project_dashboard_service.rb
new file mode 100644
index 00000000000..756d387c0e6
--- /dev/null
+++ b/app/services/metrics/dashboard/project_dashboard_service.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+# Searches a projects repository for a metrics dashboard and formats the output.
+# Expects any custom dashboards will be located in `.gitlab/dashboards`
+# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards.
+module Metrics
+ module Dashboard
+ class ProjectDashboardService < ::Metrics::Dashboard::BaseService
+ DASHBOARD_ROOT = ".gitlab/dashboards"
+
+ class << self
+ def all_dashboard_paths(project)
+ file_finder(project)
+ .list_files_for(DASHBOARD_ROOT)
+ .map do |filepath|
+ {
+ path: filepath,
+ display_name: name_for_path(filepath),
+ default: false
+ }
+ end
+ end
+
+ def file_finder(project)
+ Gitlab::Template::Finders::RepoTemplateFinder.new(project, DASHBOARD_ROOT, '.yml')
+ end
+
+ # Grabs the filepath after the base directory.
+ def name_for_path(filepath)
+ filepath.delete_prefix("#{DASHBOARD_ROOT}/")
+ end
+ end
+
+ private
+
+ # Searches the project repo for a custom-defined dashboard.
+ def get_raw_dashboard
+ yml = self.class.file_finder(project).read(dashboard_path)
+
+ YAML.safe_load(yml)
+ end
+
+ def cache_key
+ "project_#{project.id}_metrics_dashboard_#{dashboard_path}"
+ end
+ end
+ end
+end
diff --git a/app/services/metrics/dashboard/system_dashboard_service.rb b/app/services/metrics/dashboard/system_dashboard_service.rb
new file mode 100644
index 00000000000..fcd71aadb03
--- /dev/null
+++ b/app/services/metrics/dashboard/system_dashboard_service.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+# Fetches the system metrics dashboard and formats the output.
+# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards.
+module Metrics
+ module Dashboard
+ class SystemDashboardService < ::Metrics::Dashboard::BaseService
+ SYSTEM_DASHBOARD_PATH = 'config/prometheus/common_metrics.yml'
+ SYSTEM_DASHBOARD_NAME = 'Default'
+
+ class << self
+ def all_dashboard_paths(_project)
+ [{
+ path: SYSTEM_DASHBOARD_PATH,
+ display_name: SYSTEM_DASHBOARD_NAME,
+ default: true
+ }]
+ end
+
+ def system_dashboard?(filepath)
+ filepath == SYSTEM_DASHBOARD_PATH
+ end
+ end
+
+ private
+
+ def dashboard_path
+ SYSTEM_DASHBOARD_PATH
+ end
+
+ # Returns the base metrics shipped with every GitLab service.
+ def get_raw_dashboard
+ yml = File.read(Rails.root.join(dashboard_path))
+
+ YAML.safe_load(yml)
+ end
+
+ def cache_key
+ "metrics_dashboard_#{dashboard_path}"
+ end
+
+ def insert_project_metrics?
+ true
+ end
+ end
+ end
+end
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index 1b46f6d8a72..194c4a43dbc 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -21,7 +21,7 @@ module Notes
if quick_actions_service.supported?(note)
options = { merge_request_diff_head_sha: merge_request_diff_head_sha }
- content, update_params = quick_actions_service.execute(note, options)
+ content, update_params, message = quick_actions_service.execute(note, options)
only_commands = content.empty?
@@ -52,7 +52,7 @@ module Notes
# We must add the error after we call #save because errors are reset
# when #save is called
if only_commands
- note.errors.add(:commands_only, 'Commands applied')
+ note.errors.add(:commands_only, message.presence || _('Commands did not apply'))
end
end
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 5aa804666f0..21fab22e0d4 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -418,7 +418,9 @@ class NotificationService
[pipeline.user], :watch,
custom_action: :"#{pipeline.status}_pipeline",
target: pipeline
- ).map(&:notification_email)
+ ).map do |user|
+ user.notification_email_for(pipeline.project.group)
+ end
if recipients.any?
mailer.public_send(email_template, pipeline, recipients).deliver_later
@@ -593,7 +595,7 @@ class NotificationService
end
def deliver_access_request_email(recipient, member)
- mailer.member_access_requested_email(member.real_source_type, member.id, recipient.user.notification_email).deliver_later
+ mailer.member_access_requested_email(member.real_source_type, member.id, recipient.user.id).deliver_later
end
def fallback_to_group_owners_maintainers?(recipients, member)
diff --git a/app/services/projects/base_move_relations_service.rb b/app/services/projects/base_move_relations_service.rb
index 24dec1f3a45..3a159cef58b 100644
--- a/app/services/projects/base_move_relations_service.rb
+++ b/app/services/projects/base_move_relations_service.rb
@@ -10,17 +10,5 @@ module Projects
true
end
-
- private
-
- # rubocop: disable CodeReuse/ActiveRecord
- def prepare_relation(relation, id_param = :id)
- if Gitlab::Database.postgresql?
- relation
- else
- relation.model.where("#{id_param}": relation.pluck(id_param))
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
end
end
diff --git a/app/services/projects/fetch_statistics_increment_service.rb b/app/services/projects/fetch_statistics_increment_service.rb
index 8644e6bf313..b150fd2d9f1 100644
--- a/app/services/projects/fetch_statistics_increment_service.rb
+++ b/app/services/projects/fetch_statistics_increment_service.rb
@@ -12,14 +12,9 @@ module Projects
increment_fetch_count_sql = <<~SQL
INSERT INTO #{table_name} (project_id, date, fetch_count)
VALUES (#{project.id}, '#{Date.today}', 1)
+ ON CONFLICT (project_id, date) DO UPDATE SET fetch_count = #{table_name}.fetch_count + 1
SQL
- increment_fetch_count_sql += if Gitlab::Database.postgresql?
- "ON CONFLICT (project_id, date) DO UPDATE SET fetch_count = #{table_name}.fetch_count + 1"
- else
- "ON DUPLICATE KEY UPDATE fetch_count = #{table_name}.fetch_count + 1"
- end
-
ActiveRecord::Base.connection.execute(increment_fetch_count_sql)
end
diff --git a/app/services/projects/move_deploy_keys_projects_service.rb b/app/services/projects/move_deploy_keys_projects_service.rb
index b6a3af8c7b8..01419563538 100644
--- a/app/services/projects/move_deploy_keys_projects_service.rb
+++ b/app/services/projects/move_deploy_keys_projects_service.rb
@@ -16,8 +16,7 @@ module Projects
private
def move_deploy_keys_projects
- prepare_relation(non_existent_deploy_keys_projects)
- .update_all(project_id: @project.id)
+ non_existent_deploy_keys_projects.update_all(project_id: @project.id)
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/services/projects/move_lfs_objects_projects_service.rb b/app/services/projects/move_lfs_objects_projects_service.rb
index 308a54ad06e..10e19014db4 100644
--- a/app/services/projects/move_lfs_objects_projects_service.rb
+++ b/app/services/projects/move_lfs_objects_projects_service.rb
@@ -16,8 +16,7 @@ module Projects
private
def move_lfs_objects_projects
- prepare_relation(non_existent_lfs_objects_projects)
- .update_all(project_id: @project.lfs_storage_project.id)
+ non_existent_lfs_objects_projects.update_all(project_id: @project.lfs_storage_project.id)
end
def remove_remaining_lfs_objects_project
diff --git a/app/services/projects/move_notification_settings_service.rb b/app/services/projects/move_notification_settings_service.rb
index e740c44bd26..65a888fe26b 100644
--- a/app/services/projects/move_notification_settings_service.rb
+++ b/app/services/projects/move_notification_settings_service.rb
@@ -16,8 +16,7 @@ module Projects
private
def move_notification_settings
- prepare_relation(non_existent_notifications)
- .update_all(source_id: @project.id)
+ non_existent_notifications.update_all(source_id: @project.id)
end
# Remove remaining notification settings from source_project
diff --git a/app/services/projects/move_project_authorizations_service.rb b/app/services/projects/move_project_authorizations_service.rb
index 2985ba89014..c95ad60ab5e 100644
--- a/app/services/projects/move_project_authorizations_service.rb
+++ b/app/services/projects/move_project_authorizations_service.rb
@@ -21,8 +21,7 @@ module Projects
private
def move_project_authorizations
- prepare_relation(non_existent_authorization, :user_id)
- .update_all(project_id: @project.id)
+ non_existent_authorization.update_all(project_id: @project.id)
end
def remove_remaining_authorizations
diff --git a/app/services/projects/move_project_group_links_service.rb b/app/services/projects/move_project_group_links_service.rb
index cf4b291c761..d1aa9af2bcb 100644
--- a/app/services/projects/move_project_group_links_service.rb
+++ b/app/services/projects/move_project_group_links_service.rb
@@ -20,8 +20,7 @@ module Projects
private
def move_group_links
- prepare_relation(non_existent_group_links)
- .update_all(project_id: @project.id)
+ non_existent_group_links.update_all(project_id: @project.id)
end
# Remove remaining project group links from source_project
diff --git a/app/services/projects/move_project_members_service.rb b/app/services/projects/move_project_members_service.rb
index faf389241d2..de4e7e5a1e3 100644
--- a/app/services/projects/move_project_members_service.rb
+++ b/app/services/projects/move_project_members_service.rb
@@ -20,7 +20,7 @@ module Projects
private
def move_project_members
- prepare_relation(non_existent_members).update_all(source_id: @project.id)
+ non_existent_members.update_all(source_id: @project.id)
end
def remove_remaining_members
diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb
index 8ff73522e5f..7f944e25887 100644
--- a/app/services/quick_actions/interpret_service.rb
+++ b/app/services/quick_actions/interpret_service.rb
@@ -31,17 +31,19 @@ module QuickActions
end
# Takes a text and interprets the commands that are extracted from it.
- # Returns the content without commands, and hash of changes to be applied to a record.
+ # Returns the content without commands, a hash of changes to be applied to a record
+ # and a string containing the execution_message to show to the user.
def execute(content, quick_action_target, only: nil)
- return [content, {}] unless current_user.can?(:use_quick_actions)
+ return [content, {}, ''] unless current_user.can?(:use_quick_actions)
@quick_action_target = quick_action_target
@updates = {}
+ @execution_message = {}
content, commands = extractor.extract_commands(content, only: only)
extract_updates(commands)
- [content, @updates]
+ [content, @updates, execution_messages_for(commands)]
end
# Takes a text and interprets the commands that are extracted from it.
@@ -119,8 +121,12 @@ module QuickActions
labels_params.scan(/"([^"]+)"|([^ ]+)/).flatten.compact
end
- def find_label_references(labels_param)
- find_labels(labels_param).map(&:to_reference)
+ def find_label_references(labels_param, format = :id)
+ labels_to_reference(find_labels(labels_param), format)
+ end
+
+ def labels_to_reference(labels, format = :id)
+ labels.map { |l| l.to_reference(format: format) }
end
def find_label_ids(labels_param)
@@ -128,11 +134,24 @@ module QuickActions
end
def explain_commands(commands)
+ map_commands(commands, :explain)
+ end
+
+ def execution_messages_for(commands)
+ map_commands(commands, :execute_message).join(' ')
+ end
+
+ def map_commands(commands, method)
commands.map do |name, arg|
definition = self.class.definition_by_name(name)
next unless definition
- definition.explain(self, arg)
+ case method
+ when :explain
+ definition.explain(self, arg)
+ when :execute_message
+ @execution_message[name.to_sym] || definition.execute_message(self, arg)
+ end
end.compact
end
diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb
index 4a26d2be2af..ae67b4f5256 100644
--- a/app/services/users/refresh_authorized_projects_service.rb
+++ b/app/services/users/refresh_authorized_projects_service.rb
@@ -102,13 +102,7 @@ module Users
end
def fresh_authorizations
- klass = if Group.supports_nested_objects?
- Gitlab::ProjectAuthorizations::WithNestedGroups
- else
- Gitlab::ProjectAuthorizations::WithoutNestedGroups
- end
-
- klass.new(user).calculate
+ Gitlab::ProjectAuthorizations.new(user).calculate
end
end
end
diff --git a/app/services/wiki_pages/base_service.rb b/app/services/wiki_pages/base_service.rb
index e259f5bd1bc..b9df690c2b7 100644
--- a/app/services/wiki_pages/base_service.rb
+++ b/app/services/wiki_pages/base_service.rb
@@ -8,6 +8,12 @@ module WikiPages
page_data = Gitlab::DataBuilder::WikiPage.build(page, current_user, action)
@project.execute_hooks(page_data, :wiki_page_hooks)
@project.execute_services(page_data, :wiki_page_hooks)
+ increment_usage(action)
+ end
+
+ # This method throws an error if the action is an unanticipated value.
+ def increment_usage(action)
+ Gitlab::UsageDataCounters::WikiPageCounter.count(action)
end
end
end