Commit c0f549a9 authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch 'fix/ci-first-job-allow-failure' into 'master'

Fix CI builds scheduler when first build in stage is allowed to fail

This fixes an edge case in CI builds scheduler when first build in stage was marked as allowed to fail.

Closes #3192

See merge request !2869
parents c943dae6 bee26f9c
...@@ -63,6 +63,7 @@ v 8.5.0 (unreleased) ...@@ -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 CI builds badge, add a new link to builds badge, deprecate the old one
- Fix broken link to project in build notification emails - Fix broken link to project in build notification emails
- Ability to see and sort on vote count from Issues and MR lists - 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 v 8.4.4
- Update omniauth-saml gem to 1.4.2 - Update omniauth-saml gem to 1.4.2
......
...@@ -34,6 +34,7 @@ module Ci ...@@ -34,6 +34,7 @@ module Ci
build = commit.builds.create!(build_attrs) build = commit.builds.create!(build_attrs)
build.execute_hooks build.execute_hooks
build
end end
end end
end end
......
module Ci module Ci
class Status class Status
def self.get_status(statuses) def self.get_status(statuses)
statuses.reject! { |status| status.try(&:allow_failure?) }
if statuses.none? if statuses.none?
'skipped' 'skipped'
elsif statuses.all?(&:success?) elsif statuses.all? { |status| status.success? || status.ignored? }
'success' 'success'
elsif statuses.all?(&:pending?) elsif statuses.all?(&:pending?)
'pending' 'pending'
......
...@@ -16,10 +16,30 @@ FactoryGirl.define do ...@@ -16,10 +16,30 @@ FactoryGirl.define do
commit factory: :ci_commit commit factory: :ci_commit
trait :success do
status 'success'
end
trait :failed do
status 'failed'
end
trait :canceled do trait :canceled do
status 'canceled' status 'canceled'
end 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| after(:build) do |build, evaluator|
build.project = build.commit.project build.project = build.commit.project
end end
......
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
...@@ -247,6 +247,35 @@ describe Ci::Commit, models: true do ...@@ -247,6 +247,35 @@ describe Ci::Commit, models: true do
end end
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 context 'properly creates builds when "when" is defined' do
let(:yaml) do let(:yaml) do
{ {
......
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
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