1# frozen_string_literal: true 2 3module SystemNotes 4 class MergeRequestsService < ::SystemNotes::BaseService 5 # Called when 'merge when pipeline succeeds' is executed 6 def merge_when_pipeline_succeeds(sha) 7 body = "enabled an automatic merge when the pipeline for #{sha} succeeds" 8 9 create_note(NoteSummary.new(noteable, project, author, body, action: 'merge')) 10 end 11 12 # Called when 'merge when pipeline succeeds' is canceled 13 def cancel_merge_when_pipeline_succeeds 14 body = 'canceled the automatic merge' 15 16 create_note(NoteSummary.new(noteable, project, author, body, action: 'merge')) 17 end 18 19 # Called when 'merge when pipeline succeeds' is aborted 20 def abort_merge_when_pipeline_succeeds(reason) 21 body = "aborted the automatic merge because #{reason}" 22 23 ## 24 # TODO: Abort message should be sent by the system, not a particular user. 25 # See https://gitlab.com/gitlab-org/gitlab-foss/issues/63187. 26 create_note(NoteSummary.new(noteable, project, author, body, action: 'merge')) 27 end 28 29 def handle_merge_request_draft 30 action = noteable.work_in_progress? ? "draft" : "ready" 31 32 body = "marked this merge request as **#{action}**" 33 34 create_note(NoteSummary.new(noteable, project, author, body, action: 'title')) 35 end 36 37 def add_merge_request_draft_from_commit(commit) 38 body = "marked this merge request as **draft** from #{commit.to_reference(project)}" 39 40 create_note(NoteSummary.new(noteable, project, author, body, action: 'title')) 41 end 42 43 def resolve_all_discussions 44 body = "resolved all threads" 45 46 create_note(NoteSummary.new(noteable, project, author, body, action: 'discussion')) 47 end 48 49 def discussion_continued_in_issue(discussion, issue) 50 body = "created #{issue.to_reference} to continue this discussion" 51 note_attributes = discussion.reply_attributes.merge(project: project, author: author, note: body) 52 53 Note.create(note_attributes.merge(system: true, created_at: issue.system_note_timestamp)).tap do |note| 54 note.system_note_metadata = SystemNoteMetadata.new(action: 'discussion') 55 end 56 end 57 58 def diff_discussion_outdated(discussion, change_position) 59 merge_request = discussion.noteable 60 diff_refs = change_position.diff_refs 61 version_index = merge_request.merge_request_diffs.viewable.count 62 position_on_text = change_position.on_text? 63 text_parts = ["changed this #{position_on_text ? 'line' : 'file'} in"] 64 65 if version_params = merge_request.version_params_for(diff_refs) 66 repository = project.repository 67 anchor = position_on_text ? change_position.line_code(repository) : change_position.file_hash 68 url = url_helpers.diffs_project_merge_request_path(project, merge_request, version_params.merge(anchor: anchor)) 69 70 text_parts << "[version #{version_index} of the diff](#{url})" 71 else 72 text_parts << "version #{version_index} of the diff" 73 end 74 75 body = text_parts.join(' ') 76 note_attributes = discussion.reply_attributes.merge(project: project, author: author, note: body) 77 78 Note.create(note_attributes.merge(system: true)).tap do |note| 79 note.system_note_metadata = SystemNoteMetadata.new(action: 'outdated') 80 end 81 end 82 83 # Called when a branch in Noteable is changed 84 # 85 # branch_type - 'source' or 'target' 86 # event_type - the source of event: 'update' or 'delete' 87 # old_branch - old branch name 88 # new_branch - new branch name 89 90 # Example Note text is based on event_type: 91 # 92 # update: "changed target branch from `Old` to `New`" 93 # delete: "deleted the `Old` branch. This merge request now targets the `New` branch" 94 # 95 # Returns the created Note object 96 def change_branch(branch_type, event_type, old_branch, new_branch) 97 body = 98 case event_type.to_s 99 when 'delete' 100 "deleted the `#{old_branch}` branch. This merge request now targets the `#{new_branch}` branch" 101 when 'update' 102 "changed #{branch_type} branch from `#{old_branch}` to `#{new_branch}`" 103 else 104 raise ArgumentError, "invalid value for event_type: #{event_type}" 105 end 106 107 create_note(NoteSummary.new(noteable, project, author, body, action: 'branch')) 108 end 109 110 # Called when a branch in Noteable is added or deleted 111 # 112 # branch_type - :source or :target 113 # branch - branch name 114 # presence - :add or :delete 115 # 116 # Example Note text: 117 # 118 # "restored target branch `feature`" 119 # 120 # Returns the created Note object 121 def change_branch_presence(branch_type, branch, presence) 122 verb = 123 if presence == :add 124 'restored' 125 else 126 'deleted' 127 end 128 129 body = "#{verb} #{branch_type} branch `#{branch}`" 130 131 create_note(NoteSummary.new(noteable, project, author, body, action: 'branch')) 132 end 133 134 # Called when a branch is created from the 'new branch' button on a issue 135 # Example note text: 136 # 137 # "created branch `201-issue-branch-button`" 138 def new_issue_branch(branch, branch_project: nil) 139 branch_project ||= project 140 link = url_helpers.project_compare_path(branch_project, from: branch_project.default_branch, to: branch) 141 142 body = "created branch [`#{branch}`](#{link}) to address this issue" 143 144 create_note(NoteSummary.new(noteable, project, author, body, action: 'branch')) 145 end 146 147 def new_merge_request(merge_request) 148 body = "created merge request #{merge_request.to_reference(project)} to address this issue" 149 150 create_note(NoteSummary.new(noteable, project, author, body, action: 'merge')) 151 end 152 153 def picked_into_branch(branch_name, pick_commit) 154 link = url_helpers.project_tree_path(project, branch_name) 155 156 body = "picked the changes into the branch [`#{branch_name}`](#{link}) with commit #{pick_commit}" 157 158 summary = NoteSummary.new(noteable, project, author, body, action: 'cherry_pick') 159 summary.note[:commit_id] = pick_commit 160 161 create_note(summary) 162 end 163 164 # Called when the merge request is approved by user 165 # 166 # Example Note text: 167 # 168 # "approved this merge request" 169 # 170 # Returns the created Note object 171 def approve_mr 172 body = "approved this merge request" 173 174 create_note(NoteSummary.new(noteable, project, author, body, action: 'approved')) 175 end 176 177 def unapprove_mr 178 body = "unapproved this merge request" 179 180 create_note(NoteSummary.new(noteable, project, author, body, action: 'unapproved')) 181 end 182 end 183end 184