mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-15 21:39:00 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -1 +1 @@
|
||||
3a73e8c517a6075dc923e470fb2c4ae5c2b5d31d
|
||||
6b7e0f4350032c3519eab68747eda6515cd784b4
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
@ -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
|
1
db/schema_migrations/20250725123842
Normal file
1
db/schema_migrations/20250725123842
Normal file
@ -0,0 +1 @@
|
||||
7106f96dae5a305cb076ea030f0209649a8c6b0d04adf3df17893182e21e0895
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 ""
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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') }
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
|
||||
|
Reference in New Issue
Block a user