diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-27 18:09:21 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-27 18:09:21 +0000 |
commit | e0fa0638a422c3e20d4423c9bb69d79afc9c7d3d (patch) | |
tree | 9abb3c0706576bbda895fe9539a55556930606e2 /app/services | |
parent | f8d15ca65390475e356b06dedc51e10ccd179f86 (diff) | |
download | gitlab-ce-e0fa0638a422c3e20d4423c9bb69d79afc9c7d3d.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/ci/update_ci_ref_status_service.rb | 65 | ||||
-rw-r--r-- | app/services/merge_requests/create_pipeline_service.rb | 23 | ||||
-rw-r--r-- | app/services/notification_service.rb | 7 |
3 files changed, 83 insertions, 12 deletions
diff --git a/app/services/ci/update_ci_ref_status_service.rb b/app/services/ci/update_ci_ref_status_service.rb new file mode 100644 index 00000000000..e5e5b94b629 --- /dev/null +++ b/app/services/ci/update_ci_ref_status_service.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module Ci + class UpdateCiRefStatusService + include Gitlab::OptimisticLocking + + attr_reader :pipeline + + def initialize(pipeline) + @pipeline = pipeline + end + + def call + save.tap { |success| after_save if success } + end + + private + + def save + might_insert = ref.new_record? + + begin + retry_optimistic_lock(ref) do + next false if ref.persisted? && + (ref.last_updated_by_pipeline_id || 0) >= pipeline.id + + ref.update(status: next_status(ref.status, pipeline.status), + last_updated_by_pipeline: pipeline) + end + rescue ActiveRecord::RecordNotUnique + if might_insert + @ref = pipeline.reset.ref_status + might_insert = false + retry + else + raise + end + end + end + + def next_status(ref_status, pipeline_status) + if ref_status == 'failed' && pipeline_status == 'success' + 'fixed' + else + pipeline_status + end + end + + def after_save + enqueue_pipeline_notification + end + + def enqueue_pipeline_notification + PipelineNotificationWorker.perform_async(pipeline.id, ref_status: ref.status) + end + + def ref + @ref ||= pipeline.ref_status || build_ref + end + + def build_ref + Ci::Ref.new(ref: pipeline.ref, project: pipeline.project, tag: pipeline.tag) + end + end +end diff --git a/app/services/merge_requests/create_pipeline_service.rb b/app/services/merge_requests/create_pipeline_service.rb index 8258efba6bf..f802aa44487 100644 --- a/app/services/merge_requests/create_pipeline_service.rb +++ b/app/services/merge_requests/create_pipeline_service.rb @@ -9,15 +9,10 @@ module MergeRequests end def create_detached_merge_request_pipeline(merge_request) - if can_use_merge_request_ref?(merge_request) - Ci::CreatePipelineService.new(merge_request.source_project, current_user, - ref: merge_request.ref_path) - .execute(:merge_request_event, merge_request: merge_request) - else - Ci::CreatePipelineService.new(merge_request.source_project, current_user, - ref: merge_request.source_branch) - .execute(:merge_request_event, merge_request: merge_request) - end + Ci::CreatePipelineService.new(merge_request.source_project, + current_user, + ref: pipeline_ref_for_detached_merge_request_pipeline(merge_request)) + .execute(:merge_request_event, merge_request: merge_request) end def can_create_pipeline_for?(merge_request) @@ -33,6 +28,16 @@ module MergeRequests def allow_duplicate params[:allow_duplicate] end + + private + + def pipeline_ref_for_detached_merge_request_pipeline(merge_request) + if can_use_merge_request_ref?(merge_request) + merge_request.ref_path + else + merge_request.source_branch + end + end end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index ac7ef6fb970..6f2bfa8169b 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -434,18 +434,19 @@ class NotificationService mailer.project_was_not_exported_email(current_user, project, errors).deliver_later end - def pipeline_finished(pipeline, recipients = nil) + def pipeline_finished(pipeline, ref_status: nil, recipients: nil) # Must always check project configuration since recipients could be a list of emails # from the PipelinesEmailService integration. return if pipeline.project.emails_disabled? - email_template = "pipeline_#{pipeline.status}_email" + ref_status ||= pipeline.status + email_template = "pipeline_#{ref_status}_email" return unless mailer.respond_to?(email_template) recipients ||= notifiable_users( [pipeline.user], :watch, - custom_action: :"#{pipeline.status}_pipeline", + custom_action: :"#{ref_status}_pipeline", target: pipeline ).map do |user| user.notification_email_for(pipeline.project.group) |