Commit c9d4418f authored by Samantha Ming's avatar Samantha Ming Committed by Thong Kuah

Configurable defaults for "Squash commits" option

Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/17613

This commit adds the capability to set squash commits options.
The configuration is done on a project settings level.
It allows configuration for squashing commits before merging.
parent 45384ccd
...@@ -385,6 +385,14 @@ module IssuablesHelper ...@@ -385,6 +385,14 @@ module IssuablesHelper
end end
end end
def issuable_squash_option?(issuable, project)
if issuable.persisted?
issuable.squash
else
project.squash_enabled_by_default?
end
end
private private
def sidebar_gutter_collapsed? def sidebar_gutter_collapsed?
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
= render 'projects/merge_request_merge_options_settings', project: @project, form: form = render 'projects/merge_request_merge_options_settings', project: @project, form: form
- if Feature.enabled?(:squash_options, @project)
= render 'projects/merge_request_squash_options_settings', form: form
= render 'projects/merge_request_merge_checks_settings', project: @project, form: form = render 'projects/merge_request_merge_checks_settings', project: @project, form: form
= render 'projects/merge_request_merge_suggestions_settings', project: @project, form: form = render 'projects/merge_request_merge_suggestions_settings', project: @project, form: form
- form = local_assigns.fetch(:form)
= form.fields_for :project_setting do |settings|
.form-group
%b= s_('ProjectSettings|Squash commits when merging')
%p.text-secondary
= s_('ProjectSettings|Set the default behavior and availability of this option in merge requests. Changes made are also applied to existing merge requests.')
= link_to "What is squashing?",
help_page_path('user/project/merge_requests/squash_and_merge.md'),
target: '_blank'
.form-check.gl-mb-2
= settings.radio_button :squash_option, :never, class: "form-check-input"
= label_tag :project_project_setting_attributes_squash_option_never, class: 'form-check-label' do
.gl-font-weight-bold
= s_('ProjectSettings|Do not allow')
.text-secondary
= s_('ProjectSettings|Squashing is never performed and the checkbox is hidden.')
.form-check.gl-mb-2
= settings.radio_button :squash_option, :default_off, class: "form-check-input"
= label_tag :project_project_setting_attributes_squash_option_default_off, class: 'form-check-label' do
.gl-font-weight-bold
= s_('ProjectSettings|Allow')
.text-secondary
= s_('ProjectSettings|Checkbox is visible and unselected by default.')
.form-check.gl-mb-2
= settings.radio_button :squash_option, :default_on, class: "form-check-input"
= label_tag :project_project_setting_attributes_squash_option_default_on, class: 'form-check-label' do
.gl-font-weight-bold
= s_('ProjectSettings|Encourage')
.text-secondary
= s_('ProjectSettings|Checkbox is visible and selected by default.')
.form-check.gl-mb-2
= settings.radio_button :squash_option, :always, class: "form-check-input"
= label_tag :project_project_setting_attributes_squash_option_always, class: 'form-check-label' do
.gl-font-weight-bold
= s_('ProjectSettings|Require')
.text-secondary
= s_('ProjectSettings|Squashing is always performed. Checkbox is visible and selected, and users cannot change it.')
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
= render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form = render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form
= render 'shared/issuable/form/merge_params', issuable: issuable = render 'shared/issuable/form/merge_params', issuable: issuable, project: project
= render 'shared/issuable/form/contribution', issuable: issuable, form: form = render 'shared/issuable/form/contribution', issuable: issuable, form: form
......
- issuable = local_assigns.fetch(:issuable) - issuable = local_assigns.fetch(:issuable)
- project = local_assigns.fetch(:project)
- return unless issuable.is_a?(MergeRequest) - return unless issuable.is_a?(MergeRequest)
- return if issuable.closed_without_fork? - return if issuable.closed_without_fork?
...@@ -14,9 +15,14 @@ ...@@ -14,9 +15,14 @@
= check_box_tag 'merge_request[force_remove_source_branch]', '1', issuable.force_remove_source_branch?, class: 'form-check-input' = check_box_tag 'merge_request[force_remove_source_branch]', '1', issuable.force_remove_source_branch?, class: 'form-check-input'
= label_tag 'merge_request[force_remove_source_branch]', class: 'form-check-label' do = label_tag 'merge_request[force_remove_source_branch]', class: 'form-check-label' do
Delete source branch when merge request is accepted. Delete source branch when merge request is accepted.
- if !project.squash_never?
.form-check .form-check
- if project.squash_always?
= hidden_field_tag 'merge_request[squash]', '1', id: nil
= check_box_tag 'merge_request[squash]', '1', project.squash_enabled_by_default?, class: 'form-check-input', disabled: 'true'
- else
= hidden_field_tag 'merge_request[squash]', '0', id: nil = hidden_field_tag 'merge_request[squash]', '0', id: nil
= check_box_tag 'merge_request[squash]', '1', issuable.squash, class: 'form-check-input' = check_box_tag 'merge_request[squash]', '1', issuable_squash_option?(issuable, project), class: 'form-check-input'
= label_tag 'merge_request[squash]', class: 'form-check-label' do = label_tag 'merge_request[squash]', class: 'form-check-label' do
Squash commits when merge request is accepted. Squash commits when merge request is accepted.
= link_to icon('question-circle'), help_page_path('user/project/merge_requests/squash_and_merge'), target: '_blank' = link_to icon('question-circle'), help_page_path('user/project/merge_requests/squash_and_merge'), target: '_blank'
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
= render_ce 'projects/merge_request_merge_options_settings', project: @project, form: form = render_ce 'projects/merge_request_merge_options_settings', project: @project, form: form
- if Feature.enabled?(:squash_options, @project)
= render_ce 'projects/merge_request_squash_options_settings', form: form
= render_ce 'projects/merge_request_merge_checks_settings', project: @project, form: form = render_ce 'projects/merge_request_merge_checks_settings', project: @project, form: form
= render 'projects/merge_request_merge_suggestions_settings', project: @project, form: form = render 'projects/merge_request_merge_suggestions_settings', project: @project, form: form
......
...@@ -17745,6 +17745,9 @@ msgstr "" ...@@ -17745,6 +17745,9 @@ msgstr ""
msgid "ProjectSettings|All discussions must be resolved" msgid "ProjectSettings|All discussions must be resolved"
msgstr "" msgstr ""
msgid "ProjectSettings|Allow"
msgstr ""
msgid "ProjectSettings|Allow users to make copies of your repository to a new project" msgid "ProjectSettings|Allow users to make copies of your repository to a new project"
msgstr "" msgstr ""
...@@ -17760,6 +17763,12 @@ msgstr "" ...@@ -17760,6 +17763,12 @@ msgstr ""
msgid "ProjectSettings|Build, test, and deploy your changes" msgid "ProjectSettings|Build, test, and deploy your changes"
msgstr "" msgstr ""
msgid "ProjectSettings|Checkbox is visible and selected by default."
msgstr ""
msgid "ProjectSettings|Checkbox is visible and unselected by default."
msgstr ""
msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions." msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
msgstr "" msgstr ""
...@@ -17778,12 +17787,18 @@ msgstr "" ...@@ -17778,12 +17787,18 @@ msgstr ""
msgid "ProjectSettings|Disable email notifications" msgid "ProjectSettings|Disable email notifications"
msgstr "" msgstr ""
msgid "ProjectSettings|Do not allow"
msgstr ""
msgid "ProjectSettings|Enable 'Delete source branch' option by default" msgid "ProjectSettings|Enable 'Delete source branch' option by default"
msgstr "" msgstr ""
msgid "ProjectSettings|Enable merge trains and pipelines for merged results" msgid "ProjectSettings|Enable merge trains and pipelines for merged results"
msgstr "" msgstr ""
msgid "ProjectSettings|Encourage"
msgstr ""
msgid "ProjectSettings|Every merge creates a merge commit" msgid "ProjectSettings|Every merge creates a merge commit"
msgstr "" msgstr ""
...@@ -17898,6 +17913,12 @@ msgstr "" ...@@ -17898,6 +17913,12 @@ msgstr ""
msgid "ProjectSettings|Repository" msgid "ProjectSettings|Repository"
msgstr "" msgstr ""
msgid "ProjectSettings|Require"
msgstr ""
msgid "ProjectSettings|Set the default behavior and availability of this option in merge requests. Changes made are also applied to existing merge requests."
msgstr ""
msgid "ProjectSettings|Share code pastes with others out of Git repository" msgid "ProjectSettings|Share code pastes with others out of Git repository"
msgstr "" msgstr ""
...@@ -17913,6 +17934,15 @@ msgstr "" ...@@ -17913,6 +17934,15 @@ msgstr ""
msgid "ProjectSettings|Snippets" msgid "ProjectSettings|Snippets"
msgstr "" msgstr ""
msgid "ProjectSettings|Squash commits when merging"
msgstr ""
msgid "ProjectSettings|Squashing is always performed. Checkbox is visible and selected, and users cannot change it."
msgstr ""
msgid "ProjectSettings|Squashing is never performed and the checkbox is hidden."
msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream" msgid "ProjectSettings|Submit changes to be merged upstream"
msgstr "" msgstr ""
......
...@@ -28,6 +28,22 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do ...@@ -28,6 +28,22 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
end end
end end
it 'shows Squash commit options', :aggregate_failures do
page.within '#js-merge-request-settings' do
expect(page).to have_content 'Do not allow'
expect(page).to have_content 'Squashing is never performed and the checkbox is hidden.'
expect(page).to have_content 'Allow'
expect(page).to have_content 'Checkbox is visible and unselected by default.'
expect(page).to have_content 'Encourage'
expect(page).to have_content 'Checkbox is visible and selected by default.'
expect(page).to have_content 'Require'
expect(page).to have_content 'Squashing is always performed. Checkbox is visible and selected, and users cannot change it.'
end
end
context 'when Merge Request and Pipelines are initially enabled', :js do context 'when Merge Request and Pipelines are initially enabled', :js do
context 'when Pipelines are initially enabled' do context 'when Pipelines are initially enabled' do
it 'shows the Merge Requests settings' do it 'shows the Merge Requests settings' do
...@@ -130,4 +146,56 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do ...@@ -130,4 +146,56 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
expect(project.remove_source_branch_after_merge).to be(false) expect(project.remove_source_branch_after_merge).to be(false)
end end
end end
describe 'Squash commits when merging', :js do
it 'initially has :squash_option set to :default_off' do
radio = find_field('project_project_setting_attributes_squash_option_default_off')
expect(radio).to be_checked
end
it 'allows :squash_option to be set to :default_on' do
choose('project_project_setting_attributes_squash_option_default_on')
within('.merge-request-settings-form') do
find('.qa-save-merge-request-changes')
click_on('Save changes')
end
find('.flash-notice')
radio = find_field('project_project_setting_attributes_squash_option_default_on')
expect(radio).to be_checked
expect(project.reload.project_setting.squash_option).to eq('default_on')
end
it 'allows :squash_option to be set to :always' do
choose('project_project_setting_attributes_squash_option_always')
within('.merge-request-settings-form') do
find('.qa-save-merge-request-changes')
click_on('Save changes')
end
find('.flash-notice')
radio = find_field('project_project_setting_attributes_squash_option_always')
expect(radio).to be_checked
expect(project.reload.project_setting.squash_option).to eq('always')
end
it 'allows :squash_option to be set to :never' do
choose('project_project_setting_attributes_squash_option_never')
within('.merge-request-settings-form') do
find('.qa-save-merge-request-changes')
click_on('Save changes')
end
find('.flash-notice')
radio = find_field('project_project_setting_attributes_squash_option_never')
expect(radio).to be_checked
expect(project.reload.project_setting.squash_option).to eq('never')
end
end
end end
...@@ -303,4 +303,28 @@ RSpec.describe IssuablesHelper do ...@@ -303,4 +303,28 @@ RSpec.describe IssuablesHelper do
end end
end end
end end
describe '#issuable_squash_option?' do
using RSpec::Parameterized::TableSyntax
where(:issuable_persisted, :squash, :squash_enabled_by_default, :expectation) do
true | true | true | true
true | false | true | false
false | false | false | false
false | false | true | true
false | true | false | false
false | true | true | true
end
with_them do
it 'returns the correct value' do
project = double(
squash_enabled_by_default?: squash_enabled_by_default
)
issuable = double(persisted?: issuable_persisted, squash: squash)
expect(helper.issuable_squash_option?(issuable, project)).to eq(expectation)
end
end
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