Commit 62d05c23 authored by Douwe Maan's avatar Douwe Maan

Merge branch '2572-namespace-fast-forward-merge' into 'master'

Namespace license checks for fast-forward merge (EES)

Closes #2572

See merge request !2272
parents 3d5a4ce5 7f9b7767
...@@ -331,6 +331,16 @@ module EE ...@@ -331,6 +331,16 @@ module EE
super unless mirror? super unless mirror?
end end
def merge_requests_rebase_enabled
super && feature_available?(:merge_request_rebase)
end
alias_method :merge_requests_rebase_enabled?, :merge_requests_rebase_enabled
def merge_requests_ff_only_enabled
super && feature_available?(:fast_forward_merge)
end
alias_method :merge_requests_ff_only_enabled?, :merge_requests_ff_only_enabled
private private
def licensed_feature_available?(feature) def licensed_feature_available?(feature)
......
...@@ -12,6 +12,7 @@ class License < ActiveRecord::Base ...@@ -12,6 +12,7 @@ class License < ActiveRecord::Base
EXPORT_ISSUES_FEATURE = 'GitLab_ExportIssues'.freeze EXPORT_ISSUES_FEATURE = 'GitLab_ExportIssues'.freeze
MERGE_REQUEST_REBASE_FEATURE = 'GitLab_MergeRequestRebase'.freeze MERGE_REQUEST_REBASE_FEATURE = 'GitLab_MergeRequestRebase'.freeze
MERGE_REQUEST_SQUASH_FEATURE = 'GitLab_MergeRequestSquash'.freeze MERGE_REQUEST_SQUASH_FEATURE = 'GitLab_MergeRequestSquash'.freeze
FAST_FORWARD_MERGE_FEATURE = 'GitLab_FastForwardMerge'.freeze
FEATURE_CODES = { FEATURE_CODES = {
geo: GEO_FEATURE, geo: GEO_FEATURE,
...@@ -21,6 +22,7 @@ class License < ActiveRecord::Base ...@@ -21,6 +22,7 @@ class License < ActiveRecord::Base
elastic_search: ELASTIC_SEARCH_FEATURE, elastic_search: ELASTIC_SEARCH_FEATURE,
related_issues: RELATED_ISSUES_FEATURE, related_issues: RELATED_ISSUES_FEATURE,
# Features that make sense to Namespace: # Features that make sense to Namespace:
fast_forward_merge: FAST_FORWARD_MERGE_FEATURE,
deploy_board: DEPLOY_BOARD_FEATURE, deploy_board: DEPLOY_BOARD_FEATURE,
file_lock: FILE_LOCK_FEATURE, file_lock: FILE_LOCK_FEATURE,
export_issues: EXPORT_ISSUES_FEATURE, export_issues: EXPORT_ISSUES_FEATURE,
...@@ -36,6 +38,7 @@ class License < ActiveRecord::Base ...@@ -36,6 +38,7 @@ class License < ActiveRecord::Base
EES_FEATURES = [ EES_FEATURES = [
{ ELASTIC_SEARCH_FEATURE => 1 }, { ELASTIC_SEARCH_FEATURE => 1 },
{ RELATED_ISSUES_FEATURE => 1 }, { RELATED_ISSUES_FEATURE => 1 },
{ FAST_FORWARD_MERGE_FEATURE => 1 },
{ EXPORT_ISSUES_FEATURE => 1 }, { EXPORT_ISSUES_FEATURE => 1 },
{ MERGE_REQUEST_REBASE_FEATURE => 1 }, { MERGE_REQUEST_REBASE_FEATURE => 1 },
{ MERGE_REQUEST_SQUASH_FEATURE => 1 } { MERGE_REQUEST_SQUASH_FEATURE => 1 }
...@@ -71,6 +74,7 @@ class License < ActiveRecord::Base ...@@ -71,6 +74,7 @@ class License < ActiveRecord::Base
{ AUDITOR_USER_FEATURE => 1 }, { AUDITOR_USER_FEATURE => 1 },
{ SERVICE_DESK_FEATURE => 1 }, { SERVICE_DESK_FEATURE => 1 },
{ OBJECT_STORAGE_FEATURE => 1 }, { OBJECT_STORAGE_FEATURE => 1 },
{ FAST_FORWARD_MERGE_FEATURE => 1 },
{ EXPORT_ISSUES_FEATURE => 1 }, { EXPORT_ISSUES_FEATURE => 1 },
{ MERGE_REQUEST_REBASE_FEATURE => 1 }, { MERGE_REQUEST_REBASE_FEATURE => 1 },
{ MERGE_REQUEST_SQUASH_FEATURE => 1 } { MERGE_REQUEST_SQUASH_FEATURE => 1 }
......
- form = local_assigns.fetch(:form) - form = local_assigns.fetch(:form)
- project = local_assigns.fetch(:project) - project = local_assigns.fetch(:project)
.form-group - if project.feature_available?(:merge_request_rebase) || project.feature_available?(:fast_forward_merge)
= label_tag :merge_method_merge, class: 'label-light' do .form-group
Merge method = label_tag :merge_method_merge, class: 'label-light' do
.radio Merge method
= label_tag :project_merge_method_merge do .radio
= form.radio_button :merge_method, :merge, class: "js-merge-method-radio" = label_tag :project_merge_method_merge do
%strong Merge commit = form.radio_button :merge_method, :merge, class: "js-merge-method-radio"
%br %strong Merge commit
%span.descr
A merge commit is created for every merge, and merging is allowed as long as there are no conflicts.
.radio
= label_tag :project_merge_method_rebase_merge do
= form.radio_button :merge_method, :rebase_merge, class: "js-merge-method-radio"
%strong Merge commit with semi-linear history
%br
%span.descr
A merge commit is created for every merge, but merging is only allowed if fast-forward merge is possible.
This way you could make sure that if this merge request would build, after merging to target branch it would also build.
- if project.feature_available?(:merge_request_rebase)
%br %br
%span.descr %span.descr
When fast-forward merge is not possible, the user is given the option to rebase. A merge commit is created for every merge, and merging is allowed as long as there are no conflicts.
.radio - if project.feature_available?(:merge_request_rebase)
= label_tag :project_merge_method_ff do .radio
= form.radio_button :merge_method, :ff, class: "js-merge-method-radio" = label_tag :project_merge_method_rebase_merge do
%strong Fast-forward merge = form.radio_button :merge_method, :rebase_merge, class: "js-merge-method-radio"
%br %strong Merge commit with semi-linear history
%span.descr %br
No merge commits are created and all merges are fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded. %span.descr
- if project.feature_available?(:merge_request_rebase) A merge commit is created for every merge, but merging is only allowed if fast-forward merge is possible.
%br This way you could make sure that if this merge request would build, after merging to target branch it would also build.
%span.descr %br
When fast-forward merge is not possible, the user is given the option to rebase. %span.descr
When fast-forward merge is not possible, the user is given the option to rebase.
- if project.feature_available?(:fast_forward_merge)
.radio
= label_tag :project_merge_method_ff do
= form.radio_button :merge_method, :ff, class: "js-merge-method-radio"
%strong Fast-forward merge
%br
%span.descr
No merge commits are created and all merges are fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded.
- if project.feature_available?(:merge_request_rebase)
%br
%span.descr
When fast-forward merge is not possible, the user is given the option to rebase.
.form-group .form-group
= form.label :merge_requests_template, class: 'label-light' do = form.label :merge_requests_template, class: 'label-light' do
......
---
title: Namespace license checks for fast-forward merge (EES)
merge_request: 2272
author:
...@@ -16,13 +16,13 @@ describe MergeRequest, models: true do ...@@ -16,13 +16,13 @@ describe MergeRequest, models: true do
let(:project) { create(:project, merge_requests_rebase_enabled: true) } let(:project) { create(:project, merge_requests_rebase_enabled: true) }
it 'returns false when the project feature is unavailable' do it 'returns false when the project feature is unavailable' do
expect(merge_request.target_project).to receive(:feature_available?).with(:merge_request_rebase).and_return(false) expect(merge_request.target_project).to receive(:feature_available?).with(:merge_request_rebase).at_least(:once).and_return(false)
is_expected.to be_falsy is_expected.to be_falsy
end end
it 'returns true when the project feature is available' do it 'returns true when the project feature is available' do
expect(merge_request.target_project).to receive(:feature_available?).with(:merge_request_rebase).and_return(true) expect(merge_request.target_project).to receive(:feature_available?).with(:merge_request_rebase).at_least(:once).and_return(true)
is_expected.to be_truthy is_expected.to be_truthy
end end
......
...@@ -266,4 +266,38 @@ describe Project, models: true do ...@@ -266,4 +266,38 @@ describe Project, models: true do
expect(project.service_desk_address).to eq("test+#{project.full_path}@mail.com") expect(project.service_desk_address).to eq("test+#{project.full_path}@mail.com")
end end
end end
describe '#merge_method' do
[
{ ff: true, rebase: true, ff_licensed: true, rebase_licensed: true, method: :ff },
{ ff: true, rebase: true, ff_licensed: true, rebase_licensed: false, method: :ff },
{ ff: true, rebase: true, ff_licensed: false, rebase_licensed: true, method: :rebase_merge },
{ ff: true, rebase: true, ff_licensed: false, rebase_licensed: false, method: :merge },
{ ff: true, rebase: false, ff_licensed: true, rebase_licensed: true, method: :ff },
{ ff: true, rebase: false, ff_licensed: true, rebase_licensed: false, method: :ff },
{ ff: true, rebase: false, ff_licensed: false, rebase_licensed: true, method: :merge },
{ ff: true, rebase: false, ff_licensed: false, rebase_licensed: false, method: :merge },
{ ff: false, rebase: true, ff_licensed: true, rebase_licensed: true, method: :rebase_merge },
{ ff: false, rebase: true, ff_licensed: true, rebase_licensed: false, method: :merge },
{ ff: false, rebase: true, ff_licensed: false, rebase_licensed: true, method: :rebase_merge },
{ ff: false, rebase: true, ff_licensed: false, rebase_licensed: false, method: :merge },
{ ff: false, rebase: false, ff_licensed: true, rebase_licensed: true, method: :merge },
{ ff: false, rebase: false, ff_licensed: true, rebase_licensed: false, method: :merge },
{ ff: false, rebase: false, ff_licensed: false, rebase_licensed: true, method: :merge },
{ ff: false, rebase: false, ff_licensed: false, rebase_licensed: false, method: :merge }
].each do |spec|
context spec.inspect do
let(:project) { build(:empty_project, merge_requests_rebase_enabled: spec[:rebase], merge_requests_ff_only_enabled: spec[:ff]) }
let(:spec) { spec }
subject { project.merge_method }
before do
stub_licensed_features(merge_request_rebase: spec[:rebase_licensed], fast_forward_merge: spec[:ff_licensed])
end
it { is_expected.to eq(spec[:method]) }
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