Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot
2025-07-30 21:07:28 +00:00
parent cdf17e1ce0
commit 908d9298b5
23 changed files with 581 additions and 26 deletions

View File

@ -1 +1 @@
3a73e8c517a6075dc923e470fb2c4ae5c2b5d31d
6b7e0f4350032c3519eab68747eda6515cd784b4

View File

@ -13,8 +13,12 @@
%h2{ class: title_classes, data: { 'settings-block-title': '' } }
= heading || @heading
- if description || @description
%p.gl-text-subtle.gl-m-0
= description || @description
- if description.is_a?(String) || @description.is_a?(String)
%p.gl-text-subtle.gl-m-0
= description || @description
- else
.gl-text-subtle.gl-m-0
= description || @description
.settings-content
.gl-pl-7.sm:gl-pl-8.gl-mt-5
= body

View File

@ -52,4 +52,8 @@ class ProjectImportData < ApplicationRecord
def user_mapping_enabled?
self.data&.dig('user_contribution_mapping_enabled') || false
end
def user_mapping_to_personal_namespace_owner_enabled?
self.data&.dig('user_mapping_to_personal_namespace_owner_enabled') || false
end
end

View File

@ -8,7 +8,8 @@
= render "layouts/bizible"
= render_if_exists "layouts/google_tag_manager_body"
= render_if_exists 'devise/shared/delete_unconfirmed_users_flash'
.gl-mb-6
= render_if_exists 'devise/shared/delete_unconfirmed_users_flash'
.well-confirmation.gl-text-center.gl-mb-6
%h1.gl-mt-0

View File

@ -9,6 +9,18 @@
= s_("ProtectedBranch|Keep stable branches secure and force developers to use merge requests.")
= link_to s_("ProtectedBranch|What are protected branches?"), help_page_path("user/project/repository/branches/protected.md")
- if @project.present?
- branch_rules_docs_link_url = help_page_path('user/project/repository/branches/branch_rules.md')
- branch_rules_link_url = project_settings_repository_path(@project, anchor: 'branch-rules')
- branch_rules_link_start = '<a href="%{url}" rel="noopener noreferrer">'.html_safe % { url: branch_rules_link_url }
= render Pajamas::AlertComponent.new( alert_options: { class: 'gl-mr-7 gl-mt-5' },
dismissible: false) do |c|
- c.with_body do
= s_("ProtectedBranch|Protected branches is moving to %{branch_rules_link_start}Branch rules%{branch_rules_link_end}.").html_safe % { branch_rules_link_start: branch_rules_link_start, branch_rules_link_end: '</a>'.html_safe }
= s_("ProtectedBranch|You can now manage branch protections, approval rules, and status checks in one place.")
= link_to s_("ProtectedBranch|How do I use branch rules?"), branch_rules_docs_link_url, target: '_blank', rel: 'noopener noreferrer'
- c.with_body do
.js-alert-protected-branch-created-container
= render Pajamas::AlertComponent.new(variant: :warning,

View File

@ -0,0 +1,10 @@
---
name: user_mapping_to_personal_namespace_owner
description: Assign imported contributions to personal namespace owner for all importers
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/525342
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/198010
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/556557
milestone: '18.3'
group: group::import
type: wip
default_enabled: false

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class RemoveDeprecatedCompliancePolicyJobInstances < Gitlab::Database::Migration[2.3]
disable_ddl_transaction!
milestone '18.3'
DEPRECATED_JOB_CLASSES = %w[Security::RefreshComplianceFrameworkSecurityPoliciesWorker]
def up
sidekiq_remove_jobs(job_klasses: DEPRECATED_JOB_CLASSES)
end
def down
# This migration removes instances of a deprecated worker and cannot be undone.
end
end

View File

@ -0,0 +1 @@
7106f96dae5a305cb076ea030f0209649a8c6b0d04adf3df17893182e21e0895

View File

@ -23,6 +23,9 @@ module Gitlab
user_contribution_mapping_enabled =
Feature.enabled?(:bitbucket_server_user_mapping, current_user)
user_mapping_to_personal_namespace_owner_enabled = user_contribution_mapping_enabled &&
Feature.enabled?(:user_mapping_to_personal_namespace_owner, current_user)
::Projects::CreateService.new(
current_user,
name: name,
@ -41,7 +44,8 @@ module Gitlab
repo_slug: repo_slug,
timeout_strategy: timeout_strategy,
bitbucket_server_notes_separate_worker: bitbucket_server_notes_separate_worker_enabled,
user_contribution_mapping_enabled: user_contribution_mapping_enabled
user_contribution_mapping_enabled: user_contribution_mapping_enabled,
user_mapping_to_personal_namespace_owner_enabled: user_mapping_to_personal_namespace_owner_enabled
}
},
skip_wiki: true

