Skip to content
Snippets Groups Projects
Commit 8409340b authored by James Lopez's avatar James Lopez
Browse files

Add missing group members to export for I/E

parent 572fb0be
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -26,7 +26,7 @@ module Projects
end
 
def project_tree_saver
Gitlab::ImportExport::ProjectTreeSaver.new(project: project, shared: @shared)
Gitlab::ImportExport::ProjectTreeSaver.new(project: project, current_user: @current_user, shared: @shared)
end
 
def uploads_saver
Loading
Loading
---
title: Add ability to export project inherited group members to Import/Export
merge_request: 8923
author:
Loading
Loading
@@ -14,6 +14,11 @@
> raketask.
> - The exports are stored in a temporary [shared directory][tmp] and are deleted
> every 24 hours by a specific worker.
> - Group members will get exported as project members, as long as the user has
> master or admin access to the group where the exported project lives. An admin
> in the import side is required to map the users, based on email or username.
> Otherwise, a supplementary comment is left to mention the original author and
> the MRs, notes or issues will be owned by the importer.
 
Existing projects running on any GitLab instance or GitLab.com can be exported
with all their related data and be moved into a new GitLab instance.
Loading
Loading
@@ -22,7 +27,7 @@ with all their related data and be moved into a new GitLab instance.
 
| GitLab version | Import/Export version |
| -------- | -------- |
| 8.16.2 to current | 0.1.6 |
| 8.17.0 to current | 0.1.6 |
| 8.13.0 | 0.1.5 |
| 8.12.0 | 0.1.4 |
| 8.10.3 | 0.1.3 |
Loading
Loading
Loading
Loading
@@ -32,6 +32,10 @@ module Gitlab
@user.id
end
 
def include?(old_author_id)
map.keys.include?(old_author_id) && map[old_author_id] != default_user_id
end
private
 
def missing_keys_tracking_hash
Loading
Loading
Loading
Loading
@@ -5,8 +5,9 @@ module Gitlab
 
attr_reader :full_path
 
def initialize(project:, shared:)
def initialize(project:, current_user:, shared:)
@project = project
@current_user = current_user
@shared = shared
@full_path = File.join(@shared.export_path, ImportExport.project_filename)
end
Loading
Loading
@@ -24,7 +25,29 @@ module Gitlab
private
 
def project_json_tree
@project.to_json(Gitlab::ImportExport::Reader.new(shared: @shared).project_tree)
project_json['project_members'] += group_members_json
project_json.to_json
end
def project_json
@project_json ||= @project.as_json(reader.project_tree)
end
def reader
@reader ||= Gitlab::ImportExport::Reader.new(shared: @shared)
end
def group_members_json
group_members.as_json(reader.group_members_tree).each do |group_member|
group_member['source_type'] = 'Project' # Make group members project members of the future import
end
end
def group_members
return [] unless @current_user.can?(:admin_group, @project.group)
MembersFinder.new(@project.project_members, @project.group).execute(@current_user)
end
end
end
Loading
Loading
Loading
Loading
@@ -21,6 +21,10 @@ module Gitlab
false
end
 
def group_members_tree
@attributes_finder.find_included(:project_members).merge(include: @attributes_finder.find(:user))
end
private
 
# Builds a hash in the format described here: http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html
Loading
Loading
Loading
Loading
@@ -89,7 +89,7 @@ module Gitlab
end
 
def has_author?(old_author_id)
admin_user? && @members_mapper.map.keys.include?(old_author_id)
admin_user? && @members_mapper.include?(old_author_id)
end
 
