Commit ca639c9b authored by Kamil Trzcinski's avatar Kamil Trzcinski

Allow to retry failed or canceled builds and fix cancel running specs failure

parent 92a83aae
......@@ -161,9 +161,7 @@ module Ci
end
def retryable?
builds.latest.any? do |build|
(build.failed? || build.canceled?) && build.retryable?
end
builds.latest.failed_or_canceled.any?(&:retryable?)
end
def cancelable?
......@@ -171,12 +169,16 @@ module Ci
end
def cancel_running
statuses.cancelable.each(&:cancel)
Gitlab::OptimisticLocking.retry_lock(statuses.cancelable) do |cancelable|
cancelable.each(&:cancel)
end
end
def retry_failed(user)
builds.latest.failed.select(&:retryable?).each do |build|
Ci::Build.retry(build, user)
Gitlab::OptimisticLocking.retry_lock(builds.latest.failed_or_canceled) do |failed|
failed.select(&:retryable?).each do |build|
Ci::Build.retry(build, user)
end
end
end
......
......@@ -73,6 +73,7 @@ module HasStatus
scope :skipped, -> { where(status: 'skipped') }
scope :running_or_pending, -> { where(status: [:running, :pending]) }
scope :finished, -> { where(status: [:success, :failed, :canceled]) }
scope :failed_or_canceled, -> { where(status: [:failed, :canceled]) }
scope :cancelable, -> do
where(status: [:running, :pending, :created])
......
......@@ -455,17 +455,74 @@ describe Ci::Pipeline, models: true do
end
describe '#cancel_running' do
let(:latest_status) { pipeline.statuses.pluck(:status) }
context 'when there is a running external job and created build' do
before do
create(:ci_build, :running, pipeline: pipeline)
create(:generic_commit_status, :running, pipeline: pipeline)
create(:ci_build, :created, pipeline: pipeline)
pipeline.cancel_running
end
it 'cancels both jobs' do
expect(pipeline.statuses.pluck(:status)).
to contain_exactly('canceled', 'canceled')
expect(latest_status).to contain_exactly('canceled', 'canceled')
end
end
context 'when builds are in different stages' do
before do
create(:ci_build, :running, stage_idx: 0, pipeline: pipeline)
create(:ci_build, :running, stage_idx: 1, pipeline: pipeline)
pipeline.cancel_running
end
it 'cancels both jobs' do
expect(latest_status).to contain_exactly('canceled', 'canceled')
end
end
end
describe '#retry_failed' do
let(:latest_status) { pipeline.statuses.latest.pluck(:status) }
context 'when there is a failed build and failed external status' do
before do
create(:ci_build, :failed, name: 'build', pipeline: pipeline)
create(:generic_commit_status, :failed, name: 'jenkins', pipeline: pipeline)
pipeline.retry_failed(nil)
end
it 'retries only build' do
expect(latest_status).to contain_exactly('pending', 'failed')
end
end
context 'when builds are in different stages' do
before do
create(:ci_build, :failed, name: 'build', stage_idx: 0, pipeline: pipeline)
create(:ci_build, :failed, name: 'jenkins', stage_idx: 1, pipeline: pipeline)
pipeline.retry_failed(nil)
end
it 'retries both builds' do
expect(latest_status).to contain_exactly('pending', 'pending')
end
end
context 'when there are canceled and failed' do
before do
create(:ci_build, :failed, name: 'build', stage_idx: 0, pipeline: pipeline)
create(:ci_build, :canceled, name: 'jenkins', stage_idx: 1, pipeline: pipeline)
pipeline.retry_failed(nil)
end
it 'retries both builds' do
expect(latest_status).to contain_exactly('pending', 'pending')
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