View File

@ -27,6 +27,10 @@ module Gitlab
if user_mapping_enabled?(project)
return unless object[:username]
if project.root_ancestor.user_namespace? && user_mapping_to_personal_namespace_owner_enabled?(project)
return project.root_ancestor.owner_id
end
source_user_for_author(object).mapped_user_id
else
find_user_id(by: :email, value: object.is_a?(Hash) ? object[:author_email] : object.author_email)
@ -60,7 +64,11 @@ module Gitlab
end
def user_mapping_enabled?(project)
!!project.import_data.user_mapping_enabled?
project.import_data.user_mapping_enabled?
end
def user_mapping_to_personal_namespace_owner_enabled?(project)
project.import_data.user_mapping_to_personal_namespace_owner_enabled?
end
def source_user_for_author(user_data)

View File

@ -5,6 +5,7 @@ module Import
module Pusher
def push_reference(project, record, attribute, source_user_identifier)
return unless user_mapping_enabled?(project)
return if map_to_personal_namespace_owner?(project)
return if source_user_identifier.nil?
source_user = source_user_mapper(project).find_source_user(source_user_identifier)
@ -38,6 +39,11 @@ module Import
def user_mapping_enabled?(project)
!!project.import_data.user_mapping_enabled?
end
def map_to_personal_namespace_owner?(project)
project.root_ancestor.user_namespace? &&
project.import_data.user_mapping_to_personal_namespace_owner_enabled?
end
end
end
end

View File

@ -50803,6 +50803,9 @@ msgstr ""
msgid "ProtectedBranch|Giving merge rights to a protected branch also gives elevated permissions for certain CI/CD features."
msgstr ""
msgid "ProtectedBranch|How do I use branch rules?"
msgstr ""
msgid "ProtectedBranch|Inherited - This setting can be changed at the group level"
msgstr ""
@ -50842,6 +50845,9 @@ msgstr ""
msgid "ProtectedBranch|Protected branches"
msgstr ""
msgid "ProtectedBranch|Protected branches is moving to %{branch_rules_link_start}Branch rules%{branch_rules_link_end}."
msgstr ""
msgid "ProtectedBranch|Reject code pushes that change files listed in the CODEOWNERS file."
msgstr ""
@ -50890,6 +50896,9 @@ msgstr ""
msgid "ProtectedBranch|You can add only groups that have this project shared. %{learn_more_link}"
msgstr ""
msgid "ProtectedBranch|You can now manage branch protections, approval rules, and status checks in one place."
msgstr ""
msgid "ProtectedBranch|default"
msgstr ""

View File

@ -694,8 +694,16 @@ FactoryBot.define do
end
trait :import_user_mapping_enabled do
import_data_attributes do
{ data: { user_contribution_mapping_enabled: true } }
after(:build) do |project|
project.import_data ||= project.build_import_data
project.import_data.merge_data({ user_contribution_mapping_enabled: true })
end
end
trait :user_mapping_to_personal_namespace_owner_enabled do
after(:build) do |project|
project.import_data ||= project.build_import_data
project.import_data.merge_data({ user_mapping_to_personal_namespace_owner_enabled: true })
end
end
end

