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

module Gitlab
  module GithubImport
    module Importer
      class IssueImporter
        include Gitlab::Import::DatabaseHelpers

        attr_reader :project, :issue, :client, :user_finder, :milestone_finder,
                    :issuable_finder

        # Imports an issue if it's a regular issue and not a pull request.
        def self.import_if_issue(issue, project, client)
          new(issue, project, client).execute unless issue.pull_request?
        end

        # issue - An instance of `Gitlab::GithubImport::Representation::Issue`.
        # project - An instance of `Project`
        # client - An instance of `Gitlab::GithubImport::Client`
        def initialize(issue, project, client)
          @issue = issue
          @project = project
          @client = client
          @user_finder = GithubImport::UserFinder.new(project, client)
          @milestone_finder = MilestoneFinder.new(project)
          @issuable_finder = GithubImport::IssuableFinder.new(project, issue)
        end

        def execute
          Issue.transaction do
            if (issue_id = create_issue)
              create_assignees(issue_id)
              issuable_finder.cache_database_id(issue_id)
            end
          end
        end

        # Creates a new GitLab issue for the current GitHub issue.
        #
        # Returns the ID of the created issue as an Integer. If the issue
        # couldn't be created this method will return `nil` instead.
        def create_issue
          author_id, author_found = user_finder.author_id_for(issue)

          description =
            MarkdownText.format(issue.description, issue.author, author_found)

          attributes = {
            iid: issue.iid,
            title: issue.truncated_title,
            author_id: author_id,
            project_id: project.id,
            description: description,
            milestone_id: milestone_finder.id_for(issue),
            state: issue.state,
            state_id: ::Issue.available_states[issue.state],
            created_at: issue.created_at,
            updated_at: issue.updated_at
          }

          insert_and_return_id(attributes, project.issues)
        rescue ActiveRecord::InvalidForeignKey
          # It's possible the project has been deleted since scheduling this
          # job. In this case we'll just skip creating the issue.
        end

        # Stores all issue assignees in the database.
        #
        # issue_id - The ID of the created issue.
        def create_assignees(issue_id)
          assignees = []

          issue.assignees.each do |assignee|
            if (user_id = user_finder.user_id_for(assignee))
              assignees << { issue_id: issue_id, user_id: user_id }
            end
          end

          Gitlab::Database.bulk_insert(IssueAssignee.table_name, assignees)
        end
      end
    end
  end
end