Commit 953e590b authored by Grzegorz Bizon's avatar Grzegorz Bizon

Make build clone/retry implementation more robust

parent 658c5f32
module Ci
class RetryBuildService < ::BaseService
CLONE_ATTRIBUTES = %i[pipeline ref tag options commands tag_list name
allow_failure stage stage_idx trigger_request
yaml_variables when environment coverage_regex]
.freeze
REJECT_ATTRIBUTES = %i[id status user token coverage trace runner
artifacts_file artifacts_metadata artifacts_size
created_at updated_at started_at finished_at
queued_at erased_by erased_at].freeze
IGNORE_ATTRIBUTES = %i[trace type lock_version project target_url
deploy job_id description].freeze
def execute(build)
reprocess(build).tap do |new_build|
build.pipeline.mark_as_processable_after_stage(build.stage_idx)
......@@ -17,24 +30,13 @@ module Ci
raise Gitlab::Access::AccessDeniedError
end
Ci::Build.create(
ref: build.ref,
tag: build.tag,
options: build.options,
commands: build.commands,
tag_list: build.tag_list,
project: build.project,
pipeline: build.pipeline,
name: build.name,
allow_failure: build.allow_failure,
stage: build.stage,
stage_idx: build.stage_idx,
trigger_request: build.trigger_request,
yaml_variables: build.yaml_variables,
when: build.when,
environment: build.environment,
coverage_regex: build.coverage_regex,
user: current_user)
attributes = CLONE_ATTRIBUTES.map do |attribute|
[attribute, build.send(attribute)]
end
attributes.push([:user, current_user])
project.builds.create(Hash[attributes])
end
end
end
......@@ -11,7 +11,7 @@ module SharedBuilds
step 'project has a recent build' do
@pipeline = create(:ci_empty_pipeline, project: @project, sha: @project.commit.sha, ref: 'master')
@build = create(:ci_build_with_coverage, pipeline: @pipeline)
@build = create(:ci_build, :coverage, pipeline: @pipeline)
end
step 'recent build is successful' do
......
......@@ -89,8 +89,9 @@ FactoryGirl.define do
tag true
end
factory :ci_build_with_coverage do
trait :coverage do
coverage 99.9
coverage_regex '/(d+)/'
end
trait :trace do
......@@ -99,6 +100,16 @@ FactoryGirl.define do
end
end
trait :erased do
erased_at Time.now
erased_by factory: :user
end
trait :queued do
queued_at Time.now
runner factory: :ci_runner
end
trait :artifacts do
after(:create) do |build, _|
build.artifacts_file =
......
......@@ -12,32 +12,36 @@ describe Ci::RetryBuildService, :services do
shared_examples 'build duplication' do
let(:build) do
create(:ci_build, :failed, :artifacts,
pipeline: pipeline,
coverage: 90.0,
coverage_regex: '/(d+)/')
create(:ci_build, :failed, :artifacts, :erased, :trace,
:queued, :coverage, pipeline: pipeline)
end
it 'clones expected attributes' do
clone_attributes = %w[ref tag project pipeline options commands tag_list
name allow_failure stage stage_idx trigger_request
yaml_variables when environment coverage_regex]
clone_attributes.each do |attribute|
describe 'clone attributes' do
described_class::CLONE_ATTRIBUTES.each do |attribute|
it "clones #{attribute} build attribute" do
expect(new_build.send(attribute)).to eq build.send(attribute)
end
end
end
it 'does not clone forbidden attributes' do
forbidden_attributes = %w[id status token user artifacts_file
artifacts_metadata coverage]
forbidden_attributes.each do |attribute|
describe 'reject attributes' do
described_class::REJECT_ATTRIBUTES.each do |attribute|
it "does not clone #{attribute} build attribute" do
expect(new_build.send(attribute)).not_to eq build.send(attribute)
end
end
end
it 'has correct number of known attributes' do
attributes =
described_class::CLONE_ATTRIBUTES +
described_class::IGNORE_ATTRIBUTES +
described_class::REJECT_ATTRIBUTES
expect(attributes.size).to eq build.attributes.size
end
end
describe '#execute' do
let(:new_build) { service.execute(build) }
......
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