View File

@ -7,7 +7,10 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestImporter, fe
include Import::UserMappingHelper
let_it_be_with_reload(:project) do
create(:project, :repository, :bitbucket_server_import, :import_user_mapping_enabled)
create(
:project, :repository, :bitbucket_server_import, :in_group,
:import_user_mapping_enabled, :user_mapping_to_personal_namespace_owner_enabled
)
end
# Identifiers taken from importers/bitbucket_server/pull_request.json
@ -17,6 +20,7 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestImporter, fe
let(:pull_request_data) { Gitlab::Json.parse(fixture_file('importers/bitbucket_server/pull_request.json')) }
let(:pull_request) { BitbucketServer::Representation::PullRequest.new(pull_request_data) }
let(:cached_references) { placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id) }
subject(:importer) { described_class.new(project, pull_request.to_hash) }
@ -45,7 +49,6 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestImporter, fe
it 'pushes placeholder references', :aggregate_failures do
importer.execute
cached_references = placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id)
expect(cached_references).to contain_exactly(
['MergeRequestReviewer', instance_of(Integer), 'user_id', reviewer_1_source_user.id],
['MergeRequestReviewer', instance_of(Integer), 'user_id', reviewer_2_source_user.id],
@ -162,6 +165,61 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestImporter, fe
importer.execute
end
context 'when importing into a personal namespace' do
let_it_be(:user_namespace) { create(:namespace) }
let_it_be(:project) do
project.update!(namespace: user_namespace)
project
end
let_it_be(:author_source_user) { generate_source_user(project, 'username') }
let_it_be(:reviewer_1_source_user) { generate_source_user(project, 'john_smith') }
let_it_be(:reviewer_2_source_user) { generate_source_user(project, 'jane_doe') }
it 'does not push placeholder references' do
importer.execute
expect(cached_references).to be_empty
end
it 'creates the merge request mapped to the personal namespace owner' do
importer.execute
merge_request = project.merge_requests.find_by_iid(pull_request.iid)
expect(merge_request.author_id).to eq(user_namespace.owner_id)
expect(merge_request.reviewer_ids).to contain_exactly(user_namespace.owner_id)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
project.build_or_assign_import_data(
data: { user_mapping_to_personal_namespace_owner_enabled: false }
).save!
end
it 'pushes placeholder references' do
importer.execute
expect(cached_references).to contain_exactly(
['MergeRequestReviewer', instance_of(Integer), 'user_id', reviewer_1_source_user.id],
['MergeRequestReviewer', instance_of(Integer), 'user_id', reviewer_2_source_user.id],
['MergeRequest', instance_of(Integer), 'author_id', author_source_user.id]
)
end
it 'creates the merge request mapped to the placeholder user' do
importer.execute
merge_request = project.merge_requests.find_by_iid(pull_request.iid)
expect(merge_request.author_id).to eq(author_source_user.mapped_user_id)
expect(merge_request.reviewer_ids).to match_array([reviewer_1_source_user.mapped_user_id,
reviewer_2_source_user.mapped_user_id])
end
end
end
context 'when user contribution mapping is disabled' do
let_it_be(:reviewer_1) { create(:user, username: 'john_smith', email: 'john@smith.com') }
let_it_be(:reviewer_2) { create(:user, username: 'jane_doe', email: 'jane@doe.com') }
@ -211,7 +269,6 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestImporter, fe
it 'does not push placeholder references' do
importer.execute
cached_references = placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id)
expect(cached_references).to be_empty
end
end

View File

