Boot on rails 7.1

Change-Id: Ib5b0ec7e617b02b7edd9d2bf72204186169f22d4
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/336192
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Build-Review: Cody Cutrer <cody@instructure.com>
QA-Review: Jacob Burroughs <jburroughs@instructure.com>
Product-Review: Jacob Burroughs <jburroughs@instructure.com>
This commit is contained in:
Jacob Burroughs 2024-01-02 09:55:28 -06:00
parent 15e0e620de
commit 1f7cf9237b
21 changed files with 1520 additions and 58 deletions

View File

@ -31,7 +31,7 @@ if Bundler.default_gemfile == gemfile
if rails_version == SUPPORTED_RAILS_VERSIONS.first
lockfile = nil unless include_plugins
elsif include_plugins
parent = "rails#{rails_versions.delete(".")}"
parent = "rails#{rails_version.delete(".")}"
end
active = rails_version == $canvas_rails && !!include_plugins

View File

@ -20,7 +20,7 @@
# NOTE: Indented gems are meant to indicate optional dependencies of parent gems
gem "bootsnap", "~> 1.16", require: false
gem "rails", "~> 7.0.4"
gem "rails", ($canvas_rails == "7.1") ? "~> 7.1.3" : "~> 7.0.4"
gem "switchman", "~> 3.5"
gem "guardrail", "~> 3.0"
gem "switchman-inst-jobs", "~> 4.0"

View File

@ -2,10 +2,10 @@ PATH
remote: ../gems/rubocop-canvas
specs:
rubocop-canvas (1.0.0)
activesupport (~> 7.0.4)
activesupport (>= 7.0)
jira_ref_parser (= 1.0.1)
outrigger (~> 3.0, >= 3.0.1)
railties (~> 7.0.4)
railties (~> 7.0)
rubocop (~> 1.19)
rubocop-rails (~> 2.19)

View File

@ -102,10 +102,10 @@ PATH
remote: gems/rubocop-canvas
specs:
rubocop-canvas (1.0.0)
activesupport (~> 7.0.4)
activesupport (>= 7.0)
jira_ref_parser (= 1.0.1)
outrigger (~> 3.0, >= 3.0.1)
railties (~> 7.0.4)
railties (~> 7.0)
rubocop (~> 1.19)
rubocop-rails (~> 2.19)
@ -113,7 +113,7 @@ PATH
remote: gems
specs:
activesupport-suspend_callbacks (0.0.1)
activesupport (>= 3.2, < 7.1)
activesupport (>= 3.2, < 7.2)
acts_as_list (0.0.1)
activerecord (>= 3.2)
adheres_to_policy (0.0.1)
@ -168,7 +168,7 @@ PATH
canvas_http
json-jwt (~> 1.10)
canvas_partman (2.0.0)
activerecord (>= 6.1, < 7.1)
activerecord (>= 6.1, < 7.2)
activerecord-pg-extensions (~> 0.4)
pg (>= 0.17, < 2.0)
canvas_quiz_statistics (0.1.0)

1379
Gemfile.rails71.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -58,6 +58,8 @@ module CanvasRails
config.action_dispatch.default_headers["Referrer-Policy"] = "no-referrer-when-downgrade"
config.action_controller.forgery_protection_origin_check = true
ActiveSupport.to_time_preserves_timezone = true
# Ensure switchman gets the new version before the main initialize_cache initializer runs
config.active_support.cache_format_version = ActiveSupport.cache_format_version = 7.0
config.app_generators do |c|
c.test_framework :rspec
@ -167,12 +169,22 @@ module CanvasRails
end
end
def initialize(connection, logger, connection_parameters, config)
unless config.key?(:prepared_statements)
config = config.dup
config[:prepared_statements] = false
if Rails.version < "7.1"
def initialize(connection, logger, connection_parameters, config)
unless config.key?(:prepared_statements)
config = config.dup
config[:prepared_statements] = false
end
super(connection, logger, connection_parameters, config)
end
else
def initialize(config)
unless config.key?(:prepared_statements)
config = config.dup
config[:prepared_statements] = false
end
super(config)
end
super(connection, logger, connection_parameters, config)
end
def connect
@ -180,7 +192,11 @@ module CanvasRails
hosts.each_with_index do |host, index|
connection_parameters = @connection_parameters.dup
connection_parameters[:host] = host
@connection = PG::Connection.connect(connection_parameters)
if Rails.version < "7.1"
@connection = PG::Connection.connect(connection_parameters)
else
@raw_connection = PG::Connection.connect(connection_parameters)
end
configure_connection
@ -323,10 +339,21 @@ module CanvasRails
def self.generate_key(*); end
end
def key_generator
def key_generator(...)
DummyKeyGenerator
end
# # This also depends on secret_key_base and is not a feature we use or currently intend to support
unless Rails.version < "7.1"
initializer "canvas.ignore_generated_token_verifier", before: "active_record.generated_token_verifier" do
config.after_initialize do
ActiveSupport.on_load(:active_record) do
self.generated_token_verifier = "UNUSED"
end
end
end
end
initializer "canvas.init_dynamic_settings", before: "canvas.extend_shard" do
settings = ConfigFile.load("consul")
if settings.present?

