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:
Diffstat (limited to 'app/services')
-rw-r--r--app/services/ci/update_ci_ref_status_service.rb65
-rw-r--r--app/services/merge_requests/create_pipeline_service.rb23
-rw-r--r--app/services/notification_service.rb7
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)