diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml index 585997fdbbe7356a0efac3aa65ef22e60ca0c795..4a743a3393b9f05966213fd4ff5283099346acc7 100644 --- a/.rubocop_todo/layout/argument_alignment.yml +++ b/.rubocop_todo/layout/argument_alignment.yml @@ -1350,7 +1350,6 @@ Layout/ArgumentAlignment: - 'spec/lib/gitlab/auth/otp/strategies/forti_token_cloud_spec.rb' - 'spec/lib/gitlab/auth/saml/auth_hash_spec.rb' - 'spec/lib/gitlab/auth/saml/user_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/bitbucket_import/project_creator_spec.rb' - 'spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb' - 'spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb' diff --git a/.rubocop_todo/layout/array_alignment.yml b/.rubocop_todo/layout/array_alignment.yml index 0ca9129e17bc3871fe764480a8d22f81b62f6ea0..e8860e75d6737dd8193577509752ed779c197636 100644 --- a/.rubocop_todo/layout/array_alignment.yml +++ b/.rubocop_todo/layout/array_alignment.yml @@ -146,7 +146,6 @@ Layout/ArrayAlignment: - 'lib/api/internal/base.rb' - 'lib/api/statistics.rb' - 'lib/gitlab/alert_management/payload/prometheus.rb' - - 'lib/gitlab/bitbucket_import/importer.rb' - 'lib/gitlab/chat/command.rb' - 'lib/gitlab/checks/single_change_access.rb' - 'lib/gitlab/ci/config/entry/default.rb' diff --git a/.rubocop_todo/layout/first_hash_element_indentation.yml b/.rubocop_todo/layout/first_hash_element_indentation.yml index e5ae116f1cfefac25babc49748b8284ca614d82e..83ce52272b78919b83d484c13b723d0eae5441dd 100644 --- a/.rubocop_todo/layout/first_hash_element_indentation.yml +++ b/.rubocop_todo/layout/first_hash_element_indentation.yml @@ -184,7 +184,6 @@ Layout/FirstHashElementIndentation: - 'spec/lib/container_registry/client_spec.rb' - 'spec/lib/gitlab/application_rate_limiter_spec.rb' - 'spec/lib/gitlab/asciidoc_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/ci/config_spec.rb' - 'spec/lib/gitlab/ci/parsers/codequality/code_climate_spec.rb' - 'spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb' diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml index a68124c649bd6454f32bea7b1eac7fdd1296a6c9..eaae37786daadf9e036f6e5ad789d62dc4383374 100644 --- a/.rubocop_todo/layout/line_length.yml +++ b/.rubocop_todo/layout/line_length.yml @@ -2517,7 +2517,6 @@ Layout/LineLength: - 'lib/gitlab/background_migration/migrate_requirements_to_work_items.rb' - 'lib/gitlab/background_migration/populate_resolved_on_default_branch_column.rb' - 'lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb' - - 'lib/gitlab/bitbucket_import/importer.rb' - 'lib/gitlab/buffered_io.rb' - 'lib/gitlab/bullet/exclusions.rb' - 'lib/gitlab/cache/helpers.rb' @@ -3601,7 +3600,6 @@ Layout/LineLength: - 'spec/lib/gitlab/background_migration/job_coordinator_spec.rb' - 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb' - 'spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/buffered_io_spec.rb' - 'spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb' - 'spec/lib/gitlab/chat/output_spec.rb' diff --git a/.rubocop_todo/lint/redundant_cop_disable_directive.yml b/.rubocop_todo/lint/redundant_cop_disable_directive.yml index 453954e9bd12a98537bafb687cef7bcc4a746d95..3473e777b221a69e75a70f2bc020379202df3f02 100644 --- a/.rubocop_todo/lint/redundant_cop_disable_directive.yml +++ b/.rubocop_todo/lint/redundant_cop_disable_directive.yml @@ -171,7 +171,6 @@ Lint/RedundantCopDisableDirective: - 'lib/gitlab/background_migration/re_expire_o_auth_tokens.rb' - 'lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings.rb' - 'lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url.rb' - - 'lib/gitlab/bitbucket_import/importer.rb' - 'lib/gitlab/buffered_io.rb' - 'lib/gitlab/cache/request_cache.rb' - 'lib/gitlab/ci/build/artifacts/metadata/entry.rb' diff --git a/.rubocop_todo/lint/unused_method_argument.yml b/.rubocop_todo/lint/unused_method_argument.yml index e23fca97b1576c0b3b0a187f7fe4be4164dbf632..7e5714ef9186b9d38ce2ac9696335680cb012c89 100644 --- a/.rubocop_todo/lint/unused_method_argument.yml +++ b/.rubocop_todo/lint/unused_method_argument.yml @@ -375,7 +375,6 @@ Lint/UnusedMethodArgument: - 'lib/gitlab/background_migration/cleanup_orphaned_routes.rb' - 'lib/gitlab/background_migration/job_coordinator.rb' - 'lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb' - - 'lib/gitlab/bitbucket_import/importer.rb' - 'lib/gitlab/cache/helpers.rb' - 'lib/gitlab/cache/metrics.rb' - 'lib/gitlab/ci/ansi2html.rb' diff --git a/.rubocop_todo/rails/time_zone.yml b/.rubocop_todo/rails/time_zone.yml index faa3cb5ecfb474b31feef43553a573aa98563b10..afe92cc4ad7f8404a832af0d1d7037430e642a80 100644 --- a/.rubocop_todo/rails/time_zone.yml +++ b/.rubocop_todo/rails/time_zone.yml @@ -48,7 +48,6 @@ Rails/TimeZone: - 'spec/lib/gitlab/app_json_logger_spec.rb' - 'spec/lib/gitlab/app_text_logger_spec.rb' - 'spec/lib/gitlab/auth/current_user_mode_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/checks/timed_logger_spec.rb' - 'spec/lib/gitlab/ci/cron_parser_spec.rb' - 'spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb' diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml index 1120d9e8a1442558fb3972255a5bfe51ccfbcd12..15f9a20a8bb6691f7282ecb2693f839288b047e3 100644 --- a/.rubocop_todo/rspec/context_wording.yml +++ b/.rubocop_todo/rspec/context_wording.yml @@ -1575,7 +1575,6 @@ RSpec/ContextWording: - 'spec/lib/gitlab/avatar_cache_spec.rb' - 'spec/lib/gitlab/background_migration/backfill_imported_issue_search_data_spec.rb' - 'spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/blame_spec.rb' - 'spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb' - 'spec/lib/gitlab/cache/helpers_spec.rb' diff --git a/.rubocop_todo/rspec/instance_variable.yml b/.rubocop_todo/rspec/instance_variable.yml index 6bf78d3c5ef770f4f8d16997a7ccb816fdb0a734..a4d4c2119c06a63852e128d52a31651db3d63a0f 100644 --- a/.rubocop_todo/rspec/instance_variable.yml +++ b/.rubocop_todo/rspec/instance_variable.yml @@ -86,7 +86,6 @@ RSpec/InstanceVariable: - 'spec/lib/extracts_ref_spec.rb' - 'spec/lib/gitlab/auth/auth_finders_spec.rb' - 'spec/lib/gitlab/auth/ldap/person_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/chat_name_token_spec.rb' - 'spec/lib/gitlab/ci/lint_spec.rb' - 'spec/lib/gitlab/ci/status/composite_spec.rb' diff --git a/.rubocop_todo/rspec/named_subject.yml b/.rubocop_todo/rspec/named_subject.yml index bcb59ffbcb7886672d41a9fe0e50a532f7868865..655ef2bbc2d65fc63ec30a602bb82d9414a72b21 100644 --- a/.rubocop_todo/rspec/named_subject.yml +++ b/.rubocop_todo/rspec/named_subject.yml @@ -1855,7 +1855,6 @@ RSpec/NamedSubject: - 'spec/lib/gitlab/background_migration/truncate_overlong_vulnerability_html_titles_spec.rb' - 'spec/lib/gitlab/background_migration/update_ci_pipeline_artifacts_unknown_locked_status_spec.rb' - 'spec/lib/gitlab/background_task_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/bitbucket_import/parallel_importer_spec.rb' - 'spec/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer_spec.rb' - 'spec/lib/gitlab/blame_spec.rb' diff --git a/.rubocop_todo/rspec/return_from_stub.yml b/.rubocop_todo/rspec/return_from_stub.yml index 034d4fe4b0984b4a0c57fb45ac62ff8ab8ba65b2..897d15c72ed5f27a6448c7cc253db81d57eda19f 100644 --- a/.rubocop_todo/rspec/return_from_stub.yml +++ b/.rubocop_todo/rspec/return_from_stub.yml @@ -114,7 +114,6 @@ RSpec/ReturnFromStub: - 'spec/lib/gitlab/auth/o_auth/user_spec.rb' - 'spec/lib/gitlab/auth/saml/user_spec.rb' - 'spec/lib/gitlab/auth_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/ci/build/policy/changes_spec.rb' - 'spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb' - 'spec/lib/gitlab/ci/status/build/failed_spec.rb' diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml index 8feedc2c4f9fd9dbbe539bed5850bec47caad698..24b70629ae4f2156fbb73e0bf27bf7e50805647b 100644 --- a/.rubocop_todo/rspec/verified_doubles.yml +++ b/.rubocop_todo/rspec/verified_doubles.yml @@ -357,7 +357,6 @@ RSpec/VerifiedDoubles: - 'spec/lib/gitlab/background_migration/batching_strategies/base_strategy_spec.rb' - 'spec/lib/gitlab/background_migration/job_coordinator_spec.rb' - 'spec/lib/gitlab/background_migration_spec.rb' - - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/bitbucket_import/project_creator_spec.rb' - 'spec/lib/gitlab/cache/import/caching_spec.rb' - 'spec/lib/gitlab/changelog/committer_spec.rb' diff --git a/.rubocop_todo/style/guard_clause.yml b/.rubocop_todo/style/guard_clause.yml index 05f3afd623201ae05ca604161d06fa548fe1f62b..429eeff378760b8338f865bf06afbc8d8358f087 100644 --- a/.rubocop_todo/style/guard_clause.yml +++ b/.rubocop_todo/style/guard_clause.yml @@ -427,7 +427,6 @@ Style/GuardClause: - 'lib/gitlab/auth/o_auth/user.rb' - 'lib/gitlab/auth/unique_ips_limiter.rb' - 'lib/gitlab/background_migration/fix_projects_without_project_feature.rb' - - 'lib/gitlab/bitbucket_import/importer.rb' - 'lib/gitlab/blob_helper.rb' - 'lib/gitlab/cache/ci/project_pipeline_status.rb' - 'lib/gitlab/changelog/config.rb' diff --git a/.rubocop_todo/style/inline_disable_annotation.yml b/.rubocop_todo/style/inline_disable_annotation.yml index 55a3320cedd2851abdfd0326a9ba92f7acedcd5d..73268a5b0dca4359b1f0cd29d7d6b5e146c79ac7 100644 --- a/.rubocop_todo/style/inline_disable_annotation.yml +++ b/.rubocop_todo/style/inline_disable_annotation.yml @@ -2396,7 +2396,6 @@ Style/InlineDisableAnnotation: - 'lib/gitlab/background_migration/update_workspaces_config_version.rb' - 'lib/gitlab/background_task.rb' - 'lib/gitlab/base_doorkeeper_controller.rb' - - 'lib/gitlab/bitbucket_import/importer.rb' - 'lib/gitlab/bitbucket_import/importers/issue_importer.rb' - 'lib/gitlab/bitbucket_import/importers/issue_notes_importer.rb' - 'lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer.rb' diff --git a/config/feature_flags/development/bitbucket_parallel_importer.yml b/config/feature_flags/development/bitbucket_parallel_importer.yml deleted file mode 100644 index 6edadec4d3b8550737772dcc7dd92ec13bc89d85..0000000000000000000000000000000000000000 --- a/config/feature_flags/development/bitbucket_parallel_importer.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: bitbucket_parallel_importer -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130731 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/423530 -milestone: '16.4' -type: development -group: group::import and integrate -default_enabled: false diff --git a/doc/development/bitbucket_cloud_importer.md b/doc/development/bitbucket_cloud_importer.md index 7d8874417a9d26739fbe4c6182a4c042c781ce59..98620ca39ebbe86f4c8946373c3f8ab23ab98f66 100644 --- a/doc/development/bitbucket_cloud_importer.md +++ b/doc/development/bitbucket_cloud_importer.md @@ -6,11 +6,6 @@ info: Any user with at least the Maintainer role can merge updates to this conte # Bitbucket Cloud importer developer documentation -The Bitbucket Cloud importer can be configured with the `bitbucket_parallel_importer` feature flag. When the feature flag is: - -- Enabled, the importer uses Sidekiq to schedule work asynchronously. -- Disabled, the importer does all the work in a single thread. - ## Prerequisites You must be authenticated with Bitbucket: diff --git a/doc/user/project/import/bitbucket.md b/doc/user/project/import/bitbucket.md index 4bf4be70f07078a07b68f5480a11bd7339601dd0..d421cbeed181036554a7d62befdf892508453eef 100644 --- a/doc/user/project/import/bitbucket.md +++ b/doc/user/project/import/bitbucket.md @@ -6,15 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Import your project from Bitbucket Cloud **(FREE ALL)** -> Parallel imports from Bitbucket Cloud [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/412614) in GitLab 16.6 [with a flag](../../../administration/feature_flags.md) named `bitbucket_parallel_importer`. Disabled by default. - Import your projects from Bitbucket Cloud to GitLab. -FLAG: -On self-managed GitLab, parallel imports are not available. Parallel imports can help when importing large projects. -To make parallel imports available, an administrator can [enable the feature flag](../../../administration/feature_flags.md) -named `bitbucket_parallel_importer`. On GitLab.com, this feature is available. - The Bitbucket importer can import: - Repository description diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb deleted file mode 100644 index 9f87bb2347c6b1ea4939e975643fdce8ab2fe6a6..0000000000000000000000000000000000000000 --- a/lib/gitlab/bitbucket_import/importer.rb +++ /dev/null @@ -1,339 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module BitbucketImport - class Importer - LABELS = [{ title: 'bug', color: '#FF0000' }, - { title: 'enhancement', color: '#428BCA' }, - { title: 'proposal', color: '#69D100' }, - { title: 'task', color: '#7F8C8D' }].freeze - - attr_reader :project, :client, :errors, :users - - ALREADY_IMPORTED_CACHE_KEY = 'bitbucket_cloud-importer/already-imported/%{project}/%{collection}' - - def initialize(project) - @project = project - @client = Bitbucket::Client.new(project.import_data.credentials) - @formatter = Gitlab::ImportFormatter.new - @ref_converter = Gitlab::BitbucketImport::RefConverter.new(project) - @labels = {} - @errors = [] - @users = {} - end - - def execute - import_wiki - import_issues - import_pull_requests - handle_errors - metrics.track_finished_import - - true - end - - def create_labels - LABELS.each do |label_params| - label = ::Labels::FindOrCreateService.new(nil, project, label_params).execute(skip_authorization: true) - if label.valid? - @labels[label_params[:title]] = label - else - raise "Failed to create label \"#{label_params[:title]}\" for project \"#{project.full_name}\"" - end - end - end - - def import_pull_request_comments(pull_request, merge_request) - comments = client.pull_request_comments(repo, pull_request.iid) - - inline_comments, pr_comments = comments.partition(&:inline?) - - import_inline_comments(inline_comments, pull_request, merge_request) - import_standalone_pr_comments(pr_comments, merge_request) - end - - private - - def already_imported?(collection, iid) - Gitlab::Cache::Import::Caching.set_includes?(cache_key(collection), iid) - end - - def mark_as_imported(collection, iid) - Gitlab::Cache::Import::Caching.set_add(cache_key(collection), iid) - end - - def cache_key(collection) - format(ALREADY_IMPORTED_CACHE_KEY, project: project.id, collection: collection) - end - - def handle_errors - return unless errors.any? - - project.import_state.update_column(:last_error, { - message: 'The remote data could not be fully imported.', - errors: errors - }.to_json) - end - - def store_pull_request_error(pull_request, ex) - backtrace = Gitlab::BacktraceCleaner.clean_backtrace(ex.backtrace) - error = { type: :pull_request, iid: pull_request.iid, errors: ex.message, trace: backtrace, raw_response: pull_request.raw&.to_json } - - Gitlab::ErrorTracking.log_exception(ex, error) - - # Omit the details from the database to avoid blowing up usage in the error column - error.delete(:trace) - error.delete(:raw_response) - - errors << error - end - - def gitlab_user_id(project, username) - find_user_id(username) || project.creator_id - end - - # rubocop: disable CodeReuse/ActiveRecord - def find_user_id(username) - return unless username - - return users[username] if users.key?(username) - - users[username] = User.by_provider_and_extern_uid(:bitbucket, username).select(:id).first&.id - end - # rubocop: enable CodeReuse/ActiveRecord - - def allocate_issues_internal_id!(project, client) - last_bitbucket_issue = client.last_issue(repo) - - return unless last_bitbucket_issue - - Issue.track_namespace_iid!(project.project_namespace, last_bitbucket_issue.iid) - end - - def repo - @repo ||= client.repo(project.import_source) - end - - def import_wiki - return if project.wiki.repository_exists? - - wiki = WikiFormatter.new(project) - - project.wiki.repository.import_repository(wiki.import_url) - rescue StandardError => e - errors << { type: :wiki, errors: e.message } - end - - def import_issues - return unless repo.issues_enabled? - - create_labels - - issue_type_id = ::WorkItems::Type.default_issue_type.id - - client.issues(repo).each_with_index do |issue, index| - next if already_imported?(:issues, issue.iid) - - # If a user creates an issue while the import is in progress, this can lead to an import failure. - # The workaround is to allocate IIDs before starting the importer. - allocate_issues_internal_id!(project, client) if index == 0 - - import_issue(issue, issue_type_id) - end - end - - # rubocop: disable CodeReuse/ActiveRecord - def import_issue(issue, issue_type_id) - description = '' - description += @formatter.author_line(issue.author) unless find_user_id(issue.author) - description += issue.description - - label_name = issue.kind - milestone = issue.milestone ? project.milestones.find_or_create_by(title: issue.milestone) : nil - - gitlab_issue = project.issues.create!( - iid: issue.iid, - title: issue.title, - description: description, - state_id: Issue.available_states[issue.state], - author_id: gitlab_user_id(project, issue.author), - namespace_id: project.project_namespace_id, - milestone: milestone, - work_item_type_id: issue_type_id, - created_at: issue.created_at, - updated_at: issue.updated_at - ) - - mark_as_imported(:issues, issue.iid) - - metrics.issues_counter.increment - - gitlab_issue.labels << @labels[label_name] - - import_issue_comments(issue, gitlab_issue) if gitlab_issue.persisted? - rescue StandardError => e - errors << { type: :issue, iid: issue.iid, errors: e.message } - end - # rubocop: enable CodeReuse/ActiveRecord - - def import_issue_comments(issue, gitlab_issue) - client.issue_comments(repo, issue.iid).each do |comment| - # The note can be blank for issue service messages like "Changed title: ..." - # We would like to import those comments as well but there is no any - # specific parameter that would allow to process them, it's just an empty comment. - # To prevent our importer from just crashing or from creating useless empty comments - # we do this check. - next unless comment.note.present? - - note = '' - note += @formatter.author_line(comment.author) unless find_user_id(comment.author) - note += @ref_converter.convert_note(comment.note.to_s) - - begin - gitlab_issue.notes.create!( - project: project, - note: note, - author_id: gitlab_user_id(project, comment.author), - created_at: comment.created_at, - updated_at: comment.updated_at - ) - rescue StandardError => e - errors << { type: :issue_comment, iid: issue.iid, errors: e.message } - end - end - end - - def import_pull_requests - pull_requests = client.pull_requests(repo) - - pull_requests.each do |pull_request| - next if already_imported?(:pull_requests, pull_request.iid) - - import_pull_request(pull_request) - end - end - - def import_pull_request(pull_request) - description = '' - description += @formatter.author_line(pull_request.author) unless find_user_id(pull_request.author) - description += pull_request.description - - source_branch_sha = pull_request.source_branch_sha - target_branch_sha = pull_request.target_branch_sha - - source_sha_from_commit_sha = project.repository.commit(source_branch_sha)&.sha - source_sha_from_merge_sha = project.repository.commit(pull_request.merge_commit_sha)&.sha - - source_branch_sha = source_sha_from_commit_sha || source_sha_from_merge_sha || source_branch_sha - target_branch_sha = project.repository.commit(target_branch_sha)&.sha || target_branch_sha - - merge_request = project.merge_requests.create!( - iid: pull_request.iid, - title: pull_request.title, - description: description, - source_project: project, - source_branch: pull_request.source_branch_name, - source_branch_sha: source_branch_sha, - target_project: project, - target_branch: pull_request.target_branch_name, - target_branch_sha: target_branch_sha, - state: pull_request.state, - author_id: gitlab_user_id(project, pull_request.author), - created_at: pull_request.created_at, - updated_at: pull_request.updated_at - ) - - mark_as_imported(:pull_requests, pull_request.iid) - - metrics.merge_requests_counter.increment - - import_pull_request_comments(pull_request, merge_request) if merge_request.persisted? - rescue StandardError => e - store_pull_request_error(pull_request, e) - end - - def import_inline_comments(inline_comments, pull_request, merge_request) - position_map = {} - discussion_map = {} - - children, parents = inline_comments.partition(&:has_parent?) - - # The Bitbucket API returns threaded replies as parent-child - # relationships. We assume that the child can appear in any order in - # the JSON. - parents.each do |comment| - position_map[comment.iid] = build_position(merge_request, comment) - end - - children.each do |comment| - position_map[comment.iid] = position_map.fetch(comment.parent_id, nil) - end - - inline_comments.each do |comment| - attributes = pull_request_comment_attributes(comment) - attributes[:discussion_id] = discussion_map[comment.parent_id] if comment.has_parent? - - attributes.merge!( - position: position_map[comment.iid], - type: 'DiffNote') - - note = merge_request.notes.create!(attributes) - - # We can't store a discussion ID until a note is created, so if - # replies are created before the parent the discussion ID won't be - # linked properly. - discussion_map[comment.iid] = note.discussion_id - rescue StandardError => e - errors << { type: :pull_request, iid: comment.iid, errors: e.message } - end - end - - def build_position(merge_request, pr_comment) - params = { - diff_refs: merge_request.diff_refs, - old_path: pr_comment.file_path, - new_path: pr_comment.file_path, - old_line: pr_comment.old_pos, - new_line: pr_comment.new_pos - } - - Gitlab::Diff::Position.new(params) - end - - def import_standalone_pr_comments(pr_comments, merge_request) - pr_comments.each do |comment| - merge_request.notes.create!(pull_request_comment_attributes(comment)) - rescue StandardError => e - errors << { type: :pull_request, iid: comment.iid, errors: e.message } - end - end - - def pull_request_comment_attributes(comment) - { - project: project, - author_id: gitlab_user_id(project, comment.author), - note: comment_note(comment), - created_at: comment.created_at, - updated_at: comment.updated_at - } - end - - def comment_note(comment) - author = @formatter.author_line(comment.author) unless find_user_id(comment.author) - author.to_s + @ref_converter.convert_note(comment.note.to_s) - end - - def log_base_data - { - class: self.class.name, - project_id: project.id, - project_path: project.full_path - } - end - - def metrics - @metrics ||= Gitlab::Import::Metrics.new(:bitbucket_importer, @project) - end - end - end -end diff --git a/lib/gitlab/bitbucket_import/importers/repository_importer.rb b/lib/gitlab/bitbucket_import/importers/repository_importer.rb index 9be7ed99436db77c6f458fbe049793847bf49fa0..cc950bbe13d45998beee8155a3dc4dc5d58a4e15 100644 --- a/lib/gitlab/bitbucket_import/importers/repository_importer.rb +++ b/lib/gitlab/bitbucket_import/importers/repository_importer.rb @@ -6,6 +6,11 @@ module Importers class RepositoryImporter include Loggable + LABELS = [{ title: 'bug', color: '#FF0000' }, + { title: 'enhancement', color: '#428BCA' }, + { title: 'proposal', color: '#69D100' }, + { title: 'task', color: '#7F8C8D' }].freeze + def initialize(project) @project = project end @@ -62,8 +67,9 @@ def import_wiki end def create_labels - importer = Gitlab::BitbucketImport::Importer.new(project) - importer.create_labels + LABELS.each do |label_params| + ::Labels::FindOrCreateService.new(nil, project, label_params).execute(skip_authorization: true) + end end def wiki diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb index fec8b3a7708fcae605b801dda53a289fc78fa6fc..6e507142e886b667bcd83872f790313421bdfd09 100644 --- a/lib/gitlab/import_sources.rb +++ b/lib/gitlab/import_sources.rb @@ -11,7 +11,7 @@ module ImportSources IMPORT_TABLE = [ ImportSource.new('github', 'GitHub', Gitlab::GithubImport::ParallelImporter), - ImportSource.new('bitbucket', 'Bitbucket Cloud', Gitlab::BitbucketImport::Importer), + ImportSource.new('bitbucket', 'Bitbucket Cloud', Gitlab::BitbucketImport::ParallelImporter), ImportSource.new('bitbucket_server', 'Bitbucket Server', Gitlab::BitbucketServerImport::ParallelImporter), ImportSource.new('fogbugz', 'FogBugz', Gitlab::FogbugzImport::Importer), ImportSource.new('git', 'Repository by URL', nil), @@ -44,15 +44,7 @@ def title(name) end def import_table - bitbucket_parallel_enabled = Feature.enabled?(:bitbucket_parallel_importer) - - return IMPORT_TABLE unless bitbucket_parallel_enabled - - import_table = IMPORT_TABLE.deep_dup - - import_table[1].importer = Gitlab::BitbucketImport::ParallelImporter if bitbucket_parallel_enabled - - import_table + IMPORT_TABLE end end end diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb deleted file mode 100644 index d468483661ad4039678f36ef8344e66b4c7d086a..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb +++ /dev/null @@ -1,559 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BitbucketImport::Importer, :clean_gitlab_redis_cache, feature_category: :importers do - include ImportSpecHelper - - before do - stub_omniauth_provider('bitbucket') - end - - let(:statuses) do - [ - "open", - "resolved", - "on hold", - "invalid", - "duplicate", - "wontfix", - "closed" # undocumented status - ] - end - - let(:reporters) do - [ - nil, - { "nickname" => "reporter1" }, - nil, - { "nickname" => "reporter2" }, - { "nickname" => "reporter1" }, - nil, - { "nickname" => "reporter3" } - ] - end - - let(:sample_issues_statuses) do - issues = [] - - statuses.map.with_index do |status, index| - issues << { - id: index, - state: status, - title: "Issue #{index}", - kind: 'bug', - content: { - raw: "Some content to issue #{index}", - markup: "markdown", - html: "Some content to issue #{index}" - } - } - end - - reporters.map.with_index do |reporter, index| - issues[index]['reporter'] = reporter - end - - issues - end - - let_it_be(:project_identifier) { 'namespace/repo' } - - let_it_be_with_reload(:project) do - create( - :project, - :repository, - import_source: project_identifier, - import_url: "https://bitbucket.org/#{project_identifier}.git", - import_data_attributes: { credentials: { 'token' => 'token' } } - ) - end - - let(:importer) { described_class.new(project) } - let(:sample) { RepoHelpers.sample_compare } - let(:issues_statuses_sample_data) do - { - count: sample_issues_statuses.count, - values: sample_issues_statuses - } - end - - let(:last_issue_data) do - { - page: 1, - pagelen: 1, - values: [sample_issues_statuses.last] - } - end - - let(:counter) { double('counter', increment: true) } - - subject { described_class.new(project) } - - describe '#import_pull_requests' do - let(:source_branch_sha) { sample.commits.last } - let(:merge_commit_sha) { sample.commits.second } - let(:target_branch_sha) { sample.commits.first } - let(:pull_request) do - instance_double( - Bitbucket::Representation::PullRequest, - iid: 10, - source_branch_sha: source_branch_sha, - source_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.source_branch, - target_branch_sha: target_branch_sha, - target_branch_name: Gitlab::Git::BRANCH_REF_PREFIX + sample.target_branch, - merge_commit_sha: merge_commit_sha, - title: 'This is a title', - description: 'This is a test pull request', - state: 'merged', - author: pull_request_author, - created_at: Time.now, - updated_at: Time.now) - end - - let(:pull_request_author) { 'other' } - let(:comments) { [@inline_note, @reply] } - - let(:author_line) { "*Created by: someuser*\n\n" } - - before do - allow(subject).to receive(:import_wiki) - allow(subject).to receive(:import_issues) - - # https://gitlab.com/gitlab-org/gitlab-test/compare/c1acaa58bbcbc3eafe538cb8274ba387047b69f8...5937ac0a7beb003549fc5fd26fc247ad - @inline_note = instance_double( - Bitbucket::Representation::PullRequestComment, - iid: 2, - file_path: '.gitmodules', - old_pos: nil, - new_pos: 4, - note: 'Hello world', - author: 'someuser', - created_at: Time.now, - updated_at: Time.now, - inline?: true, - has_parent?: false) - - @reply = instance_double( - Bitbucket::Representation::PullRequestComment, - iid: 3, - file_path: '.gitmodules', - note: 'Hello world', - author: 'someuser', - created_at: Time.now, - updated_at: Time.now, - inline?: true, - has_parent?: true, - parent_id: 2) - - allow(subject.client).to receive(:repo) - allow(subject.client).to receive(:pull_requests).and_return([pull_request]) - allow(subject.client).to receive(:pull_request_comments).with(anything, pull_request.iid).and_return(comments) - end - - it 'imports threaded discussions' do - expect { subject.execute }.to change { MergeRequest.count }.by(1) - - merge_request = MergeRequest.first - expect(merge_request.state).to eq('merged') - expect(merge_request.notes.count).to eq(2) - expect(merge_request.notes.map(&:discussion_id).uniq.count).to eq(1) - - notes = merge_request.notes.order(:id).to_a - start_note = notes.first - expect(start_note).to be_a(DiffNote) - expect(start_note.note).to include(@inline_note.note) - expect(start_note.note).to include(author_line) - - reply_note = notes.last - expect(reply_note).to be_a(DiffNote) - expect(reply_note.note).to include(@reply.note) - expect(reply_note.note).to include(author_line) - end - - context 'when author is blank' do - let(:pull_request_author) { nil } - - it 'adds created by anonymous in the description', :aggregate_failures do - expect { subject.execute }.to change { MergeRequest.count }.by(1) - - expect(MergeRequest.first.description).to include('Created by: Anonymous') - end - end - - context 'when user exists in GitLab' do - let!(:existing_user) { create(:user, username: 'someuser') } - let!(:identity) { create(:identity, provider: 'bitbucket', extern_uid: existing_user.username, user: existing_user) } - - it 'does not add author line to comments' do - expect { subject.execute }.to change { MergeRequest.count }.by(1) - - merge_request = MergeRequest.first - - notes = merge_request.notes.order(:id).to_a - start_note = notes.first - expect(start_note.note).to eq(@inline_note.note) - expect(start_note.note).not_to include(author_line) - - reply_note = notes.last - expect(reply_note.note).to eq(@reply.note) - expect(reply_note.note).not_to include(author_line) - end - end - - it 'calls RefConverter to convert Bitbucket refs to Gitlab refs' do - expect(subject.instance_values['ref_converter']).to receive(:convert_note).twice - - subject.execute - end - - context 'when importing a pull request throws an exception' do - before do - allow(pull_request).to receive(:raw).and_return({ error: "broken" }) - allow(subject.client).to receive(:pull_request_comments).and_raise(Gitlab::HTTP::Error) - end - - it 'logs an error without the backtrace' do - expect(Gitlab::ErrorTracking).to receive(:log_exception) - .with(instance_of(Gitlab::HTTP::Error), hash_including(raw_response: '{"error":"broken"}')) - - subject.execute - - expect(subject.errors.count).to eq(1) - expect(subject.errors.first.keys).to match_array(%i[type iid errors]) - end - end - - context 'when source SHA is not found in the repository' do - let(:source_branch_sha) { 'a' * Commit::MIN_SHA_LENGTH } - let(:target_branch_sha) { 'c' * Commit::MIN_SHA_LENGTH } - - it 'uses merge commit SHA for source' do - expect { subject.execute }.to change { MergeRequest.count }.by(1) - - merge_request_diff = MergeRequest.first.merge_request_diff - expect(merge_request_diff.head_commit_sha).to eq merge_commit_sha - expect(merge_request_diff.start_commit_sha).to eq target_branch_sha - end - - context 'when the merge commit SHA is also not found' do - let(:merge_commit_sha) { 'b' * Commit::MIN_SHA_LENGTH } - - it 'uses the pull request sha references' do - expect { subject.execute }.to change { MergeRequest.count }.by(1) - - merge_request_diff = MergeRequest.first.merge_request_diff - expect(merge_request_diff.head_commit_sha).to eq source_branch_sha - expect(merge_request_diff.start_commit_sha).to eq target_branch_sha - end - end - end - - context "when target_branch_sha is blank" do - let(:target_branch_sha) { nil } - - it 'creates the merge request with no target branch', :aggregate_failures do - expect { subject.execute }.to change { MergeRequest.count }.by(1) - - merge_request = MergeRequest.first - expect(merge_request.target_branch_sha).to eq(nil) - end - end - - context 'metrics' do - before do - allow(Gitlab::Metrics).to receive(:counter) { counter } - allow(pull_request).to receive(:raw).and_return('hello world') - end - - it 'counts imported pull requests' do - expect(Gitlab::Metrics).to receive(:counter).with( - :bitbucket_importer_imported_merge_requests_total, - 'The number of imported merge (pull) requests' - ) - - expect(counter).to receive(:increment) - - subject.execute - end - end - - context 'when pull request was already imported' do - let(:pull_request_already_imported) do - instance_double( - BitbucketServer::Representation::PullRequest, - iid: 11) - end - - let(:cache_key) do - format(described_class::ALREADY_IMPORTED_CACHE_KEY, project: project.id, collection: :pull_requests) - end - - before do - allow(subject.client).to receive(:pull_requests).and_return([pull_request, pull_request_already_imported]) - Gitlab::Cache::Import::Caching.set_add(cache_key, pull_request_already_imported.iid) - end - - it 'does not import the previously imported pull requests', :aggregate_failures do - expect { subject.execute }.to change { MergeRequest.count }.by(1) - - expect(Gitlab::Cache::Import::Caching.set_includes?(cache_key, pull_request.iid)).to eq(true) - end - end - end - - context 'issues statuses' do - before do - # HACK: Bitbucket::Representation.const_get('Issue') seems to return ::Issue without this - Bitbucket::Representation::Issue.new({}) - - stub_request( - :get, - "https://api.bitbucket.org/2.0/repositories/#{project_identifier}" - ).to_return(status: 200, - headers: { "Content-Type" => "application/json" }, - body: { has_issues: true, full_name: project_identifier }.to_json) - - stub_request( - :get, - "https://api.bitbucket.org/2.0/repositories/#{project_identifier}/issues?pagelen=1&sort=-created_on&state=ALL" - ).to_return(status: 200, - headers: { "Content-Type" => "application/json" }, - body: last_issue_data.to_json) - - stub_request( - :get, - "https://api.bitbucket.org/2.0/repositories/#{project_identifier}/issues?pagelen=50&sort=created_on" - ).to_return(status: 200, - headers: { "Content-Type" => "application/json" }, - body: issues_statuses_sample_data.to_json) - - stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on") - .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }) - .to_return(status: 200, body: "", headers: {}) - - sample_issues_statuses.each_with_index do |issue, index| - stub_request( - :get, - "https://api.bitbucket.org/2.0/repositories/#{project_identifier}/issues/#{issue[:id]}/comments?pagelen=50&sort=created_on" - ).to_return( - status: 200, - headers: { "Content-Type" => "application/json" }, - body: { author_info: { username: "username" }, utc_created_on: index }.to_json - ) - end - - stub_request( - :get, - "https://api.bitbucket.org/2.0/repositories/#{project_identifier}/pullrequests?pagelen=50&sort=created_on&state=ALL" - ).to_return(status: 200, - headers: { "Content-Type" => "application/json" }, - body: {}.to_json) - end - - context 'creating labels on project' do - before do - allow(importer).to receive(:import_wiki) - end - - it 'creates labels as expected' do - expect { importer.execute }.to change { Label.count }.from(0).to(Gitlab::BitbucketImport::Importer::LABELS.size) - end - - it 'does not fail if label is already existing' do - label = Gitlab::BitbucketImport::Importer::LABELS.first - ::Labels::CreateService.new(label).execute(project: project) - - expect { importer.execute }.not_to raise_error - end - - it 'does not create new labels' do - Gitlab::BitbucketImport::Importer::LABELS.each do |label| - create(:label, project: project, title: label[:title]) - end - - expect { importer.execute }.not_to change { Label.count } - end - - it 'does not update existing ones' do - label_title = Gitlab::BitbucketImport::Importer::LABELS.first[:title] - existing_label = create(:label, project: project, title: label_title) - # Reload label from database so we avoid timestamp comparison issues related to time precision when comparing - # attributes later. - existing_label.reload - - travel_to(Time.now + 1.minute) do - importer.execute - - label_after_import = project.labels.find(existing_label.id) - expect(label_after_import.attributes).to eq(existing_label.attributes) - end - end - - it 'raises an error if a label is not valid' do - stub_const("#{described_class}::LABELS", [{ title: nil, color: nil }]) - - expect { importer.create_labels }.to raise_error(StandardError, /Failed to create label/) - end - end - - it 'maps statuses to open or closed' do - allow(importer).to receive(:import_wiki) - - importer.execute - - expect(project.issues.where(state_id: Issue.available_states[:closed]).size).to eq(5) - expect(project.issues.where(state_id: Issue.available_states[:opened]).size).to eq(2) - expect(project.issues.map(&:namespace_id).uniq).to match_array([project.project_namespace_id]) - end - - describe 'wiki import' do - it 'is skipped when the wiki exists' do - expect(project.wiki).to receive(:repository_exists?) { true } - expect(project.wiki.repository).not_to receive(:import_repository) - - importer.execute - - expect(importer.errors).to be_empty - end - - it 'imports to the project disk_path' do - expect(project.wiki).to receive(:repository_exists?) { false } - expect(project.wiki.repository).to receive(:import_repository) - - importer.execute - - expect(importer.errors).to be_empty - end - end - - describe 'issue import' do - it 'allocates internal ids' do - expect(Issue).to receive(:track_namespace_iid!).with(project.project_namespace, 6) - - importer.execute - end - - it 'maps reporters to anonymous if bitbucket reporter is nil' do - allow(importer).to receive(:import_wiki) - importer.execute - - expect(project.issues.size).to eq(7) - expect(project.issues.where("description LIKE ?", '%Anonymous%').size).to eq(3) - expect(project.issues.where("description LIKE ?", '%reporter1%').size).to eq(2) - expect(project.issues.where("description LIKE ?", '%reporter2%').size).to eq(1) - expect(project.issues.where("description LIKE ?", '%reporter3%').size).to eq(1) - expect(importer.errors).to be_empty - end - - it 'sets work item type on new issues' do - allow(importer).to receive(:import_wiki) - - importer.execute - - expect(project.issues.map(&:work_item_type_id).uniq).to contain_exactly(WorkItems::Type.default_issue_type.id) - end - - context 'with issue comments' do - let(:note) { 'Hello world' } - let(:inline_note) do - instance_double(Bitbucket::Representation::Comment, note: note, author: 'someuser', created_at: Time.now, updated_at: Time.now) - end - - before do - allow_next_instance_of(Bitbucket::Client) do |instance| - allow(instance).to receive(:issue_comments).and_return([inline_note]) - end - allow(importer).to receive(:import_wiki) - end - - it 'imports issue comments' do - importer.execute - - comment = project.notes.first - expect(project.notes.size).to eq(7) - expect(comment.note).to include(note) - expect(comment.note).to include(inline_note.author) - expect(importer.errors).to be_empty - end - - it 'calls RefConverter to convert Bitbucket refs to Gitlab refs' do - expect(importer.instance_values['ref_converter']).to receive(:convert_note).exactly(7).times - - importer.execute - end - end - - context 'when issue was already imported' do - let(:cache_key) do - format(described_class::ALREADY_IMPORTED_CACHE_KEY, project: project.id, collection: :issues) - end - - before do - Gitlab::Cache::Import::Caching.set_add(cache_key, sample_issues_statuses.first[:id]) - end - - it 'does not import previously imported issues', :aggregate_failures do - expect { subject.execute }.to change { Issue.count }.by(sample_issues_statuses.size - 1) - - sample_issues_statuses.each do |sample_issues_status| - expect(Gitlab::Cache::Import::Caching.set_includes?(cache_key, sample_issues_status[:id])).to eq(true) - end - end - end - end - - context 'metrics' do - before do - allow(Gitlab::Metrics).to receive(:counter) { counter } - end - - it 'counts imported issues' do - expect(Gitlab::Metrics).to receive(:counter).with( - :bitbucket_importer_imported_issues_total, - 'The number of imported issues' - ) - - expect(counter).to receive(:increment) - - subject.execute - end - end - end - - describe '#execute' do - context 'metrics' do - let(:histogram) { double(:histogram) } - - before do - allow(subject).to receive(:import_wiki) - allow(subject).to receive(:import_issues) - allow(subject).to receive(:import_pull_requests) - - allow(Gitlab::Metrics).to receive(:counter).and_return(counter) - allow(Gitlab::Metrics).to receive(:histogram).and_return(histogram) - allow(histogram).to receive(:observe) - allow(counter).to receive(:increment) - end - - it 'counts and measures duration of imported projects' do - expect(Gitlab::Metrics).to receive(:counter).with( - :bitbucket_importer_imported_projects_total, - 'The number of imported projects' - ) - - expect(Gitlab::Metrics).to receive(:histogram).with( - :bitbucket_importer_total_duration_seconds, - 'Total time spent importing projects, in seconds', - {}, - Gitlab::Import::Metrics::IMPORT_DURATION_BUCKETS - ) - - expect(counter).to receive(:increment) - expect(histogram).to receive(:observe).with({ importer: :bitbucket_importer }, anything) - - subject.execute - end - end - end -end diff --git a/spec/lib/gitlab/import_sources_spec.rb b/spec/lib/gitlab/import_sources_spec.rb index 19f17c9079d1e43a93fbdf979bc8987b6f4d391e..48cdeee3d2feadedc16d7756e2301a60bb99c0c3 100644 --- a/spec/lib/gitlab/import_sources_spec.rb +++ b/spec/lib/gitlab/import_sources_spec.rb @@ -74,38 +74,6 @@ end end - describe '.import_table' do - subject { described_class.import_table } - - describe 'Bitbucket cloud' do - it 'returns the ParallelImporter' do - is_expected.to include( - described_class::ImportSource.new( - 'bitbucket', - 'Bitbucket Cloud', - Gitlab::BitbucketImport::ParallelImporter - ) - ) - end - - context 'when flag is disabled' do - before do - stub_feature_flags(bitbucket_parallel_importer: false) - end - - it 'returns the legacy Importer' do - is_expected.to include( - described_class::ImportSource.new( - 'bitbucket', - 'Bitbucket Cloud', - Gitlab::BitbucketImport::Importer - ) - ) - end - end - end - end - describe '.title' do import_sources = { 'github' => 'GitHub', diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb index 1aac6ac8adb49674f3d9565119c204fcf01e888f..dd6e82b9ef2e5429ab52d9c2f6ab3a440745435a 100644 --- a/spec/services/projects/import_service_spec.rb +++ b/spec/services/projects/import_service_spec.rb @@ -183,81 +183,6 @@ expect(result[:status]).to eq :error expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - Failed to import the repository [FILTERED]" end - - context 'when bitbucket_parallel_importer feature flag is disabled' do - before do - stub_feature_flags(bitbucket_parallel_importer: false) - end - - it 'succeeds if repository import is successful' do - expect(project.repository).to receive(:import_repository).and_return(true) - expect_next_instance_of(Gitlab::BitbucketImport::Importer) do |importer| - expect(importer).to receive(:execute).and_return(true) - end - - expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service| - expect(service).to receive(:execute).and_return(status: :success) - end - - result = subject.execute - - expect(result[:status]).to eq :success - end - - it 'fails if repository import fails' do - expect(project.repository) - .to receive(:import_repository) - .with('https://bitbucket.org/vim/vim.git', resolved_address: '') - .and_raise(Gitlab::Git::CommandError, 'Failed to import the repository /a/b/c') - - result = subject.execute - - expect(result[:status]).to eq :error - expect(result[:message]).to eq "Error importing repository #{project.safe_import_url} into #{project.full_path} - Failed to import the repository [FILTERED]" - end - - context 'when lfs import fails' do - it 'logs the error' do - error_message = 'error message' - - expect(project.repository).to receive(:import_repository).and_return(true) - - expect_next_instance_of(Gitlab::BitbucketImport::Importer) do |importer| - expect(importer).to receive(:execute).and_return(true) - end - - expect_next_instance_of(Projects::LfsPointers::LfsImportService) do |service| - expect(service).to receive(:execute).and_return(status: :error, message: error_message) - end - - expect(Gitlab::AppLogger).to receive(:error).with("The Lfs import process failed. #{error_message}") - - subject.execute - end - end - - context 'when repository import scheduled' do - before do - expect(project.repository).to receive(:import_repository).and_return(true) - allow(subject).to receive(:import_data) - end - - it 'downloads lfs objects if lfs_enabled is enabled for project' do - allow(project).to receive(:lfs_enabled?).and_return(true) - - expect_any_instance_of(Projects::LfsPointers::LfsImportService).to receive(:execute) - - subject.execute - end - - it 'does not download lfs objects if lfs_enabled is not enabled for project' do - allow(project).to receive(:lfs_enabled?).and_return(false) - expect_any_instance_of(Projects::LfsPointers::LfsImportService).not_to receive(:execute) - - subject.execute - end - end - end end end end diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index 3d86f7268657bf8cc7c46144f3e87d6ecb14f453..f57fdaa9b7f2149eb84896acca747942095868a4 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -5377,7 +5377,6 @@ - './spec/lib/gitlab/background_task_spec.rb' - './spec/lib/gitlab/backtrace_cleaner_spec.rb' - './spec/lib/gitlab/batch_worker_context_spec.rb' -- './spec/lib/gitlab/bitbucket_import/importer_spec.rb' - './spec/lib/gitlab/bitbucket_import/project_creator_spec.rb' - './spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb' - './spec/lib/gitlab/blame_spec.rb'