Commit 52ce8d7b authored by Furkan Ayhan's avatar Furkan Ayhan Committed by Fabio Pitino

Extract Pipeline add-job service to remove duplicate logic

We are using the same logic in three difference places, and here
we are unifying the usage.
parent 715fc55a
# frozen_string_literal: true
module Ci
module PipelineCreation
class AddJobService
attr_reader :pipeline
def initialize(pipeline)
@pipeline = pipeline
raise "Pipeline must be persisted for this service to be used" unless @pipeline.persisted?
end
def execute(job, save: true)
assign_pipeline_attributes(job)
Ci::Pipeline.transaction do
BulkInsertableAssociations.with_bulk_insert { job.save! } if save
job.update_older_statuses_retried! if Feature.enabled?(:ci_fix_commit_status_retried, @pipeline.project, default_enabled: :yaml)
end
job
end
private
def assign_pipeline_attributes(job)
# these also ensures other invariants such as
# a job takes project and ref from the pipeline it belongs to
job.pipeline = @pipeline
job.project = @pipeline.project
job.ref = @pipeline.ref
end
end
end
end
......@@ -34,18 +34,11 @@ module Ci
def reprocess!(build)
check_access!(build)
attributes = self.class.clone_accessors.to_h do |attribute|
[attribute, build.public_send(attribute)] # rubocop:disable GitlabSecurity/PublicSend
end
new_build = clone_build(build)
::Ci::PipelineCreation::AddJobService.new(build.pipeline).execute(new_build)
build.reset # refresh the data to get new values of `retried` and `processed`.
attributes[:user] = current_user
Ci::Build.transaction do
create_build!(attributes).tap do |new_build|
new_build.update_older_statuses_retried!
build.reset # refresh the data to get new values of `retried` and `processed`.
end
end
new_build
end
# rubocop: enable CodeReuse/ActiveRecord
......@@ -59,13 +52,19 @@ module Ci
def check_assignable_runners!(build); end
def create_build!(attributes)
build = project.builds.new(attributes)
build.assign_attributes(::Gitlab::Ci::Pipeline::Seed::Build.environment_attributes_for(build))
BulkInsertableAssociations.with_bulk_insert do
build.save!
def clone_build(build)
project.builds.new(build_attributes(build)).tap do |new_build|
new_build.assign_attributes(::Gitlab::Ci::Pipeline::Seed::Build.environment_attributes_for(new_build))
end
build
end
def build_attributes(build)
attributes = self.class.clone_accessors.to_h do |attribute|
[attribute, build.public_send(attribute)] # rubocop:disable GitlabSecurity/PublicSend
end
attributes[:user] = current_user
attributes
end
end
end
......
......@@ -31,8 +31,9 @@ module Projects
register_attempt
# Create status notifying the deployment of pages
@status = create_status
@status.update_older_statuses_retried! if Feature.enabled?(:ci_fix_commit_status_retried, project, default_enabled: :yaml)
@status = build_commit_status
::Ci::PipelineCreation::AddJobService.new(@build.pipeline).execute(@status)
@status.enqueue!
@status.run!
......@@ -70,12 +71,9 @@ module Projects
super
end
def create_status
def build_commit_status
GenericCommitStatus.new(
project: project,
pipeline: build.pipeline,
user: build.user,
ref: build.ref,
stage: 'deploy',
name: 'pages:deploy'
)
......
......@@ -100,7 +100,7 @@ module API
status.assign_attributes(attributes_for_keys(updatable_optional_attributes))
if status.valid?
status.update_older_statuses_retried! if Feature.enabled?(:ci_fix_commit_status_retried, user_project, default_enabled: :yaml)
::Ci::PipelineCreation::AddJobService.new(pipeline).execute(status, save: false)
else
render_validation_error!(status)
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::PipelineCreation::AddJobService do
let_it_be(:pipeline) { create(:ci_pipeline) }
let(:job) { build(:ci_build) }
subject(:service) { described_class.new(pipeline) }
context 'when the pipeline is not persisted' do
let(:pipeline) { build(:ci_pipeline) }
it 'raises error' do
expect { service }.to raise_error('Pipeline must be persisted for this service to be used')
end
end
it 'assigns pipeline attributes to the job' do
expect do
service.execute(job)
end.to change { job.slice(:pipeline, :project, :ref) }.to(
pipeline: pipeline, project: pipeline.project, ref: pipeline.ref
)
end
it 'returns the job itself' do
expect(service.execute(job)).to eq(job)
end
it 'calls update_older_statuses_retried!' do
expect(job).to receive(:update_older_statuses_retried!)
service.execute(job)
end
context 'when the FF ci_fix_commit_status_retried is disabled' do
before do
stub_feature_flags(ci_fix_commit_status_retried: false)
end
it 'does not call update_older_statuses_retried!' do
expect(job).not_to receive(:update_older_statuses_retried!)
service.execute(job)
end
end
end
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