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