Disallow migrations with the wrong versions

This custom Rubocop ensures that we don't end up with migrations that
are too new for Solidus's minimum required Rails version.

This has happened a few times lately. See #6192 and #6220 for more
context. It would be nice to avoid conflicts like these in an automated
way.
This commit is contained in:
benjamin wil 2025-04-17 14:16:55 -07:00
parent 68cb0c6354
commit 7d1a43d369
5 changed files with 87 additions and 1 deletions

View File

@ -5,6 +5,7 @@ inherit_from: .rubocop_todo.yml
require:
- rubocop-performance
- rubocop-rails
- ./tasks/linting/wrong_migration_version.rb
AllCops:
Exclude:

View File

@ -5,6 +5,8 @@ module Spree
def self.solidus_version = VERSION
def self.minimum_required_rails_version = "7.0"
def self.previous_solidus_minor_version = "4.5"
def self.solidus_gem_version = Gem::Version.new(solidus_version)

View File

@ -27,7 +27,10 @@ Gem::Specification.new do |s|
actionmailer actionpack actionview activejob activemodel activerecord
activestorage activesupport railties
].each do |rails_dep|
s.add_dependency rails_dep, ['>= 7.0', '< 8.1.0.beta1']
s.add_dependency rails_dep, [
">= #{Spree.minimum_required_rails_version}",
"< 8.1.0.beta1"
]
end
s.add_dependency 'activemerchant', '~> 1.66'

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
require_relative '../../core/lib/spree/core/version'
module Solidus
class WrongMigrationVersion < RuboCop::Cop::Base
MSG = "Subclasses of ActiveRecord::Migration must use a migration version " \
"of <= #{Spree.minimum_required_rails_version}"
def on_class(node)
return unless (superclass = node.parent_class)
return unless superclass.source&.start_with?("ActiveRecord::Migration")
return unless (given_version_arg = superclass.arguments.first&.value)
unless meets_solidus_minimum_required_rails_version? given_version_arg
add_offense node, message: MSG
end
end
private
def meets_solidus_minimum_required_rails_version?(version_argument)
Gem::Version.new(version_argument) <=
Gem::Version.new(Spree.minimum_required_rails_version)
end
end
end

View File

@ -0,0 +1,53 @@
# frozen_string_literal: true
require "rubocop"
require "rubocop/rspec/support"
require_relative "wrong_migration_version"
RSpec.describe Solidus::WrongMigrationVersion do
include RuboCop::RSpec::ExpectOffense
subject(:cop) { described_class.new RuboCop::Config.new }
it "finds migration versions greater than the Solidus minimum required Rails version offensive" do
greater_than_minimum_version = Gem::Version
.new(Spree.minimum_required_rails_version)
.bump
.to_s
expect_offense(<<~RUBY)
class TestMigration < ActiveRecord::Migration[#{greater_than_minimum_version}]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Solidus/WrongMigrationVersion: Subclasses of ActiveRecord::Migration must use a migration version of <= 7.0
end
RUBY
end
it "finds migration versions less than the Solidus minimum required Rails version inoffensive" do
expect_no_offenses(<<~RUBY)
class TestMigration < ActiveRecord::Migration[3.0]
end
RUBY
end
it "finds migration versions equal to the Solidus minimum required Rails version inoffensive" do
expect_no_offenses(<<~RUBY)
class TestMigration < ActiveRecord::Migration[#{Spree.minimum_required_rails_version}]
end
RUBY
end
it "finds non-migration classes inoffensive" do
expect_no_offenses(<<~RUBY)
class NotAMigration
end
RUBY
end
it "finds non-migration subclasses inoffensive" do
expect_no_offenses(<<~RUBY)
class SubclassOfNotAMigration < NotAMigration
end
RUBY
end
end