discourse/script/promote_migrations

110 lines
2.8 KiB
Ruby
Executable File

#!/usr/bin/env ruby
# frozen_string_literal: true
# This script will promote post_migrate files
# which have existed for more than one Discourse
# stable version cycle.
#
# Renames will be staged in git, but not committed
#
# Usage:
# script/promote_migrations [--dry-run] [--plugins]
require 'open3'
require 'fileutils'
VERSION_REGEX = %r{\/(\d+)_}
DRY_RUN = !!ARGV.delete('--dry-run')
PLUGINS = false
if i = ARGV.find_index('--plugins-base')
ARGV.delete_at(i)
PLUGINS = true
PLUGINS_BASE = ARGV.delete_at(i)
elsif ARGV.delete('--plugins')
PLUGINS = true
PLUGINS_BASE = 'plugins'
end
raise "Unknown arguments: #{ARGV.join(', ')}" if ARGV.length > 0
def run(*args, capture: true)
out, s = Open3.capture2(*args)
if s.exitstatus != 0
STDERR.puts "Command failed: '#{args.join(' ')}'"
exit 1
end
out.strip
end
current_version = run 'git describe --abbrev=0 --match "v*"'
puts "Current version is #{current_version}"
run 'git fetch'
current_stable_version =
run 'git describe --abbrev=0 --match "v*" origin/stable'
puts "Current stable version is #{current_stable_version}"
minor = current_stable_version[/^(v\d+\.\d+)\./, 1]
previous_stable_version =
run "git describe --abbrev=0 --match 'v*' --exclude '#{minor}*' origin/stable"
puts "Previous stable version is #{previous_stable_version}"
stable_post_migrate_filenames =
run(
'git',
'ls-tree',
'--name-only',
'-r',
previous_stable_version,
'db/post_migrate'
).split("\n")
stable_post_migrate_filenames.sort!
latest_stable_post_migration = stable_post_migrate_filenames.last
puts "The latest core post_migrate file in #{previous_stable_version} is #{latest_stable_post_migration}"
puts 'Promoting this, and all earlier post_migrates, to regular migrations'
promote_threshold = latest_stable_post_migration[VERSION_REGEX, 1].to_i
current_post_migrations =
if PLUGINS
puts 'Looking in plugins...'
Dir.glob("#{PLUGINS_BASE}/**/db/post_migrate/*")
else
Dir.glob('db/post_migrate/*')
end
if current_post_migrations.length == 0
puts 'No post_migrate files found. All done'
end
current_post_migrations.each do |path|
version = path[VERSION_REGEX, 1].to_i
file = File.basename(path)
dir = File.dirname(path)
if version <= promote_threshold
print "Promoting #{path}..."
if DRY_RUN
puts ' (dry run)'
else
run 'mkdir', '-p', "#{dir}/../migrate"
run 'git', '-C', dir, 'mv', file, "../migrate/#{file}"
puts ' (done)'
end
end
end
puts 'Done! File moves are staged and ready for commit.'
puts 'Suggested commit message:'
puts '-' * 20
puts <<~TEXT
DEV: Promote historic post_deploy migrations
This commit promotes all post_deploy migrations which existed in Discourse #{previous_stable_version} (timestamp <= #{promote_threshold})
TEXT
puts '-' * 20