Compare commits

...

1 commit

Author SHA1 Message Date
022ac59467 fix migrator
- rename migration so it happens first
- postdeployment database migrator now migrates database and data migrations in chronological order
2025-02-18 01:46:08 -08:00
2 changed files with 72 additions and 60 deletions

View file

@ -6,6 +6,25 @@ module PostDeployment
class DatabaseMigrator class DatabaseMigrator
include LoggingHelper include LoggingHelper
class CombinedMigration
attr_reader :version, :name, :migration, :type
def initialize(version, name, migration, type)
@version = version
@name = name
@migration = migration
@type = type
end
def schema_migration?
@type == :schema
end
def data_migration?
@type == :data
end
end
def initialize(test_mode:, verbose:) def initialize(test_mode:, verbose:)
@test_mode = test_mode @test_mode = test_mode
@verbose = verbose @verbose = verbose
@ -18,92 +37,85 @@ module PostDeployment
if @test_mode if @test_mode
simulate_migrations simulate_migrations
else else
perform_migrations_in_order perform_migrations
end end
end end
private private
def simulate_migrations def collect_pending_migrations
log_step "TEST MODE: Would run pending migrations..." # Collect schema migrations
schema_context = ActiveRecord::Base.connection.pool.migration_context
schema_migrations = schema_context.migrations.map do |migration|
CombinedMigration.new(
migration.version,
migration.name,
migration,
:schema
)
end
# Check schema migrations # Collect data migrations
pending_schema_migrations = ActiveRecord::Base.connection.pool.migration_context.needs_migration?
schema_migrations = ActiveRecord::Base.connection.pool.migration_context.migrations
# Check data migrations
data_migrations_path = DataMigrate.config.data_migrations_path data_migrations_path = DataMigrate.config.data_migrations_path
data_migration_context = DataMigrate::MigrationContext.new(data_migrations_path) data_migration_context = DataMigrate::MigrationContext.new(data_migrations_path)
pending_data_migrations = data_migration_context.needs_migration? data_migrations = data_migration_context.migrations.map do |migration|
data_migrations = data_migration_context.migrations CombinedMigration.new(
migration.version,
migration.name,
migration,
:data
)
end
if pending_schema_migrations || pending_data_migrations # Combine and sort all migrations by version
if schema_migrations.any? (schema_migrations + data_migrations).sort_by(&:version)
log_step "Would apply #{schema_migrations.size} pending schema migrations:" end
schema_migrations.each do |migration|
log_step "#{migration.name}"
end
end
if data_migrations.any? def simulate_migrations
log_step "\nWould apply #{data_migrations.size} pending data migrations:" pending_migrations = collect_pending_migrations
data_migrations.each do |migration|
log_step "#{migration.name}" if pending_migrations.any?
end log_step "TEST MODE: Would run #{pending_migrations.size} pending migrations in this order:"
pending_migrations.each do |migration|
type = migration.schema_migration? ? 'schema' : 'data'
log_step " • [#{type}] #{migration.name} (#{migration.version})"
end end
else else
log_step "No pending migrations." log_step 'No pending migrations.'
end end
end end
def perform_migrations def perform_migrations
ActiveRecord::Migration.verbose = @verbose ActiveRecord::Migration.verbose = @verbose
pending_migrations = collect_pending_migrations
# Run schema migrations return log_step 'No pending migrations.' if pending_migrations.empty?
schema_version = ActiveRecord::Base.connection.pool.migration_context.current_version
ActiveRecord::Tasks::DatabaseTasks.migrate
new_schema_version = ActiveRecord::Base.connection.pool.migration_context.current_version
# Run data migrations schema_context = ActiveRecord::Base.connection.pool.migration_context
data_migrations_path = DataMigrate.config.data_migrations_path data_context = DataMigrate::MigrationContext.new(DataMigrate.config.data_migrations_path)
data_migration_context = DataMigrate::MigrationContext.new(data_migrations_path)
data_version = data_migration_context.current_version initial_schema_version = schema_context.current_version
data_migration_context.migrate initial_data_version = data_context.current_version
new_data_version = data_migration_context.current_version
if schema_version == new_schema_version && data_version == new_data_version pending_migrations.each do |combined_migration|
log_step "No pending migrations." if combined_migration.schema_migration?
else # Execute schema migration using Rails migration context
if schema_version != new_schema_version schema_context.run(:up, combined_migration.version)
log_step "Migrated schema from version #{schema_version} to #{new_schema_version}" else
end # Execute data migration using data-migrate context
if data_version != new_data_version data_context.run(:up, combined_migration.version)
log_step "Migrated data from version #{data_version} to #{new_data_version}"
end end
end end
end
def perform_migrations_in_order final_schema_version = schema_context.current_version
schema_context = ActiveRecord::Base.connection.migration_context final_data_version = data_context.current_version
schema_migrations = schema_context.migrations
data_migrations_path = DataMigrate.config.data_migrations_path if initial_schema_version != final_schema_version
data_context = DataMigrate::MigrationContext.new(data_migrations_path) log_step "Migrated schema from version #{initial_schema_version} to #{final_schema_version}"
data_migrations = data_context.migrations end
all_migrations = (schema_migrations + data_migrations).sort_by(&:version) if initial_data_version != final_data_version
log_step "Migrated data from version #{initial_data_version} to #{final_data_version}"
all_migrations.each do |migration|
if migration.filename.start_with?(data_migrations_path)
say "Running data migration: #{migration.name}"
# Run the data migration (you might need to call `data_context.run(migration)` or similar)
data_context.run(migration)
else
say "Running schema migration: #{migration.name}"
# Run the schema migration (Rails will handle this for you)
schema_context.run(migration)
end
end end
end end
end end