Read about our upcoming Code of Conduct on this issue

Commit 6b7586c0 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu
Browse files

Upgrade to Rails 5.2

Updates changed method names and fixes spec failures
parent 8c5a9dddc494
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do
begin
exec "yarnpkg", *ARGV
rescue Errno::ENOENT
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1
end
end
require File.expand_path('boot', __dir__) require_relative 'boot'
require 'rails/all' # Based on https://github.com/rails/rails/blob/v5.2.3/railties/lib/rails/all.rb
# Only load the railties we need instead of loading everything
require 'active_record/railtie'
require 'action_controller/railtie'
require 'action_view/railtie'
require 'action_mailer/railtie'
require 'rails/test_unit/railtie'
Bundler.require(:default, Rails.env) Bundler.require(*Rails.groups)
module Gitlab module Gitlab
class Application < Rails::Application class Application < Rails::Application
...@@ -25,6 +31,8 @@ class Application < Rails::Application ...@@ -25,6 +31,8 @@ class Application < Rails::Application
# Application configuration should go into files in config/initializers # Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded. # -- all .rb files in that directory are automatically loaded.
config.active_record.sqlite3.represent_boolean_as_integer = true
# Sidekiq uses eager loading, but directories not in the standard Rails # Sidekiq uses eager loading, but directories not in the standard Rails
# directories must be added to the eager load paths: # directories must be added to the eager load paths:
# https://github.com/mperham/sidekiq/wiki/FAQ#why-doesnt-sidekiq-autoload-my-rails-application-code # https://github.com/mperham/sidekiq/wiki/FAQ#why-doesnt-sidekiq-autoload-my-rails-application-code
...@@ -86,13 +94,6 @@ class Application < Rails::Application ...@@ -86,13 +94,6 @@ class Application < Rails::Application
# Configure the default encoding used in templates for Ruby 1.9. # Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8" config.encoding = "utf-8"
# ActionCable mount point.
# The default Rails' mount point is `/cable` which may conflict with existing
# namespaces/users.
# https://github.com/rails/rails/blob/5-0-stable/actioncable/lib/action_cable.rb#L38
# Please change this value when configuring ActionCable for real usage.
config.action_cable.mount_path = "/-/cable"
# Configure sensitive parameters which will be filtered from the log file. # Configure sensitive parameters which will be filtered from the log file.
# #
# Parameters filtered: # Parameters filtered:
...@@ -272,5 +273,10 @@ class Application < Rails::Application ...@@ -272,5 +273,10 @@ class Application < Rails::Application
Gitlab::Routing.add_helpers(project_url_helpers) Gitlab::Routing.add_helpers(project_url_helpers)
Gitlab::Routing.add_helpers(MilestonesRoutingHelper) Gitlab::Routing.add_helpers(MilestonesRoutingHelper)
end end
# This makes generated cookies to be compatible with Rails 5.1 and older
# We can remove this when we're confident that there are no issues with the Rails 5.2 upgrade
# and we won't need to rollback to older versions
config.action_dispatch.use_authenticated_cookie_encryption = false
end end
end end
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
config.cache_classes = false config.cache_classes = false
# Show full error reports and disable caching # Show full error reports and disable caching
config.active_record.verbose_query_logs = true
config.consider_all_requests_local = true config.consider_all_requests_local = true
config.action_controller.perform_caching = false config.action_controller.perform_caching = false
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' } config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
# Show full error reports and disable caching # Show full error reports and disable caching
config.active_record.verbose_query_logs = true
config.consider_all_requests_local = true config.consider_all_requests_local = true
config.action_controller.perform_caching = false config.action_controller.perform_caching = false
......
...@@ -22,7 +22,7 @@ module RegisterDateTimeWithTimeZone ...@@ -22,7 +22,7 @@ module RegisterDateTimeWithTimeZone
# #
# When schema dumping, `timestamptz` columns will be output as # When schema dumping, `timestamptz` columns will be output as
# `t.datetime_with_timezone`. # `t.datetime_with_timezone`.
def initialize_type_map(mapping) def initialize_type_map(mapping = type_map)
super mapping super mapping
mapping.register_type 'timestamptz' do |_, _, sql_type| mapping.register_type 'timestamptz' do |_, _, sql_type|
...@@ -51,7 +51,7 @@ module RegisterDateTimeWithTimeZone ...@@ -51,7 +51,7 @@ module RegisterDateTimeWithTimeZone
# #
# When schema dumping, `timestamp` columns will be output as # When schema dumping, `timestamp` columns will be output as
# `t.datetime_with_timezone`. # `t.datetime_with_timezone`.
def initialize_type_map(mapping) def initialize_type_map(mapping = type_map)
super mapping super mapping
mapping.register_type(/timestamp/i) do |sql_type| mapping.register_type(/timestamp/i) do |sql_type|
......
module ActiveRecord module ActiveRecord
module Associations module Associations
class Preloader class Preloader
class NullPreloader
def self.new(klass, owners, reflection, preload_scope)
self
end
def self.run(preloader)
end
def self.preloaded_records
[]
end
end
module NoCommitPreloader module NoCommitPreloader
def preloader_for(reflection, owners, rhs_klass) def preloader_for(reflection, owners)
return NullPreloader if rhs_klass == ::Commit return NullPreloader if owners.first.association(reflection.name).klass == ::Commit
super super
end end
......
# frozen_string_literal: true
# This is backport of https://github.com/rails/rails/pull/26815/files
# Enabled by default for every non-production environment
module ActiveRecord
class LogSubscriber
module VerboseQueryLogs
def debug(progname = nil, &block)
return unless super
log_query_source
end
def log_query_source
source_line, line_number = extract_callstack(caller_locations)
if source_line
if defined?(::Rails.root)
app_root = "#{::Rails.root}/".freeze
source_line = source_line.sub(app_root, "")
end
logger.debug(" ↳ #{source_line}:#{line_number}")
end
end
def extract_callstack(callstack)
line = callstack.find do |frame|
frame.absolute_path && !ignored_callstack(frame.absolute_path)
end
offending_line = line || callstack.first
[
offending_line.path,
offending_line.lineno,
offending_line.label
]
end
LOG_SUBSCRIBER_FILE = ActiveRecord::LogSubscriber.method(:logger).source_location.first
RAILS_GEM_ROOT = File.expand_path("../../../..", LOG_SUBSCRIBER_FILE) + "/"
APP_CONFIG_ROOT = File.expand_path("..", __dir__) + "/"
def ignored_callstack(path)
path.start_with?(APP_CONFIG_ROOT, RAILS_GEM_ROOT, RbConfig::CONFIG["rubylibdir"])
end
end
if Rails.version.start_with?("5.2")
raise "Remove this monkey patch: #{__FILE__}"
else
prepend(VerboseQueryLogs) unless Rails.env.production?
end
end
end
...@@ -2,17 +2,14 @@ ...@@ -2,17 +2,14 @@
require 'active_record/migration' require 'active_record/migration'
module ActiveRecord module ActiveRecord
class Migrator class MigrationContext
class << self alias_method :migrations_unmemoized, :migrations
alias_method :migrations_unmemoized, :migrations
# This method is called a large number of times per rspec example, and # This method is called a large number of times per rspec example, and
# it reads + parses `db/migrate/*` each time. Memoizing it can save 0.5 # it reads + parses `db/migrate/*` each time. Memoizing it can save 0.5
# seconds per spec. # seconds per spec.
def migrations(paths) def migrations
@migrations ||= {} @migrations ||= migrations_unmemoized
(@migrations[paths] ||= migrations_unmemoized(paths)).dup
end
end end
end end
end end
......
...@@ -22,10 +22,11 @@ def _update_row(attribute_names, attempted_action = "update") ...@@ -22,10 +22,11 @@ def _update_row(attribute_names, attempted_action = "update")
# Patched because when `lock_version` is read as `0`, it may actually be `NULL` in the DB. # Patched because when `lock_version` is read as `0`, it may actually be `NULL` in the DB.
possible_previous_lock_value = previous_lock_value.to_i == 0 ? [nil, 0] : previous_lock_value possible_previous_lock_value = previous_lock_value.to_i == 0 ? [nil, 0] : previous_lock_value
affected_rows = self.class.unscoped._update_record( affected_rows = self.class.unscoped.where(
arel_attributes_with_values(attribute_names), locking_column => possible_previous_lock_value,
self.class.primary_key => id_in_database, self.class.primary_key => id_in_database
locking_column => possible_previous_lock_value ).update_all(
attributes_with_values_for_update(attribute_names)
) )
if affected_rows != 1 if affected_rows != 1
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
.map { |k, v| { key: k, value: v } } .map { |k, v| { key: k, value: v } }
payload = { payload = {
time: event.time.utc.iso8601(3), time: Time.now.utc.iso8601(3),
params: params, params: params,
remote_ip: event.payload[:remote_ip], remote_ip: event.payload[:remote_ip],
user_id: event.payload[:user_id], user_id: event.payload[:user_id],
......
...@@ -15,7 +15,6 @@ module ActiveRecord ...@@ -15,7 +15,6 @@ module ActiveRecord
module ConnectionAdapters module ConnectionAdapters
class Mysql2Adapter < AbstractMysqlAdapter class Mysql2Adapter < AbstractMysqlAdapter
alias_method :__gitlab_add_index, :add_index alias_method :__gitlab_add_index, :add_index
alias_method :__gitlab_add_index_sql, :add_index_sql
alias_method :__gitlab_add_index_options, :add_index_options alias_method :__gitlab_add_index_options, :add_index_options
def add_index(table_name, column_name, options = {}) def add_index(table_name, column_name, options = {})
...@@ -24,12 +23,6 @@ def add_index(table_name, column_name, options = {}) ...@@ -24,12 +23,6 @@ def add_index(table_name, column_name, options = {})
end end
end end
def add_index_sql(table_name, column_name, options = {})
unless options[:opclasses]
__gitlab_add_index_sql(table_name, column_name, options)
end
end
def add_index_options(table_name, column_name, options = {}) def add_index_options(table_name, column_name, options = {})
if options[:using] && options[:using] == :gin if options[:using] && options[:using] == :gin
options = options.dup options = options.dup
......
...@@ -94,8 +94,8 @@ def with!(opts = :chain, *rest) # :nodoc: ...@@ -94,8 +94,8 @@ def with!(opts = :chain, *rest) # :nodoc:
end end
end end
def build_arel def build_arel(aliases)
arel = super() arel = super
build_with(arel) if @values[:with] build_with(arel) if @values[:with]
......
...@@ -10,11 +10,11 @@ ...@@ -10,11 +10,11 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20190703130053) do ActiveRecord::Schema.define(version: 2019_07_03_130053) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
enable_extension "pg_trgm" enable_extension "pg_trgm"
enable_extension "plpgsql"
create_table "abuse_reports", id: :serial, force: :cascade do |t| create_table "abuse_reports", id: :serial, force: :cascade do |t|
t.integer "reporter_id" t.integer "reporter_id"
......
...@@ -205,7 +205,9 @@ def paginate_with_limit_optimization(relation) ...@@ -205,7 +205,9 @@ def paginate_with_limit_optimization(relation)
limited_total_count = pagination_data.total_count_with_limit limited_total_count = pagination_data.total_count_with_limit
if limited_total_count > Kaminari::ActiveRecordRelationMethods::MAX_COUNT_LIMIT if limited_total_count > Kaminari::ActiveRecordRelationMethods::MAX_COUNT_LIMIT
pagination_data.without_count # The call to `total_count_with_limit` memoizes `@arel` because of a call to `references_eager_loaded_tables?`
# We need to call `reset` because `without_count` relies on `@arel` being unmemoized
pagination_data.reset.without_count
else else
pagination_data pagination_data
end end
......
...@@ -7,8 +7,7 @@ module Runner ...@@ -7,8 +7,7 @@ module Runner
JOB_TOKEN_PARAM = :token JOB_TOKEN_PARAM = :token
def runner_registration_token_valid? def runner_registration_token_valid?
ActiveSupport::SecurityUtils.variable_size_secure_compare(params[:token], ActiveSupport::SecurityUtils.secure_compare(params[:token], Gitlab::CurrentSettings.runners_registration_token)
Gitlab::CurrentSettings.runners_registration_token)
end end
def authenticate_runner! def authenticate_runner!
......
...@@ -45,7 +45,7 @@ def uncached_application_settings ...@@ -45,7 +45,7 @@ def uncached_application_settings
# need to be added to the application settings. To prevent Rake tasks # need to be added to the application settings. To prevent Rake tasks
# and other callers from failing, use any loaded settings and return # and other callers from failing, use any loaded settings and return
# defaults for missing columns. # defaults for missing columns.
if ActiveRecord::Migrator.needs_migration? if ActiveRecord::Base.connection.migration_context.needs_migration?
db_attributes = current_settings&.attributes || {} db_attributes = current_settings&.attributes || {}
fake_application_settings(db_attributes) fake_application_settings(db_attributes)
elsif current_settings.present? elsif current_settings.present?
......
...@@ -128,7 +128,7 @@ def self.nulls_last_order(field, direction = 'ASC') ...@@ -128,7 +128,7 @@ def self.nulls_last_order(field, direction = 'ASC')
order = "#{field} IS NULL, #{order}" if direction == 'ASC' order = "#{field} IS NULL, #{order}" if direction == 'ASC'
end end
order Arel.sql(order)
end end
def self.nulls_first_order(field, direction = 'ASC') def self.nulls_first_order(field, direction = 'ASC')
...@@ -142,7 +142,7 @@ def self.nulls_first_order(field, direction = 'ASC') ...@@ -142,7 +142,7 @@ def self.nulls_first_order(field, direction = 'ASC')
order = "#{field} IS NULL, #{order}" if direction == 'DESC' order = "#{field} IS NULL, #{order}" if direction == 'DESC'
end end
order Arel.sql(order)
end end
def self.random def self.random
......
...@@ -24,7 +24,7 @@ def self.create_and_execute_trigger?(table) ...@@ -24,7 +24,7 @@ def self.create_and_execute_trigger?(table)
begin begin
from(nil) from(nil)
.pluck("has_table_privilege(#{quoted_table}, 'TRIGGER')") .pluck(Arel.sql("has_table_privilege(#{quoted_table}, 'TRIGGER')"))
.first .first
rescue ActiveRecord::StatementInvalid rescue ActiveRecord::StatementInvalid
# This error is raised when using a non-existing table name. In this # This error is raised when using a non-existing table name. In this
......
...@@ -23,10 +23,11 @@ ...@@ -23,10 +23,11 @@
control_count = ActiveRecord::QueryRecorder.new { get :index }.count control_count = ActiveRecord::QueryRecorder.new { get :index }.count
create(:ci_runner, :tagged_only) create_list(:ci_runner, 5, :tagged_only)
# There is still an N+1 query for `runner.builds.count` # There is still an N+1 query for `runner.builds.count`
expect { get :index }.not_to exceed_query_limit(control_count + 1) # We also need to add 1 because it takes 2 queries to preload tags
expect { get :index }.not_to exceed_query_limit(control_count + 6)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(response.body).to have_content('tag1') expect(response.body).to have_content('tag1')
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
shared_examples 'resource with a custom avatar' do |source_type| shared_examples 'resource with a custom avatar' do |source_type|
it 'returns a custom avatar image' do it 'returns a custom avatar image' do
expect(public_send("#{source_type}_icon", *helper_args)) expect(public_send("#{source_type}_icon", *helper_args))
.to eq "<img src=\"#{resource.avatar.url}\" alt=\"Banana sample\" />" .to eq "<img src=\"#{resource.avatar.url}\" />"
end end
end end
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment