Commit 4567e624 authored by Kamil Trzcinski's avatar Kamil Trzcinski Committed by Grzegorz Bizon

Make pipeline processing asynchronous

Conflicts:
	app/models/ci/pipeline.rb
	app/models/commit_status.rb
parent d9f9ad9d
...@@ -67,7 +67,7 @@ module Ci ...@@ -67,7 +67,7 @@ module Ci
environment: build.environment, environment: build.environment,
status_event: 'enqueue' status_event: 'enqueue'
) )
MergeRequests::AddTodoWhenBuildFailsService.new(build.project, nil).close(new_build) MergeRequests::AddTodoWhenBuildFailsService.new(build.project, nil).close(new_build.pipeline)
build.pipeline.mark_as_processable_after_stage(build.stage_idx) build.pipeline.mark_as_processable_after_stage(build.stage_idx)
new_build new_build
end end
......
...@@ -73,6 +73,14 @@ module Ci ...@@ -73,6 +73,14 @@ module Ci
after_transition do |pipeline, transition| after_transition do |pipeline, transition|
pipeline.execute_hooks unless transition.loopback? pipeline.execute_hooks unless transition.loopback?
end end
after_transition [:created, :pending, :running] => :success do |pipeline|
MergeRequests::MergeWhenBuildSucceedsService.new(pipeline.project, nil).trigger(pipeline)
end
after_transition any => :failed do |pipeline|
MergeRequests::AddTodoWhenBuildFailsService.new(pipeline.project, nil).execute(pipeline)
end
end end
# ref can't be HEAD or SHA, can only be branch/tag name # ref can't be HEAD or SHA, can only be branch/tag name
...@@ -251,9 +259,8 @@ module Ci ...@@ -251,9 +259,8 @@ module Ci
Ci::ProcessPipelineService.new(project, user).execute(self) Ci::ProcessPipelineService.new(project, user).execute(self)
end end
def build_updated def update_status
with_lock do with_lock do
reload
case latest_builds_status case latest_builds_status
when 'pending' then enqueue when 'pending' then enqueue
when 'running' then run when 'running' then run
......
...@@ -74,10 +74,6 @@ class CommitStatus < ActiveRecord::Base ...@@ -74,10 +74,6 @@ class CommitStatus < ActiveRecord::Base
true true
end end
after_transition do |commit_status, transition|
commit_status.pipeline.try(:build_updated) unless transition.loopback?
end
after_transition [:created, :pending, :running] => :success do |commit_status| after_transition [:created, :pending, :running] => :success do |commit_status|
MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.pipeline.project, nil).trigger(commit_status) MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.pipeline.project, nil).trigger(commit_status)
end end
...@@ -85,6 +81,16 @@ class CommitStatus < ActiveRecord::Base ...@@ -85,6 +81,16 @@ class CommitStatus < ActiveRecord::Base
after_transition any => :failed do |commit_status| after_transition any => :failed do |commit_status|
MergeRequests::AddTodoWhenBuildFailsService.new(commit_status.pipeline.project, nil).execute(commit_status) MergeRequests::AddTodoWhenBuildFailsService.new(commit_status.pipeline.project, nil).execute(commit_status)
end end
after_transition do |commit_status, transition|
if commit_status.pipeline && !transition.loopback?
ProcessPipelineWorker.perform_async(
commit_status.pipeline.id,
process: HasStatus.COMPLETED_STATUSES.include?(commit_status.status))
end
true
end
end end
delegate :sha, :short_sha, to: :pipeline delegate :sha, :short_sha, to: :pipeline
......
module MergeRequests module MergeRequests
class AddTodoWhenBuildFailsService < MergeRequests::BaseService class AddTodoWhenBuildFailsService < MergeRequests::BaseService
# Adds a todo to the parent merge_request when a CI build fails # Adds a todo to the parent merge_request when a CI build fails
def execute(commit_status) def execute(pipeline)
each_merge_request(commit_status) do |merge_request| each_merge_request(pipeline) do |merge_request|
todo_service.merge_request_build_failed(merge_request) todo_service.merge_request_build_failed(merge_request)
end end
end end
# Closes any pending build failed todos for the parent MRs when a build is retried # Closes any pending build failed todos for the parent MRs when a build is retried
def close(commit_status) def close(pipeline)
each_merge_request(commit_status) do |merge_request| each_merge_request(pipeline) do |merge_request|
todo_service.merge_request_build_retried(merge_request) todo_service.merge_request_build_retried(merge_request)
end end
end end
......
...@@ -42,11 +42,11 @@ module MergeRequests ...@@ -42,11 +42,11 @@ module MergeRequests
super(:merge_request) super(:merge_request)
end end
def merge_request_from(commit_status) def merge_request_from(pipeline)
branches = commit_status.ref branches = pipeline.ref
# This is for ref-less builds # This is for ref-less builds
branches ||= @project.repository.branch_names_contains(commit_status.sha) branches ||= @project.repository.branch_names_contains(pipeline.sha)
return [] if branches.blank? return [] if branches.blank?
...@@ -56,14 +56,11 @@ module MergeRequests ...@@ -56,14 +56,11 @@ module MergeRequests
merge_requests.uniq.select(&:source_project) merge_requests.uniq.select(&:source_project)
end end
def each_merge_request(commit_status) def each_merge_request(pipeline)
merge_request_from(commit_status).each do |merge_request| merge_request_from(commit_status).each do |merge_request|
pipeline = merge_request.pipeline next unless pipeline == merge_request.pipeline
next unless pipeline yield merge_request
next unless pipeline.sha == commit_status.sha
yield merge_request, pipeline
end end
end end
end end
......
...@@ -19,11 +19,12 @@ module MergeRequests ...@@ -19,11 +19,12 @@ module MergeRequests
end end
# Triggers the automatic merge of merge_request once the build succeeds # Triggers the automatic merge of merge_request once the build succeeds
def trigger(commit_status) def trigger(pipeline)
each_merge_request(commit_status) do |merge_request, pipeline| return unless pipeline.success?
each_merge_request(pipeline) do |merge_request|
next unless merge_request.merge_when_build_succeeds? next unless merge_request.merge_when_build_succeeds?
next unless merge_request.mergeable? next unless merge_request.mergeable?
next unless pipeline.success?
MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id, merge_request.merge_params) MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id, merge_request.merge_params)
end end
......
class ProcessPipelineWorker
include Sidekiq::Worker
sidekiq_options queue: :default
def perform(pipeline_id, params)
begin
pipeline = Ci::Pipeline.find(pipeline_id)
rescue ActiveRecord::RecordNotFound
return
end
pipeline.process! if params[:process]
pipeline.update_status
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