diff options
-rw-r--r-- | app/services/ci/process_pipeline_service.rb | 15 | ||||
-rw-r--r-- | spec/factories/ci/pipelines.rb | 11 | ||||
-rw-r--r-- | spec/services/ci/process_pipeline_service_spec.rb | 47 |
3 files changed, 52 insertions, 21 deletions
diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb index e6bd1d1460c..2e028c44d8b 100644 --- a/app/services/ci/process_pipeline_service.rb +++ b/app/services/ci/process_pipeline_service.rb @@ -5,6 +5,8 @@ module Ci def execute(pipeline) @pipeline = pipeline + ensure_created_builds! # TODO, remove me in 9.0 + new_builds = stage_indexes_of_created_builds.map do |index| process_stage(index) @@ -67,5 +69,18 @@ module Ci def created_builds pipeline.builds.created end + + # This method is DEPRECATED and should be removed in 9.0. + # + # We need it to maintain backwards compatibility with previous versions + # when builds were not created within one transaction with the pipeline. + # + def ensure_created_builds! + return if created_builds.any? + + Ci::CreatePipelineBuildsService + .new(project, current_user) + .execute(pipeline) + end end end diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb index ac2a1ba5dff..3c35dae8772 100644 --- a/spec/factories/ci/pipelines.rb +++ b/spec/factories/ci/pipelines.rb @@ -29,5 +29,16 @@ FactoryGirl.define do allow(commit).to receive(:ci_yaml_file) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) } end end + + factory(:ci_pipeline_with_yaml) do + transient { yaml nil } + + after(:build) do |pipeline, evaluator| + raise ArgumentError unless evaluator.yaml + + allow(pipeline).to receive(:ci_yaml_file) + .and_return(YAML.dump(evaluator.yaml)) + end + end end end diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb index b130f876259..306943a5488 100644 --- a/spec/services/ci/process_pipeline_service_spec.rb +++ b/spec/services/ci/process_pipeline_service_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Ci::ProcessPipelineService, services: true do - let(:pipeline) { create(:ci_pipeline, ref: 'master') } + let(:pipeline) { create(:ci_empty_pipeline, ref: 'master') } let(:user) { create(:user) } describe '#execute' do @@ -293,57 +293,62 @@ describe Ci::ProcessPipelineService, services: true do end end - context 'when there are builds in multiple stages' do + context 'when there are builds that are not created yet' do + let(:pipeline) do + create(:ci_pipeline_with_yaml, yaml: config) + end + + let(:config) do + { rspec: { stage: 'test', script: 'rspec' }, + deploy: { stage: 'deploy', script: 'rsync' } } + end + before do create(:ci_build, :created, pipeline: pipeline, name: 'linux', stage: 'build', stage_idx: 0) create(:ci_build, :created, pipeline: pipeline, name: 'mac', stage: 'build', stage_idx: 0) - create(:ci_build, :created, pipeline: pipeline, name: 'rspec', stage: 'test', stage_idx: 1) - create(:ci_build, :created, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 1) - create(:ci_build, :created, pipeline: pipeline, name: 'deploy', stage: 'deploy', stage_idx: 2) end it 'processes the pipeline' do # Currently we have five builds with state created # expect(builds.count).to eq(0) - expect(all_builds.count).to eq(5) + expect(all_builds.count).to eq(2) - # Process builds will mark the created as pending + # Process builds service will enqueue builds from the first stage. # process_pipeline expect(builds.count).to eq(2) - expect(all_builds.count).to eq(5) + expect(all_builds.count).to eq(2) - # When builds succeed we will enqueue remaining builds - # We will have 2 succeeded, 2 pending (from stage test), - # total 5 (one more build from deploy) + # When builds succeed we will enqueue remaining builds. + # + # We will have 2 succeeded, 1 pending (from stage test), total 4 (two + # additional build from `.gitlab-ci.yml`). # succeed_pending process_pipeline expect(builds.success.count).to eq(2) - expect(builds.pending.count).to eq(2) - expect(all_builds.count).to eq(5) + expect(builds.pending.count).to eq(1) + expect(all_builds.count).to eq(4) - # When we succeed the 2 pending from stage test, - # We will queue a deploy stage. + # When pending build succeeds in stage test, we enqueue deploy stage. # succeed_pending process_pipeline expect(builds.pending.count).to eq(1) - expect(builds.success.count).to eq(4) - expect(all_builds.count).to eq(5) + expect(builds.success.count).to eq(3) + expect(all_builds.count).to eq(4) - # When we succeed last pending build, we will have - # a total of 5 succeeded builds + # When the last one succeeds we have 4 successful builds. # succeed_pending process_pipeline - expect(builds.success.count).to eq(5) - expect(all_builds.count).to eq(5) + expect(builds.success.count).to eq(4) + expect(all_builds.count).to eq(4) end end end |