Commit cf516851 authored by Matija Čupić's avatar Matija Čupić

Refactor bridge status update logic

Refactors the bridge status update logic to be centralized in one single
place.
parent 5ee1bd04
...@@ -329,7 +329,7 @@ module Ci ...@@ -329,7 +329,7 @@ module Ci
end end
def self.bridgeable_statuses def self.bridgeable_statuses
::Ci::Pipeline.all_statuses - [:created, :preparing, :pending] ::Ci::Pipeline::AVAILABLE_STATUSES - %w[created preparing pending]
end end
def stages_count def stages_count
......
...@@ -72,10 +72,6 @@ module HasStatus ...@@ -72,10 +72,6 @@ module HasStatus
def completed_statuses def completed_statuses
COMPLETED_STATUSES.map(&:to_sym) COMPLETED_STATUSES.map(&:to_sym)
end end
def all_statuses
AVAILABLE_STATUSES.map(&:to_sym)
end
end end
included do included do
......
...@@ -97,7 +97,7 @@ module EE ...@@ -97,7 +97,7 @@ module EE
end end
end end
after_transition any => ::Ci::Pipeline.bridgeable_statuses do |pipeline| after_transition any => ::Ci::Pipeline.bridgeable_statuses.map(&:to_sym) do |pipeline|
next unless pipeline.downstream_bridges.any? next unless pipeline.downstream_bridges.any?
pipeline.run_after_commit do pipeline.run_after_commit do
......
...@@ -6,26 +6,13 @@ module Ci ...@@ -6,26 +6,13 @@ module Ci
def execute(pipeline) def execute(pipeline)
pipeline.downstream_bridges.each do |bridge| pipeline.downstream_bridges.each do |bridge|
process_bridge(pipeline.status, bridge) bridge.save! if self.class.process_bridge(pipeline.status, bridge)
end end
end end
def process_bridge(status, bridge) def self.process_bridge(status, bridge)
case status if ::Ci::Pipeline.bridgeable_statuses.include?(status)
when 'success' bridge.status = status
bridge.success!
when 'failed'
bridge.drop!
when 'canceled'
bridge.cancel!
when 'skipped'
bridge.skip!
when 'running'
bridge.run!
when 'manual'
bridge.update(status: 'manual')
when 'scheduled'
bridge.update(status: 'scheduled')
else else
raise InvalidUpstreamStatusError raise InvalidUpstreamStatusError
end end
......
...@@ -19,13 +19,13 @@ module Ci ...@@ -19,13 +19,13 @@ module Ci
return unless upstream_pipeline return unless upstream_pipeline
bridge_updates = { upstream_pipeline: upstream_pipeline } bridge.upstream_pipeline = upstream_pipeline
if ::Ci::Pipeline.bridgeable_statuses.include?(upstream_pipeline.status.to_sym) if ::Ci::Pipeline.bridgeable_statuses.include?(upstream_pipeline.status)
bridge_updates[:status] = upstream_pipeline.status ::Ci::PipelineBridgeStatusService.process_bridge(upstream_pipeline.status, bridge)
end end
bridge.update!(bridge_updates) bridge.save!
end end
private private
......
...@@ -5,40 +5,68 @@ require 'spec_helper' ...@@ -5,40 +5,68 @@ require 'spec_helper'
describe Ci::PipelineBridgeStatusService do describe Ci::PipelineBridgeStatusService do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, status, project: project) } let(:pipeline) { create(:ci_pipeline, status: status, project: project) }
describe '#execute' do describe '#execute' do
subject { described_class.new(project, user).execute(pipeline) } subject { described_class.new(project, user).execute(pipeline) }
context 'when pipeline has bridged jobs' do context 'when pipeline has bridged jobs' do
let(:bridge) { create(:ci_bridge, status: :pending) } let(:bridge) { create(:ci_bridge, status: 'pending') }
before do before do
pipeline.downstream_bridges << bridge pipeline.downstream_bridges << bridge
end end
context 'when pipeline has the same status as the bridge' do
let(:status) { 'running' }
before do
bridge.status = 'running'
end
it 'does not update the bridge status' do
expect { subject }.not_to change { bridge.status }
end
it 'does not save the bridge' do
expect(bridge).not_to receive(:save!)
end
end
context 'when pipeline starts running' do context 'when pipeline starts running' do
let(:status) { :running } let(:status) { 'running' }
it 'updates the bridge status with the pipeline status' do it 'updates the bridge status with the pipeline status' do
expect { subject }.to change { bridge.status }.from('pending').to('running') expect { subject }.to change { bridge.status }.from('pending').to('running')
end end
it 'persists the status change' do
expect(bridge).to be_persisted
end
end end
context 'when pipeline succeeds' do context 'when pipeline succeeds' do
let(:status) { :success } let(:status) { 'success' }
it 'updates the bridge status with the pipeline status' do it 'updates the bridge status with the pipeline status' do
expect { subject }.to change { bridge.status }.from('pending').to('success') expect { subject }.to change { bridge.status }.from('pending').to('success')
end end
it 'persists the status change' do
expect(bridge).to be_persisted
end
end end
context 'when pipeline gets blocked' do context 'when pipeline gets blocked' do
let(:status) { :blocked } let(:status) { 'manual' }
it 'updates the bridge status with the pipeline status' do it 'updates the bridge status with the pipeline status' do
expect { subject }.to change { bridge.status }.from('pending').to('manual') expect { subject }.to change { bridge.status }.from('pending').to('manual')
end end
it 'persists the status change' do
expect(bridge).to be_persisted
end
end end
end end
end end
......
...@@ -1929,6 +1929,13 @@ describe Ci::Pipeline, :mailer do ...@@ -1929,6 +1929,13 @@ describe Ci::Pipeline, :mailer do
it { is_expected.to be_an(Array) } it { is_expected.to be_an(Array) }
end end
describe '.bridgeable_statuses' do
subject { described_class.bridgeable_statuses }
it { is_expected.to be_an(Array) }
it { is_expected.not_to include('created', 'preparing', 'pending') }
end
describe '#status' do describe '#status' do
let(:build) do let(:build) do
create(:ci_build, :created, pipeline: pipeline, name: 'test') create(:ci_build, :created, pipeline: pipeline, name: 'test')
......
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