Make sure that every job has a stage assigned

This commit is contained in:
Grzegorz Bizon 2017-10-06 11:45:23 +02:00
parent 823a9d351b
commit 503f213670
2 changed files with 75 additions and 3 deletions

View file

@ -14,7 +14,6 @@ class CommitStatus < ActiveRecord::Base
delegate :sha, :short_sha, to: :pipeline
validates :pipeline, presence: true, unless: :importing?
validates :name, presence: true, unless: :importing?
alias_attribute :author, :user
@ -46,6 +45,21 @@ class CommitStatus < ActiveRecord::Base
runner_system_failure: 4
}
##
# We still create some CommitStatuses outside of CreatePipelineService.
#
# These are pages deployments and external statuses.
#
before_create do |status|
next if status.stage_id.present? || importing?
ensure_pipeline_stage! do |stage|
status.run_after_commit do
StageUpdateWorker.perform_async(stage.id)
end
end
end
state_machine :status do
event :process do
transition [:skipped, :manual] => :created
@ -174,4 +188,16 @@ class CommitStatus < ActiveRecord::Base
v =~ /\d+/ ? v.to_i : v
end
end
private
def ensure_pipeline_stage!
attributes = { name: stage, pipeline: pipeline, project: project }
Ci::Stage.create!(attributes).tap do |stage|
self.stage_id = stage.id
yield stage
end
end
end

View file

@ -1,9 +1,9 @@
require 'spec_helper'
describe CommitStatus do
let(:project) { create(:project, :repository) }
set(:project) { create(:project, :repository) }
let(:pipeline) do
set(:pipeline) do
create(:ci_pipeline, project: project, sha: project.commit.id)
end
@ -464,4 +464,50 @@ describe CommitStatus do
it { is_expected.to be_script_failure }
end
end
describe 'ensure stage assignment' do
context 'when commit status has a stage_id assigned' do
let!(:stage) do
create(:ci_stage_entity, project: project, pipeline: pipeline)
end
let(:commit_status) do
create(:commit_status, stage_id: stage.id, name: 'rspec', stage: 'test')
end
it 'does not create a new stage' do
expect { commit_status }.not_to change { Ci::Stage.count }
expect(commit_status.stage_id).to eq stage.id
end
end
context 'when commit status does not have a stage_id assigned' do
let(:commit_status) do
create(:commit_status, name: 'rspec', stage: 'test', status: :success)
end
let(:stage) { Ci::Stage.first }
it 'creates a new stage' do
expect { commit_status }.to change { Ci::Stage.count }.by(1)
expect(stage.name).to eq 'test'
expect(stage.project).to eq commit_status.project
expect(stage.pipeline).to eq commit_status.pipeline
expect(stage.status).to eq commit_status.status
expect(commit_status.stage_id).to eq stage.id
end
end
context 'when commit status is being imported' do
let(:commit_status) do
create(:commit_status, name: 'rspec', stage: 'test', importing: true)
end
it 'does not create a new stage' do
expect { commit_status }.not_to change { Ci::Stage.count }
expect(commit_status.stage_id).not_to be_present
end
end
end
end