@ -6,7 +6,10 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Appro
include Import::UserMappingHelper
let_it_be_with_reload(:project) do
create(:project, :repository, :bitbucket_server_import, :import_user_mapping_enabled)
create(
:project, :repository, :bitbucket_server_import, :in_group,
:import_user_mapping_enabled, :user_mapping_to_personal_namespace_owner_enabled
)
end
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
@ -108,6 +111,56 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Appro
end
end
context 'when importing into a personal namespace' do
let_it_be(:user_namespace) { create(:namespace) }
let_it_be(:project) do
project.update!(namespace: user_namespace)
project
end
let_it_be(:source_user) { generate_source_user(project, approved_event[:approver_username]) }
it 'does not push placeholder references' do
importer.execute(approved_event)
expect(cached_references).to be_empty
end
it 'creates the approval, reviewer and approval note mapped to the personal namespace owner' do
importer.execute(approved_event)
expect(merge_request.approvals.first.user_id).to eq(user_namespace.owner_id)
expect(merge_request.notes.first.author_id).to eq(user_namespace.owner_id)
expect(merge_request.reviewers.first.id).to eq(user_namespace.owner_id)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
project.build_or_assign_import_data(
data: { user_mapping_to_personal_namespace_owner_enabled: false }
).save!
end
it 'pushes placeholder references' do
importer.execute(approved_event)
expect(cached_references).to contain_exactly(
['Approval', instance_of(Integer), 'user_id', source_user.id],
['MergeRequestReviewer', instance_of(Integer), 'user_id', source_user.id],
['Note', instance_of(Integer), 'author_id', source_user.id]
)
end
it 'creates the approval, reviewer and approval note mapped to the placeholder user' do
importer.execute(approved_event)
expect(merge_request.approvals.first.user_id).to eq(source_user.mapped_user_id)
expect(merge_request.notes.first.author_id).to eq(source_user.mapped_user_id)
expect(merge_request.reviewers.first.id).to eq(source_user.mapped_user_id)
end
end
end
context 'when user contribution mapping is disabled' do
let_it_be(:pull_request_author) do
create(:user, username: 'pull_request_author', email: 'pull_request_author@example.org')

View File

@ -6,7 +6,10 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Decli
include Import::UserMappingHelper
let_it_be_with_reload(:project) do
create(:project, :repository, :bitbucket_server_import, :import_user_mapping_enabled)
create(
:project, :repository, :bitbucket_server_import, :in_group,
:import_user_mapping_enabled, :user_mapping_to_personal_namespace_owner_enabled
)
end
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
@ -22,6 +25,8 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Decli
let_it_be(:source_user) { generate_source_user(project, declined_event[:decliner_username]) }
let(:cached_references) { placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id) }
def expect_log(stage:, message:, iid:, event_id:)
allow(Gitlab::BitbucketServerImport::Logger).to receive(:info).and_call_original
expect(Gitlab::BitbucketServerImport::Logger)
@ -34,7 +39,6 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Decli
it 'pushes placeholder references' do
importer.execute(declined_event)
cached_references = placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id)
expect(cached_references).to contain_exactly(
['Event', instance_of(Integer), 'author_id', source_user.id],
["ResourceStateEvent", instance_of(Integer), "user_id", source_user.id],
@ -90,6 +94,56 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Decli
end
end
context 'when importing into a personal namespace' do
let_it_be(:user_namespace) { create(:namespace) }
let_it_be(:project) do
project.update!(namespace: user_namespace)
project
end
let_it_be(:source_user) { generate_source_user(project, declined_event[:decliner_username]) }
it 'does not push placeholder references' do
importer.execute(declined_event)
expect(cached_references).to be_empty
end
it 'imports the declined event mapped to the personal namespace owner' do
importer.execute(declined_event)
expect(merge_request.resource_state_events.first.user_id).to eq(user_namespace.owner_id)
expect(merge_request.metrics.reload.latest_closed_by_id).to eq(user_namespace.owner_id)
expect(merge_request.events.first.author_id).to eq(user_namespace.owner_id)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
project.build_or_assign_import_data(
data: { user_mapping_to_personal_namespace_owner_enabled: false }
).save!
end
it 'pushes placeholder references' do
importer.execute(declined_event)
expect(cached_references).to contain_exactly(
['Event', instance_of(Integer), 'author_id', source_user.id],
["ResourceStateEvent", instance_of(Integer), "user_id", source_user.id],
['MergeRequest::Metrics', instance_of(Integer), 'latest_closed_by_id', source_user.id]
)
end
it 'imports the declined event mapped to the placeholder user' do
importer.execute(declined_event)
expect(merge_request.resource_state_events.first.user_id).to eq(source_user.mapped_user_id)
expect(merge_request.metrics.reload.latest_closed_by_id).to eq(source_user.mapped_user_id)
expect(merge_request.events.first.author_id).to eq(source_user.mapped_user_id)
end
end
end
context 'when user contribution mapping is disabled' do
let_it_be(:decliner_author) { create(:user, username: 'decliner_author', email: 'decliner_author@example.org') }
@ -106,7 +160,6 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Decli
it 'does not push placeholder references' do
importer.execute(declined_event)
cached_references = placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id)
expect(cached_references).to be_empty
end

