Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-07-20 15:26:25 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-20 15:26:25 +0300
commita09983ae35713f5a2bbb100981116d31ce99826e (patch)
tree2ee2af7bd104d57086db360a7e6d8c9d5d43667a /app/services/merge_requests
parent18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff)
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'app/services/merge_requests')
-rw-r--r--app/services/merge_requests/approval_service.rb56
-rw-r--r--app/services/merge_requests/base_service.rb16
-rw-r--r--app/services/merge_requests/create_pipeline_service.rb20
-rw-r--r--app/services/merge_requests/create_service.rb6
-rw-r--r--app/services/merge_requests/ff_merge_service.rb2
-rw-r--r--app/services/merge_requests/merge_base_service.rb2
-rw-r--r--app/services/merge_requests/merge_service.rb3
-rw-r--r--app/services/merge_requests/post_merge_service.rb1
-rw-r--r--app/services/merge_requests/remove_approval_service.rb43
-rw-r--r--app/services/merge_requests/squash_service.rb7
-rw-r--r--app/services/merge_requests/update_service.rb56
11 files changed, 175 insertions, 37 deletions
diff --git a/app/services/merge_requests/approval_service.rb b/app/services/merge_requests/approval_service.rb
new file mode 100644
index 00000000000..150ec85fca9
--- /dev/null
+++ b/app/services/merge_requests/approval_service.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ class ApprovalService < MergeRequests::BaseService
+ def execute(merge_request)
+ return unless can_be_approved?(merge_request)
+
+ approval = merge_request.approvals.new(user: current_user)
+
+ return success unless save_approval(approval)
+
+ reset_approvals_cache(merge_request)
+ create_event(merge_request)
+ create_approval_note(merge_request)
+ mark_pending_todos_as_done(merge_request)
+ execute_approval_hooks(merge_request, current_user)
+
+ success
+ end
+
+ private
+
+ def can_be_approved?(merge_request)
+ current_user.can?(:approve_merge_request, merge_request)
+ end
+
+ def reset_approvals_cache(merge_request)
+ merge_request.approvals.reset
+ end
+
+ def execute_approval_hooks(merge_request, current_user)
+ # Only one approval is required for a merge request to be approved
+ execute_hooks(merge_request, 'approved')
+ end
+
+ def save_approval(approval)
+ Approval.safe_ensure_unique do
+ approval.save
+ end
+ end
+
+ def create_approval_note(merge_request)
+ SystemNoteService.approve_mr(merge_request, current_user)
+ end
+
+ def mark_pending_todos_as_done(merge_request)
+ todo_service.resolve_todos_for_target(merge_request, current_user)
+ end
+
+ def create_event(merge_request)
+ event_service.approve_mr(merge_request, current_user)
+ end
+ end
+end
+
+MergeRequests::ApprovalService.prepend_if_ee('EE::MergeRequests::ApprovalService')
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index 7f7bfa29af7..7e301f311e9 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -2,6 +2,7 @@
module MergeRequests
class BaseService < ::IssuableBaseService
+ extend ::Gitlab::Utils::Override
include MergeRequests::AssignsMergeParams
def create_note(merge_request, state = merge_request.state)
@@ -29,6 +30,11 @@ module MergeRequests
.execute_for_merge_request(merge_request)
end
+ def cancel_review_app_jobs!(merge_request)
+ environments = merge_request.environments.in_review_folder.available
+ environments.each { |environment| environment.cancel_deployment_jobs! }
+ end
+
def source_project
@source_project ||= merge_request.source_project
end
@@ -58,6 +64,12 @@ module MergeRequests
super
end
+ override :handle_quick_actions
+ def handle_quick_actions(merge_request)
+ super
+ handle_wip_event(merge_request)
+ end
+
def handle_wip_event(merge_request)
if wip_event = params.delete(:wip_event)
# We update the title that is provided in the params or we use the mr title
@@ -90,10 +102,6 @@ module MergeRequests
MergeRequests::CreatePipelineService.new(project, user).execute(merge_request)
end
- def can_use_merge_request_ref?(merge_request)
- !merge_request.for_fork?
- end
-
def abort_auto_merge(merge_request, reason)
AutoMergeService.new(project, current_user).abort(merge_request, reason)
end
diff --git a/app/services/merge_requests/create_pipeline_service.rb b/app/services/merge_requests/create_pipeline_service.rb
index f802aa44487..f9352f10fea 100644
--- a/app/services/merge_requests/create_pipeline_service.rb
+++ b/app/services/merge_requests/create_pipeline_service.rb
@@ -9,7 +9,7 @@ module MergeRequests
end
def create_detached_merge_request_pipeline(merge_request)
- Ci::CreatePipelineService.new(merge_request.source_project,
+ Ci::CreatePipelineService.new(pipeline_project(merge_request),
current_user,
ref: pipeline_ref_for_detached_merge_request_pipeline(merge_request))
.execute(:merge_request_event, merge_request: merge_request)
@@ -31,13 +31,29 @@ module MergeRequests
private
+ def pipeline_project(merge_request)
+ if can_create_pipeline_in_target_project?(merge_request)
+ merge_request.target_project
+ else
+ merge_request.source_project
+ end
+ end
+
def pipeline_ref_for_detached_merge_request_pipeline(merge_request)
- if can_use_merge_request_ref?(merge_request)
+ if can_create_pipeline_in_target_project?(merge_request)
merge_request.ref_path
else
merge_request.source_branch
end
end
+
+ def can_create_pipeline_in_target_project?(merge_request)
+ if Gitlab::Ci::Features.allow_to_create_merge_request_pipelines_in_target_project?(merge_request.target_project)
+ can?(current_user, :create_pipeline, merge_request.target_project)
+ else
+ merge_request.for_same_project?
+ end
+ end
end
end
diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb
index 1cdfba41432..ac84a13f437 100644
--- a/app/services/merge_requests/create_service.rb
+++ b/app/services/merge_requests/create_service.rb
@@ -33,12 +33,6 @@ module MergeRequests
super
end
- # Override from IssuableBaseService
- def handle_quick_actions_on_create(merge_request)
- super
- handle_wip_event(merge_request)
- end
-
private
def set_projects!
diff --git a/app/services/merge_requests/ff_merge_service.rb b/app/services/merge_requests/ff_merge_service.rb
index 6f1fa607ef9..b3896d61a78 100644
--- a/app/services/merge_requests/ff_merge_service.rb
+++ b/app/services/merge_requests/ff_merge_service.rb
@@ -16,7 +16,7 @@ module MergeRequests
merge_request.target_branch,
merge_request: merge_request)
- if merge_request.squash
+ if merge_request.squash_on_merge?
merge_request.update_column(:squash_commit_sha, merge_request.in_progress_merge_commit_sha)
end
diff --git a/app/services/merge_requests/merge_base_service.rb b/app/services/merge_requests/merge_base_service.rb
index 27b5e31faab..fe09c92aab9 100644
--- a/app/services/merge_requests/merge_base_service.rb
+++ b/app/services/merge_requests/merge_base_service.rb
@@ -20,7 +20,7 @@ module MergeRequests
def source
strong_memoize(:source) do
- if merge_request.squash
+ if merge_request.squash_on_merge?
squash_sha!
else
merge_request.diff_head_sha
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 8d57a76f7d0..961a7cb1ef6 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -27,6 +27,7 @@ module MergeRequests
success
end
end
+
log_info("Merge process finished on JID #{merge_jid} with state #{state}")
rescue MergeError => e
handle_merge_error(log_message: e.message, save_message_on_model: true)
@@ -56,6 +57,8 @@ module MergeRequests
'Only fast-forward merge is allowed for your project. Please update your source branch'
elsif !@merge_request.mergeable?
'Merge request is not mergeable'
+ elsif !@merge_request.squash && project.squash_always?
+ 'This project requires squashing commits when merge requests are accepted.'
end
raise_error(error) if error
diff --git a/app/services/merge_requests/post_merge_service.rb b/app/services/merge_requests/post_merge_service.rb
index 0364c0dd479..fdf8f442297 100644
--- a/app/services/merge_requests/post_merge_service.rb
+++ b/app/services/merge_requests/post_merge_service.rb
@@ -18,6 +18,7 @@ module MergeRequests
invalidate_cache_counts(merge_request, users: merge_request.assignees)
merge_request.update_project_counter_caches
delete_non_latest_diffs(merge_request)
+ cancel_review_app_jobs!(merge_request)
cleanup_environments(merge_request)
end
diff --git a/app/services/merge_requests/remove_approval_service.rb b/app/services/merge_requests/remove_approval_service.rb
new file mode 100644
index 00000000000..3164d0b4069
--- /dev/null
+++ b/app/services/merge_requests/remove_approval_service.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ class RemoveApprovalService < MergeRequests::BaseService
+ # rubocop: disable CodeReuse/ActiveRecord
+ def execute(merge_request)
+ return unless merge_request.approved_by?(current_user)
+
+ # paranoid protection against running wrong deletes
+ return unless merge_request.id && current_user.id
+
+ approval = merge_request.approvals.where(user: current_user)
+
+ trigger_approval_hooks(merge_request) do
+ next unless approval.destroy_all # rubocop: disable Cop/DestroyAll
+
+ reset_approvals_cache(merge_request)
+ create_note(merge_request)
+ end
+
+ success
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ private
+
+ def reset_approvals_cache(merge_request)
+ merge_request.approvals.reset
+ end
+
+ def trigger_approval_hooks(merge_request)
+ yield
+
+ execute_hooks(merge_request, 'unapproved')
+ end
+
+ def create_note(merge_request)
+ SystemNoteService.unapprove_mr(merge_request, current_user)
+ end
+ end
+end
+
+MergeRequests::RemoveApprovalService.prepend_if_ee('EE::MergeRequests::RemoveApprovalService')
diff --git a/app/services/merge_requests/squash_service.rb b/app/services/merge_requests/squash_service.rb
index 4b04d42b48e..faa2e921581 100644
--- a/app/services/merge_requests/squash_service.rb
+++ b/app/services/merge_requests/squash_service.rb
@@ -11,11 +11,14 @@ module MergeRequests
return success(squash_sha: merge_request.diff_head_sha)
end
+ return error(s_('MergeRequests|This project does not allow squashing commits when merge requests are accepted.')) if squash_forbidden?
+
if squash_in_progress?
return error(s_('MergeRequests|Squash task canceled: another squash is already in progress.'))
end
squash! || error(s_('MergeRequests|Failed to squash. Should be done manually.'))
+
rescue SquashInProgressError
error(s_('MergeRequests|An error occurred while checking whether another squash is in progress.'))
end
@@ -40,6 +43,10 @@ module MergeRequests
raise SquashInProgressError, e.message
end
+ def squash_forbidden?
+ target_project.squash_never?
+ end
+
def repository
target_project.repository
end
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 561695baeab..29e0c22b155 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -2,6 +2,8 @@
module MergeRequests
class UpdateService < MergeRequests::BaseService
+ extend ::Gitlab::Utils::Override
+
def execute(merge_request)
# We don't allow change of source/target projects and source branch
# after merge request was created
@@ -9,14 +11,11 @@ module MergeRequests
params.delete(:target_project_id)
params.delete(:source_branch)
- merge_from_quick_action(merge_request) if params[:merge]
-
if merge_request.closed_without_fork?
params.delete(:target_branch)
params.delete(:force_remove_source_branch)
end
- handle_wip_event(merge_request)
update_task_event(merge_request) || update(merge_request)
end
@@ -77,26 +76,6 @@ module MergeRequests
todo_service.update_merge_request(merge_request, current_user)
end
- def merge_from_quick_action(merge_request)
- last_diff_sha = params.delete(:merge)
-
- 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
- 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
-
def reopen_service
MergeRequests::ReopenService
end
@@ -134,6 +113,37 @@ module MergeRequests
issuable, issuable.project, current_user, branch_type,
old_branch, new_branch)
end
+
+ override :handle_quick_actions
+ def handle_quick_actions(merge_request)
+ super
+ merge_from_quick_action(merge_request) if params[:merge]
+ end
+
+ def merge_from_quick_action(merge_request)
+ last_diff_sha = params.delete(:merge)
+
+ 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
+ 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
+
+ override :quick_action_options
+ def quick_action_options
+ { merge_request_diff_head_sha: params.delete(:merge_request_diff_head_sha) }
+ end
end
end