View File

@ -27,7 +27,7 @@
# 3. Create a Consul setting private/canvas/rails_version with <supported version> as the contents
# the default version (corresponding to the bare Gemfile.lock) must be listed first
SUPPORTED_RAILS_VERSIONS = %w[7.0].freeze
SUPPORTED_RAILS_VERSIONS = %w[7.0 7.1].freeze
unless defined?($canvas_rails)
file_path = File.expand_path("RAILS_VERSION", __dir__)

View File

@ -747,11 +747,27 @@ class ActiveRecord::Base
self.updated_at = Time.now.utc if touch
if new_record?
self.created_at = updated_at if touch
self.id = self.class._insert_record(
attributes_with_values(attribute_names_for_partial_inserts)
.transform_values { |attr| attr.is_a?(ActiveModel::Attribute) ? attr.value : attr }
)
if Rails.version < "7.1"
self.id = self.class._insert_record(
attributes_with_values(attribute_names_for_partial_inserts)
.transform_values { |attr| attr.is_a?(ActiveModel::Attribute) ? attr.value : attr }
)
else
returning_values = returning_columns = self.class._returning_columns_for_insert
self.class._insert_record(
attributes_with_values(attribute_names_for_partial_inserts)
.transform_values { |attr| attr.is_a?(ActiveModel::Attribute) ? attr.value : attr },
returning_columns
)
if returning_values
returning_columns.zip(returning_values).each do |column, value|
_write_attribute(column, value) unless _read_attribute(column)
end
end
end
@new_record = false
@previously_new_record = true
else
update_columns(
attributes_with_values(attribute_names_for_partial_updates)
@ -1319,7 +1335,7 @@ ActiveRecord::Relation.class_eval do
def union(*scopes, from: false)
table = connection.quote_local_table_name(table_name)
scopes.unshift(self)
scopes = scopes.reject { |s| s.is_a?(ActiveRecord::NullRelation) }
scopes = scopes.reject { |s| (Rails.version < "7.1") ? s.is_a?(ActiveRecord::NullRelation) : s.null_relation? }
return scopes.first if scopes.length == 1
return self if scopes.empty?
@ -1705,7 +1721,7 @@ ActiveRecord::ConnectionAdapters::SchemaStatements.class_eval do
fks = foreign_keys(from_table).select { |fk| fk.defined_for?(**options) }
# prefer a FK on a column named after the table
if options[:to_table]
column = foreign_key_column_for(options[:to_table])
column = (Rails.version < "7.1") ? foreign_key_column_for(options[:to_table]) : foreign_key_column_for(options[:to_table], "id")
return fks.find { |fk| fk.column == column } || fks.first
end
fks.first
@ -1949,11 +1965,20 @@ ActiveRecord::Relation.prepend(ExplainAnalyze)
module TableRename
RENAMES = {}.freeze
def columns(table_name)
if (old_name = RENAMES[table_name]) && connection.table_exists?(old_name)
table_name = old_name
if Rails.version < "7.1"
def columns(table_name)
if (old_name = RENAMES[table_name]) && connection.table_exists?(old_name)
table_name = old_name
end
super
end
else
def columns(connection, table_name)
if (old_name = RENAMES[table_name]) && connection.table_exists?(old_name)
table_name = old_name
end
super
end
super
end
end
@ -2136,7 +2161,7 @@ module UserContentSerialization
end
ActiveRecord::Base.include(UserContentSerialization)
if Rails.version >= "6.1"
if Rails.version >= "6.1" && Rails.version < "7.1"
# Hopefully this can be removed with https://github.com/rails/rails/commit/6beee45c3f071c6a17149be0fabb1697609edbe8
# having made a released version of rails; if not bump the rails version in this comment and leave the comment to be revisited
# on the next rails bump
@ -2213,6 +2238,9 @@ module AdditionalIgnoredColumns
cache_class = ActiveRecord::Base.singleton_class
return super unless cache_class.columns_to_ignore_enabled
# Ensure table_name doesn't error out
set_base_class
cache_class.columns_to_ignore_cache[table_name] ||= DynamicSettings.find("activerecord/ignored_columns", tree: :store, ignore_fallback_overrides: true)[table_name, failsafe: ""]&.split(",") || []
super + cache_class.columns_to_ignore_cache[table_name]
end

View File

@ -34,7 +34,8 @@ module PostgreSQLAdapterExtensions
def configure_connection
super
@connection.set_notice_receiver do |result|
conn = (Rails.version < "7.1") ? @connection : @raw_connection
conn.set_notice_receiver do |result|
severity = result.result_error_field(PG::PG_DIAG_SEVERITY_NONLOCALIZED)
rails_severity = case severity
when "WARNING", "NOTICE"
@ -243,7 +244,7 @@ module PostgreSQLAdapterExtensions
# internal_metadata to exist and this guard isn't really useful there either
return if ["schema_migrations", "internal_metadata"].include?(table_name)
# If the function doesn't exist yet it will be backfilled
return unless ::ActiveRecord::InternalMetadata[:guard_dangerous_changes_installed]
return unless ((Rails.version < "7.1") ? ::ActiveRecord::InternalMetadata : ::ActiveRecord::InternalMetadata.new(self))[:guard_dangerous_changes_installed]
["UPDATE", "DELETE"].each do |operation|
trigger_name = "guard_excessive_#{operation.downcase}s"
@ -452,6 +453,11 @@ module ReferenceDefinitionExtensions
end
module SchemaStatementsExtensions
# TODO: move this to activerecord-pg-extensions
def valid_column_definition_options
super + [:delay_validation]
end
def add_column_for_alter(table_name, column_name, type, **options)
td = create_table_definition(table_name)
cd = td.new_column_definition(column_name, type, **options)

View File

@ -18,6 +18,25 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
ADDITIONAL_ALLOWED_CLASSES = [
ActiveSupport::HashWithIndifferentAccess,
ActiveSupport::SafeBuffer,
ActiveSupport::TimeWithZone,
ActiveSupport::TimeZone,
ActionController::Parameters,
BigDecimal,
Date,
DateTime,
Mime::Type,
Mime::NullType,
OpenObject,
OpenStruct,
Symbol,
Time,
URI::HTTP,
URI::HTTPS
].freeze
# SafeYAML-like interface, but vanilla Psych
module SafeYAML
class << self
@ -29,23 +48,7 @@ module SafeYAML
end
self.permitted_classes = []
whitelist_class!(
ActiveSupport::HashWithIndifferentAccess,
ActiveSupport::TimeWithZone,
ActiveSupport::TimeZone,
ActionController::Parameters,
BigDecimal,
Date,
DateTime,
Mime::Type,
Mime::NullType,
OpenObject,
OpenStruct,
Symbol,
Time,
URI::HTTP,
URI::HTTPS
)
whitelist_class!(*ADDITIONAL_ALLOWED_CLASSES)
module Psych
if ::Psych::VERSION < "4"
@ -74,6 +77,8 @@ module SafeYAML
end
Psych.singleton_class.prepend(SafeYAML::Psych)
ActiveRecord.yaml_column_permitted_classes = ADDITIONAL_ALLOWED_CLASSES
module ScalarScannerFix
# in rubies < 2.7, Psych uses a regex to identify an integer, then strips commas and underscores,
# then checks _again_ against the regex. In 2.7, the second check was eliminated because the

View File

@ -44,6 +44,10 @@ Rails.application.config.after_initialize do
return {} unless self.class.columns_hash.key?("settings")
s = super
# Am not sure how this happens
if s.is_a?(String)
s = JSON.parse(s)
end
if s.nil?
self.settings = s = {}
end

View File

@ -2,7 +2,7 @@ PATH
remote: .
specs:
activesupport-suspend_callbacks (0.0.1)
activesupport (>= 3.2, < 7.1)
activesupport (>= 3.2, < 7.2)
GEM
remote: https://rubygems.org/

View File

@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.add_dependency "activesupport", ">= 3.2", "< 7.1"
spec.add_dependency "activesupport", ">= 3.2", "< 7.2"
spec.add_development_dependency "bundler", "~> 2.2"
spec.add_development_dependency "debug"

View File

@ -151,7 +151,7 @@ module ActiveSupport::Callbacks
yield if block_given?
else
env = Filters::Environment.new(self, false, nil)
next_sequence = callbacks.compile
next_sequence = (ActiveSupport.version < "7.1") ? callbacks.compile : callbacks.compile(nil)
invoke_sequence = proc do
skipped = nil

View File

@ -19,12 +19,20 @@
#
require "active_support/cache"
require "active_support/version"
module CanvasCache
module RedisCacheStore
module ClassMethods
ActiveSupport::Cache::RedisCacheStore.singleton_class.prepend(self)
# Rails.version < "7.1"
unless ActiveSupport.version < "7.1"
def retrieve_pool_options(_options)
false
end
end
def build_redis(**redis_options)
Redis.patch
return ::Redis::Cluster.new(**redis_options) if redis_options.key?(:nodes)

View File

@ -2,7 +2,7 @@ PATH
remote: .
specs:
canvas_partman (2.0.0)
activerecord (>= 6.1, < 7.1)
activerecord (>= 6.1, < 7.2)
activerecord-pg-extensions (~> 0.4)
pg (>= 0.17, < 2.0)

View File

@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]
spec.license = "AGPL"
spec.add_dependency "activerecord", ">= 6.1", "< 7.1"
spec.add_dependency "activerecord", ">= 6.1", "< 7.2"
spec.add_dependency "activerecord-pg-extensions", "~> 0.4"
spec.add_dependency "pg", ">= 0.17", "< 2.0"

