summaryrefslogtreecommitdiff
path: root/app/services/git/process_ref_changes_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/git/process_ref_changes_service.rb')
-rw-r--r--app/services/git/process_ref_changes_service.rb75
1 files changed, 75 insertions, 0 deletions
diff --git a/app/services/git/process_ref_changes_service.rb b/app/services/git/process_ref_changes_service.rb
new file mode 100644
index 00000000000..3052bed51bc
--- /dev/null
+++ b/app/services/git/process_ref_changes_service.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+module Git
+ class ProcessRefChangesService < BaseService
+ PIPELINE_PROCESS_LIMIT = 4
+
+ def execute
+ changes = params[:changes]
+
+ process_changes_by_action(:branch, changes.branch_changes)
+ process_changes_by_action(:tag, changes.tag_changes)
+ end
+
+ private
+
+ def process_changes_by_action(ref_type, changes)
+ changes_by_action = group_changes_by_action(changes)
+
+ changes_by_action.each do |action, changes|
+ process_changes(ref_type, action, changes, execute_project_hooks: execute_project_hooks?(changes)) if changes.any?
+ end
+ end
+
+ def group_changes_by_action(changes)
+ changes.group_by do |change|
+ change_action(change)
+ end
+ end
+
+ def change_action(change)
+ return :created if Gitlab::Git.blank_ref?(change[:oldrev])
+ return :removed if Gitlab::Git.blank_ref?(change[:newrev])
+
+ :pushed
+ end
+
+ def execute_project_hooks?(changes)
+ (changes.size <= Gitlab::CurrentSettings.push_event_hooks_limit) || Feature.enabled?(:git_push_execute_all_project_hooks, project)
+ end
+
+ def process_changes(ref_type, action, changes, execute_project_hooks:)
+ push_service_class = push_service_class_for(ref_type)
+
+ create_bulk_push_event = changes.size > Gitlab::CurrentSettings.push_event_activities_limit
+
+ changes.each do |change|
+ push_service_class.new(
+ project,
+ current_user,
+ change: change,
+ push_options: params[:push_options],
+ create_pipelines: change[:index] < PIPELINE_PROCESS_LIMIT || Feature.enabled?(:git_push_create_all_pipelines, project),
+ execute_project_hooks: execute_project_hooks,
+ create_push_event: !create_bulk_push_event
+ ).execute
+ end
+
+ create_bulk_push_event(ref_type, action, changes) if create_bulk_push_event
+ end
+
+ def create_bulk_push_event(ref_type, action, changes)
+ EventCreateService.new.bulk_push(
+ project,
+ current_user,
+ Gitlab::DataBuilder::Push.build_bulk(action: action, ref_type: ref_type, changes: changes)
+ )
+ end
+
+ def push_service_class_for(ref_type)
+ return Git::TagPushService if ref_type == :tag
+
+ Git::BranchPushService
+ end
+ end
+end