summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-10-06 11:45:23 +0200
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-11-06 11:04:09 +0100
commit503f21367051c18412d6bdf3d4586eaddaf69087 (patch)
tree489c5a40f3660969dc729e6da2f44a410f301126
parent823a9d351b49a6be8c12cfe06edb4aa6ec08fe95 (diff)
downloadgitlab-ce-503f21367051c18412d6bdf3d4586eaddaf69087.tar.gz
Make sure that every job has a stage assigned
-rw-r--r--app/models/commit_status.rb28
-rw-r--r--spec/models/commit_status_spec.rb50
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