summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--app/services/ci/create_builds_service.rb1
-rw-r--r--lib/ci/status.rb4
-rw-r--r--spec/factories/ci/builds.rb20
-rw-r--r--spec/lib/ci/status_spec.rb37
-rw-r--r--spec/models/ci/commit_spec.rb29
-rw-r--r--spec/services/ci/create_builds_service_spec.rb28
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