diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2019-07-31 11:16:51 +0200 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2019-08-01 12:19:37 +0200 |
commit | 8cf06c054325c664e9ff1365d6c32edb9058405a (patch) | |
tree | af36751298adb5f10de161917b25c453e04f47b1 /app/services/ci/process_pipeline_service.rb | |
parent | f10295b2956665d351eb413d380673090cb13b24 (diff) | |
download | gitlab-ce-implement-dag.tar.gz |
Add support for DAGimplement-dag
This implements the support for `needs:` keyword
as part of GitLab CI. That makes some of the jobs
to be run out of order.
Diffstat (limited to 'app/services/ci/process_pipeline_service.rb')
-rw-r--r-- | app/services/ci/process_pipeline_service.rb | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index 207cc5017d0..c92c5f66d97 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -4,19 +4,23 @@ module Ci class ProcessPipelineService < BaseService attr_reader :pipeline - def execute(pipeline) + def execute(pipeline, trigger_build_name = nil) @pipeline = pipeline update_retried - new_builds = + success = stage_indexes_of_created_processables.flat_map do |index| process_stage(index) - end + end.any? + + # we evaluate dependent needs, + # only when the another job has finished + success = process_builds_with_needs(trigger_build_name) || success @pipeline.update_status - new_builds.any? + success end private @@ -36,6 +40,30 @@ module Ci end end + def process_builds_with_needs(trigger_build_name) + return false unless trigger_build_name + return false unless Feature.enabled?(:ci_dag_support, project) + + success = false + + created_processables.with_needs(trigger_build_name).find_each do |build| + success = process_build_with_needs(build) || success + end + + success + end + + def process_build_with_needs(build) + current_status = status_for_build_needs(build.needs.map(&:name)) + + return unless HasStatus::COMPLETED_STATUSES.include?(current_status) + + Gitlab::OptimisticLocking.retry_lock(build) do |subject| + Ci::ProcessBuildService.new(project, @user) + .execute(build, current_status) + end + end + # rubocop: disable CodeReuse/ActiveRecord def status_for_prior_stages(index) pipeline.builds.where('stage_idx < ?', index).latest.status || 'success' @@ -43,6 +71,12 @@ module Ci # rubocop: enable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord + def status_for_build_needs(needs) + pipeline.builds.where(name: needs).latest.status || 'success' + end + # rubocop: enable CodeReuse/ActiveRecord + + # rubocop: disable CodeReuse/ActiveRecord def stage_indexes_of_created_processables created_processables.order(:stage_idx).pluck(Arel.sql('DISTINCT stage_idx')) end |