def missing_author_note(updated_at, author_name)
Loading
Loading
Loading
Loading
@@ -116,5 +116,27 @@ describe Gitlab::ImportExport::MembersMapper, services: true do
expect(members_mapper.map[exported_user_id]).to eq(user2.id)
end
end
context 'importing group members' do
let(:group) { create(:group) }
let(:project) { create(:empty_project, namespace: group) }
let(:members_mapper) do
described_class.new(
exported_members: exported_members, user: user, project: project)
end
before do
group.add_users([user, user2], GroupMember::DEVELOPER)
user.update(email: 'invite@test.com')
end
it 'maps the importer' do
expect(members_mapper.map[-1]).to eq(user.id)
end
it 'maps the group member' do
expect(members_mapper.map[exported_user_id]).to eq(user2.id)
end
end
end
end
Loading
Loading
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
describe 'saves the project tree into a json object' do
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
let(:project_tree_saver) { described_class.new(project: project, shared: shared) }
let(:project_tree_saver) { described_class.new(project: project, current_user: user, shared: shared) }
let(:export_path) { "#{Dir::tmpdir}/project_tree_saver_spec" }
let(:user) { create(:user) }
let(:project) { setup_project }
Loading
Loading
@@ -92,7 +92,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
end
 
it 'has pipeline builds' do
expect(saved_project_json['pipelines'].first['statuses'].count { |hash| hash['type'] == 'Ci::Build'}).to eq(1)
expect(saved_project_json['pipelines'].first['statuses'].count { |hash| hash['type'] == 'Ci::Build' }).to eq(1)
end
 
it 'has pipeline commits' do
Loading
Loading
@@ -112,13 +112,13 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
end
 
it 'has project and group labels' do
label_types = saved_project_json['issues'].first['label_links'].map { |link| link['label']['type']}
label_types = saved_project_json['issues'].first['label_links'].map { |link| link['label']['type'] }
 
expect(label_types).to match_array(['ProjectLabel', 'GroupLabel'])
end
 
it 'has priorities associated to labels' do
priorities = saved_project_json['issues'].first['label_links'].map { |link| link['label']['priorities']}
priorities = saved_project_json['issues'].first['label_links'].map { |link| link['label']['priorities'] }
 
expect(priorities.flatten).not_to be_empty
end
Loading
Loading
@@ -140,6 +140,51 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
 
expect(project_tree_saver.save).to be true
end
context 'group members' do
let(:user2) { create(:user, email: 'group@member.com') }
let(:member_emails) do
saved_project_json['project_members'].map do |pm|
pm['user']['email']
end
end
before do
Group.first.add_developer(user2)
end
it 'does not export group members if it has no permission' do
Group.first.add_developer(user)
expect(member_emails).not_to include('group@member.com')
end
it 'does not export group members as master' do
Group.first.add_master(user)
expect(member_emails).not_to include('group@member.com')
end
it 'exports group members as group owner' do
Group.first.add_owner(user)
expect(member_emails).to include('group@member.com')
end
context 'as admin' do
let(:user) { create(:admin) }
it 'exports group members as admin' do
expect(member_emails).to include('group@member.com')
end
it 'exports group members as project members' do
member_types = saved_project_json['project_members'].map { |pm| pm['source_type'] }
expect(member_types).to all(eq('Project'))
end
end
end
end
end
 
Loading
Loading
@@ -167,10 +212,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
commit_status = create(:commit_status, project: project)
 
ci_pipeline = create(:ci_pipeline,
project: project,
sha: merge_request.diff_head_sha,
ref: merge_request.source_branch,
statuses: [commit_status])
project: project,
sha: merge_request.diff_head_sha,
ref: merge_request.source_branch,
statuses: [commit_status])
 
create(:ci_build, pipeline: ci_pipeline, project: project)
create(:milestone, project: project)
Loading
Loading
Loading
Loading
@@ -86,6 +86,10 @@ describe Gitlab::ImportExport::Reader, lib: true do
expect(described_class.new(shared: shared).project_tree).to match(include: [{ issues: { methods: [:name] } }])
end
 
it 'generates the correct hash for group members' do
expect(described_class.new(shared: shared).group_members_tree).to match({ include: { user: { only: [:email] } } })
end
def setup_yaml(hash)
allow(YAML).to receive(:load_file).with(test_config).and_return(hash)
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment