Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 17:34:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 17:34:42 +0300
commit9f46488805e86b1bc341ea1620b866016c2ce5ed (patch)
treef9748c7e287041e37d6da49e0a29c9511dc34768 /lib/gitlab/jira_import
parentdfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff)
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'lib/gitlab/jira_import')
-rw-r--r--lib/gitlab/jira_import/base_importer.rb5
-rw-r--r--lib/gitlab/jira_import/handle_labels_service.rb39
-rw-r--r--lib/gitlab/jira_import/issue_serializer.rb62
-rw-r--r--lib/gitlab/jira_import/issues_importer.rb2
-rw-r--r--lib/gitlab/jira_import/labels_importer.rb26
-rw-r--r--lib/gitlab/jira_import/metadata_collector.rb57
-rw-r--r--lib/gitlab/jira_import/user_mapper.rb53
7 files changed, 200 insertions, 44 deletions
diff --git a/lib/gitlab/jira_import/base_importer.rb b/lib/gitlab/jira_import/base_importer.rb
index 5381812186d..306736df30f 100644
--- a/lib/gitlab/jira_import/base_importer.rb
+++ b/lib/gitlab/jira_import/base_importer.rb
@@ -3,12 +3,13 @@
module Gitlab
module JiraImport
class BaseImporter
- attr_reader :project, :client, :formatter, :jira_project_key
+ attr_reader :project, :client, :formatter, :jira_project_key, :running_import
def initialize(project)
project.validate_jira_import_settings!
- @jira_project_key = project.latest_jira_import&.jira_project_key
+ @running_import = project.latest_jira_import
+ @jira_project_key = running_import&.jira_project_key
raise Projects::ImportService::Error, _('Unable to find Jira project to import data from.') unless @jira_project_key
diff --git a/lib/gitlab/jira_import/handle_labels_service.rb b/lib/gitlab/jira_import/handle_labels_service.rb
new file mode 100644
index 00000000000..1b00515cced
--- /dev/null
+++ b/lib/gitlab/jira_import/handle_labels_service.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module JiraImport
+ class HandleLabelsService
+ def initialize(project, jira_labels)
+ @project = project
+ @jira_labels = jira_labels
+ end
+
+ def execute
+ return if jira_labels.blank?
+
+ existing_labels = LabelsFinder.new(nil, project: project, title: jira_labels)
+ .execute(skip_authorization: true).select(:id, :name)
+ new_labels = create_missing_labels(existing_labels)
+
+ label_ids = existing_labels.map(&:id)
+ label_ids += new_labels if new_labels.present?
+ label_ids
+ end
+
+ private
+
+ attr_reader :project, :jira_labels
+
+ def create_missing_labels(existing_labels)
+ labels_to_create = jira_labels - existing_labels.map(&:name)
+ return if labels_to_create.empty?
+
+ new_labels_hash = labels_to_create.map do |title|
+ { project_id: project.id, title: title, type: 'ProjectLabel' }
+ end
+
+ Label.insert_all(new_labels_hash).rows.flatten
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/jira_import/issue_serializer.rb b/lib/gitlab/jira_import/issue_serializer.rb
index cdcb62ac6e9..df57680073e 100644
--- a/lib/gitlab/jira_import/issue_serializer.rb
+++ b/lib/gitlab/jira_import/issue_serializer.rb
@@ -3,15 +3,14 @@
module Gitlab
module JiraImport
class IssueSerializer
- attr_reader :jira_issue, :project, :params, :formatter
- attr_accessor :metadata
+ attr_reader :jira_issue, :project, :import_owner_id, :params, :formatter
- def initialize(project, jira_issue, params = {})
+ def initialize(project, jira_issue, import_owner_id, params = {})
@jira_issue = jira_issue
@project = project
+ @import_owner_id = import_owner_id
@params = params
@formatter = Gitlab::ImportFormatter.new
- @metadata = []
end
def execute
@@ -23,7 +22,9 @@ module Gitlab
state_id: map_status(jira_issue.status.statusCategory),
updated_at: jira_issue.updated,
created_at: jira_issue.created,
- author_id: project.creator_id # TODO: map actual author: https://gitlab.com/gitlab-org/gitlab/-/issues/210580
+ author_id: reporter,
+ assignee_ids: assignees,
+ label_ids: label_ids
}
end
@@ -35,10 +36,8 @@ module Gitlab
def description
body = []
- body << formatter.author_line(jira_issue.reporter.displayName)
- body << formatter.assignee_line(jira_issue.assignee.displayName) if jira_issue.assignee
body << jira_issue.description
- body << add_metadata
+ body << MetadataCollector.new(jira_issue).execute
body.join
end
@@ -52,48 +51,33 @@ module Gitlab
end
end
- def add_metadata
- add_field(%w(issuetype name), 'Issue type')
- add_field(%w(priority name), 'Priority')
- add_labels
- add_field('environment', 'Environment')
- add_field('duedate', 'Due date')
- add_parent
- add_versions
-
- return if metadata.empty?
-
- metadata.join("\n").prepend("\n\n---\n\n**Issue metadata**\n\n")
+ def map_user_id(jira_user)
+ Gitlab::JiraImport::UserMapper.new(project, jira_user).execute&.id
end
- def add_field(keys, field_label)
- value = fields.dig(*keys)
- return if value.blank?
-
- metadata << "- #{field_label}: #{value}"
+ def reporter
+ map_user_id(jira_issue.reporter&.attrs) || import_owner_id
end
- def add_labels
- return if fields['labels'].blank?
-
- metadata << "- Labels: #{fields['labels'].join(', ')}"
- end
+ def assignees
+ found_user_id = map_user_id(jira_issue.assignee&.attrs)
- def add_parent
- parent_issue_key = fields.dig('parent', 'key')
- return if parent_issue_key.blank?
+ return unless found_user_id
- metadata << "- Parent issue: [#{parent_issue_key}] #{fields['parent']['fields']['summary']}"
+ [found_user_id]
end
- def add_versions
- return if fields['fixVersions'].blank?
+ # We already create labels in Gitlab::JiraImport::LabelsImporter stage but
+ # there is a possibility it may fail or
+ # new labels were created on the Jira in the meantime
+ def label_ids
+ return if jira_issue.fields['labels'].blank?
- metadata << "- Fix versions: #{fields['fixVersions'].map { |version| version['name'] }.join(', ')}"
+ Gitlab::JiraImport::HandleLabelsService.new(project, jira_issue.fields['labels']).execute
end
- def fields
- jira_issue.fields
+ def logger
+ @logger ||= Gitlab::Import::Logger.build
end
end
end
diff --git a/lib/gitlab/jira_import/issues_importer.rb b/lib/gitlab/jira_import/issues_importer.rb
index 6543b633ddf..8c18e58d9df 100644
--- a/lib/gitlab/jira_import/issues_importer.rb
+++ b/lib/gitlab/jira_import/issues_importer.rb
@@ -57,7 +57,7 @@ module Gitlab
# For such cases we exit early if issue was already imported.
next if already_imported?(jira_issue.id)
- issue_attrs = IssueSerializer.new(project, jira_issue, { iid: next_iid }).execute
+ issue_attrs = IssueSerializer.new(project, jira_issue, running_import.user_id, { iid: next_iid }).execute
Gitlab::JiraImport::ImportIssueWorker.perform_async(project.id, jira_issue.id, issue_attrs, job_waiter.key)
job_waiter.jobs_remaining += 1
diff --git a/lib/gitlab/jira_import/labels_importer.rb b/lib/gitlab/jira_import/labels_importer.rb
index 35c434e48a4..6e6842e06bf 100644
--- a/lib/gitlab/jira_import/labels_importer.rb
+++ b/lib/gitlab/jira_import/labels_importer.rb
@@ -5,6 +5,8 @@ module Gitlab
class LabelsImporter < BaseImporter
attr_reader :job_waiter
+ MAX_LABELS = 500
+
def initialize(project)
super
@job_waiter = JobWaiter.new
@@ -19,15 +21,35 @@ module Gitlab
def cache_import_label(project)
label = project.jira_imports.by_jira_project_key(jira_project_key).last.label
- raise Projects::ImportService::Error, _('Failed to find import label for jira import.') unless label
+ raise Projects::ImportService::Error, _('Failed to find import label for Jira import.') unless label
JiraImport.cache_import_label_id(project.id, label.id)
end
def import_jira_labels
- # todo: import jira labels, see https://gitlab.com/gitlab-org/gitlab/-/issues/212651
+ start_at = 0
+ loop do
+ break if process_jira_page(start_at)
+
+ start_at += MAX_LABELS
+ end
+
job_waiter
end
+
+ def process_jira_page(start_at)
+ request = "/rest/api/2/label?maxResults=#{MAX_LABELS}&startAt=#{start_at}"
+ response = client.get(request)
+
+ return true if response['values'].blank?
+ return true unless response.key?('isLast')
+
+ Gitlab::JiraImport::HandleLabelsService.new(project, response['values']).execute
+
+ response['isLast']
+ rescue => e
+ Gitlab::ErrorTracking.track_exception(e, project_id: project.id, request: request)
+ end
end
end
end
diff --git a/lib/gitlab/jira_import/metadata_collector.rb b/lib/gitlab/jira_import/metadata_collector.rb
new file mode 100644
index 00000000000..4551f38ba98
--- /dev/null
+++ b/lib/gitlab/jira_import/metadata_collector.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module JiraImport
+ class MetadataCollector
+ attr_accessor :jira_issue, :metadata
+
+ def initialize(jira_issue)
+ @jira_issue = jira_issue
+ @metadata = []
+ end
+
+ def execute
+ add_field(%w(issuetype name), 'Issue type')
+ add_field(%w(priority name), 'Priority')
+ add_field('environment', 'Environment')
+ add_field('duedate', 'Due date')
+ add_parent
+ add_versions
+
+ return if metadata.empty?
+
+ metadata.join("\n").prepend("\n\n---\n\n**Issue metadata**\n\n")
+ end
+
+ private
+
+ def add_field(keys, field_label)
+ value = fields.dig(*keys)
+ return if value.blank?
+
+ metadata << "- #{field_label}: #{value}"
+ end
+
+ def add_parent
+ parent_issue_key = fields.dig('parent', 'key')
+
+ return if parent_issue_key.blank?
+
+ parent_summary_key = fields.dig('parent', 'fields', 'summary')
+
+ metadata << "- Parent issue: [#{parent_issue_key}] #{parent_summary_key}".strip
+ end
+
+ def add_versions
+ return if fields['fixVersions'].blank? || !fields['fixVersions'].is_a?(Array)
+
+ versions = fields['fixVersions'].map { |version| version['name'] }.compact.join(', ')
+ metadata << "- Fix versions: #{versions}"
+ end
+
+ def fields
+ jira_issue.fields
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/jira_import/user_mapper.rb b/lib/gitlab/jira_import/user_mapper.rb
new file mode 100644
index 00000000000..208ee49b724
--- /dev/null
+++ b/lib/gitlab/jira_import/user_mapper.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module JiraImport
+ class UserMapper
+ include ::Gitlab::Utils::StrongMemoize
+
+ def initialize(project, jira_user)
+ @project = project
+ @jira_user = jira_user
+ end
+
+ def execute
+ return unless jira_user
+
+ email = jira_user['emailAddress']
+
+ # We also include emails that are not yet confirmed
+ users = User.by_any_email(email).to_a
+
+ user = users.first
+
+ # this event should never happen but we should log it in case we have invalid data
+ log_user_mapping_message('Multiple users found for an email address', email) if users.count > 1
+
+ unless project.project_member(user) || project.group&.group_member(user)
+ log_user_mapping_message('Jira user not found', email)
+
+ return
+ end
+
+ user
+ end
+
+ private
+
+ attr_reader :project, :jira_user, :params
+
+ def log_user_mapping_message(message, email)
+ logger.info(
+ project_id: project.id,
+ project_path: project.full_path,
+ user_email: email,
+ message: message
+ )
+ end
+
+ def logger
+ @logger ||= Gitlab::Import::Logger.build
+ end
+ end
+ end
+end