diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/repositories.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/changelog/config.rb | 9 | ||||
-rw-r--r-- | lib/gitlab/github_import/importer/events/cross_referenced.rb | 86 | ||||
-rw-r--r-- | lib/gitlab/github_import/importer/issue_event_importer.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/github_import/importer/note_importer.rb | 11 | ||||
-rw-r--r-- | lib/gitlab/github_import/importer/single_endpoint_issue_events_importer.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/github_import/markdown_text.rb | 30 | ||||
-rw-r--r-- | lib/gitlab/github_import/representation/issue_event.rb | 4 |
8 files changed, 149 insertions, 10 deletions
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 2e21f591667..4c7cc6be8b6 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -238,6 +238,10 @@ module API end params do use :release_params + + optional :config_file, + type: String, + desc: "The file path to the configuration file as stored in the project's Git repository. Defaults to '.gitlab/changelog_config.yml'" end get ':id/repository/changelog' do service = ::Repositories::ChangelogService.new( @@ -262,6 +266,10 @@ module API type: String, desc: 'The branch to commit the changelog changes to' + optional :config_file, + type: String, + desc: "The file path to the configuration file as stored in the project's Git repository. Defaults to '.gitlab/changelog_config.yml'" + optional :file, type: String, desc: 'The file to commit the changelog changes to', diff --git a/lib/gitlab/changelog/config.rb b/lib/gitlab/changelog/config.rb index 9cb3d71f5c3..8fcc03ec437 100644 --- a/lib/gitlab/changelog/config.rb +++ b/lib/gitlab/changelog/config.rb @@ -7,9 +7,9 @@ module Gitlab # When rendering changelog entries, authors are not included. AUTHORS_NONE = 'none' - # The path to the configuration file as stored in the project's Git + # The default path to the configuration file as stored in the project's Git # repository. - FILE_PATH = '.gitlab/changelog_config.yml' + DEFAULT_FILE_PATH = '.gitlab/changelog_config.yml' # The default date format to use for formatting release dates. DEFAULT_DATE_FORMAT = '%Y-%m-%d' @@ -36,8 +36,9 @@ module Gitlab attr_accessor :date_format, :categories, :template, :tag_regex, :always_credit_user_ids - def self.from_git(project, user = nil) - if (yaml = project.repository.changelog_config.presence) + def self.from_git(project, user = nil, path = nil) + yaml = project.repository.changelog_config('HEAD', path.presence || DEFAULT_FILE_PATH) + if yaml.present? from_hash(project, YAML.safe_load(yaml), user) else new(project) diff --git a/lib/gitlab/github_import/importer/events/cross_referenced.rb b/lib/gitlab/github_import/importer/events/cross_referenced.rb new file mode 100644 index 00000000000..20b902cfe50 --- /dev/null +++ b/lib/gitlab/github_import/importer/events/cross_referenced.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +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`. + 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? + + note_body = cross_reference_note_content(mentioned_in_record.gfm_reference(project)) + track_activity(mentioned_in_record_class) + create_note(issue_event, note_body) + end + + private + + def track_activity(mentioned_in_class) + 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) + Note.create!( + system: true, + noteable_type: Issue.name, + noteable_id: issue_event.issue_db_id, + 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 + ) + + Gitlab::GithubImport::IssuableFinder.new(project, mentioned_in_adapter).database_id + end + + def cross_reference_note_content(gfm_reference) + "#{::SystemNotes::IssuablesService.cross_reference_note_prefix}#{gfm_reference}" + end + end + end + end + end +end diff --git a/lib/gitlab/github_import/importer/issue_event_importer.rb b/lib/gitlab/github_import/importer/issue_event_importer.rb index 955cfa5a0d0..e451af61ec3 100644 --- a/lib/gitlab/github_import/importer/issue_event_importer.rb +++ b/lib/gitlab/github_import/importer/issue_event_importer.rb @@ -30,6 +30,9 @@ module Gitlab 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) else Gitlab::GithubImport::Logger.debug( message: 'UNSUPPORTED_EVENT_TYPE', diff --git a/lib/gitlab/github_import/importer/note_importer.rb b/lib/gitlab/github_import/importer/note_importer.rb index 673f56b5753..1410006af26 100644 --- a/lib/gitlab/github_import/importer/note_importer.rb +++ b/lib/gitlab/github_import/importer/note_importer.rb @@ -21,14 +21,12 @@ module Gitlab author_id, author_found = user_finder.author_id_for(note) - note_body = MarkdownText.format(note.note, note.author, author_found) - attributes = { noteable_type: note.noteable_type, noteable_id: noteable_id, project_id: project.id, author_id: author_id, - note: note_body, + note: note_body(author_found), discussion_id: note.discussion_id, system: false, created_at: note.created_at, @@ -48,6 +46,13 @@ module Gitlab def find_noteable_id GithubImport::IssuableFinder.new(project, note).database_id end + + private + + def note_body(author_found) + text = MarkdownText.convert_ref_links(note.note, project) + MarkdownText.format(text, note.author, author_found) + end end end end 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 00267400a6c..45bbc25e637 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 @@ -19,6 +19,7 @@ module Gitlab end 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) @@ -68,6 +69,13 @@ module Gitlab def collection_options { state: 'all', sort: 'created', direction: 'asc' } end + + # Cross-referenced events on Github doesn't have id. + def compose_associated_id!(issue, event) + return if event.event != 'cross-referenced' + + event.id = "cross-reference##{issue.id}-in-#{event.source.issue.id}" + end end end end diff --git a/lib/gitlab/github_import/markdown_text.rb b/lib/gitlab/github_import/markdown_text.rb index 0b1c221bbec..692016bd005 100644 --- a/lib/gitlab/github_import/markdown_text.rb +++ b/lib/gitlab/github_import/markdown_text.rb @@ -5,8 +5,34 @@ module Gitlab class MarkdownText include Gitlab::EncodingHelper - def self.format(*args) - new(*args).to_s + ISSUE_REF_MATCHER = '%{github_url}/%{import_source}/issues' + PULL_REF_MATCHER = '%{github_url}/%{import_source}/pull' + + class << self + def format(*args) + new(*args).to_s + end + + # Links like `https://domain.github.com/<namespace>/<project>/pull/<iid>` needs to be converted + def convert_ref_links(text, project) + matcher_options = { github_url: github_url, import_source: project.import_source } + issue_ref_matcher = ISSUE_REF_MATCHER % matcher_options + pull_ref_matcher = PULL_REF_MATCHER % matcher_options + + url_helpers = Rails.application.routes.url_helpers + text.gsub(issue_ref_matcher, url_helpers.project_issues_url(project)) + .gsub(pull_ref_matcher, url_helpers.project_merge_requests_url(project)) + end + + private + + # Returns github domain without slash in the end + def github_url + oauth_config = Gitlab::Auth::OAuth::Provider.config_for('github') || {} + url = oauth_config['url'].presence || 'https://github.com' + url = url.chop if url.end_with?('/') + url + end end # text - The Markdown text as a String. diff --git a/lib/gitlab/github_import/representation/issue_event.rb b/lib/gitlab/github_import/representation/issue_event.rb index f62507a331b..9016338db3b 100644 --- a/lib/gitlab/github_import/representation/issue_event.rb +++ b/lib/gitlab/github_import/representation/issue_event.rb @@ -9,7 +9,8 @@ module Gitlab attr_reader :attributes - expose_attribute :id, :actor, :event, :commit_id, :label_title, :old_title, :new_title, :created_at + 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. @@ -24,6 +25,7 @@ module Gitlab 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 ) |