View File

@ -6,7 +6,10 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Inlin
include Import::UserMappingHelper
let_it_be_with_reload(:project) do
create(:project, :repository, :bitbucket_server_import, :import_user_mapping_enabled)
create(
:project, :repository, :bitbucket_server_import, :in_group,
:import_user_mapping_enabled, :user_mapping_to_personal_namespace_owner_enabled
)
end
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
@ -194,6 +197,60 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Inlin
end
end
context 'when importing into a personal namespace' do
let_it_be(:user_namespace) { create(:namespace) }
let_it_be(:project) do
project.update!(namespace: user_namespace)
project
end
let_it_be(:reply_source_user) { generate_source_user(project, reply[:author_username]) }
let_it_be(:note_source_user) { generate_source_user(project, pr_inline_comment[:author_username]) }
it 'does not push placeholder references' do
importer.execute(pr_inline_comment)
expect(cached_references).to be_empty
end
it 'imports the threaded discussion mapped to the personal namespace owner' do
importer.execute(pr_inline_comment)
notes = merge_request.notes.order(:id).to_a
start_note = notes.first
reply_note = notes.last
expect(start_note.author_id).to eq(user_namespace.owner_id)
expect(reply_note.author_id).to eq(user_namespace.owner_id)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
project.build_or_assign_import_data(
data: { user_mapping_to_personal_namespace_owner_enabled: false }
).save!
end
it 'pushes placeholder references' do
importer.execute(pr_inline_comment)
expect(cached_references).to contain_exactly(
['DiffNote', instance_of(Integer), 'author_id', note_source_user.id],
['DiffNote', instance_of(Integer), 'author_id', reply_source_user.id]
)
end
it 'imports the threaded discussion mapped to the placeholder user' do
importer.execute(pr_inline_comment)
notes = merge_request.notes.order(:id).to_a
start_note = notes.first
reply_note = notes.last
expect(start_note.author_id).to eq(note_source_user.mapped_user_id)
expect(reply_note.author_id).to eq(reply_source_user.mapped_user_id)
end
end
end
context 'when user contribution mapping is disabled' do
let_it_be(:reply_author) { create(:user, username: 'reply_author', email: 'reply_author@example.org') }
let_it_be(:inline_note_author) do

View File

