diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 12e187024dd3a35ddfa7da23d9733093630b58b7..6b07dbdf3ea4d3dcd107f0ac9b37b1da28707404 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -50,13 +50,9 @@ class CommitStatus < ActiveRecord::Base # # 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 + before_create unless: :importing? do + Ci::EnsureStageService.new(project, user).execute(self) do |stage| + self.run_after_commit { StageUpdateWorker.perform_async(stage.id) } end end @@ -188,24 +184,4 @@ class CommitStatus < ActiveRecord::Base v =~ /\d+/ ? v.to_i : v end end - - private - - def ensure_pipeline_stage! - (find_stage || create_stage!).tap do |stage| - self.stage_id = stage.id - - yield stage - end - end - - def find_stage - pipeline.stages.find_by(name: stage) - end - - def create_stage! - Ci::Stage.create!(name: stage, - pipeline: pipeline, - project: project) - end end diff --git a/app/services/ci/ensure_stage_service.rb b/app/services/ci/ensure_stage_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..dc2f49e8db13641d550667dcf71f3c7986fea307 --- /dev/null +++ b/app/services/ci/ensure_stage_service.rb @@ -0,0 +1,39 @@ +module Ci + ## + # We call this service everytime we persist a CI/CD job. + # + # In most cases a job should already have a stage assigned, but in cases it + # doesn't have we need to either find existing one or create a brand new + # stage. + # + class EnsureStageService < BaseService + def execute(build) + @build = build + + return if build.stage_id.present? + return if build.invalid? + + ensure_stage.tap do |stage| + build.stage_id = stage.id + + yield stage if block_given? + end + end + + private + + def ensure_stage + find_stage || create_stage + end + + def find_stage + @build.pipeline.stages.find_by(name: @build.stage) + end + + def create_stage + Ci::Stage.create!(name: @build.stage, + pipeline: @build.pipeline, + project: @build.project) + end + end +end diff --git a/spec/factories/commit_statuses.rb b/spec/factories/commit_statuses.rb index 169590deb8ead521b07e6d157a623dfb38e5905d..abbe37df90efda910e5892250cb9b2a3d4fec152 100644 --- a/spec/factories/commit_statuses.rb +++ b/spec/factories/commit_statuses.rb @@ -1,6 +1,7 @@ FactoryGirl.define do factory :commit_status, class: CommitStatus do name 'default' + stage 'test' status 'success' description 'commit status' pipeline factory: :ci_pipeline_with_one_job