Retry migration removing stages in case of duplicates

This commit is contained in:
Grzegorz Bizon 2018-02-05 16:22:19 +01:00
parent 5f57c7a5a5
commit b5c69ce3ab
2 changed files with 26 additions and 4 deletions

View File

@ -3,12 +3,15 @@ class RemoveRedundantPipelineStages < ActiveRecord::Migration
DOWNTIME = false
def up
remove_concurrent_index :ci_stages, [:pipeline_id, :name]
disable_ddl_transaction!
def up(attempts: 100)
remove_outdated_index!
remove_redundant_pipeline_stages!
add_concurrent_index :ci_stages, [:pipeline_id, :name], unique: true
add_unique_index!
rescue ActiveRecord::RecordNotUnique
retry if (attempts -= 1) > 0
raise
end
def down
@ -18,6 +21,16 @@ class RemoveRedundantPipelineStages < ActiveRecord::Migration
private
def remove_outdated_index!
return unless index_exists?(:ci_stages, [:pipeline_id, :name])
remove_concurrent_index :ci_stages, [:pipeline_id, :name]
end
def add_unique_index!
add_concurrent_index :ci_stages, [:pipeline_id, :name], unique: true
end
def remove_redundant_pipeline_stages!
redundant_stages_ids = <<~SQL
SELECT id FROM ci_stages WHERE (pipeline_id, name) IN (

View File

@ -36,4 +36,13 @@ describe RemoveRedundantPipelineStages, :migration do
expect(builds.all.count).to eq 6
expect(builds.all.pluck(:stage_id).compact).to eq [102]
end
it 'retries when duplicated stages are being created during migration' do
allow(subject).to receive(:remove_outdated_index!)
expect(subject).to receive(:remove_redundant_pipeline_stages!).exactly(3).times
allow(subject).to receive(:add_unique_index!)
.and_raise(ActiveRecord::RecordNotUnique.new('Duplicated stages present!'))
expect { subject.up(attempts: 3) }.to raise_error ActiveRecord::RecordNotUnique
end
end