@ -6,7 +6,10 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Merge
include Import::UserMappingHelper
let_it_be_with_reload(:project) do
create(:project, :repository, :bitbucket_server_import, :import_user_mapping_enabled)
create(
:project, :repository, :bitbucket_server_import, :in_group,
:import_user_mapping_enabled, :user_mapping_to_personal_namespace_owner_enabled
)
end
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
@ -24,6 +27,8 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Merge
let_it_be(:source_user) { generate_source_user(project, merge_event[:committer_username]) }
let(:cached_references) { placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id) }
def expect_log(stage:, message:, iid:, event_id:)
allow(Gitlab::BitbucketServerImport::Logger).to receive(:info).and_call_original
expect(Gitlab::BitbucketServerImport::Logger)
@ -36,7 +41,6 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Merge
it 'pushes placeholder references' do
importer.execute(merge_event)
cached_references = placeholder_user_references(::Import::SOURCE_BITBUCKET_SERVER, project.import_state.id)
expect(cached_references).to contain_exactly(
['MergeRequest::Metrics', instance_of(Integer), 'merged_by_id', source_user.id]
)
@ -59,6 +63,54 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Merge
importer.execute(merge_event)
end
context 'when importing into a personal namespace' do
let_it_be(:user_namespace) { create(:namespace) }
let_it_be(:project) do
project.update!(namespace: user_namespace)
project
end
let_it_be(:source_user) { generate_source_user(project, merge_event[:committer_username]) }
it 'does not push placeholder references' do
importer.execute(merge_event)
expect(cached_references).to be_empty
end
it 'imports the merge event mapped to the personal namespace owner' do
importer.execute(merge_event)
metrics = merge_request.metrics.reload
expect(metrics.merged_by_id).to eq(user_namespace.owner_id)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
project.build_or_assign_import_data(
data: { user_mapping_to_personal_namespace_owner_enabled: false }
).save!
end
it 'pushes placeholder references' do
importer.execute(merge_event)
expect(cached_references).to contain_exactly(
['MergeRequest::Metrics', instance_of(Integer), 'merged_by_id', source_user.id]
)
end
it 'imports the merge event mapped to the placeholder user' do
importer.execute(merge_event)
metrics = merge_request.metrics.reload
expect(metrics.merged_by_id).to eq(source_user.mapped_user_id)
end
end
end
context 'when user contribution mapping is disabled' do
let_it_be(:pull_request_author) do
create(:user, username: 'pull_request_author', email: 'pull_request_author@example.org')

View File

@ -6,7 +6,10 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Stand
include Import::UserMappingHelper
let_it_be_with_reload(:project) do
create(:project, :repository, :bitbucket_server_import, :import_user_mapping_enabled)
create(
:project, :repository, :bitbucket_server_import, :in_group,
:import_user_mapping_enabled, :user_mapping_to_personal_namespace_owner_enabled
)
end
let_it_be(:merge_request) { create(:merge_request, source_project: project) }
@ -216,6 +219,52 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotes::Stand
end
end
context 'when importing into a personal namespace' do
let_it_be(:user_namespace) { create(:namespace) }
let_it_be(:project) do
project.update!(namespace: user_namespace)
project
end
let_it_be(:source_user) { generate_source_user(project, pr_comment[:author_username]) }
it 'does not push placeholder references' do
importer.execute(pr_comment)
expect(cached_references).to be_empty
end
it 'imports the stand alone comments mapped to the personal namespace owner' do
expect { importer.execute(pr_comment) }.to change { Note.count }.by(1)
expect(merge_request.notes.first).to have_attributes(
author_id: user_namespace.owner_id
)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
project.build_or_assign_import_data(
data: { user_mapping_to_personal_namespace_owner_enabled: false }
).save!
end
it 'pushes placeholder reference' do
importer.execute(pr_comment)
expect(cached_references).to contain_exactly(
['Note', instance_of(Integer), 'author_id', source_user.id]
)
end
it 'imports the stand alone comments mapped to the placeholder user' do
expect { importer.execute(pr_comment) }.to change { Note.count }.by(1)
expect(merge_request.notes.first).to have_attributes(
author_id: source_user.mapped_user_id
)
end
end
end
context 'when user contribution mapping is disabled' do
let_it_be(:note_author) { create(:user, username: 'note_author', email: 'note_author@example.org') }

View File

