1# frozen_string_literal: true
2
3module MergeRequests
4  # PostMergeService class
5  #
6  # Mark existing merge request as merged
7  # and execute all hooks and notifications
8  #
9  class PostMergeService < MergeRequests::BaseService
10    include RemovesRefs
11
12    MAX_RETARGET_MERGE_REQUESTS = 4
13
14    def execute(merge_request)
15      return if merge_request.merged?
16
17      # Mark the merge request as merged, everything that happens afterwards is
18      # executed once
19      merge_request.mark_as_merged
20
21      create_event(merge_request)
22      todo_service.merge_merge_request(merge_request, current_user)
23
24      merge_request_activity_counter.track_merge_mr_action(user: current_user)
25
26      create_note(merge_request)
27      close_issues(merge_request)
28      notification_service.merge_mr(merge_request, current_user)
29      invalidate_cache_counts(merge_request, users: merge_request.assignees | merge_request.reviewers)
30      merge_request.update_project_counter_caches
31      remove_all_attention_requests(merge_request)
32      delete_non_latest_diffs(merge_request)
33      cancel_review_app_jobs!(merge_request)
34      cleanup_environments(merge_request)
35      cleanup_refs(merge_request)
36
37      execute_hooks(merge_request, 'merge')
38    end
39
40    private
41
42    def close_issues(merge_request)
43      return unless merge_request.target_branch == project.default_branch
44
45      closed_issues = merge_request.visible_closing_issues_for(current_user)
46
47      closed_issues.each do |issue|
48        Issues::CloseService.new(project: project, current_user: current_user).execute(issue, commit: merge_request)
49      end
50    end
51
52    def delete_non_latest_diffs(merge_request)
53      DeleteNonLatestDiffsService.new(merge_request).execute
54    end
55
56    def create_merge_event(merge_request, current_user)
57      EventCreateService.new.merge_mr(merge_request, current_user)
58    end
59
60    def create_event(merge_request)
61      # Making sure MergeRequest::Metrics updates are in sync with
62      # Event creation.
63      Event.transaction do
64        merge_event = create_merge_event(merge_request, current_user)
65        merge_request_metrics_service(merge_request).merge(merge_event)
66      end
67    end
68  end
69end
70
71MergeRequests::PostMergeService.prepend_mod_with('MergeRequests::PostMergeService')
72