summaryrefslogtreecommitdiff
path: root/app/services/merge_requests
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-20 18:38:24 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-20 18:38:24 +0000
commit983a0bba5d2a042c4a3bbb22432ec192c7501d82 (patch)
treeb153cd387c14ba23bd5a07514c7c01fddf6a78a0 /app/services/merge_requests
parenta2bddee2cdb38673df0e004d5b32d9f77797de64 (diff)
downloadgitlab-ce-983a0bba5d2a042c4a3bbb22432ec192c7501d82.tar.gz
Add latest changes from gitlab-org/gitlab@12-10-stable-ee
Diffstat (limited to 'app/services/merge_requests')
-rw-r--r--app/services/merge_requests/merge_orchestration_service.rb40
-rw-r--r--app/services/merge_requests/pushed_branches_service.rb32
-rw-r--r--app/services/merge_requests/update_service.rb19
3 files changed, 85 insertions, 6 deletions
diff --git a/app/services/merge_requests/merge_orchestration_service.rb b/app/services/merge_requests/merge_orchestration_service.rb
new file mode 100644
index 00000000000..24341ef1145
--- /dev/null
+++ b/app/services/merge_requests/merge_orchestration_service.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ class MergeOrchestrationService < ::BaseService
+ def execute(merge_request)
+ return unless can_merge?(merge_request)
+
+ merge_request.update(merge_error: nil)
+
+ if can_merge_automatically?(merge_request)
+ auto_merge_service.execute(merge_request)
+ else
+ merge_request.merge_async(current_user.id, params)
+ end
+ end
+
+ def can_merge?(merge_request)
+ can_merge_automatically?(merge_request) || can_merge_immediately?(merge_request)
+ end
+
+ def preferred_auto_merge_strategy(merge_request)
+ auto_merge_service.preferred_strategy(merge_request)
+ end
+
+ private
+
+ def can_merge_immediately?(merge_request)
+ merge_request.can_be_merged_by?(current_user) &&
+ merge_request.mergeable_state?
+ end
+
+ def can_merge_automatically?(merge_request)
+ auto_merge_service.available_strategies(merge_request).any?
+ end
+
+ def auto_merge_service
+ @auto_merge_service ||= AutoMergeService.new(project, current_user, params)
+ end
+ end
+end
diff --git a/app/services/merge_requests/pushed_branches_service.rb b/app/services/merge_requests/pushed_branches_service.rb
new file mode 100644
index 00000000000..afcf0f7678a
--- /dev/null
+++ b/app/services/merge_requests/pushed_branches_service.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ class PushedBranchesService < MergeRequests::BaseService
+ include ::Gitlab::Utils::StrongMemoize
+
+ # Skip moving this logic into models since it's too specific
+ # rubocop: disable CodeReuse/ActiveRecord
+ def execute
+ return [] if branch_names.blank?
+
+ source_branches = project.source_of_merge_requests.opened
+ .from_source_branches(branch_names).pluck(:source_branch)
+
+ target_branches = project.merge_requests.opened
+ .by_target_branch(branch_names).distinct.pluck(:target_branch)
+
+ source_branches.concat(target_branches).to_set
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ private
+
+ def branch_names
+ strong_memoize(:branch_names) do
+ params[:changes].map do |change|
+ Gitlab::Git.branch_name(change[:ref])
+ end.compact
+ end
+ end
+ end
+end
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 1516e33a7c6..2d33e87bf4b 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -79,14 +79,21 @@ module MergeRequests
def merge_from_quick_action(merge_request)
last_diff_sha = params.delete(:merge)
- return unless merge_request.mergeable_with_quick_action?(current_user, last_diff_sha: last_diff_sha)
- merge_request.update(merge_error: nil)
-
- if merge_request.head_pipeline_active?
- AutoMergeService.new(project, current_user, { sha: last_diff_sha }).execute(merge_request, AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
+ if Feature.enabled?(:merge_orchestration_service, merge_request.project, default_enabled: true)
+ MergeRequests::MergeOrchestrationService
+ .new(project, current_user, { sha: last_diff_sha })
+ .execute(merge_request)
else
- merge_request.merge_async(current_user.id, { sha: last_diff_sha })
+ return unless merge_request.mergeable_with_quick_action?(current_user, last_diff_sha: last_diff_sha)
+
+ merge_request.update(merge_error: nil)
+
+ if merge_request.head_pipeline_active?
+ AutoMergeService.new(project, current_user, { sha: last_diff_sha }).execute(merge_request, AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
+ else
+ merge_request.merge_async(current_user.id, { sha: last_diff_sha })
+ end
end
end