@ -78,7 +78,8 @@ RSpec.describe Gitlab::BitbucketServerImport::ProjectCreator, feature_category:
repo_slug: repo_slug,
timeout_strategy: timeout_strategy,
bitbucket_server_notes_separate_worker: true,
user_contribution_mapping_enabled: true
user_contribution_mapping_enabled: true,
user_mapping_to_personal_namespace_owner_enabled: true
}
},
skip_wiki: true
@ -90,10 +91,11 @@ RSpec.describe Gitlab::BitbucketServerImport::ProjectCreator, feature_category:
creator.execute
end
context 'when feature flags are disabled' do
context 'when all feature flags are disabled' do
before do
stub_feature_flags(bitbucket_server_notes_separate_worker: false)
stub_feature_flags(bitbucket_server_user_mapping: false)
stub_feature_flags(user_mapping_to_personal_namespace_owner: false)
end
it 'disables these options in the import_data' do
@ -105,7 +107,64 @@ RSpec.describe Gitlab::BitbucketServerImport::ProjectCreator, feature_category:
repo_slug: repo_slug,
timeout_strategy: timeout_strategy,
bitbucket_server_notes_separate_worker: false,
user_contribution_mapping_enabled: false
user_contribution_mapping_enabled: false,
user_mapping_to_personal_namespace_owner_enabled: false
}
}
}
expect(Projects::CreateService).to receive(:new)
.with(current_user, a_hash_including(expected_params))
creator.execute
end
end
context 'when user_mapping_to_personal_namespace_owner is enabled but bitbucket_server_user_mapping is disabled' do
before do
stub_feature_flags(bitbucket_server_user_mapping: false)
stub_feature_flags(user_mapping_to_personal_namespace_owner: true)
end
it 'sets user_mapping_to_personal_namespace_owner_enabled to false' do
expected_params = {
import_data: {
credentials: session_data,
data: {
project_key: project_key,
repo_slug: repo_slug,
timeout_strategy: timeout_strategy,
bitbucket_server_notes_separate_worker: true,
user_contribution_mapping_enabled: false,
user_mapping_to_personal_namespace_owner_enabled: false
}
}
}
expect(Projects::CreateService).to receive(:new)
.with(current_user, a_hash_including(expected_params))
creator.execute
end
end
context 'when user_mapping_to_personal_namespace_owner is disabled but bitbucket_server_user_mapping is enabled' do
before do
stub_feature_flags(bitbucket_server_user_mapping: true)
stub_feature_flags(user_mapping_to_personal_namespace_owner: false)
end
it 'sets user_mapping_to_personal_namespace_owner_enabled to false' do
expected_params = {
import_data: {
credentials: session_data,
data: {
project_key: project_key,
repo_slug: repo_slug,
timeout_strategy: timeout_strategy,
bitbucket_server_notes_separate_worker: true,
user_contribution_mapping_enabled: true,
user_mapping_to_personal_namespace_owner_enabled: false
}
}
}

View File

