diff options
Diffstat (limited to 'app/services/git/process_ref_changes_service.rb')
-rw-r--r-- | app/services/git/process_ref_changes_service.rb | 75 |
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 |