Merge branch 'osw-reset-merge-status-from-mergeable-mrs' into 'master'
Reset merge status from mergeable MRs See merge request gitlab-org/gitlab-ce!28843
This commit is contained in:
commit
3e4862ac6d
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Reset merge status from mergeable MRs
|
||||
merge_request: 28843
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class AddIndexToMergeRequestsStateAndMergeStatus < ActiveRecord::Migration[5.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_index :merge_requests, [:state, :merge_status],
|
||||
where: "state = 'opened' AND merge_status = 'can_be_merged'"
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index :merge_requests, [:state, :merge_status]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class EnqueueResetMergeStatus < ActiveRecord::Migration[5.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
BATCH_SIZE = 10_000
|
||||
MIGRATION = 'ResetMergeStatus'
|
||||
DELAY_INTERVAL = 5.minutes.to_i
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
say 'Scheduling `ResetMergeStatus` jobs'
|
||||
|
||||
# We currently have around 135_000 opened, mergeable MRs in GitLab.com. This iteration
|
||||
# will schedule around 13 batches of 10_000 MRs, which should take around 1 hour to
|
||||
# complete.
|
||||
relation = MergeRequest.where(state: 'opened', merge_status: 'can_be_merged')
|
||||
|
||||
relation.each_batch(of: BATCH_SIZE) do |batch, index|
|
||||
range = batch.pluck('MIN(id)', 'MAX(id)').first
|
||||
|
||||
BackgroundMigrationWorker.perform_in(index * DELAY_INTERVAL, MIGRATION, range)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20190527194900) do
|
||||
ActiveRecord::Schema.define(version: 20190530154715) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -1361,6 +1361,7 @@ ActiveRecord::Schema.define(version: 20190527194900) do
|
|||
t.index ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree
|
||||
t.index ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_and_branch_state_opened", where: "((state)::text = 'opened'::text)", using: :btree
|
||||
t.index ["source_project_id", "source_branch"], name: "index_merge_requests_on_source_project_id_and_source_branch", using: :btree
|
||||
t.index ["state", "merge_status"], name: "index_merge_requests_on_state_and_merge_status", where: "(((state)::text = 'opened'::text) AND ((merge_status)::text = 'can_be_merged'::text))", using: :btree
|
||||
t.index ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree
|
||||
t.index ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid", unique: true, using: :btree
|
||||
t.index ["target_project_id", "iid"], name: "index_merge_requests_on_target_project_id_and_iid_opened", where: "((state)::text = 'opened'::text)", using: :btree
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
# Updates the range of given MRs to merge_status "unchecked", if they're opened
|
||||
# and mergeable.
|
||||
class ResetMergeStatus
|
||||
def perform(from_id, to_id)
|
||||
relation = MergeRequest.where(id: from_id..to_id,
|
||||
state: 'opened',
|
||||
merge_status: 'can_be_merged')
|
||||
|
||||
relation.update_all(merge_status: 'unchecked')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Gitlab::BackgroundMigration::ResetMergeStatus, :migration, schema: 20190528180441 do
|
||||
let(:namespaces) { table(:namespaces) }
|
||||
let(:projects) { table(:projects) }
|
||||
let(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab-org') }
|
||||
let(:project) { projects.create(namespace_id: namespace.id, name: 'foo') }
|
||||
let(:merge_requests) { table(:merge_requests) }
|
||||
|
||||
def create_merge_request(id, extra_params = {})
|
||||
params = {
|
||||
id: id,
|
||||
target_project_id: project.id,
|
||||
target_branch: 'master',
|
||||
source_project_id: project.id,
|
||||
source_branch: 'mr name',
|
||||
title: "mr name#{id}"
|
||||
}.merge(extra_params)
|
||||
|
||||
merge_requests.create!(params)
|
||||
end
|
||||
|
||||
it 'correctly updates opened mergeable MRs to unchecked' do
|
||||
create_merge_request(1, state: 'opened', merge_status: 'can_be_merged')
|
||||
create_merge_request(2, state: 'opened', merge_status: 'can_be_merged')
|
||||
create_merge_request(3, state: 'opened', merge_status: 'can_be_merged')
|
||||
create_merge_request(4, state: 'merged', merge_status: 'can_be_merged')
|
||||
create_merge_request(5, state: 'opened', merge_status: 'cannot_be_merged')
|
||||
|
||||
subject.perform(1, 5)
|
||||
|
||||
expected_rows = [
|
||||
{ id: 1, state: 'opened', merge_status: 'unchecked' },
|
||||
{ id: 2, state: 'opened', merge_status: 'unchecked' },
|
||||
{ id: 3, state: 'opened', merge_status: 'unchecked' },
|
||||
{ id: 4, state: 'merged', merge_status: 'can_be_merged' },
|
||||
{ id: 5, state: 'opened', merge_status: 'cannot_be_merged' }
|
||||
]
|
||||
|
||||
rows = merge_requests.order(:id).map do |row|
|
||||
row.attributes.slice('id', 'state', 'merge_status').symbolize_keys
|
||||
end
|
||||
|
||||
expect(rows).to eq(expected_rows)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20190528180441_enqueue_reset_merge_status.rb')
|
||||
|
||||
describe EnqueueResetMergeStatus, :migration, :sidekiq do
|
||||
let(:namespaces) { table(:namespaces) }
|
||||
let(:projects) { table(:projects) }
|
||||
let(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab-org') }
|
||||
let(:project) { projects.create(namespace_id: namespace.id, name: 'foo') }
|
||||
let(:merge_requests) { table(:merge_requests) }
|
||||
|
||||
def create_merge_request(id, extra_params = {})
|
||||
params = {
|
||||
id: id,
|
||||
target_project_id: project.id,
|
||||
target_branch: 'master',
|
||||
source_project_id: project.id,
|
||||
source_branch: 'mr name',
|
||||
title: "mr name#{id}"
|
||||
}.merge(extra_params)
|
||||
|
||||
merge_requests.create!(params)
|
||||
end
|
||||
|
||||
it 'correctly schedules background migrations' do
|
||||
create_merge_request(1, state: 'opened', merge_status: 'can_be_merged')
|
||||
create_merge_request(2, state: 'opened', merge_status: 'can_be_merged')
|
||||
create_merge_request(3, state: 'opened', merge_status: 'can_be_merged')
|
||||
create_merge_request(4, state: 'merged', merge_status: 'can_be_merged')
|
||||
create_merge_request(5, state: 'opened', merge_status: 'unchecked')
|
||||
|
||||
stub_const("#{described_class.name}::BATCH_SIZE", 2)
|
||||
|
||||
Sidekiq::Testing.fake! do
|
||||
Timecop.freeze do
|
||||
migrate!
|
||||
|
||||
expect(described_class::MIGRATION)
|
||||
.to be_scheduled_delayed_migration(5.minutes, 1, 2)
|
||||
|
||||
expect(described_class::MIGRATION)
|
||||
.to be_scheduled_delayed_migration(10.minutes, 3, 3)
|
||||
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue