diff options
Diffstat (limited to 'lib/gitlab/github_import')
26 files changed, 320 insertions, 155 deletions
diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb index d2495b32800..11a41149274 100644 --- a/lib/gitlab/github_import/client.rb +++ b/lib/gitlab/github_import/client.rb @@ -107,7 +107,7 @@ module Gitlab # # rubocop: disable GitlabSecurity/PublicSend def each_page(method, *args, &block) - return to_enum(__method__, method, *args) unless block_given? + return to_enum(__method__, method, *args) unless block page = if args.last.is_a?(Hash) && args.last[:page] @@ -134,7 +134,7 @@ module Gitlab # method - The method to send to Octokit for querying data. # args - Any arguments to pass to the Octokit method. def each_object(method, *args, &block) - return to_enum(__method__, method, *args) unless block_given? + return to_enum(__method__, method, *args) unless block each_page(method, *args) do |page| page.objects.each do |object| diff --git a/lib/gitlab/github_import/importer/events/base_importer.rb b/lib/gitlab/github_import/importer/events/base_importer.rb new file mode 100644 index 00000000000..9ab1d916d33 --- /dev/null +++ b/lib/gitlab/github_import/importer/events/base_importer.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Gitlab + module GithubImport + module Importer + module Events + # Base class for importing issue events during project import from GitHub + class BaseImporter + # project - An instance of `Project`. + # client - An instance of `Gitlab::GithubImport::Client`. + def initialize(project, client) + @project = project + @user_finder = UserFinder.new(project, client) + end + + # issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`. + def execute(issue_event) + raise NotImplementedError + end + + private + + attr_reader :project, :user_finder + + def author_id(issue_event, author_key: :actor) + user_finder.author_id_for(issue_event, author_key: author_key).first + end + + def issuable_db_id(object) + IssuableFinder.new(project, object).database_id + end + end + end + end + end +end diff --git a/lib/gitlab/github_import/importer/events/changed_assignee.rb b/lib/gitlab/github_import/importer/events/changed_assignee.rb new file mode 100644 index 00000000000..c8f6335e4a8 --- /dev/null +++ b/lib/gitlab/github_import/importer/events/changed_assignee.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Gitlab + module GithubImport + module Importer + module Events + class ChangedAssignee < BaseImporter + def execute(issue_event) + assignee_id = author_id(issue_event, author_key: :assignee) + assigner_id = author_id(issue_event, author_key: :assigner) + + note_body = parse_body(issue_event, assigner_id, assignee_id) + + create_note(issue_event, note_body, assigner_id) + end + + private + + def create_note(issue_event, note_body, assigner_id) + Note.create!( + system: true, + noteable_type: Issue.name, + noteable_id: issuable_db_id(issue_event), + project: project, + author_id: assigner_id, + note: note_body, + system_note_metadata: SystemNoteMetadata.new( + { + action: "assignee", + created_at: issue_event.created_at, + updated_at: issue_event.created_at + } + ), + created_at: issue_event.created_at, + updated_at: issue_event.created_at + ) + end + + def parse_body(issue_event, assigner_id, assignee_id) + Gitlab::I18n.with_default_locale do + if issue_event.event == "unassigned" + "unassigned #{User.find(assigner_id).to_reference}" + else + "assigned to #{User.find(assignee_id).to_reference}" + end + end + end + end + end + end + end +end diff --git a/lib/gitlab/github_import/importer/events/changed_label.rb b/lib/gitlab/github_import/importer/events/changed_label.rb index 6c408158b02..818a9202745 100644 --- a/lib/gitlab/github_import/importer/events/changed_label.rb +++ b/lib/gitlab/github_import/importer/events/changed_label.rb @@ -4,25 +4,17 @@ module Gitlab module GithubImport module Importer module Events - class ChangedLabel - def initialize(project, user_id) - @project = project - @user_id = user_id - end - - # issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`. + class ChangedLabel < BaseImporter def execute(issue_event) create_event(issue_event) end private - attr_reader :project, :user_id - def create_event(issue_event) ResourceLabelEvent.create!( - issue_id: issue_event.issue_db_id, - user_id: user_id, + issue_id: issuable_db_id(issue_event), + user_id: author_id(issue_event), label_id: label_finder.id_for(issue_event.label_title), action: action(issue_event.event), created_at: issue_event.created_at diff --git a/lib/gitlab/github_import/importer/events/changed_milestone.rb b/lib/gitlab/github_import/importer/events/changed_milestone.rb new file mode 100644 index 00000000000..3164c041dc3 --- /dev/null +++ b/lib/gitlab/github_import/importer/events/changed_milestone.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Gitlab + module GithubImport + module Importer + module Events + class ChangedMilestone < BaseImporter + # GitHub API doesn't provide the historical state of an issue for + # de/milestoned issue events. So we'll assign the default state to + # those events that are imported from GitHub. + DEFAULT_STATE = Issue.available_states[:opened] + + def execute(issue_event) + create_event(issue_event) + end + + private + + def create_event(issue_event) + ResourceMilestoneEvent.create!( + issue_id: issuable_db_id(issue_event), + user_id: author_id(issue_event), + created_at: issue_event.created_at, + milestone_id: project.milestones.find_by_title(issue_event.milestone_title)&.id, + action: action(issue_event.event), + state: DEFAULT_STATE + ) + end + + def action(event_type) + return ResourceMilestoneEvent.actions[:remove] if event_type == 'demilestoned' + + ResourceMilestoneEvent.actions[:add] + end + end + end + end + end +end diff --git a/lib/gitlab/github_import/importer/events/closed.rb b/lib/gitlab/github_import/importer/events/closed.rb index 8b2136c9b24..ca8730d0f27 100644 --- a/lib/gitlab/github_import/importer/events/closed.rb +++ b/lib/gitlab/github_import/importer/events/closed.rb @@ -4,15 +4,7 @@ module Gitlab module GithubImport module Importer module Events - class Closed - attr_reader :project, :user_id - - def initialize(project, user_id) - @project = project - @user_id = user_id - end - - # issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`. + class Closed < BaseImporter def execute(issue_event) create_event(issue_event) create_state_event(issue_event) @@ -23,10 +15,10 @@ module Gitlab def create_event(issue_event) Event.create!( project_id: project.id, - author_id: user_id, + author_id: author_id(issue_event), action: 'closed', target_type: Issue.name, - target_id: issue_event.issue_db_id, + target_id: issuable_db_id(issue_event), created_at: issue_event.created_at, updated_at: issue_event.created_at ) @@ -34,8 +26,8 @@ module Gitlab def create_state_event(issue_event) ResourceStateEvent.create!( - user_id: user_id, - issue_id: issue_event.issue_db_id, + user_id: author_id(issue_event), + issue_id: issuable_db_id(issue_event), source_commit: issue_event.commit_id, state: 'closed', close_after_error_tracking_resolve: false, diff --git a/lib/gitlab/github_import/importer/events/cross_referenced.rb b/lib/gitlab/github_import/importer/events/cross_referenced.rb index 20b902cfe50..89fc1bdeb09 100644 --- a/lib/gitlab/github_import/importer/events/cross_referenced.rb +++ b/lib/gitlab/github_import/importer/events/cross_referenced.rb @@ -4,15 +4,7 @@ module Gitlab module GithubImport module Importer module Events - class CrossReferenced - attr_reader :project, :user_id - - def initialize(project, user_id) - @project = project - @user_id = user_id - end - - # issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`. + 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) @@ -21,14 +13,15 @@ module Gitlab ) 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) - create_note(issue_event, note_body) + track_activity(mentioned_in_record_class, user_id) + create_note(issue_event, note_body, user_id) end private - def track_activity(mentioned_in_class) + def track_activity(mentioned_in_class, user_id) return if mentioned_in_class != Issue Gitlab::UsageDataCounters::HLLRedisCounter.track_event( @@ -37,11 +30,11 @@ module Gitlab ) end - def create_note(issue_event, note_body) + def create_note(issue_event, note_body, user_id) Note.create!( system: true, noteable_type: Issue.name, - noteable_id: issue_event.issue_db_id, + noteable_id: issuable_db_id(issue_event), project: project, author_id: user_id, note: note_body, @@ -73,7 +66,7 @@ module Gitlab iid: number, issuable_type: record_class.name ) - Gitlab::GithubImport::IssuableFinder.new(project, mentioned_in_adapter).database_id + issuable_db_id(mentioned_in_adapter) end def cross_reference_note_content(gfm_reference) diff --git a/lib/gitlab/github_import/importer/events/renamed.rb b/lib/gitlab/github_import/importer/events/renamed.rb index 6a11c492210..96d112b04c6 100644 --- a/lib/gitlab/github_import/importer/events/renamed.rb +++ b/lib/gitlab/github_import/importer/events/renamed.rb @@ -4,27 +4,19 @@ module Gitlab module GithubImport module Importer module Events - class Renamed - def initialize(project, user_id) - @project = project - @user_id = user_id - end - - # issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent` + class Renamed < BaseImporter def execute(issue_event) Note.create!(note_params(issue_event)) end private - attr_reader :project, :user_id - def note_params(issue_event) { - noteable_id: issue_event.issue_db_id, + noteable_id: issuable_db_id(issue_event), noteable_type: Issue.name, project_id: project.id, - author_id: user_id, + author_id: author_id(issue_event), note: parse_body(issue_event), system: true, created_at: issue_event.created_at, diff --git a/lib/gitlab/github_import/importer/events/reopened.rb b/lib/gitlab/github_import/importer/events/reopened.rb index c0f3802bc46..b75344bf817 100644 --- a/lib/gitlab/github_import/importer/events/reopened.rb +++ b/lib/gitlab/github_import/importer/events/reopened.rb @@ -4,15 +4,7 @@ module Gitlab module GithubImport module Importer module Events - class Reopened - attr_reader :project, :user_id - - def initialize(project, user_id) - @project = project - @user_id = user_id - end - - # issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`. + class Reopened < BaseImporter def execute(issue_event) create_event(issue_event) create_state_event(issue_event) @@ -23,10 +15,10 @@ module Gitlab def create_event(issue_event) Event.create!( project_id: project.id, - author_id: user_id, + author_id: author_id(issue_event), action: 'reopened', target_type: Issue.name, - target_id: issue_event.issue_db_id, + target_id: issuable_db_id(issue_event), created_at: issue_event.created_at, updated_at: issue_event.created_at ) @@ -34,8 +26,8 @@ module Gitlab def create_state_event(issue_event) ResourceStateEvent.create!( - user_id: user_id, - issue_id: issue_event.issue_db_id, + user_id: author_id(issue_event), + issue_id: issuable_db_id(issue_event), state: 'reopened', created_at: issue_event.created_at ) diff --git a/lib/gitlab/github_import/importer/issue_event_importer.rb b/lib/gitlab/github_import/importer/issue_event_importer.rb index e451af61ec3..ef456e56ee1 100644 --- a/lib/gitlab/github_import/importer/issue_event_importer.rb +++ b/lib/gitlab/github_import/importer/issue_event_importer.rb @@ -4,7 +4,7 @@ module Gitlab module GithubImport module Importer class IssueEventImporter - attr_reader :issue_event, :project, :client, :user_finder + attr_reader :issue_event, :project, :client # issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`. # project - An instance of `Project`. @@ -13,26 +13,16 @@ module Gitlab @issue_event = issue_event @project = project @client = client - @user_finder = UserFinder.new(project, client) end + # TODO: Add MergeRequest events support + # https://gitlab.com/groups/gitlab-org/-/epics/7673 def execute - case issue_event.event - when 'closed' - Gitlab::GithubImport::Importer::Events::Closed.new(project, author_id) - .execute(issue_event) - when 'reopened' - Gitlab::GithubImport::Importer::Events::Reopened.new(project, author_id) - .execute(issue_event) - when 'labeled', 'unlabeled' - Gitlab::GithubImport::Importer::Events::ChangedLabel.new(project, author_id) - .execute(issue_event) - when 'renamed' - Gitlab::GithubImport::Importer::Events::Renamed.new(project, author_id) - .execute(issue_event) - when 'cross-referenced' - Gitlab::GithubImport::Importer::Events::CrossReferenced.new(project, author_id) - .execute(issue_event) + return if issue_event.issuable_type == 'MergeRequest' + + importer = event_importer_class(issue_event) + if importer + importer.new(project, client).execute(issue_event) else Gitlab::GithubImport::Logger.debug( message: 'UNSUPPORTED_EVENT_TYPE', @@ -43,9 +33,23 @@ module Gitlab private - def author_id - id, _status = user_finder.author_id_for(issue_event, author_key: :actor) - id + def event_importer_class(issue_event) + case issue_event.event + when 'closed' + Gitlab::GithubImport::Importer::Events::Closed + when 'reopened' + Gitlab::GithubImport::Importer::Events::Reopened + when 'labeled', 'unlabeled' + Gitlab::GithubImport::Importer::Events::ChangedLabel + when 'renamed' + Gitlab::GithubImport::Importer::Events::Renamed + when 'milestoned', 'demilestoned' + Gitlab::GithubImport::Importer::Events::ChangedMilestone + when 'cross-referenced' + Gitlab::GithubImport::Importer::Events::CrossReferenced + when 'assigned', 'unassigned' + Gitlab::GithubImport::Importer::Events::ChangedAssignee + end end end end diff --git a/lib/gitlab/github_import/importer/issue_events_importer.rb b/lib/gitlab/github_import/importer/issue_events_importer.rb new file mode 100644 index 00000000000..71dd99f91f9 --- /dev/null +++ b/lib/gitlab/github_import/importer/issue_events_importer.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Gitlab + module GithubImport + module Importer + class IssueEventsImporter + include ParallelScheduling + + def importer_class + IssueEventImporter + end + + def representation_class + Representation::IssueEvent + end + + def sidekiq_worker_class + ImportIssueEventWorker + end + + def object_type + :issue_event + end + + def collection_method + :repository_issue_events + end + + def id_for_already_imported_cache(event) + event.id + end + end + end + end +end diff --git a/lib/gitlab/github_import/importer/issue_importer.rb b/lib/gitlab/github_import/importer/issue_importer.rb index e7d41856b04..d964bae3dd2 100644 --- a/lib/gitlab/github_import/importer/issue_importer.rb +++ b/lib/gitlab/github_import/importer/issue_importer.rb @@ -56,7 +56,8 @@ module Gitlab milestone_id: milestone_finder.id_for(issue), state_id: ::Issue.available_states[issue.state], created_at: issue.created_at, - updated_at: issue.updated_at + updated_at: issue.updated_at, + work_item_type_id: issue.work_item_type_id } insert_and_return_id(attributes, project.issues) diff --git a/lib/gitlab/github_import/importer/issues_importer.rb b/lib/gitlab/github_import/importer/issues_importer.rb index 6cc1a61b332..21d9ce8cd2d 100644 --- a/lib/gitlab/github_import/importer/issues_importer.rb +++ b/lib/gitlab/github_import/importer/issues_importer.rb @@ -6,6 +6,12 @@ module Gitlab class IssuesImporter include ParallelScheduling + def initialize(project, client, parallel: true) + super + + @work_item_type_id = ::WorkItems::Type.default_issue_type.id + end + def importer_class IssueAndLabelLinksImporter end @@ -33,6 +39,12 @@ module Gitlab def collection_options { state: 'all', sort: 'created', direction: 'asc' } end + + private + + def additional_object_data + { work_item_type_id: @work_item_type_id } + end end end end diff --git a/lib/gitlab/github_import/importer/releases_importer.rb b/lib/gitlab/github_import/importer/releases_importer.rb index 7241e1ef703..51d364772d2 100644 --- a/lib/gitlab/github_import/importer/releases_importer.rb +++ b/lib/gitlab/github_import/importer/releases_importer.rb @@ -27,9 +27,10 @@ module Gitlab def build(release) existing_tags.add(release.tag_name) - build_hash = { + { name: release.name, tag: release.tag_name, + author_id: fetch_author_id(release), description: description_for(release), created_at: release.created_at, updated_at: release.created_at, @@ -37,12 +38,6 @@ module Gitlab released_at: release.published_at || Time.current, project_id: project.id } - - if Feature.enabled?(:import_release_authors_from_github, project) - build_hash[:author_id] = fetch_author_id(release) - end - - build_hash end def each_release diff --git a/lib/gitlab/github_import/importer/single_endpoint_issue_events_importer.rb b/lib/gitlab/github_import/importer/single_endpoint_issue_events_importer.rb index 45bbc25e637..8e4015acbbc 100644 --- a/lib/gitlab/github_import/importer/single_endpoint_issue_events_importer.rb +++ b/lib/gitlab/github_import/importer/single_endpoint_issue_events_importer.rb @@ -18,13 +18,16 @@ module Gitlab { project: project.id, collection: collection_method } end + # In single endpoint there is no issue info to which associated related + # To make it possible to identify issue in separated worker we need to patch + # Sawyer instances here with issue number def each_associated(parent_record, associated) compose_associated_id!(parent_record, associated) return if already_imported?(associated) Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched) - associated.issue_db_id = parent_record.id + associated.issue = { 'number' => parent_record.iid } yield(associated) mark_as_imported(associated) diff --git a/lib/gitlab/github_import/issuable_finder.rb b/lib/gitlab/github_import/issuable_finder.rb index da205ebd345..e7a1b7b3368 100644 --- a/lib/gitlab/github_import/issuable_finder.rb +++ b/lib/gitlab/github_import/issuable_finder.rb @@ -69,6 +69,8 @@ module Gitlab object.noteable_id elsif object.respond_to?(:iid) object.iid + elsif object.respond_to?(:issuable_id) + object.issuable_id else raise( TypeError, diff --git a/lib/gitlab/github_import/parallel_scheduling.rb b/lib/gitlab/github_import/parallel_scheduling.rb index ab20b372d53..a8c18c74d24 100644 --- a/lib/gitlab/github_import/parallel_scheduling.rb +++ b/lib/gitlab/github_import/parallel_scheduling.rb @@ -63,7 +63,7 @@ module Gitlab # Imports all the objects in sequence in the current thread. def sequential_import each_object_to_import do |object| - repr = representation_class.from_api_response(object) + repr = representation_class.from_api_response(object, additional_object_data) importer_class.new(repr, project, client).execute end @@ -72,26 +72,9 @@ module Gitlab # Imports all objects in parallel by scheduling a Sidekiq job for every # individual object. def parallel_import - if parallel_import_batch.present? - spread_parallel_import - else - parallel_import_deprecated - end - end - - def parallel_import_deprecated - waiter = JobWaiter.new - - each_object_to_import do |object| - repr = representation_class.from_api_response(object) - - sidekiq_worker_class - .perform_async(project.id, repr.to_hash, waiter.key) + raise 'Batch settings must be defined for parallel import' if parallel_import_batch.blank? - waiter.jobs_remaining += 1 - end - - waiter + spread_parallel_import end def spread_parallel_import @@ -100,7 +83,7 @@ module Gitlab import_arguments = [] each_object_to_import do |object| - repr = representation_class.from_api_response(object) + repr = representation_class.from_api_response(object, additional_object_data) import_arguments << [project.id, repr.to_hash, waiter.key] @@ -223,6 +206,10 @@ module Gitlab private + def additional_object_data + {} + end + def info(project_id, extra = {}) Logger.info(log_attributes(project_id, extra)) end diff --git a/lib/gitlab/github_import/representation/diff_note.rb b/lib/gitlab/github_import/representation/diff_note.rb index 883abef9bdb..64aa6ea5cb4 100644 --- a/lib/gitlab/github_import/representation/diff_note.rb +++ b/lib/gitlab/github_import/representation/diff_note.rb @@ -20,7 +20,7 @@ module Gitlab # Builds a diff note from a GitHub API response. # # note - An instance of `Sawyer::Resource` containing the note details. - def self.from_api_response(note) + def self.from_api_response(note, additional_data = {}) matches = note.html_url.match(NOTEABLE_ID_REGEX) unless matches diff --git a/lib/gitlab/github_import/representation/issue.rb b/lib/gitlab/github_import/representation/issue.rb index db4a8188c03..9d457ec1c2f 100644 --- a/lib/gitlab/github_import/representation/issue.rb +++ b/lib/gitlab/github_import/representation/issue.rb @@ -11,13 +11,13 @@ module Gitlab expose_attribute :iid, :title, :description, :milestone_number, :created_at, :updated_at, :state, :assignees, - :label_names, :author + :label_names, :author, :work_item_type_id # Builds an issue from a GitHub API response. # # issue - An instance of `Sawyer::Resource` containing the issue # details. - def self.from_api_response(issue) + def self.from_api_response(issue, additional_data = {}) user = if issue.user Representation::User.from_api_response(issue.user) @@ -36,7 +36,8 @@ module Gitlab author: user, created_at: issue.created_at, updated_at: issue.updated_at, - pull_request: issue.pull_request ? true : false + pull_request: issue.pull_request ? true : false, + work_item_type_id: additional_data[:work_item_type_id] } new(hash) diff --git a/lib/gitlab/github_import/representation/issue_event.rb b/lib/gitlab/github_import/representation/issue_event.rb index 9016338db3b..67a5df73a97 100644 --- a/lib/gitlab/github_import/representation/issue_event.rb +++ b/lib/gitlab/github_import/representation/issue_event.rb @@ -10,34 +10,7 @@ module Gitlab attr_reader :attributes expose_attribute :id, :actor, :event, :commit_id, :label_title, :old_title, :new_title, - :source, :created_at - expose_attribute :issue_db_id # set in SingleEndpointIssueEventsImporter#each_associated - - # Builds a event from a GitHub API response. - # - # event - An instance of `Sawyer::Resource` containing the event details. - def self.from_api_response(event) - new( - id: event.id, - actor: event.actor && Representation::User.from_api_response(event.actor), - event: event.event, - commit_id: event.commit_id, - label_title: event.label && event.label[:name], - old_title: event.rename && event.rename[:from], - new_title: event.rename && event.rename[:to], - source: event.source, - issue_db_id: event.issue_db_id, - created_at: event.created_at - ) - end - - # Builds a event using a Hash that was built from a JSON payload. - def self.from_json_hash(raw_hash) - hash = Representation.symbolize_hash(raw_hash) - hash[:actor] &&= Representation::User.from_json_hash(hash[:actor]) - - new(hash) - end + :milestone_title, :issue, :source, :assignee, :assigner, :created_at # attributes - A Hash containing the event details. The keys of this # Hash (and any nested hashes) must be symbols. @@ -48,6 +21,60 @@ module Gitlab def github_identifiers { id: id } end + + def issuable_type + issue && issue[:pull_request].present? ? 'MergeRequest' : 'Issue' + end + + def issuable_id + issue && issue[:number] + end + + class << self + # Builds an event from a GitHub API response. + # + # event - An instance of `Sawyer::Resource` containing the event details. + def from_api_response(event, additional_data = {}) + new( + id: event.id, + actor: user_representation(event.actor), + event: event.event, + commit_id: event.commit_id, + label_title: event.label && event.label[:name], + old_title: event.rename && event.rename[:from], + new_title: event.rename && event.rename[:to], + milestone_title: event.milestone && event.milestone[:title], + issue: event.issue&.to_h&.symbolize_keys, + source: event.source, + assignee: user_representation(event.assignee), + assigner: user_representation(event.assigner), + created_at: event.created_at + ) + end + + # Builds an event using a Hash that was built from a JSON payload. + def from_json_hash(raw_hash) + hash = Representation.symbolize_hash(raw_hash) + hash[:actor] = user_representation(hash[:actor], source: :hash) + hash[:assignee] = user_representation(hash[:assignee], source: :hash) + hash[:assigner] = user_representation(hash[:assigner], source: :hash) + + new(hash) + end + + private + + def user_representation(data, source: :api_response) + return unless data + + case source + when :api_response + Representation::User.from_api_response(data) + when :hash + Representation::User.from_json_hash(data) + end + end + end end end end diff --git a/lib/gitlab/github_import/representation/lfs_object.rb b/lib/gitlab/github_import/representation/lfs_object.rb index 18737bfcde3..cd614db2161 100644 --- a/lib/gitlab/github_import/representation/lfs_object.rb +++ b/lib/gitlab/github_import/representation/lfs_object.rb @@ -12,7 +12,7 @@ module Gitlab expose_attribute :oid, :link, :size # Builds a lfs_object - def self.from_api_response(lfs_object) + def self.from_api_response(lfs_object, additional_data = {}) new( oid: lfs_object.oid, link: lfs_object.link, diff --git a/lib/gitlab/github_import/representation/note.rb b/lib/gitlab/github_import/representation/note.rb index bbf20b7e9e6..ae56c370b19 100644 --- a/lib/gitlab/github_import/representation/note.rb +++ b/lib/gitlab/github_import/representation/note.rb @@ -17,7 +17,7 @@ module Gitlab # Builds a note from a GitHub API response. # # note - An instance of `Sawyer::Resource` containing the note details. - def self.from_api_response(note) + def self.from_api_response(note, additional_data = {}) matches = note.html_url.match(NOTEABLE_TYPE_REGEX) if !matches || !matches[:type] diff --git a/lib/gitlab/github_import/representation/pull_request.rb b/lib/gitlab/github_import/representation/pull_request.rb index 82bcdee8b2b..2adac2af502 100644 --- a/lib/gitlab/github_import/representation/pull_request.rb +++ b/lib/gitlab/github_import/representation/pull_request.rb @@ -18,7 +18,7 @@ module Gitlab # Builds a PR from a GitHub API response. # # issue - An instance of `Sawyer::Resource` containing the PR details. - def self.from_api_response(pr) + def self.from_api_response(pr, additional_data = {}) assignee = Representation::User.from_api_response(pr.assignee) if pr.assignee user = Representation::User.from_api_response(pr.user) if pr.user merged_by = Representation::User.from_api_response(pr.merged_by) if pr.merged_by diff --git a/lib/gitlab/github_import/representation/pull_request_review.rb b/lib/gitlab/github_import/representation/pull_request_review.rb index 70c1e51ffdd..8a7ecf0c588 100644 --- a/lib/gitlab/github_import/representation/pull_request_review.rb +++ b/lib/gitlab/github_import/representation/pull_request_review.rb @@ -11,7 +11,7 @@ module Gitlab expose_attribute :author, :note, :review_type, :submitted_at, :merge_request_id, :review_id - def self.from_api_response(review) + def self.from_api_response(review, additional_data = {}) user = Representation::User.from_api_response(review.user) if review.user new( diff --git a/lib/gitlab/github_import/representation/user.rb b/lib/gitlab/github_import/representation/user.rb index fac8920a3f2..4ef916cc41c 100644 --- a/lib/gitlab/github_import/representation/user.rb +++ b/lib/gitlab/github_import/representation/user.rb @@ -14,7 +14,7 @@ module Gitlab # Builds a user from a GitHub API response. # # user - An instance of `Sawyer::Resource` containing the user details. - def self.from_api_response(user) + def self.from_api_response(user, additional_data = {}) new( id: user.id, login: user.login diff --git a/lib/gitlab/github_import/user_finder.rb b/lib/gitlab/github_import/user_finder.rb index efaa2ce3002..6d6a00d260d 100644 --- a/lib/gitlab/github_import/user_finder.rb +++ b/lib/gitlab/github_import/user_finder.rb @@ -40,7 +40,17 @@ module Gitlab # If the object has no author ID we'll use the ID of the GitLab ghost # user. def author_id_for(object, author_key: :author) - user_info = author_key == :actor ? object&.actor : object&.author + user_info = case author_key + when :actor + object&.actor + when :assignee + object&.assignee + when :assigner + object&.assigner + else + object&.author + end + id = user_info ? user_id_for(user_info) : GithubImport.ghost_user_id if id @@ -148,7 +158,7 @@ module Gitlab # rubocop: disable CodeReuse/ActiveRecord def query_id_for_github_email(email) - User.by_any_email(email).pluck(:id).first + User.by_any_email(email).pick(:id) end # rubocop: enable CodeReuse/ActiveRecord |