Make build clone/retry implementation more robust
This commit is contained in:
parent
658c5f32a3
commit
953e590b18
4 changed files with 54 additions and 37 deletions
|
@ -1,5 +1,18 @@
|
||||||
module Ci
|
module Ci
|
||||||
class RetryBuildService < ::BaseService
|
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)
|
def execute(build)
|
||||||
reprocess(build).tap do |new_build|
|
reprocess(build).tap do |new_build|
|
||||||
build.pipeline.mark_as_processable_after_stage(build.stage_idx)
|
build.pipeline.mark_as_processable_after_stage(build.stage_idx)
|
||||||
|
@ -17,24 +30,13 @@ module Ci
|
||||||
raise Gitlab::Access::AccessDeniedError
|
raise Gitlab::Access::AccessDeniedError
|
||||||
end
|
end
|
||||||
|
|
||||||
Ci::Build.create(
|
attributes = CLONE_ATTRIBUTES.map do |attribute|
|
||||||
ref: build.ref,
|
[attribute, build.send(attribute)]
|
||||||
tag: build.tag,
|
end
|
||||||
options: build.options,
|
|
||||||
commands: build.commands,
|
attributes.push([:user, current_user])
|
||||||
tag_list: build.tag_list,
|
|
||||||
project: build.project,
|
project.builds.create(Hash[attributes])
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ module SharedBuilds
|
||||||
|
|
||||||
step 'project has a recent build' do
|
step 'project has a recent build' do
|
||||||
@pipeline = create(:ci_empty_pipeline, project: @project, sha: @project.commit.sha, ref: 'master')
|
@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
|
end
|
||||||
|
|
||||||
step 'recent build is successful' do
|
step 'recent build is successful' do
|
||||||
|
|
|
@ -89,8 +89,9 @@ FactoryGirl.define do
|
||||||
tag true
|
tag true
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :ci_build_with_coverage do
|
trait :coverage do
|
||||||
coverage 99.9
|
coverage 99.9
|
||||||
|
coverage_regex '/(d+)/'
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :trace do
|
trait :trace do
|
||||||
|
@ -99,6 +100,16 @@ FactoryGirl.define do
|
||||||
end
|
end
|
||||||
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
|
trait :artifacts do
|
||||||
after(:create) do |build, _|
|
after(:create) do |build, _|
|
||||||
build.artifacts_file =
|
build.artifacts_file =
|
||||||
|
|
|
@ -12,30 +12,34 @@ describe Ci::RetryBuildService, :services do
|
||||||
|
|
||||||
shared_examples 'build duplication' do
|
shared_examples 'build duplication' do
|
||||||
let(:build) do
|
let(:build) do
|
||||||
create(:ci_build, :failed, :artifacts,
|
create(:ci_build, :failed, :artifacts, :erased, :trace,
|
||||||
pipeline: pipeline,
|
:queued, :coverage, pipeline: pipeline)
|
||||||
coverage: 90.0,
|
|
||||||
coverage_regex: '/(d+)/')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'clones expected attributes' do
|
describe 'clone attributes' do
|
||||||
clone_attributes = %w[ref tag project pipeline options commands tag_list
|
described_class::CLONE_ATTRIBUTES.each do |attribute|
|
||||||
name allow_failure stage stage_idx trigger_request
|
it "clones #{attribute} build attribute" do
|
||||||
yaml_variables when environment coverage_regex]
|
expect(new_build.send(attribute)).to eq build.send(attribute)
|
||||||
|
end
|
||||||
clone_attributes.each do |attribute|
|
|
||||||
expect(new_build.send(attribute)).to eq build.send(attribute)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not clone forbidden attributes' do
|
describe 'reject attributes' do
|
||||||
forbidden_attributes = %w[id status token user artifacts_file
|
described_class::REJECT_ATTRIBUTES.each do |attribute|
|
||||||
artifacts_metadata coverage]
|
it "does not clone #{attribute} build attribute" do
|
||||||
|
expect(new_build.send(attribute)).not_to eq build.send(attribute)
|
||||||
forbidden_attributes.each do |attribute|
|
end
|
||||||
expect(new_build.send(attribute)).not_to eq build.send(attribute)
|
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
|
|
Loading…
Reference in a new issue