diff options
Diffstat (limited to 'scripts/decomposition/generate-loose-foreign-key')
-rwxr-xr-x | scripts/decomposition/generate-loose-foreign-key | 138 |
1 files changed, 20 insertions, 118 deletions
diff --git a/scripts/decomposition/generate-loose-foreign-key b/scripts/decomposition/generate-loose-foreign-key index 35f84c64ce1..3f4c510020a 100755 --- a/scripts/decomposition/generate-loose-foreign-key +++ b/scripts/decomposition/generate-loose-foreign-key @@ -6,10 +6,8 @@ require 'optparse' $options = { - milestone: "#{Gitlab.version_info.major}.#{Gitlab.version_info.minor}", cross_schema: false, dry_run: false, - branch: true, rspec: true } @@ -24,18 +22,10 @@ OptionParser.new do |opts| $options[:dry_run] = v end - opts.on("-b", "--[no-]branch", "Create or not a new branch") do |v| - $options[:branch] = v - end - opts.on("-r", "--[no-]rspec", "Create or not a rspecs automatically") do |v| $options[:rspec] = v end - opts.on("-m", "--milestone MILESTONE", "Specify custom milestone (current: #{$options[:milestone]})") do |v| - $options[:milestone] = v - end - opts.on("-h", "--help", "Prints this help") do puts opts exit @@ -50,9 +40,7 @@ unless system("git diff --quiet") raise "There are uncommitted changes. Commit to continue." end -if Gitlab::Database.database_base_models.many? - raise 'Cannot run in multiple-databases mode. Use only `main:` in `config/database.yml`.' -end +$files_affected = [] puts "Re-creating current test database" ActiveRecord::Tasks::DatabaseTasks.drop_current @@ -86,6 +74,18 @@ def exec_cmd(*args, fail: nil) false end +def write_file(file_path, content) + $files_affected << file_path + File.write(file_path, content) +end + +def print_files_affected + puts "The following files have been generated/modified:" + $files_affected.each do |filepath| + puts filepath + end +end + def has_lfk?(definition) Gitlab::Database::LooseForeignKeys.definitions.any? do |lfk_definition| lfk_definition.from_table == definition.from_table && @@ -147,12 +147,10 @@ def add_definition_to_yaml(definition) end # emulate existing formatting - File.write( + write_file( Rails.root.join('config/gitlab_loose_foreign_keys.yml'), content.to_yaml.gsub(/^([- ] )/, ' \1') ) - - exec_cmd("git", "add", "config/gitlab_loose_foreign_keys.yml") end def generate_migration(definition) @@ -185,12 +183,9 @@ def generate_migration(definition) end EOF - File.write(migration_name, content) + write_file(migration_name, content) - exec_cmd("git", "add", migration_name, fail: "Failed to add migration file.") exec_cmd("bin/rails", "db:migrate", fail: "Failed to run db:migrate.") - exec_cmd("git", "add", "db/schema_migrations/#{timestamp}", "db/structure.sql", fail: "There are uncommitted changes. We should not have any.") - exec_cmd("git diff --exit-code --name-only", fail: "There are uncommitted changes. We should not have any.") end def class_by_table_name @@ -232,33 +227,7 @@ def add_test_to_specs(definition) lines = File.readlines(spec_path) insert_line = lines.count - 1 lines.insert(insert_line, "\n", *spec_test.lines) - File.write(spec_path, lines.join("")) - - # find a matching line - test_lines = (1..lines.count).select do |line| - lines[line-1].include?("it_behaves_like 'cleanup by a loose foreign key' do") - end.join(":") - - loop do - if system("bin/rspec", "#{spec_path}:#{test_lines}") - puts "Test seems fine?" - break - end - - puts "--------------------------------------------------" - puts "Test failed:" - puts "Edit: vim #{spec_path} (lines #{test_lines})" - puts "Re-run: bin/rspec #{spec_path}:#{test_lines}" - puts "--------------------------------------------------" - puts "Running bash. To exit do 'Ctrl-D' to re-run, or do 'Ctrl-C' to break (and ignore failure)." - puts - - unless exec_cmd("bash") - break - end - end - - exec_cmd("git", "add", spec_path, fail: "There are uncommitted changes. We should not have any.") + write_file(spec_path, lines.join("")) end def update_no_cross_db_foreign_keys_spec(definition) @@ -274,76 +243,7 @@ def update_no_cross_db_foreign_keys_spec(definition) return end - File.write(spec_path, updated.join("")) - exec_cmd("git", "add", spec_path, fail: "Failed to add changes from #{spec_path}") -end - -def commit_changes(definition) - branch_name = "remove-#{definition.to_table}_#{definition.from_table}_#{definition.column}-fk" - commit_title = "Swap FK #{definition.from_table} to #{definition.to_table} for LFK" - mr_title = "Swap FK #{definition.from_table}.#{definition.column} to #{definition.to_table} for LFK" - description = <<-EOF.strip_heredoc - Swaps FK for #{definition.from_table}.#{definition.column} to #{definition.to_table} - - Changelog: changed - EOF - - commit_message = "#{commit_title}\n\n#{description}" - - existing_branch = %x[git rev-parse --abbrev-ref HEAD].strip - - if $options[:branch] - unless exec_cmd("git", "checkout", "-b", branch_name) - raise "Failed to create branch: #{branch_name}" - end - end - - unless exec_cmd("git", "commit", "-m", commit_message) - raise "Failed to commit changes." - end - - if $options[:branch] - exec_cmd("git", "push", "origin", "-u", "HEAD", - "-o", "merge_request.create", - "-o", "merge_request.target=#{existing_branch}", - "-o", "merge_request.milestone=#{$options[:milestone]}", - "-o", "merge_request.title=#{mr_title}" - ) - - puts - puts "--------------------------------------------------" - puts "Put this as MR description:" - puts "--------------------------------------------------" - puts <<-EOF.strip_heredoc - ## What does this MR do and why? - - Per https://gitlab.com/groups/gitlab-org/-/epics/7249 - - As part of our CI "decomposition" efforts we need to remove all foreign keys that are cross-database (ie. between the planned \`main\` and \`ci\` databases). We are going to replace them all with ["loose foreign keys"](https://docs.gitlab.com/ee/development/database/loose_foreign_keys.html). - - Related: <DETAIL> - - ## Validations - - - **Best team to review (check off when reviewed):** TBD - - [ ] No way for user to access once parent is deleted. Please explain: <DETAIL> - - [ ] Possible to access once parent deleted but low user impact. Please explain: <DETAIL> - - [ ] Possible Sidekiq workers that may load directly and possibly lead to exceptions. Please explain: <DETAIL> - - [ ] Possible user impact to be evaluated or mitigated. Please explain: <DETAIL> - - [ ] Is this FK safe to be removed to avoid LOCKing problems? (Explanation: https://gitlab.com/groups/gitlab-org/-/epics/7249#note_819662046). Please explain: <DETAIL> - - ## MR acceptance checklist - - This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability. - - * [ ] I have evaluated the [MR acceptance checklist](https://docs.gitlab.com/ee/development/code_review.html#acceptance-checklist) for this MR. - - /label ~"ci-decomposition::phase4" ~"database::review pending" ~"devops::enablement" ~"group::sharding" ~"section::enablement" ~"sharding::active" ~"type::feature" ~"workflow::in dev" ~backend ~"ci-decomposition" ~database ~"Category:Sharding" - /milestone %"#{$options[:milestone]}" - /assign_reviewer @ahegyi - EOF - puts "--------------------------------------------------" - end + write_file(spec_path, updated.join("")) end all_foreign_keys = ActiveRecord::Base.connection.tables.flat_map do |table| @@ -400,6 +300,8 @@ all_foreign_keys.each_with_index do |definition, idx| generate_migration(definition) add_test_to_specs(definition) update_no_cross_db_foreign_keys_spec(definition) - commit_changes(definition) end + +print_files_affected + puts |