@ -4,9 +4,13 @@ require 'spec_helper'
RSpec.describe Gitlab::BitbucketServerImport::UserFinder, :clean_gitlab_redis_shared_state, feature_category: :importers do
let_it_be(:user) { create(:user) }
let_it_be(:user_namespace) { create(:namespace) }
let_it_be_with_reload(:project) do
create(:project, :repository, :bitbucket_server_import, :import_user_mapping_enabled)
create(
:project, :repository, :bitbucket_server_import, :in_group,
:import_user_mapping_enabled, :user_mapping_to_personal_namespace_owner_enabled
)
end
let(:source_user) { build_stubbed(:import_source_user, :completed) }
@ -31,6 +35,31 @@ RSpec.describe Gitlab::BitbucketServerImport::UserFinder, :clean_gitlab_redis_sh
user_finder.author_id(user_representation)
).to eq(source_user.mapped_user.id)
end
context 'when the project is imported into a personal namespace' do
before do
project.update!(namespace: user_namespace)
end
it 'returns the user namespace owner id' do
author_id = user_finder.author_id(user_representation)
expect(author_id).to eq(user_namespace.owner_id)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
allow(project.import_data).to receive(:user_mapping_to_personal_namespace_owner_enabled?)
.and_return(false)
end
it 'returns the mapped user' do
expect(
user_finder.author_id(user_representation)
).to eq(source_user.mapped_user.id)
end
end
end
end
describe '#uid' do
@ -53,6 +82,39 @@ RSpec.describe Gitlab::BitbucketServerImport::UserFinder, :clean_gitlab_redis_sh
expect(user_id).to be_nil
end
context 'when the project is imported into a personal namespace' do
before do
project.update!(namespace: user_namespace)
end
it 'returns the user namespace owner id' do
user_id = user_finder.uid(user_representation)
expect(user_id).to eq(user_namespace.owner_id)
end
context 'when user_mapping_to_personal_namespace_owner is disabled' do
before do
allow(project.import_data).to receive(:user_mapping_to_personal_namespace_owner_enabled?)
.and_return(false)
end
it 'takes a user data hash and finds the mapped user ID' do
user_id = user_finder.uid(user_representation)
expect(user_id).to eq(source_user.mapped_user.id)
end
it 'returns nil when username is nil' do
user_representation[:username] = nil
user_id = user_finder.uid(user_representation)
expect(user_id).to be_nil
end
end
end
end
context 'when user contribution mapping is disabled' do

View File

@ -53,9 +53,11 @@ RSpec.describe ProjectImportData do
describe '#user_mapping_enabled?' do
it 'returns user_contribution_mapping_enabled when present in data' do
import_data = described_class.new(data: { 'user_contribution_mapping_enabled' => true })
import_data_enabled = described_class.new(data: { 'user_contribution_mapping_enabled' => true })
import_data_disabled = described_class.new(data: { 'user_contribution_mapping_enabled' => false })
expect(import_data.user_mapping_enabled?).to be(true)
expect(import_data_enabled.user_mapping_enabled?).to be(true)
expect(import_data_disabled.user_mapping_enabled?).to be(false)
end
it 'returns false when user_contribution_mapping_enabled is not present in data' do
@ -70,4 +72,26 @@ RSpec.describe ProjectImportData do
expect(import_data.user_mapping_enabled?).to be(false)
end
end
describe '#user_mapping_to_personal_namespace_owner_enabled?' do
it 'returns user_mapping_to_personal_namespace_owner_enabled when present in data', :aggregate_failures do
import_data_enabled = described_class.new(data: { 'user_mapping_to_personal_namespace_owner_enabled' => true })
import_data_disabled = described_class.new(data: { 'user_mapping_to_personal_namespace_owner_enabled' => false })
expect(import_data_enabled.user_mapping_to_personal_namespace_owner_enabled?).to be(true)
expect(import_data_disabled.user_mapping_to_personal_namespace_owner_enabled?).to be(false)
end
it 'returns false when user_mapping_to_personal_namespace_owner_enabled is not present in data' do
import_data = described_class.new(data: { 'number' => 10 })
expect(import_data.user_mapping_to_personal_namespace_owner_enabled?).to be(false)
end
it 'returns false when data is nil' do
import_data = described_class.new
expect(import_data.user_mapping_to_personal_namespace_owner_enabled?).to be(false)
end
end
end

View File

@ -3,7 +3,13 @@
require 'spec_helper'
RSpec.describe Gitlab::BitbucketServerImport::Stage::FinishImportWorker, feature_category: :importers do
let_it_be(:project) { create(:project, :import_started, import_type: :bitbucket_server) }
let_it_be_with_reload(:project) do
create(
:project, :import_started, :in_group,
:user_mapping_to_personal_namespace_owner_enabled,
import_type: :bitbucket_server
)
end
subject(:worker) { described_class.new }