diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/services/ci/create_builds_service.rb | 1 | ||||
-rw-r--r-- | lib/ci/status.rb | 4 | ||||
-rw-r--r-- | spec/factories/ci/builds.rb | 20 | ||||
-rw-r--r-- | spec/lib/ci/status_spec.rb | 37 | ||||
-rw-r--r-- | spec/models/ci/commit_spec.rb | 29 | ||||
-rw-r--r-- | spec/services/ci/create_builds_service_spec.rb | 28 |
7 files changed, 117 insertions, 3 deletions
diff --git a/CHANGELOG b/CHANGELOG index 08a9b8df4a0..b0d08d97226 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -63,6 +63,7 @@ v 8.5.0 (unreleased) - Fix CI builds badge, add a new link to builds badge, deprecate the old one - Fix broken link to project in build notification emails - Ability to see and sort on vote count from Issues and MR lists + - Fix builds scheduler when first build in stage was allowed to fail v 8.4.4 - Update omniauth-saml gem to 1.4.2 diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb index ad901f2da5d..002f7ba1278 100644 --- a/app/services/ci/create_builds_service.rb +++ b/app/services/ci/create_builds_service.rb @@ -34,6 +34,7 @@ module Ci build = commit.builds.create!(build_attrs) build.execute_hooks + build end end end diff --git a/lib/ci/status.rb b/lib/ci/status.rb index c02b3b8f3e4..3fb1fe29494 100644 --- a/lib/ci/status.rb +++ b/lib/ci/status.rb @@ -1,11 +1,9 @@ module Ci class Status def self.get_status(statuses) - statuses.reject! { |status| status.try(&:allow_failure?) } - if statuses.none? 'skipped' - elsif statuses.all?(&:success?) + elsif statuses.all? { |status| status.success? || status.ignored? } 'success' elsif statuses.all?(&:pending?) 'pending' diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index c1b6ecd329a..1243647a78d 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -16,10 +16,30 @@ FactoryGirl.define do commit factory: :ci_commit + trait :success do + status 'success' + end + + trait :failed do + status 'failed' + end + trait :canceled do status 'canceled' end + trait :running do + status 'running' + end + + trait :pending do + status 'pending' + end + + trait :allowed_to_fail do + allow_failure true + end + after(:build) do |build, evaluator| build.project = build.commit.project end diff --git a/spec/lib/ci/status_spec.rb b/spec/lib/ci/status_spec.rb new file mode 100644 index 00000000000..cc4199dc7b6 --- /dev/null +++ b/spec/lib/ci/status_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe Ci::Status do + describe '.get_status' do + subject { described_class.get_status(builds) } + + context 'all builds successful' do + let(:builds) { Array.new(2) { create(:ci_build, :success) } } + it { is_expected.to eq 'success' } + end + + context 'at least one build failed' do + let(:builds) { [create(:ci_build, :success), create(:ci_build, :failed)] } + it { is_expected.to eq 'failed' } + end + + context 'at least one running' do + let(:builds) { [create(:ci_build, :success), create(:ci_build, :running)] } + it { is_expected.to eq 'running' } + end + + context 'at least one pending' do + let(:builds) { [create(:ci_build, :success), create(:ci_build, :pending)] } + it { is_expected.to eq 'running' } + end + + context 'build success and failed but allowed to fail' do + let(:builds) { [create(:ci_build, :success), create(:ci_build, :failed, :allowed_to_fail)] } + it { is_expected.to eq 'success' } + end + + context 'one build failed but allowed to fail' do + let(:builds) { [create(:ci_build, :failed, :allowed_to_fail)] } + it { is_expected.to eq 'success' } + end + end +end diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb index dfc0cc3be1c..4dc309a4255 100644 --- a/spec/models/ci/commit_spec.rb +++ b/spec/models/ci/commit_spec.rb @@ -247,6 +247,35 @@ describe Ci::Commit, models: true do end end + + context 'custom stage with first job allowed to fail' do + let(:yaml) do + { + stages: ['clean', 'test'], + clean_job: { + stage: 'clean', + allow_failure: true, + script: 'BUILD', + }, + test_job: { + stage: 'test', + script: 'TEST', + }, + } + end + + before do + stub_ci_commit_yaml_file(YAML.dump(yaml)) + create_builds + end + + it 'properly schedules builds' do + expect(commit.builds.pluck(:status)).to contain_exactly('pending') + commit.builds.running_or_pending.each(&:drop) + expect(commit.builds.pluck(:status)).to contain_exactly('pending', 'failed') + end + end + context 'properly creates builds when "when" is defined' do let(:yaml) do { diff --git a/spec/services/ci/create_builds_service_spec.rb b/spec/services/ci/create_builds_service_spec.rb new file mode 100644 index 00000000000..1fca3628686 --- /dev/null +++ b/spec/services/ci/create_builds_service_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe Ci::CreateBuildsService, services: true do + let(:commit) { create(:ci_commit) } + let(:user) { create(:user) } + + describe '#execute' do + # Using stubbed .gitlab-ci.yml created in commit factory + # + + subject do + described_class.new.execute(commit, 'test', 'master', nil, user, nil, status) + end + + context 'next builds available' do + let(:status) { 'success' } + + it { is_expected.to be_an_instance_of Array } + it { is_expected.to all(be_an_instance_of Ci::Build) } + end + + context 'builds skipped' do + let(:status) { 'skipped' } + + it { is_expected.to be_empty } + end + end +end |