summaryrefslogtreecommitdiff
path: root/lib/gitlab/github_import/importer/pull_request_review_importer.rb
blob: dd5b7c93ced7154265ee792bb506a1c343d93e97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# frozen_string_literal: true

module Gitlab
  module GithubImport
    module Importer
      class PullRequestReviewImporter
        def initialize(review, project, client)
          @review = review
          @project = project
          @client = client
          @merge_request = project.merge_requests.find_by_id(review.merge_request_id)
        end

        def execute
          user_finder = GithubImport::UserFinder.new(project, client)
          gitlab_user_id = user_finder.user_id_for(review.author)

          if gitlab_user_id
            add_review_note!(gitlab_user_id)
            add_approval!(gitlab_user_id)
          else
            add_complementary_review_note!(project.creator_id)
          end
        end

        private

        attr_reader :review, :merge_request, :project, :client

        def add_review_note!(author_id)
          return if review.note.empty?

          add_note!(author_id, review_note_content)
        end

        def add_complementary_review_note!(author_id)
          return if review.note.empty? && !review.approval?

          note_body = MarkdownText.format(
            review_note_content,
            review.author
          )

          add_note!(author_id, note_body)
        end

        def review_note_content
          header = "**Review:** #{review.review_type.humanize}"

          if review.note.present?
            "#{header}\n\n#{review.note}"
          else
            header
          end
        end

        def add_note!(author_id, note)
          note = Note.new(note_attributes(author_id, note))

          note.save!
        end

        def note_attributes(author_id, note, extra = {})
          {
            importing: true,
            noteable_id: merge_request.id,
            noteable_type: 'MergeRequest',
            project_id: project.id,
            author_id: author_id,
            note: note,
            system: false,
            created_at: submitted_at,
            updated_at: submitted_at
          }.merge(extra)
        end

        def add_approval!(user_id)
          return unless review.review_type == 'APPROVED'

          approval_attribues = {
            merge_request_id: merge_request.id,
            user_id: user_id,
            created_at: submitted_at,
            updated_at: submitted_at
          }

          result = ::Approval.insert(
            approval_attribues,
            returning: [:id],
            unique_by: [:user_id, :merge_request_id]
          )

          if result.rows.present?
            add_approval_system_note!(user_id)
          end
        end

        def add_approval_system_note!(user_id)
          attributes = note_attributes(
            user_id,
            'approved this merge request',
            system: true,
            system_note_metadata: SystemNoteMetadata.new(action: 'approved')
          )

          Note.create!(attributes)
        end

        def submitted_at
          @submitted_at ||= (review.submitted_at || merge_request.updated_at)
        end
      end
    end
  end
end