diff --git a/app/models/concerns/import/has_import_source.rb b/app/models/concerns/import/has_import_source.rb index f617c7accc386acf28c6e9825eb760a51e2967a3..cdede6ddc7740e7e7e8c808f8823a2482d110011 100644 --- a/app/models/concerns/import/has_import_source.rb +++ b/app/models/concerns/import/has_import_source.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true module Import + SOURCE_DIRECT_TRANSFER = :gitlab_migration # aka BulkImports + module HasImportSource extend ActiveSupport::Concern IMPORT_SOURCES = { none: 0, # not imported - gitlab_migration: 1, # aka direct transfer & bulk_import + SOURCE_DIRECT_TRANSFER => 1, gitlab_project: 2, # aka gitlab import/export github: 3, bitbucket: 4, # aka bitbucket cloud diff --git a/lib/bulk_imports/ndjson_pipeline.rb b/lib/bulk_imports/ndjson_pipeline.rb index d7976389c80ee24dd2ad86636ecb901cdb3a885b..a038d445f0ba91e1a662e3ce6c5ff650d9ec09be 100644 --- a/lib/bulk_imports/ndjson_pipeline.rb +++ b/lib/bulk_imports/ndjson_pipeline.rb @@ -26,7 +26,8 @@ def transform(context, data) members_mapper: members_mapper, object_builder: object_builder, user: context.current_user, - excluded_keys: import_export_config.relation_excluded_keys(key) + excluded_keys: import_export_config.relation_excluded_keys(key), + import_source: Import::SOURCE_DIRECT_TRANSFER ) end diff --git a/lib/gitlab/import_export/base/relation_factory.rb b/lib/gitlab/import_export/base/relation_factory.rb index c3021f034cd5784adbfb5c236dd2ccdf793c5d48..966fd15270e9b8d51af88f8c44b9274719719b97 100644 --- a/lib/gitlab/import_export/base/relation_factory.rb +++ b/lib/gitlab/import_export/base/relation_factory.rb @@ -46,7 +46,8 @@ def self.relation_class(relation_name) relation_name.to_s.constantize end - def initialize(relation_sym:, relation_index:, relation_hash:, members_mapper:, object_builder:, user:, importable:, excluded_keys: []) + # rubocop:disable Metrics/ParameterLists -- Keyword arguments are not adding complexity to initializer + def initialize(relation_sym:, relation_index:, relation_hash:, members_mapper:, object_builder:, user:, importable:, excluded_keys: [], import_source: nil) @relation_sym = relation_sym @relation_name = self.class.overrides[relation_sym]&.to_sym || relation_sym @relation_index = relation_index @@ -55,6 +56,7 @@ def initialize(relation_sym:, relation_index:, relation_hash:, members_mapper:, @object_builder = object_builder @user = user @importable = importable + @import_source = import_source @imported_object_retries = 0 @relation_hash[importable_column_name] = @importable.id @original_user = {} @@ -67,6 +69,7 @@ def initialize(relation_sym:, relation_index:, relation_hash:, members_mapper:, # from the object attributes and the export will fail. @relation_hash.except!(*excluded_keys) end + # rubocop:enable Metrics/ParameterLists # Creates an object from an actual model with name "relation_sym" with params from # the relation_hash, updating references with new object IDs, mapping users using @@ -182,6 +185,10 @@ def imported_object existing_or_new_object.importing = true end + if @import_source && existing_or_new_object.respond_to?(:imported_from) + existing_or_new_object.imported_from = @import_source + end + existing_or_new_object rescue ActiveRecord::RecordNotUnique # as the operation is not atomic, retry in the unlikely scenario an INSERT is diff --git a/spec/lib/bulk_imports/ndjson_pipeline_spec.rb b/spec/lib/bulk_imports/ndjson_pipeline_spec.rb index 55a9292e48d0388338f2aaf4ec2a8c068b0cc774..56ebb885f5e02150fbdfef07b4e7883f265bc582 100644 --- a/spec/lib/bulk_imports/ndjson_pipeline_spec.rb +++ b/spec/lib/bulk_imports/ndjson_pipeline_spec.rb @@ -143,7 +143,8 @@ def initialize(portable, user, context) members_mapper: instance_of(BulkImports::UsersMapper), object_builder: Gitlab::ImportExport::Group::ObjectBuilder, user: user, - excluded_keys: nil + excluded_keys: nil, + import_source: Import::SOURCE_DIRECT_TRANSFER ) .and_return(relation_object) expect(relation_object).to receive(:assign_attributes).with(group: group) diff --git a/spec/lib/gitlab/import_export/base/relation_factory_spec.rb b/spec/lib/gitlab/import_export/base/relation_factory_spec.rb index 5e63804c51c2834bad9ce3f94a0e0e359ee7096d..86238e8d6e35d03ee8b135b98bc7ca27e238c880 100644 --- a/spec/lib/gitlab/import_export/base/relation_factory_spec.rb +++ b/spec/lib/gitlab/import_export/base/relation_factory_spec.rb @@ -2,13 +2,14 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::Base::RelationFactory do +RSpec.describe Gitlab::ImportExport::Base::RelationFactory, feature_category: :importers do let(:user) { create(:admin) } let(:project) { create(:project) } let(:members_mapper) { double('members_mapper').as_null_object } let(:relation_sym) { :project_snippets } let(:relation_hash) { {} } let(:excluded_keys) { [] } + let(:import_source) { nil } subject do described_class.create( # rubocop:disable Rails/SaveBang @@ -19,7 +20,8 @@ members_mapper: members_mapper, user: user, importable: project, - excluded_keys: excluded_keys + excluded_keys: excluded_keys, + import_source: import_source ) end @@ -90,6 +92,24 @@ expect(subject).to be_instance_of(Note) end + context 'when import_source is given' do + let(:import_source) { Import::SOURCE_DIRECT_TRANSFER } + + it 'sets the imported_from' do + expect(subject.imported_from).to eq(import_source.to_s) + end + + context 'when object does not have an imported_from attribute' do + let(:relation_sym) { :user } + let(:relation_hash) { attributes_for(:user) } + + it 'works without an error' do + expect(subject).not_to respond_to(:imported_from) # Sanity check: This must be true for test subject + expect(subject).to be_instance_of(User) + end + end + end + context 'when relation contains user references' do let(:new_user) { create(:user) } let(:exported_member) do