From 503f21367051c18412d6bdf3d4586eaddaf69087 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Fri, 6 Oct 2017 11:45:23 +0200 Subject: Make sure that every job has a stage assigned --- app/models/commit_status.rb | 28 +++++++++++++++++++++- spec/models/commit_status_spec.rb | 50 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index f3888528940..7f2295dd4da 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -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 diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 858ec831200..6c94f463a6a 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -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 -- cgit v1.2.1