2019-10-11 14:06:15 -04:00
|
|
|
# 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)
|
2021-12-10 07:10:18 -05:00
|
|
|
|
|
|
|
perform_housekeeping
|
2019-10-11 14:06:15 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def process_changes_by_action(ref_type, changes)
|
|
|
|
changes_by_action = group_changes_by_action(changes)
|
|
|
|
|
2019-10-17 08:07:33 -04:00
|
|
|
changes_by_action.each do |action, changes|
|
|
|
|
process_changes(ref_type, action, changes, execute_project_hooks: execute_project_hooks?(changes)) if changes.any?
|
2019-10-11 14:06:15 -04:00
|
|
|
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
|
|
|
|
|
2019-10-16 14:08:01 -04:00
|
|
|
def execute_project_hooks?(changes)
|
2020-03-17 11:09:10 -04:00
|
|
|
changes.size <= Gitlab::CurrentSettings.push_event_hooks_limit
|
2019-10-16 14:08:01 -04:00
|
|
|
end
|
|
|
|
|
2019-10-17 08:07:33 -04:00
|
|
|
def process_changes(ref_type, action, changes, execute_project_hooks:)
|
2019-10-11 14:06:15 -04:00
|
|
|
push_service_class = push_service_class_for(ref_type)
|
|
|
|
|
2019-10-17 08:07:33 -04:00
|
|
|
create_bulk_push_event = changes.size > Gitlab::CurrentSettings.push_event_activities_limit
|
2020-08-31 11:10:41 -04:00
|
|
|
merge_request_branches = merge_request_branches_for(ref_type, changes)
|
2019-10-17 08:07:33 -04:00
|
|
|
|
2019-10-11 14:06:15 -04:00
|
|
|
changes.each do |change|
|
|
|
|
push_service_class.new(
|
|
|
|
project,
|
|
|
|
current_user,
|
|
|
|
change: change,
|
|
|
|
push_options: params[:push_options],
|
2020-04-21 11:21:10 -04:00
|
|
|
merge_request_branches: merge_request_branches,
|
2021-08-03 14:10:02 -04:00
|
|
|
create_pipelines: under_process_limit?(change),
|
2019-10-17 08:07:33 -04:00
|
|
|
execute_project_hooks: execute_project_hooks,
|
|
|
|
create_push_event: !create_bulk_push_event
|
2019-10-11 14:06:15 -04:00
|
|
|
).execute
|
|
|
|
end
|
2019-10-17 08:07:33 -04:00
|
|
|
|
|
|
|
create_bulk_push_event(ref_type, action, changes) if create_bulk_push_event
|
|
|
|
end
|
|
|
|
|
2021-08-03 14:10:02 -04:00
|
|
|
def under_process_limit?(change)
|
|
|
|
change[:index] < PIPELINE_PROCESS_LIMIT || Feature.enabled?(:git_push_create_all_pipelines, project)
|
|
|
|
end
|
|
|
|
|
2019-10-17 08:07:33 -04:00
|
|
|
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)
|
|
|
|
)
|
2019-10-11 14:06:15 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def push_service_class_for(ref_type)
|
|
|
|
return Git::TagPushService if ref_type == :tag
|
|
|
|
|
|
|
|
Git::BranchPushService
|
|
|
|
end
|
2020-04-21 11:21:10 -04:00
|
|
|
|
2020-08-31 11:10:41 -04:00
|
|
|
def merge_request_branches_for(ref_type, changes)
|
|
|
|
return [] if ref_type == :tag
|
|
|
|
|
2021-05-11 23:10:21 -04:00
|
|
|
MergeRequests::PushedBranchesService.new(project: project, current_user: current_user, params: { changes: changes }).execute
|
2020-04-21 11:21:10 -04:00
|
|
|
end
|
2021-12-10 07:10:18 -05:00
|
|
|
|
|
|
|
def perform_housekeeping
|
|
|
|
housekeeping = Repositories::HousekeepingService.new(project)
|
|
|
|
housekeeping.increment!
|
|
|
|
housekeeping.execute if housekeeping.needed?
|
|
|
|
rescue Repositories::HousekeepingService::LeaseTaken
|
|
|
|
end
|
2019-10-11 14:06:15 -04:00
|
|
|
end
|
|
|
|
end
|