From a5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 16 Jun 2021 18:25:58 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-0-stable-ee --- .../web_upload_strategy_spec.rb | 22 ++++++++++++----- spec/lib/gitlab/import_export/all_models.yml | 28 +++++++++++----------- .../import_export/base/relation_factory_spec.rb | 9 +++++++ .../gitlab/import_export/command_line_util_spec.rb | 23 ++++++++++++++++++ .../decompressed_archive_size_validator_spec.rb | 8 +++++++ .../gitlab/import_export/group/tree_saver_spec.rb | 2 +- .../import_export/import_failure_service_spec.rb | 2 +- .../import_export/json/legacy_reader/file_spec.rb | 2 +- .../import_export/json/legacy_reader/hash_spec.rb | 2 +- .../import_export/json/legacy_writer_spec.rb | 2 +- .../import_export/json/ndjson_reader_spec.rb | 2 +- .../import_export/json/ndjson_writer_spec.rb | 2 +- .../json/streaming_serializer_spec.rb | 4 ++-- .../legacy_relation_tree_saver_spec.rb | 4 ++-- .../import_export/project/export_task_spec.rb | 2 +- .../import_export/project/import_task_spec.rb | 2 +- .../project/sample/relation_tree_restorer_spec.rb | 2 +- .../import_export/project/tree_restorer_spec.rb | 20 +++++++--------- .../import_export/relation_tree_restorer_spec.rb | 8 +++---- .../gitlab/import_export/safe_model_attributes.yml | 2 +- spec/lib/gitlab/import_export/shared_spec.rb | 22 +++++++++++++++++ 21 files changed, 119 insertions(+), 51 deletions(-) (limited to 'spec/lib/gitlab/import_export') diff --git a/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb b/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb index 38f1d48798b..451fd6c6f46 100644 --- a/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb +++ b/spec/lib/gitlab/import_export/after_export_strategies/web_upload_strategy_spec.rb @@ -27,20 +27,30 @@ RSpec.describe Gitlab::ImportExport::AfterExportStrategies::WebUploadStrategy do expect(subject.new(url: example_url, http_method: 'whatever')).not_to be_valid end - it 'onyl allow urls as upload urls' do + it 'only allow urls as upload urls' do expect(subject.new(url: example_url)).to be_valid expect(subject.new(url: 'whatever')).not_to be_valid end end describe '#execute' do - it 'removes the exported project file after the upload' do - allow(strategy).to receive(:send_file) - allow(strategy).to receive(:handle_response_error) + context 'when upload succeeds' do + before do + allow(strategy).to receive(:send_file) + allow(strategy).to receive(:handle_response_error) + end + + it 'does not remove the exported project file after the upload' do + expect(project).not_to receive(:remove_exports) - expect(project).to receive(:remove_exports) + strategy.execute(user, project) + end - strategy.execute(user, project) + it 'has finished export status' do + strategy.execute(user, project) + + expect(project.export_status).to eq(:finished) + end end context 'when upload fails' do diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index f81db1413c2..781c55f8d9b 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -342,10 +342,9 @@ container_repositories: - project - name project: -- external_approval_rules +- external_status_checks - taggings - base_tags -- tags - topic_taggings - topics - chat_services @@ -362,11 +361,11 @@ project: - boards - last_event - integrations -- campfire_service -- confluence_service -- datadog_service -- discord_service -- drone_ci_service +- campfire_integration +- confluence_integration +- datadog_integration +- discord_integration +- drone_ci_integration - emails_on_push_service - pipelines_email_service - mattermost_slash_commands_service @@ -376,26 +375,25 @@ project: - pivotaltracker_service - prometheus_service - flowdock_service -- assembla_service -- asana_service +- assembla_integration +- asana_integration - slack_service - microsoft_teams_service - mattermost_service - hangouts_chat_service - unify_circuit_service -- buildkite_service -- bamboo_service +- buildkite_integration +- bamboo_integration - teamcity_service - pushover_service - jira_service - redmine_service - youtrack_service -- custom_issue_tracker_service -- bugzilla_service +- custom_issue_tracker_integration +- bugzilla_integration - ewm_service - external_wiki_service - mock_ci_service -- mock_deployment_service - mock_monitoring_service - forked_to_members - forked_from_project @@ -571,6 +569,7 @@ project: - exported_protected_branches - incident_management_oncall_schedules - incident_management_oncall_rotations +- incident_management_escalation_policies - debian_distributions - merge_request_metrics - security_orchestration_policy_configuration @@ -624,6 +623,7 @@ metrics_setting: - project protected_environments: - project +- group - deploy_access_levels deploy_access_levels: - protected_environment 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 df33b4896a4..6a7ff33465d 100644 --- a/spec/lib/gitlab/import_export/base/relation_factory_spec.rb +++ b/spec/lib/gitlab/import_export/base/relation_factory_spec.rb @@ -43,6 +43,15 @@ RSpec.describe Gitlab::ImportExport::Base::RelationFactory do end end + context 'when author relation' do + let(:relation_sym) { :author } + let(:relation_hash) { { 'name' => 'User', 'project_id' => project.id } } + + it 'returns author hash unchanged' do + expect(subject).to eq(relation_hash) + end + end + context 'when #setup_models is not implemented' do it 'raises NotImplementedError' do expect { subject }.to raise_error(NotImplementedError) diff --git a/spec/lib/gitlab/import_export/command_line_util_spec.rb b/spec/lib/gitlab/import_export/command_line_util_spec.rb index 4000e303816..39a10f87083 100644 --- a/spec/lib/gitlab/import_export/command_line_util_spec.rb +++ b/spec/lib/gitlab/import_export/command_line_util_spec.rb @@ -42,6 +42,8 @@ RSpec.describe Gitlab::ImportExport::CommandLineUtil do filename = File.basename(tempfile.path) subject.gzip(dir: path, filename: filename) + + expect(File.exist?("#{tempfile.path}.gz")).to eq(true) end context 'when exception occurs' do @@ -50,4 +52,25 @@ RSpec.describe Gitlab::ImportExport::CommandLineUtil do end end end + + describe '#gunzip' do + it 'decompresses specified file' do + tmpdir = Dir.mktmpdir + filename = 'labels.ndjson.gz' + gz_filepath = "spec/fixtures/bulk_imports/gz/#{filename}" + FileUtils.copy_file(gz_filepath, File.join(tmpdir, filename)) + + subject.gunzip(dir: tmpdir, filename: filename) + + expect(File.exist?(File.join(tmpdir, 'labels.ndjson'))).to eq(true) + + FileUtils.remove_entry(tmpdir) + end + + context 'when exception occurs' do + it 'raises an exception' do + expect { subject.gunzip(dir: path, filename: 'test') }.to raise_error(Gitlab::ImportExport::Error) + end + end + end end diff --git a/spec/lib/gitlab/import_export/decompressed_archive_size_validator_spec.rb b/spec/lib/gitlab/import_export/decompressed_archive_size_validator_spec.rb index 96c467e78d6..fe3b638d20f 100644 --- a/spec/lib/gitlab/import_export/decompressed_archive_size_validator_spec.rb +++ b/spec/lib/gitlab/import_export/decompressed_archive_size_validator_spec.rb @@ -24,6 +24,14 @@ RSpec.describe Gitlab::ImportExport::DecompressedArchiveSizeValidator do it 'returns true' do expect(subject.valid?).to eq(true) end + + context 'when waiter thread no longer exists' do + it 'does not raise exception' do + allow(Process).to receive(:getpgid).and_raise(Errno::ESRCH) + + expect(subject.valid?).to eq(true) + end + end end context 'when file exceeds allowed decompressed size' do diff --git a/spec/lib/gitlab/import_export/group/tree_saver_spec.rb b/spec/lib/gitlab/import_export/group/tree_saver_spec.rb index 908896e4891..c52daa8ccfd 100644 --- a/spec/lib/gitlab/import_export/group/tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/group/tree_saver_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Gitlab::ImportExport::Group::TreeSaver do end it 'fails to export a group' do - allow_next_instance_of(Gitlab::ImportExport::JSON::NdjsonWriter) do |ndjson_writer| + allow_next_instance_of(Gitlab::ImportExport::Json::NdjsonWriter) do |ndjson_writer| allow(ndjson_writer).to receive(:write_relation_array).and_raise(RuntimeError, 'exception') end diff --git a/spec/lib/gitlab/import_export/import_failure_service_spec.rb b/spec/lib/gitlab/import_export/import_failure_service_spec.rb index c8bb067d40c..51f1fc9c6a2 100644 --- a/spec/lib/gitlab/import_export/import_failure_service_spec.rb +++ b/spec/lib/gitlab/import_export/import_failure_service_spec.rb @@ -43,7 +43,7 @@ RSpec.describe Gitlab::ImportExport::ImportFailureService do let(:importable) { create(:merge_request) } it 'raise exception' do - expect { subject }.to raise_exception(ActiveRecord::AssociationNotFoundError, "Association named 'import_failures' was not found on MergeRequest; perhaps you misspelled it?") + expect { subject }.to raise_exception(ActiveRecord::AssociationNotFoundError, /Association named 'import_failures' was not found on MergeRequest/) end end end diff --git a/spec/lib/gitlab/import_export/json/legacy_reader/file_spec.rb b/spec/lib/gitlab/import_export/json/legacy_reader/file_spec.rb index e092891f236..793b3ebfb9e 100644 --- a/spec/lib/gitlab/import_export/json/legacy_reader/file_spec.rb +++ b/spec/lib/gitlab/import_export/json/legacy_reader/file_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_relative 'shared_example' -RSpec.describe Gitlab::ImportExport::JSON::LegacyReader::File do +RSpec.describe Gitlab::ImportExport::Json::LegacyReader::File do it_behaves_like 'import/export json legacy reader' do let(:valid_path) { 'spec/fixtures/lib/gitlab/import_export/light/project.json' } let(:data) { valid_path } diff --git a/spec/lib/gitlab/import_export/json/legacy_reader/hash_spec.rb b/spec/lib/gitlab/import_export/json/legacy_reader/hash_spec.rb index e47122b6151..57d66dc0f50 100644 --- a/spec/lib/gitlab/import_export/json/legacy_reader/hash_spec.rb +++ b/spec/lib/gitlab/import_export/json/legacy_reader/hash_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' require_relative 'shared_example' -RSpec.describe Gitlab::ImportExport::JSON::LegacyReader::Hash do +RSpec.describe Gitlab::ImportExport::Json::LegacyReader::Hash do it_behaves_like 'import/export json legacy reader' do let(:path) { 'spec/fixtures/lib/gitlab/import_export/light/project.json' } diff --git a/spec/lib/gitlab/import_export/json/legacy_writer_spec.rb b/spec/lib/gitlab/import_export/json/legacy_writer_spec.rb index eb7a2d4aa8b..ab2c4cc2059 100644 --- a/spec/lib/gitlab/import_export/json/legacy_writer_spec.rb +++ b/spec/lib/gitlab/import_export/json/legacy_writer_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::JSON::LegacyWriter do +RSpec.describe Gitlab::ImportExport::Json::LegacyWriter do let(:path) { "#{Dir.tmpdir}/legacy_writer_spec/test.json" } subject do diff --git a/spec/lib/gitlab/import_export/json/ndjson_reader_spec.rb b/spec/lib/gitlab/import_export/json/ndjson_reader_spec.rb index b477ac45577..0ca4c4ccc87 100644 --- a/spec/lib/gitlab/import_export/json/ndjson_reader_spec.rb +++ b/spec/lib/gitlab/import_export/json/ndjson_reader_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::JSON::NdjsonReader do +RSpec.describe Gitlab::ImportExport::Json::NdjsonReader do include ImportExport::CommonUtil let(:fixture) { 'spec/fixtures/lib/gitlab/import_export/light/tree' } diff --git a/spec/lib/gitlab/import_export/json/ndjson_writer_spec.rb b/spec/lib/gitlab/import_export/json/ndjson_writer_spec.rb index 2a5e802bdc5..9be95591ae9 100644 --- a/spec/lib/gitlab/import_export/json/ndjson_writer_spec.rb +++ b/spec/lib/gitlab/import_export/json/ndjson_writer_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" -RSpec.describe Gitlab::ImportExport::JSON::NdjsonWriter do +RSpec.describe Gitlab::ImportExport::Json::NdjsonWriter do include ImportExport::CommonUtil let(:path) { "#{Dir.tmpdir}/ndjson_writer_spec/tree" } diff --git a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb index a0b2faaecfe..deb22de9160 100644 --- a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb +++ b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::ImportExport::JSON::StreamingSerializer do +RSpec.describe Gitlab::ImportExport::Json::StreamingSerializer do let_it_be(:user) { create(:user) } let_it_be(:release) { create(:release) } let_it_be(:group) { create(:group) } @@ -27,7 +27,7 @@ RSpec.describe Gitlab::ImportExport::JSON::StreamingSerializer do end let(:exportable_path) { 'project' } - let(:json_writer) { instance_double('Gitlab::ImportExport::JSON::LegacyWriter') } + let(:json_writer) { instance_double('Gitlab::ImportExport::Json::LegacyWriter') } let(:hash) { { name: exportable.name, description: exportable.description }.stringify_keys } let(:include) { [] } let(:custom_orderer) { nil } diff --git a/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb b/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb index 454cc74b9d4..3b7ed7cb32b 100644 --- a/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb @@ -28,7 +28,7 @@ RSpec.describe Gitlab::ImportExport::LegacyRelationTreeSaver do stub_feature_flags(export_reduce_relation_batch_size: true) end - include_examples 'FastHashSerializer with batch size', Gitlab::ImportExport::JSON::StreamingSerializer::SMALLER_BATCH_SIZE + include_examples 'FastHashSerializer with batch size', Gitlab::ImportExport::Json::StreamingSerializer::SMALLER_BATCH_SIZE end context 'when export_reduce_relation_batch_size feature flag is disabled' do @@ -36,7 +36,7 @@ RSpec.describe Gitlab::ImportExport::LegacyRelationTreeSaver do stub_feature_flags(export_reduce_relation_batch_size: false) end - include_examples 'FastHashSerializer with batch size', Gitlab::ImportExport::JSON::StreamingSerializer::BATCH_SIZE + include_examples 'FastHashSerializer with batch size', Gitlab::ImportExport::Json::StreamingSerializer::BATCH_SIZE end end end diff --git a/spec/lib/gitlab/import_export/project/export_task_spec.rb b/spec/lib/gitlab/import_export/project/export_task_spec.rb index 7fcd2187a90..3dd1e9257cc 100644 --- a/spec/lib/gitlab/import_export/project/export_task_spec.rb +++ b/spec/lib/gitlab/import_export/project/export_task_spec.rb @@ -2,7 +2,7 @@ require 'rake_helper' -RSpec.describe Gitlab::ImportExport::Project::ExportTask do +RSpec.describe Gitlab::ImportExport::Project::ExportTask, :silence_stdout do let_it_be(:username) { 'root' } let(:namespace_path) { username } let_it_be(:user) { create(:user, username: username) } diff --git a/spec/lib/gitlab/import_export/project/import_task_spec.rb b/spec/lib/gitlab/import_export/project/import_task_spec.rb index 90f4501acdc..c847224cb9b 100644 --- a/spec/lib/gitlab/import_export/project/import_task_spec.rb +++ b/spec/lib/gitlab/import_export/project/import_task_spec.rb @@ -2,7 +2,7 @@ require 'rake_helper' -RSpec.describe Gitlab::ImportExport::Project::ImportTask, :request_store do +RSpec.describe Gitlab::ImportExport::Project::ImportTask, :request_store, :silence_stdout do let(:username) { 'root' } let(:namespace_path) { username } let!(:user) { create(:user, username: username) } diff --git a/spec/lib/gitlab/import_export/project/sample/relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/sample/relation_tree_restorer_spec.rb index f87f79d4462..f6a028383f2 100644 --- a/spec/lib/gitlab/import_export/project/sample/relation_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project/sample/relation_tree_restorer_spec.rb @@ -77,7 +77,7 @@ RSpec.describe Gitlab::ImportExport::Project::Sample::RelationTreeRestorer do let(:relation_factory) { Gitlab::ImportExport::Project::Sample::RelationFactory } let(:reader) { Gitlab::ImportExport::Reader.new(shared: shared) } let(:path) { 'spec/fixtures/lib/gitlab/import_export/sample_data/tree' } - let(:relation_reader) { Gitlab::ImportExport::JSON::NdjsonReader.new(path) } + let(:relation_reader) { Gitlab::ImportExport::Json::NdjsonReader.new(path) } it 'initializes relation_factory with date_calculator as parameter' do expect(Gitlab::ImportExport::Project::Sample::RelationFactory).to receive(:create).with(hash_including(:date_calculator)).at_least(:once).times diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb index bc5e6ea7bb3..1b5fba85020 100644 --- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb @@ -600,9 +600,8 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do setup_import_export_config('light') setup_reader(reader) - expect(project) - .to receive(:merge_requests) - .and_raise(exception) + expect(project).to receive(:merge_requests).and_call_original + expect(project).to receive(:merge_requests).and_raise(exception) end it 'report post import error' do @@ -618,12 +617,9 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do setup_import_export_config('light') setup_reader(reader) - expect(project) - .to receive(:merge_requests) - .and_raise(exception) - expect(project) - .to receive(:merge_requests) - .and_call_original + expect(project).to receive(:merge_requests).and_call_original + expect(project).to receive(:merge_requests).and_raise(exception) + expect(project).to receive(:merge_requests).and_call_original expect(restored_project_json).to eq(true) end @@ -824,9 +820,9 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do end before do - allow_any_instance_of(Gitlab::ImportExport::JSON::LegacyReader::File).to receive(:exist?).and_return(true) - allow_any_instance_of(Gitlab::ImportExport::JSON::NdjsonReader).to receive(:exist?).and_return(false) - allow_any_instance_of(Gitlab::ImportExport::JSON::LegacyReader::File).to receive(:tree_hash) { tree_hash } + allow_any_instance_of(Gitlab::ImportExport::Json::LegacyReader::File).to receive(:exist?).and_return(true) + allow_any_instance_of(Gitlab::ImportExport::Json::NdjsonReader).to receive(:exist?).and_return(false) + allow_any_instance_of(Gitlab::ImportExport::Json::LegacyReader::File).to receive(:tree_hash) { tree_hash } end context 'no group visibility' do diff --git a/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb index d3c14b1f8fe..9325cdac9ed 100644 --- a/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/relation_tree_restorer_spec.rb @@ -96,7 +96,7 @@ RSpec.describe Gitlab::ImportExport::RelationTreeRestorer do context 'using legacy reader' do let(:path) { 'spec/fixtures/lib/gitlab/import_export/complex/project.json' } let(:relation_reader) do - Gitlab::ImportExport::JSON::LegacyReader::File.new( + Gitlab::ImportExport::Json::LegacyReader::File.new( path, relation_names: reader.project_relation_names, allowed_path: 'project' @@ -117,14 +117,14 @@ RSpec.describe Gitlab::ImportExport::RelationTreeRestorer do context 'using ndjson reader' do let(:path) { 'spec/fixtures/lib/gitlab/import_export/complex/tree' } - let(:relation_reader) { Gitlab::ImportExport::JSON::NdjsonReader.new(path) } + let(:relation_reader) { Gitlab::ImportExport::Json::NdjsonReader.new(path) } it_behaves_like 'import project successfully' end context 'with invalid relations' do let(:path) { 'spec/fixtures/lib/gitlab/import_export/project_with_invalid_relations/tree' } - let(:relation_reader) { Gitlab::ImportExport::JSON::NdjsonReader.new(path) } + let(:relation_reader) { Gitlab::ImportExport::Json::NdjsonReader.new(path) } it 'logs the invalid relation and its errors' do expect(relation_tree_restorer.shared.logger) @@ -151,7 +151,7 @@ RSpec.describe Gitlab::ImportExport::RelationTreeRestorer do let(:object_builder) { Gitlab::ImportExport::Group::ObjectBuilder } let(:relation_factory) { Gitlab::ImportExport::Group::RelationFactory } let(:relation_reader) do - Gitlab::ImportExport::JSON::LegacyReader::File.new( + Gitlab::ImportExport::Json::LegacyReader::File.new( path, relation_names: reader.group_relation_names) end diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index 70ebff2a54e..2173bee6b4b 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -102,7 +102,6 @@ ProjectLabel: - template - description - priority -- remove_on_close Milestone: - id - title @@ -702,6 +701,7 @@ ProjectSetting: ProtectedEnvironment: - id - project_id +- group_id - name - created_at - updated_at diff --git a/spec/lib/gitlab/import_export/shared_spec.rb b/spec/lib/gitlab/import_export/shared_spec.rb index 22f2d4c5077..feeb88397eb 100644 --- a/spec/lib/gitlab/import_export/shared_spec.rb +++ b/spec/lib/gitlab/import_export/shared_spec.rb @@ -37,6 +37,28 @@ RSpec.describe Gitlab::ImportExport::Shared do end end + context 'with a group on disk' do + describe '#base_path' do + it 'uses hashed storage path' do + group = create(:group) + subject = described_class.new(group) + base_path = %(/tmp/gitlab_exports/@groups/) + + expect(subject.base_path).to match(/#{base_path}\h{2}\/\h{2}\/\h{64}/) + end + end + end + + context 'when exportable type is unsupported' do + describe '#base_path' do + it 'raises' do + subject = described_class.new('test') + + expect { subject.base_path }.to raise_error(Gitlab::ImportExport::Error, 'Unsupported Exportable Type String') + end + end + end + describe '#error' do let(:error) { StandardError.new('Error importing into /my/folder Permission denied @ unlink_internal - /var/opt/gitlab/gitlab-rails/shared/a/b/c/uploads/file') } -- cgit v1.2.3