View File

@ -125,7 +125,7 @@ module CanvasPartman::Concerns
end
end
def _insert_record(values)
def _insert_record(values, ...)
prev_table = @arel_table
prev_builder = @predicate_builder
@arel_table = arel_table_from_key_values(values)

View File

@ -21,8 +21,13 @@
class EventStream::Failure < ActiveRecord::Base
self.table_name = :event_stream_failures
serialize :payload, Hash
serialize :backtrace, Array
if Rails.version < "7.1"
serialize :payload, Hash
serialize :backtrace, Array
else
serialize :payload, type: Hash
serialize :backtrace, type: Array
end
def self.log!(operation, stream, record, exception)
return if stream.raise_on_error

View File

@ -2,10 +2,10 @@ PATH
remote: .
specs:
rubocop-canvas (1.0.0)
activesupport (~> 7.0.4)
activesupport (>= 7.0)
jira_ref_parser (= 1.0.1)
outrigger (~> 3.0, >= 3.0.1)
railties (~> 7.0.4)
railties (~> 7.0)
rubocop (~> 1.19)
rubocop-rails (~> 2.19)

View File

@ -12,10 +12,10 @@ Gem::Specification.new do |spec|
spec.files = Dir.glob("{lib,spec}/**/*") + %w[test.sh]
spec.require_paths = ["lib"]
spec.add_dependency "activesupport", "~> 7.0.4"
spec.add_dependency "activesupport", ">= 7.0"
spec.add_dependency "jira_ref_parser", "1.0.1"
spec.add_dependency "outrigger", "~> 3.0", ">= 3.0.1"
spec.add_dependency "railties", "~> 7.0.4"
spec.add_dependency "railties", "~> 7.0"
spec.add_dependency "rubocop", "~> 1.19"
spec.add_dependency "rubocop-rails", "~> 2.19"