Commit 8a1f75bd authored by Alessio Caiazza's avatar Alessio Caiazza Committed by Robert Speicher

Add pull mirror branch prefix

With this setting we can set a prefix to branches during pull mirroring
parent d15eb48c
---
title: Add pull_mirror_branch_prefix column on projects table
merge_request: 17368
author:
type: added
# frozen_string_literal: true
class AddPullMirrorBranchPrefixToProjects < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
add_column :projects, :pull_mirror_branch_prefix, :string, limit: 50
end
end
...@@ -2922,6 +2922,7 @@ ActiveRecord::Schema.define(version: 2019_09_27_074328) do ...@@ -2922,6 +2922,7 @@ ActiveRecord::Schema.define(version: 2019_09_27_074328) do
t.boolean "emails_disabled" t.boolean "emails_disabled"
t.integer "max_pages_size" t.integer "max_pages_size"
t.integer "max_artifacts_size" t.integer "max_artifacts_size"
t.string "pull_mirror_branch_prefix", limit: 50
t.index "lower((name)::text)", name: "index_projects_on_lower_name" t.index "lower((name)::text)", name: "index_projects_on_lower_name"
t.index ["archived", "pending_delete", "merge_requests_require_code_owner_approval"], name: "projects_requiring_code_owner_approval", where: "((pending_delete = false) AND (archived = false) AND (merge_requests_require_code_owner_approval = true))" t.index ["archived", "pending_delete", "merge_requests_require_code_owner_approval"], name: "projects_requiring_code_owner_approval", where: "((pending_delete = false) AND (archived = false) AND (merge_requests_require_code_owner_approval = true))"
t.index ["created_at"], name: "index_projects_on_created_at" t.index ["created_at"], name: "index_projects_on_created_at"
......
...@@ -67,6 +67,7 @@ module EE ...@@ -67,6 +67,7 @@ module EE
:mirror_trigger_builds, :mirror_trigger_builds,
:only_mirror_protected_branches, :only_mirror_protected_branches,
:mirror_overwrites_diverged_branches, :mirror_overwrites_diverged_branches,
:pull_mirror_branch_prefix,
import_data_attributes: %i[ import_data_attributes: %i[
id id
......
...@@ -140,6 +140,9 @@ module EE ...@@ -140,6 +140,9 @@ module EE
validates :approvals_before_merge, numericality: true, allow_blank: true validates :approvals_before_merge, numericality: true, allow_blank: true
validates :pull_mirror_branch_prefix, length: { maximum: 50 }
validate :check_pull_mirror_branch_prefix
with_options if: :mirror? do with_options if: :mirror? do
validates :import_url, presence: true validates :import_url, presence: true
validates :mirror_user, presence: true validates :mirror_user, presence: true
...@@ -671,5 +674,14 @@ module EE ...@@ -671,5 +674,14 @@ module EE
def validate_board_limit(board) def validate_board_limit(board)
# Board limits are disabled in EE, so this method is just a no-op. # Board limits are disabled in EE, so this method is just a no-op.
end end
def check_pull_mirror_branch_prefix
return if pull_mirror_branch_prefix.blank?
return unless pull_mirror_branch_prefix_changed?
unless ::Gitlab::GitRefValidator.validate("#{pull_mirror_branch_prefix}master")
errors.add(:pull_mirror_branch_prefix, _('Invalid Git ref'))
end
end
end end
end end
...@@ -34,7 +34,7 @@ module Projects ...@@ -34,7 +34,7 @@ module Projects
errors = [] errors = []
repository.upstream_branches.each do |upstream_branch| repository.upstream_branches.each do |upstream_branch|
name = upstream_branch.name name = target_branch_name(upstream_branch.name)
next if skip_branch?(name) next if skip_branch?(name)
...@@ -147,5 +147,11 @@ module Projects ...@@ -147,5 +147,11 @@ module Projects
def log_error(error_message) def log_error(error_message)
service_logger.error(base_payload.merge(error_message: error_message)) service_logger.error(base_payload.merge(error_message: error_message))
end end
def target_branch_name(upstream_branch_name)
return upstream_branch_name unless Feature.enabled?(:pull_mirror_branch_prefix, project)
"#{project.pull_mirror_branch_prefix}#{upstream_branch_name}"
end
end end
end end
...@@ -37,6 +37,13 @@ ...@@ -37,6 +37,13 @@
.help-block .help-block
= _('This user will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches. Upon creation or when reassigning you can only assign yourself to be the mirror user.') = _('This user will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches. Upon creation or when reassigning you can only assign yourself to be the mirror user.')
- if Feature.enabled?(:pull_mirror_branch_prefix, @project)
.form-group
= f.label :pull_mirror_branch_prefix, _('Branch prefix'), class: 'label-light'
= f.text_field :pull_mirror_branch_prefix, class: 'form-control', placeholder: 'Example: upstream/'
.help-block
= _("Mirrored branches will have this prefix. If you enabled 'Only mirror protected branches' you need to include this prefix on protected branches in this project or nothing will be mirrored.")
.form-check.append-bottom-10 .form-check.append-bottom-10
= f.check_box :mirror_overwrites_diverged_branches, class: 'form-check-input', checked: false = f.check_box :mirror_overwrites_diverged_branches, class: 'form-check-input', checked: false
= f.label :mirror_overwrites_diverged_branches, _('Overwrite diverged branches'), class: 'form-check-label' = f.label :mirror_overwrites_diverged_branches, _('Overwrite diverged branches'), class: 'form-check-label'
......
...@@ -26,6 +26,7 @@ describe 'Project settings > [EE] repository' do ...@@ -26,6 +26,7 @@ describe 'Project settings > [EE] repository' do
expect(page).to have_no_selector('#project_mirror_user_id', visible: false) expect(page).to have_no_selector('#project_mirror_user_id', visible: false)
expect(page).to have_no_selector('#project_mirror_overwrites_diverged_branches') expect(page).to have_no_selector('#project_mirror_overwrites_diverged_branches')
expect(page).to have_no_selector('#project_mirror_trigger_builds') expect(page).to have_no_selector('#project_mirror_trigger_builds')
expect(page).to have_no_selector('#project_pull_mirror_branch_prefix')
end end
end end
end end
...@@ -45,6 +46,21 @@ describe 'Project settings > [EE] repository' do ...@@ -45,6 +46,21 @@ describe 'Project settings > [EE] repository' do
expect(page).to have_selector('#project_mirror_user_id', visible: false) expect(page).to have_selector('#project_mirror_user_id', visible: false)
expect(page).to have_selector('#project_mirror_overwrites_diverged_branches') expect(page).to have_selector('#project_mirror_overwrites_diverged_branches')
expect(page).to have_selector('#project_mirror_trigger_builds') expect(page).to have_selector('#project_mirror_trigger_builds')
expect(page).to have_selector('#project_pull_mirror_branch_prefix')
end
end
context 'pull_mirror_branch_prefix feature flag disabled' do
before do
stub_feature_flags(pull_mirror_branch_prefix: false)
end
it 'shows pull mirror settings', :js do
visit project_settings_repository_path(project)
page.within('.project-mirror-settings') do
expect(page).to have_no_selector('#project_pull_mirror_branch_prefix')
end
end end
end end
......
...@@ -193,6 +193,16 @@ describe Project do ...@@ -193,6 +193,16 @@ describe Project do
project2.update(mirror: true, import_url: generate(:url), mirror_user: project.creator) project2.update(mirror: true, import_url: generate(:url), mirror_user: project.creator)
end.to change { ProjectImportState.where(project: project2).count }.from(0).to(1) end.to change { ProjectImportState.where(project: project2).count }.from(0).to(1)
end end
describe 'pull_mirror_branch_prefix' do
it { is_expected.to validate_length_of(:pull_mirror_branch_prefix).is_at_most(50) }
it 'rejects invalid git refs' do
project = build(:project, pull_mirror_branch_prefix: 'an invalid prefix..')
expect(project).not_to be_valid
end
end
end end
describe 'setting up a mirror' do describe 'setting up a mirror' do
......
...@@ -140,6 +140,38 @@ describe Projects::UpdateMirrorService do ...@@ -140,6 +140,38 @@ describe Projects::UpdateMirrorService do
end end
context "updating branches" do context "updating branches" do
context 'when pull_mirror_branch_prefix is set' do
let(:pull_mirror_branch_prefix) { 'upstream/' }
before do
project.update(pull_mirror_branch_prefix: pull_mirror_branch_prefix)
end
it "creates new branches" do
stub_fetch_mirror(project)
service.execute
expect(project.repository.branch_names).to include("#{pull_mirror_branch_prefix}new-branch")
expect(project.repository.branch_names).not_to include('new-branch')
end
context 'when pull_mirror_branch_prefix feature flag is disabled' do
before do
stub_feature_flags(pull_mirror_branch_prefix: false)
end
it "creates new branches" do
stub_fetch_mirror(project)
service.execute
expect(project.repository.branch_names).not_to include("#{pull_mirror_branch_prefix}new-branch")
expect(project.repository.branch_names).to include('new-branch')
end
end
end
context 'when mirror only protected branches option is set' do context 'when mirror only protected branches option is set' do
let(:new_protected_branch_name) { 'new-branch' } let(:new_protected_branch_name) { 'new-branch' }
let(:protected_branch_name) { 'existing-branch' } let(:protected_branch_name) { 'existing-branch' }
......
...@@ -139,6 +139,7 @@ excluded_attributes: ...@@ -139,6 +139,7 @@ excluded_attributes:
- :mirror_trigger_builds - :mirror_trigger_builds
- :only_mirror_protected_branches - :only_mirror_protected_branches
- :pull_mirror_available_overridden - :pull_mirror_available_overridden
- :pull_mirror_branch_prefix
- :mirror_overwrites_diverged_branches - :mirror_overwrites_diverged_branches
- :packages_enabled - :packages_enabled
- :mirror_last_update_at - :mirror_last_update_at
......
...@@ -2421,6 +2421,9 @@ msgstr "" ...@@ -2421,6 +2421,9 @@ msgstr ""
msgid "Branch not loaded - %{branchId}" msgid "Branch not loaded - %{branchId}"
msgstr "" msgstr ""
msgid "Branch prefix"
msgstr ""
msgid "BranchSwitcherPlaceholder|Search branches" msgid "BranchSwitcherPlaceholder|Search branches"
msgstr "" msgstr ""
...@@ -8688,6 +8691,9 @@ msgstr "" ...@@ -8688,6 +8691,9 @@ msgstr ""
msgid "Introducing Your Conversational Development Index" msgid "Introducing Your Conversational Development Index"
msgstr "" msgstr ""
msgid "Invalid Git ref"
msgstr ""
msgid "Invalid Insights config file detected" msgid "Invalid Insights config file detected"
msgstr "" msgstr ""
...@@ -10168,6 +10174,9 @@ msgstr "" ...@@ -10168,6 +10174,9 @@ msgstr ""
msgid "Mirror user" msgid "Mirror user"
msgstr "" msgstr ""
msgid "Mirrored branches will have this prefix. If you enabled 'Only mirror protected branches' you need to include this prefix on protected branches in this project or nothing will be mirrored."
msgstr ""
msgid "Mirrored repositories" msgid "Mirrored repositories"
msgstr "" msgstr ""
......
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