mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 19:54:41 +08:00
49f39434c4
Post-deploy migrations exist to allow for seamless Discourse upgrades. By design, they cause migrations to run out of numerical order. This has the potential to cause some unexpected edge cases. To reduce the likelihood of these edge cases, we will promote historical post_deploy migrations to regular migrations after a full Discourse stable release cycle. This script is intended to be run at least during every Discourse release cycle. This means that truly seamless upgrades will not be possible between non-consecutive Discourse versions. (Upgrades will still work, but may cause some server errors for users during the upgrade)
98 lines
2.5 KiB
Ruby
Executable File
98 lines
2.5 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.include? '--dry-run'
|
|
PLUGINS = ARGV.include? '--plugins'
|
|
|
|
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/*/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 <<~MESSAGE
|
|
DEV: Promote historic post_deploy migrations
|
|
|
|
This commit promotes all post_deploy migrations which existed in Discourse #{previous_stable_version} (timestamp <= #{promote_threshold})
|
|
MESSAGE
|
|
puts '-' * 20
|
|
|