Commit 202f290b authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'remove-relation-rename-service' into 'master'

Remove Relation rename service

See merge request gitlab-org/gitlab!26004
parents d5c4c4bf a73929e4
......@@ -195,16 +195,17 @@ module Gitlab
The [current version history](../user/project/settings/import_export.md) also displays the equivalent GitLab version
and it is useful for knowing which versions won't be compatible between them.
| GitLab version | Import/Export version |
| ---------------- | --------------------- |
| 11.1 to current | 0.2.4 |
| 10.8 | 0.2.3 |
| 10.4 | 0.2.2 |
| Exporting GitLab version | Importing GitLab version |
| -------------------------- | -------------------------- |
| 11.7 to current | 11.7 to current |
| 11.1 to 11.6 | 11.1 to 11.6 |
| 10.8 to 11.0 | 10.8 to 11.0 |
| 10.4 to 10.7 | 10.4 to 10.7 |
| ... | ... |
| 8.10.3 | 0.1.3 |
| 8.10.0 | 0.1.2 |
| 8.9.5 | 0.1.1 |
| 8.9.0 | 0.1.0 |
| 8.10.3 to 8.11 | 8.10.3 to 8.11 |
| 8.10.0 to 8.10.2 | 8.10.0 to 8.10.2 |
| 8.9.5 to 8.9.11 | 8.9.5 to 8.9.11 |
| 8.9.0 to 8.9.4 | 8.9.0 to 8.9.4 |
### When to bump the version up
......@@ -223,28 +224,6 @@ Every time we bump the version, the integration specs will fail and can be fixed
bundle exec rake gitlab:import_export:bump_version
```
### Renaming columns or models
This is a relatively common occurrence that will require a version bump.
There is also the _RC problem_ - GitLab.com runs an RC, prior to any customers,
meaning that we want to bump the version up in the next version (or patch release).
For example:
1. Add rename to `RelationRenameService` in X.Y
1. Remove it from `RelationRenameService` in X.Y + 1
1. Bump Import/Export version in X.Y + 1
```ruby
module Gitlab
module ImportExport
class RelationRenameService
RENAMES = {
'pipelines' => 'ci_pipelines' # Added in 11.6, remove in 11.7
}.freeze
```
## A quick dive into the code
### Import/Export configuration (`import_export.yml`)
......
......@@ -42,22 +42,23 @@ Note the following:
The following table lists updates to Import/Export:
| GitLab version | Import/Export schema version |
| ---------------- | --------------------- |
| 11.1 to current | 0.2.4 |
| 10.8 | 0.2.3 |
| 10.4 | 0.2.2 |
| 10.3 | 0.2.1 |
| 10.0 | 0.2.0 |
| 9.4.0 | 0.1.8 |
| 9.2.0 | 0.1.7 |
| 8.17.0 | 0.1.6 |
| 8.13.0 | 0.1.5 |
| 8.12.0 | 0.1.4 |
| 8.10.3 | 0.1.3 |
| 8.10.0 | 0.1.2 |
| 8.9.5 | 0.1.1 |
| 8.9.0 | 0.1.0 |
| Exporting GitLab version | Importing GitLab version |
| -------------------------- | -------------------------- |
| 11.7 to current | 11.7 to current |
| 11.1 to 11.6 | 11.1 to 11.6 |
| 10.8 to 11.0 | 10.8 to 11.0 |
| 10.4 to 10.7 | 10.4 to 10.7 |
| 10.3 | 10.3 |
| 10.0 to 10.2 | 10.0 to 10.2 |
| 9.4 to 9.6 | 9.4 to 9.6 |
| 9.2 to 9.3 | 9.2 to 9.3 |
| 8.17 to 9.1 | 8.17 to 9.1 |
| 8.13 to 8.16 | 8.13 to 8.16 |
| 8.12 | 8.12 |
| 8.10.3 to 8.11 | 8.10.3 to 8.11 |
| 8.10.0 to 8.10.2 | 8.10.0 to 8.10.2 |
| 8.9.5 to 8.9.11 | 8.9.5 to 8.9.11 |
| 8.9.0 to 8.9.4 | 8.9.0 to 8.9.4 |
Projects can be exported and imported only between versions of GitLab with matching Import/Export versions.
......
......@@ -21,8 +21,6 @@ module Gitlab
@tree_hash = read_tree_hash
@project_members = @tree_hash.delete('project_members')
RelationRenameService.rename(@tree_hash)
if relation_tree_restorer.restore
import_failure_service.with_retry(action: 'set_latest_merge_request_diff_ids!') do
@project.merge_requests.set_latest_merge_request_diff_ids!
......
......@@ -35,8 +35,6 @@ module Gitlab
end
project_tree['project_members'] += group_members_array
RelationRenameService.add_new_associations(project_tree)
end
def reader
......
# frozen_string_literal: true
# This class is intended to help with relation renames within Gitlab versions
# and allow compatibility between versions.
# If you have to change one relationship name that is imported/exported,
# you should add it to the RENAMES constant indicating the old name and the
# new one.
# The behavior of these renamed relationships should be transient and it should
# only last one release until you completely remove the renaming from the list.
#
# When importing, this class will check the hash and:
# - if only the old relationship name is found, it will rename it with the new one
# - if only the new relationship name is found, it will do nothing
# - if it finds both, it will use the new relationship data
#
# When exporting, this class will duplicate the keys in the resulting file.
# This way, if we open the file in an old version of the exporter it will work
# and also it will with the newer versions.
module Gitlab
module ImportExport
class RelationRenameService
RENAMES = {
'pipelines' => 'ci_pipelines' # Added in 11.6, remove in 11.7
}.freeze
def self.rename(tree_hash)
return unless tree_hash&.present?
RENAMES.each do |old_name, new_name|
old_entry = tree_hash.delete(old_name)
next if tree_hash[new_name]
next unless old_entry
tree_hash[new_name] = old_entry
end
end
def self.add_new_associations(tree_hash)
RENAMES.each do |old_name, new_name|
next if tree_hash.key?(old_name)
tree_hash[old_name] = tree_hash[new_name]
end
end
end
end
end
......@@ -6318,7 +6318,7 @@
]
}
],
"pipelines": [
"ci_pipelines": [
{
"id": 36,
"project_id": 5,
......
......@@ -89,8 +89,6 @@ describe 'Test coverage of the Project Import' do
def relations_from_json(json_file)
json = ActiveSupport::JSON.decode(IO.read(json_file))
Gitlab::ImportExport::RelationRenameService.rename(json)
[].tap {|res| gather_relations({ project: json }, res, [])}
.map {|relation_names| relation_names.join('.')}
end
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::ImportExport::RelationRenameService do
include ImportExport::CommonUtil
let(:renames) do
{
'example_relation1' => 'new_example_relation1',
'example_relation2' => 'new_example_relation2'
}
end
let(:user) { create(:admin) }
let(:group) { create(:group, :nested) }
let!(:project) { create(:project, :builds_disabled, :issues_disabled, group: group, name: 'project', path: 'project') }
let(:shared) { project.import_export_shared }
before do
stub_const("#{described_class}::RENAMES", renames)
end
context 'when importing' do
let(:project_tree_restorer) { Gitlab::ImportExport::Project::TreeRestorer.new(user: user, shared: shared, project: project) }
let(:file_content) { IO.read(File.join(shared.export_path, 'project.json')) }
let(:json_file) { ActiveSupport::JSON.decode(file_content) }
before do
setup_import_export_config('complex')
allow(ActiveSupport::JSON).to receive(:decode).and_call_original
allow(ActiveSupport::JSON).to receive(:decode).with(file_content).and_return(json_file)
end
context 'when the file has only old relationship names' do
# Configuring the json as an old version exported file, with only
# the previous association with the old name
before do
renames.each do |old_name, _|
json_file[old_name.to_s] = []
end
end
it 'renames old relationships to the new name' do
expect(json_file.keys).to include(*renames.keys)
project_tree_restorer.restore
expect(json_file.keys).to include(*renames.values)
expect(json_file.keys).not_to include(*renames.keys)
end
end
context 'when the file has both the old and new relationships' do
# Configuring the json as the new version exported file, with both
# the old association name and the new one
before do
renames.each do |old_name, new_name|
json_file[old_name.to_s] = [1]
json_file[new_name.to_s] = [2]
end
end
it 'uses the new relationships and removes the old ones from the hash' do
expect(json_file.keys).to include(*renames.keys)
project_tree_restorer.restore
expect(json_file.keys).to include(*renames.values)
expect(json_file.values_at(*renames.values).flatten.uniq.first).to eq 2
expect(json_file.keys).not_to include(*renames.keys)
end
end
context 'when the file has only new relationship names' do
# Configuring the json as the future version exported file, with only
# the new association name
before do
renames.each do |_, new_name|
json_file[new_name.to_s] = []
end
end
it 'uses the new relationships' do
expect(json_file.keys).not_to include(*renames.keys)
project_tree_restorer.restore
expect(json_file.keys).to include(*renames.values)
end
end
end
context 'when exporting' do
let(:export_content_path) { project_tree_saver.full_path }
let(:export_content_hash) { ActiveSupport::JSON.decode(File.read(export_content_path)) }
let(:injected_hash) { renames.values.product([{}]).to_h }
let(:relation_tree_saver) { Gitlab::ImportExport::RelationTreeSaver.new }
let(:project_tree_saver) do
Gitlab::ImportExport::Project::TreeSaver.new(
project: project, current_user: user, shared: shared)
end
before do
allow(project_tree_saver).to receive(:tree_saver).and_return(relation_tree_saver)
end
it 'adds old relationships to the exported file' do
# we inject relations with new names that should be rewritten
expect(relation_tree_saver).to receive(:serialize).and_wrap_original do |method, *args|
method.call(*args).merge(injected_hash)
end
expect(project_tree_saver.save).to eq(true)
expect(export_content_hash.keys).to include(*renames.keys)
expect(export_content_hash.keys).to include(*renames.values)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment