summaryrefslogtreecommitdiff
path: root/lib/gitlab/github_import/importer/events/cross_referenced.rb
blob: b56ae186d3c5d81511f76537cee98dd8303c0e56 (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
# frozen_string_literal: true

module Gitlab
  module GithubImport
    module Importer
      module Events
        class CrossReferenced < BaseImporter
          def execute(issue_event)
            mentioned_in_record_class = mentioned_in_type(issue_event)
            mentioned_in_number = issue_event.source.dig(:issue, :number)
            mentioned_in_record = init_mentioned_in(
              mentioned_in_record_class, mentioned_in_number
            )
            return if mentioned_in_record.nil?

            user_id = author_id(issue_event)
            note_body = cross_reference_note_content(mentioned_in_record.gfm_reference(project))
            track_activity(mentioned_in_record_class, user_id)
            create_note(issue_event, note_body, user_id)
          end

          private

          def track_activity(mentioned_in_class, user_id)
            return if mentioned_in_class != Issue

            Gitlab::UsageDataCounters::HLLRedisCounter.track_event(
              Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CROSS_REFERENCED,
              values: user_id
            )
          end

          def create_note(issue_event, note_body, user_id)
            Note.create!(
              system: true,
              noteable_type: issuable_type(issue_event),
              noteable_id: issuable_db_id(issue_event),
              project: project,
              author_id: user_id,
              note: note_body,
              system_note_metadata: SystemNoteMetadata.new(action: 'cross_reference'),
              created_at: issue_event.created_at
            )
          end

          def mentioned_in_type(issue_event)
            is_pull_request = issue_event.source.dig(:issue, :pull_request).present?
            is_pull_request ? MergeRequest : Issue
          end

          # record_class - Issue/MergeRequest
          def init_mentioned_in(record_class, iid)
            db_id = fetch_mentioned_in_db_id(record_class, iid)
            return if db_id.nil?

            record = record_class.new(id: db_id, iid: iid)
            record.project = project
            record.readonly!
            record
          end

          # record_class - Issue/MergeRequest
          def fetch_mentioned_in_db_id(record_class, number)
            sawyer_mentioned_in_adapter = Struct.new(:iid, :issuable_type, keyword_init: true)
            mentioned_in_adapter = sawyer_mentioned_in_adapter.new(
              iid: number, issuable_type: record_class.name
            )

            issuable_db_id(mentioned_in_adapter)
          end

          def cross_reference_note_content(gfm_reference)
            "#{::SystemNotes::IssuablesService.cross_reference_note_prefix}#{gfm_reference}"
          end
        end
      end
    end
  end
end