1# frozen_string_literal: true
2
3# SystemNoteService
4#
5# Used for creating system notes (e.g., when a user references a merge request
6# from an issue, an issue's assignee changes, an issue is closed, etc.)
7module SystemNoteService
8  extend self
9
10  # Called when commits are added to a merge request
11  #
12  # noteable         - Noteable object
13  # project          - Project owning noteable
14  # author           - User performing the change
15  # new_commits      - Array of Commits added since last push
16  # existing_commits - Array of Commits added in a previous push
17  # oldrev           - Optional String SHA of a previous Commit
18  #
19  # Returns the created Note object
20  def add_commits(noteable, project, author, new_commits, existing_commits = [], oldrev = nil)
21    ::SystemNotes::CommitService.new(noteable: noteable, project: project, author: author).add_commits(new_commits, existing_commits, oldrev)
22  end
23
24  # Called when a commit was tagged
25  #
26  # noteable  - Noteable object
27  # project   - Project owning noteable
28  # author    - User performing the tag
29  # tag_name  - The created tag name
30  #
31  # Returns the created Note object
32  def tag_commit(noteable, project, author, tag_name)
33    ::SystemNotes::CommitService.new(noteable: noteable, project: project, author: author).tag_commit(tag_name)
34  end
35
36  def change_assignee(noteable, project, author, assignee)
37    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).change_assignee(assignee)
38  end
39
40  def change_issuable_assignees(issuable, project, author, old_assignees)
41    ::SystemNotes::IssuablesService.new(noteable: issuable, project: project, author: author).change_issuable_assignees(old_assignees)
42  end
43
44  def change_issuable_reviewers(issuable, project, author, old_reviewers)
45    ::SystemNotes::IssuablesService.new(noteable: issuable, project: project, author: author).change_issuable_reviewers(old_reviewers)
46  end
47
48  def relate_issue(noteable, noteable_ref, user)
49    ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).relate_issue(noteable_ref)
50  end
51
52  def unrelate_issue(noteable, noteable_ref, user)
53    ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).unrelate_issue(noteable_ref)
54  end
55
56  # Called when the due_date of a Noteable is changed
57  #
58  # noteable  - Noteable object
59  # project   - Project owning noteable
60  # author    - User performing the change
61  # due_date  - Due date being assigned, or nil
62  #
63  # Example Note text:
64  #
65  #   "removed due date"
66  #
67  #   "changed due date to September 20, 2018"
68  #
69  # Returns the created Note object
70  def change_due_date(noteable, project, author, due_date)
71    ::SystemNotes::TimeTrackingService.new(noteable: noteable, project: project, author: author).change_due_date(due_date)
72  end
73
74  # Called when the estimated time of a Noteable is changed
75  #
76  # noteable      - Noteable object
77  # project       - Project owning noteable
78  # author        - User performing the change
79  # time_estimate - Estimated time
80  #
81  # Example Note text:
82  #
83  #   "removed time estimate"
84  #
85  #   "changed time estimate to 3d 5h"
86  #
87  # Returns the created Note object
88  def change_time_estimate(noteable, project, author)
89    ::SystemNotes::TimeTrackingService.new(noteable: noteable, project: project, author: author).change_time_estimate
90  end
91
92  # Called when the spent time of a Noteable is changed
93  #
94  # noteable   - Noteable object
95  # project    - Project owning noteable
96  # author     - User performing the change
97  # time_spent - Spent time
98  #
99  # Example Note text:
100  #
101  #   "removed time spent"
102  #
103  #   "added 2h 30m of time spent"
104  #
105  # Returns the created Note object
106  def change_time_spent(noteable, project, author)
107    ::SystemNotes::TimeTrackingService.new(noteable: noteable, project: project, author: author).change_time_spent
108  end
109
110  def close_after_error_tracking_resolve(issue, project, author)
111    ::SystemNotes::IssuablesService.new(noteable: issue, project: project, author: author).close_after_error_tracking_resolve
112  end
113
114  def change_status(noteable, project, author, status, source = nil)
115    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).change_status(status, source)
116  end
117
118  def request_attention(noteable, project, author, user)
119    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).request_attention(user)
120  end
121
122  def remove_attention_request(noteable, project, author, user)
123    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).remove_attention_request(user)
124  end
125
126  # Called when 'merge when pipeline succeeds' is executed
127  def merge_when_pipeline_succeeds(noteable, project, author, sha)
128    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author).merge_when_pipeline_succeeds(sha)
129  end
130
131  # Called when 'merge when pipeline succeeds' is canceled
132  def cancel_merge_when_pipeline_succeeds(noteable, project, author)
133    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author).cancel_merge_when_pipeline_succeeds
134  end
135
136  # Called when 'merge when pipeline succeeds' is aborted
137  def abort_merge_when_pipeline_succeeds(noteable, project, author, reason)
138    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author).abort_merge_when_pipeline_succeeds(reason)
139  end
140
141  def handle_merge_request_draft(noteable, project, author)
142    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author).handle_merge_request_draft
143  end
144
145  def add_merge_request_draft_from_commit(noteable, project, author, commit)
146    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author).add_merge_request_draft_from_commit(commit)
147  end
148
149  def resolve_all_discussions(merge_request, project, author)
150    ::SystemNotes::MergeRequestsService.new(noteable: merge_request, project: project, author: author).resolve_all_discussions
151  end
152
153  def discussion_continued_in_issue(discussion, project, author, issue)
154    ::SystemNotes::MergeRequestsService.new(project: project, author: author).discussion_continued_in_issue(discussion, issue)
155  end
156
157  def diff_discussion_outdated(discussion, project, author, change_position)
158    ::SystemNotes::MergeRequestsService.new(project: project, author: author).diff_discussion_outdated(discussion, change_position)
159  end
160
161  def change_title(noteable, project, author, old_title)
162    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).change_title(old_title)
163  end
164
165  def change_description(noteable, project, author)
166    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).change_description
167  end
168
169  def change_issue_confidentiality(issue, project, author)
170    ::SystemNotes::IssuablesService.new(noteable: issue, project: project, author: author).change_issue_confidentiality
171  end
172
173  # Called when a branch in Noteable is changed
174  #
175  # noteable    - Noteable object
176  # project     - Project owning noteable
177  # author      - User performing the change
178  # branch_type - 'source' or 'target'
179  # event_type  - the source of event: 'update' or 'delete'
180  # old_branch  - old branch name
181  # new_branch  - new branch name
182  #
183  # Example Note text is based on event_type:
184  #
185  #   update: "changed target branch from `Old` to `New`"
186  #   delete: "deleted the `Old` branch. This merge request now targets the `New` branch"
187  #
188  # Returns the created Note object
189  def change_branch(noteable, project, author, branch_type, event_type, old_branch, new_branch)
190    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author)
191      .change_branch(branch_type, event_type, old_branch, new_branch)
192  end
193
194  # Called when a branch in Noteable is added or deleted
195  #
196  # noteable    - Noteable object
197  # project     - Project owning noteable
198  # author      - User performing the change
199  # branch_type - :source or :target
200  # branch      - branch name
201  # presence    - :add or :delete
202  #
203  # Example Note text:
204  #
205  #   "restored target branch `feature`"
206  #
207  # Returns the created Note object
208  def change_branch_presence(noteable, project, author, branch_type, branch, presence)
209    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author).change_branch_presence(branch_type, branch, presence)
210  end
211
212  # Called when a branch is created from the 'new branch' button on a issue
213  # Example note text:
214  #
215  #   "created branch `201-issue-branch-button`"
216  def new_issue_branch(issue, project, author, branch, branch_project: nil)
217    ::SystemNotes::MergeRequestsService.new(noteable: issue, project: project, author: author).new_issue_branch(branch, branch_project: branch_project)
218  end
219
220  def new_merge_request(issue, project, author, merge_request)
221    ::SystemNotes::MergeRequestsService.new(noteable: issue, project: project, author: author).new_merge_request(merge_request)
222  end
223
224  def cross_reference(mentioned, mentioned_in, author)
225    ::SystemNotes::IssuablesService.new(noteable: mentioned, author: author).cross_reference(mentioned_in)
226  end
227
228  def cross_reference_exists?(mentioned, mentioned_in)
229    ::SystemNotes::IssuablesService.new(noteable: mentioned).cross_reference_exists?(mentioned_in)
230  end
231
232  def change_task_status(noteable, project, author, new_task)
233    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).change_task_status(new_task)
234  end
235
236  def noteable_moved(noteable, project, noteable_ref, author, direction:)
237    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).noteable_moved(noteable_ref, direction)
238  end
239
240  def noteable_cloned(noteable, project, noteable_ref, author, direction:)
241    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).noteable_cloned(noteable_ref, direction)
242  end
243
244  def mark_duplicate_issue(noteable, project, author, canonical_issue)
245    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).mark_duplicate_issue(canonical_issue)
246  end
247
248  def mark_canonical_issue_of_duplicate(noteable, project, author, duplicate_issue)
249    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).mark_canonical_issue_of_duplicate(duplicate_issue)
250  end
251
252  def add_email_participants(noteable, project, author, body)
253    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).add_email_participants(body)
254  end
255
256  def discussion_lock(issuable, author)
257    ::SystemNotes::IssuablesService.new(noteable: issuable, project: issuable.project, author: author).discussion_lock
258  end
259
260  def cross_reference_disallowed?(mentioned, mentioned_in)
261    ::SystemNotes::IssuablesService.new(noteable: mentioned).cross_reference_disallowed?(mentioned_in)
262  end
263
264  def zoom_link_added(issue, project, author)
265    ::SystemNotes::ZoomService.new(noteable: issue, project: project, author: author).zoom_link_added
266  end
267
268  def zoom_link_removed(issue, project, author)
269    ::SystemNotes::ZoomService.new(noteable: issue, project: project, author: author).zoom_link_removed
270  end
271
272  def auto_resolve_prometheus_alert(noteable, project, author)
273    ::SystemNotes::IssuablesService.new(noteable: noteable, project: project, author: author).auto_resolve_prometheus_alert
274  end
275
276  # Parameters:
277  #   - version [DesignManagement::Version]
278  #
279  # Example Note text:
280  #
281  #   "added [1 designs](link-to-version)"
282  #   "changed [2 designs](link-to-version)"
283  #
284  # Returns [Array<Note>]: the created Note objects
285  def design_version_added(version)
286    ::SystemNotes::DesignManagementService.new(noteable: version.issue, project: version.issue.project, author: version.author).design_version_added(version)
287  end
288
289  # Called when a new discussion is created on a design
290  #
291  # discussion_note - DiscussionNote
292  #
293  # Example Note text:
294  #
295  #   "started a discussion on screen.png"
296  #
297  # Returns the created Note object
298  def design_discussion_added(discussion_note)
299    design = discussion_note.noteable
300
301    ::SystemNotes::DesignManagementService.new(noteable: design.issue, project: design.project, author: discussion_note.author).design_discussion_added(discussion_note)
302  end
303
304  # Called when the merge request is approved by user
305  #
306  # noteable - Noteable object
307  # user     - User performing approve
308  #
309  # Example Note text:
310  #
311  #   "approved this merge request"
312  #
313  # Returns the created Note object
314  def approve_mr(noteable, user)
315    merge_requests_service(noteable, noteable.project, user).approve_mr
316  end
317
318  def unapprove_mr(noteable, user)
319    merge_requests_service(noteable, noteable.project, user).unapprove_mr
320  end
321
322  def change_alert_status(alert, author)
323    ::SystemNotes::AlertManagementService.new(noteable: alert, project: alert.project, author: author).change_alert_status(alert)
324  end
325
326  def new_alert_issue(alert, issue, author)
327    ::SystemNotes::AlertManagementService.new(noteable: alert, project: alert.project, author: author).new_alert_issue(issue)
328  end
329
330  def create_new_alert(alert, monitoring_tool)
331    ::SystemNotes::AlertManagementService.new(noteable: alert, project: alert.project).create_new_alert(monitoring_tool)
332  end
333
334  def change_incident_severity(incident, author)
335    ::SystemNotes::IncidentService.new(noteable: incident, project: incident.project, author: author).change_incident_severity
336  end
337
338  def resolve_incident_status(incident, author)
339    ::SystemNotes::IncidentService.new(noteable: incident, project: incident.project, author: author).resolve_incident_status
340  end
341
342  def log_resolving_alert(alert, monitoring_tool)
343    ::SystemNotes::AlertManagementService.new(noteable: alert, project: alert.project).log_resolving_alert(monitoring_tool)
344  end
345
346  def change_issue_type(issue, author)
347    ::SystemNotes::IssuablesService.new(noteable: issue, project: issue.project, author: author).change_issue_type
348  end
349
350  private
351
352  def merge_requests_service(noteable, project, author)
353    ::SystemNotes::MergeRequestsService.new(noteable: noteable, project: project, author: author)
354  end
355end
356
357SystemNoteService.prepend_mod_with('SystemNoteService')
358