discourse/script/promote_migrations
David Taylor 1d5d9646c6
DEV: Promote old post-deploy migrations to pre-deploy (#38595)
This promotes all post-migrations which existed in `v2026.1` to regular
pre-deploy migrations. We do this after each stable/esr release to
reduce the probability of pre/post deploy timing issues.
2026-03-13 19:09:30 +00:00

99 lines
2.6 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
# ESR 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
run "git fetch"
current_version = run 'git describe --abbrev=0 --match "v*"'
puts "Current version is #{current_version}"
current_esr_version = run 'git describe --abbrev=0 --match "v*" esr'
puts "Current esr version is #{current_esr_version}"
minor = current_esr_version[/^(v\d+\.\d+)\./, 1]
previous_esr_version = "#{minor}.0"
puts "Previous esr version is #{previous_esr_version}"
esr_post_migrate_filenames =
run("git", "ls-tree", "--name-only", "-r", previous_esr_version, "db/post_migrate").split("\n")
esr_post_migrate_filenames.sort!
latest_esr_post_migration = esr_post_migrate_filenames.last
puts "The latest core post_migrate file in #{previous_esr_version} is #{latest_esr_post_migration}"
puts "Promoting this, and all earlier post_migrates, to regular migrations"
promote_threshold = latest_esr_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
puts "No post_migrate files found. All done" if current_post_migrations.length == 0
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_esr_version} (timestamp <= #{promote_threshold})
TEXT
puts "-" * 20