Commit aeb67dd4 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Upgrade to Rails 5.2

Updates changed method names and fixes spec failures
parent ecffca5d
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'rails', '5.1.7' gem 'rails', '5.2.3'
# Improves copy-on-write performance for MRI # Improves copy-on-write performance for MRI
gem 'nakayoshi_fork', '~> 0.0.4' gem 'nakayoshi_fork', '~> 0.0.4'
......
...@@ -6,44 +6,48 @@ GEM ...@@ -6,44 +6,48 @@ GEM
ace-rails-ap (4.1.2) ace-rails-ap (4.1.2)
acme-client (2.0.2) acme-client (2.0.2)
faraday (~> 0.9, >= 0.9.1) faraday (~> 0.9, >= 0.9.1)
actioncable (5.1.7) actioncable (5.2.3)
actionpack (= 5.1.7) actionpack (= 5.2.3)
nio4r (~> 2.0) nio4r (~> 2.0)
websocket-driver (~> 0.6.1) websocket-driver (>= 0.6.1)
actionmailer (5.1.7) actionmailer (5.2.3)
actionpack (= 5.1.7) actionpack (= 5.2.3)
actionview (= 5.1.7) actionview (= 5.2.3)
activejob (= 5.1.7) activejob (= 5.2.3)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (5.1.7) actionpack (5.2.3)
actionview (= 5.1.7) actionview (= 5.2.3)
activesupport (= 5.1.7) activesupport (= 5.2.3)
rack (~> 2.0) rack (~> 2.0)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.1.7) actionview (5.2.3)
activesupport (= 5.1.7) activesupport (= 5.2.3)
builder (~> 3.1) builder (~> 3.1)
erubi (~> 1.4) erubi (~> 1.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3) rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.1.7) activejob (5.2.3)
activesupport (= 5.1.7) activesupport (= 5.2.3)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (5.1.7) activemodel (5.2.3)
activesupport (= 5.1.7) activesupport (= 5.2.3)
activerecord (5.1.7) activerecord (5.2.3)
activemodel (= 5.1.7) activemodel (= 5.2.3)
activesupport (= 5.1.7) activesupport (= 5.2.3)
arel (~> 8.0) arel (>= 9.0)
activerecord-explain-analyze (0.1.0) activerecord-explain-analyze (0.1.0)
activerecord (>= 4) activerecord (>= 4)
pg pg
activerecord_sane_schema_dumper (1.0) activerecord_sane_schema_dumper (1.0)
rails (>= 5, < 6) rails (>= 5, < 6)
activesupport (5.1.7) activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
marcel (~> 0.3.1)
activesupport (5.2.3)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
...@@ -60,7 +64,7 @@ GEM ...@@ -60,7 +64,7 @@ GEM
apollo_upload_server (2.0.0.beta.3) apollo_upload_server (2.0.0.beta.3)
graphql (>= 1.8) graphql (>= 1.8)
rails (>= 4.2) rails (>= 4.2)
arel (8.0.0) arel (9.0.0)
asana (0.8.1) asana (0.8.1)
faraday (~> 0.9) faraday (~> 0.9)
faraday_middleware (~> 0.9) faraday_middleware (~> 0.9)
...@@ -504,6 +508,8 @@ GEM ...@@ -504,6 +508,8 @@ GEM
mail (2.7.1) mail (2.7.1)
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
mail_room (0.9.1) mail_room (0.9.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
mdl (0.5.0) mdl (0.5.0)
kramdown (~> 1.12, >= 1.12.0) kramdown (~> 1.12, >= 1.12.0)
mixlib-cli (~> 1.7, >= 1.7.0) mixlib-cli (~> 1.7, >= 1.7.0)
...@@ -706,17 +712,18 @@ GEM ...@@ -706,17 +712,18 @@ GEM
rack-test (1.1.0) rack-test (1.1.0)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rack-timeout (0.5.1) rack-timeout (0.5.1)
rails (5.1.7) rails (5.2.3)
actioncable (= 5.1.7) actioncable (= 5.2.3)
actionmailer (= 5.1.7) actionmailer (= 5.2.3)
actionpack (= 5.1.7) actionpack (= 5.2.3)
actionview (= 5.1.7) actionview (= 5.2.3)
activejob (= 5.1.7) activejob (= 5.2.3)
activemodel (= 5.1.7) activemodel (= 5.2.3)
activerecord (= 5.1.7) activerecord (= 5.2.3)
activesupport (= 5.1.7) activestorage (= 5.2.3)
activesupport (= 5.2.3)
bundler (>= 1.3.0) bundler (>= 1.3.0)
railties (= 5.1.7) railties (= 5.2.3)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.2) rails-controller-testing (1.0.2)
actionpack (~> 5.x, >= 5.0.1) actionpack (~> 5.x, >= 5.0.1)
...@@ -730,12 +737,12 @@ GEM ...@@ -730,12 +737,12 @@ GEM
rails-i18n (5.1.1) rails-i18n (5.1.1)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
railties (>= 5.0, < 6) railties (>= 5.0, < 6)
railties (5.1.7) railties (5.2.3)
actionpack (= 5.1.7) actionpack (= 5.2.3)
activesupport (= 5.1.7) activesupport (= 5.2.3)
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.19.0, < 2.0)
rainbow (3.0.0) rainbow (3.0.0)
raindrops (0.19.0) raindrops (0.19.0)
rake (12.3.2) rake (12.3.2)
...@@ -1019,7 +1026,7 @@ GEM ...@@ -1019,7 +1026,7 @@ GEM
hashdiff hashdiff
webpack-rails (0.9.11) webpack-rails (0.9.11)
railties (>= 3.2.0) railties (>= 3.2.0)
websocket-driver (0.6.5) websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3) websocket-extensions (0.1.3)
wikicloth (0.8.1) wikicloth (0.8.1)
...@@ -1206,7 +1213,7 @@ DEPENDENCIES ...@@ -1206,7 +1213,7 @@ DEPENDENCIES
rack-oauth2 (~> 1.9.3) rack-oauth2 (~> 1.9.3)
rack-proxy (~> 0.6.0) rack-proxy (~> 0.6.0)
rack-timeout rack-timeout
rails (= 5.1.7) rails (= 5.2.3)
rails-controller-testing rails-controller-testing
rails-i18n (~> 5.1) rails-i18n (~> 5.1)
rainbow (~> 3.0) rainbow (~> 3.0)
......
...@@ -28,7 +28,7 @@ module RequiresWhitelistedMonitoringClient ...@@ -28,7 +28,7 @@ module RequiresWhitelistedMonitoringClient
def valid_token? def valid_token?
token = params[:token].presence || request.headers['TOKEN'] token = params[:token].presence || request.headers['TOKEN']
token.present? && token.present? &&
ActiveSupport::SecurityUtils.variable_size_secure_compare( ActiveSupport::SecurityUtils.secure_compare(
token, token,
Gitlab::CurrentSettings.health_check_access_token Gitlab::CurrentSettings.health_check_access_token
) )
......
...@@ -107,7 +107,7 @@ class GroupsController < Groups::ApplicationController ...@@ -107,7 +107,7 @@ class GroupsController < Groups::ApplicationController
if Groups::UpdateService.new(@group, current_user, group_params).execute if Groups::UpdateService.new(@group, current_user, group_params).execute
redirect_to edit_group_path(@group, anchor: params[:update_section]), notice: "Group '#{@group.name}' was successfully updated." redirect_to edit_group_path(@group, anchor: params[:update_section]), notice: "Group '#{@group.name}' was successfully updated."
else else
@group.restore_path! @group.path = @group.path_before_last_save || @group.path_was
render action: "edit" render action: "edit"
end end
......
...@@ -578,7 +578,7 @@ module Ci ...@@ -578,7 +578,7 @@ module Ci
end end
def valid_token?(token) def valid_token?(token)
self.token && ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.token) self.token && ActiveSupport::SecurityUtils.secure_compare(token, self.token)
end end
def has_tags? def has_tags?
......
...@@ -196,7 +196,7 @@ module Ci ...@@ -196,7 +196,7 @@ module Ci
sql = 'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC' sql = 'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC'
query = ApplicationRecord.send(:sanitize_sql_array, [sql, sources[:merge_request_event]]) # rubocop:disable GitlabSecurity/PublicSend query = ApplicationRecord.send(:sanitize_sql_array, [sql, sources[:merge_request_event]]) # rubocop:disable GitlabSecurity/PublicSend
order(query) order(Arel.sql(query))
end end
scope :for_user, -> (user) { where(user: user) } scope :for_user, -> (user) { where(user: user) }
......
...@@ -33,6 +33,7 @@ module HasStatus ...@@ -33,6 +33,7 @@ module HasStatus
canceled = scope_relevant.canceled.select('count(*)').to_sql canceled = scope_relevant.canceled.select('count(*)').to_sql
warnings = scope_warnings.select('count(*) > 0').to_sql.presence || 'false' warnings = scope_warnings.select('count(*) > 0').to_sql.presence || 'false'
Arel.sql(
"(CASE "(CASE
WHEN (#{builds})=(#{skipped}) AND (#{warnings}) THEN 'success' WHEN (#{builds})=(#{skipped}) AND (#{warnings}) THEN 'success'
WHEN (#{builds})=(#{skipped}) THEN 'skipped' WHEN (#{builds})=(#{skipped}) THEN 'skipped'
...@@ -49,6 +50,7 @@ module HasStatus ...@@ -49,6 +50,7 @@ module HasStatus
WHEN (#{created})>0 THEN 'running' WHEN (#{created})>0 THEN 'running'
ELSE 'failed' ELSE 'failed'
END)" END)"
)
end end
def status def status
...@@ -88,22 +90,22 @@ module HasStatus ...@@ -88,22 +90,22 @@ module HasStatus
state :scheduled, value: 'scheduled' state :scheduled, value: 'scheduled'
end end
scope :created, -> { where(status: 'created') } scope :created, -> { with_status(:created) }
scope :preparing, -> { where(status: 'preparing') } scope :preparing, -> { with_status(:preparing) }
scope :relevant, -> { where(status: AVAILABLE_STATUSES - ['created']) } scope :relevant, -> { without_status(:created) }
scope :running, -> { where(status: 'running') } scope :running, -> { with_status(:running) }
scope :pending, -> { where(status: 'pending') } scope :pending, -> { with_status(:pending) }
scope :success, -> { where(status: 'success') } scope :success, -> { with_status(:success) }
scope :failed, -> { where(status: 'failed') } scope :failed, -> { with_status(:failed) }
scope :canceled, -> { where(status: 'canceled') } scope :canceled, -> { with_status(:canceled) }
scope :skipped, -> { where(status: 'skipped') } scope :skipped, -> { with_status(:skipped) }
scope :manual, -> { where(status: 'manual') } scope :manual, -> { with_status(:manual) }
scope :scheduled, -> { where(status: 'scheduled') } scope :scheduled, -> { with_status(:scheduled) }
scope :alive, -> { where(status: [:created, :preparing, :pending, :running]) } scope :alive, -> { with_status(:created, :preparing, :pending, :running) }
scope :created_or_pending, -> { where(status: [:created, :pending]) } scope :created_or_pending, -> { with_status(:created, :pending) }
scope :running_or_pending, -> { where(status: [:running, :pending]) } scope :running_or_pending, -> { with_status(:running, :pending) }
scope :finished, -> { where(status: [:success, :failed, :canceled]) } scope :finished, -> { with_status(:success, :failed, :canceled) }
scope :failed_or_canceled, -> { where(status: [:failed, :canceled]) } scope :failed_or_canceled, -> { with_status(:failed, :canceled) }
scope :cancelable, -> do scope :cancelable, -> do
where(status: [:running, :preparing, :pending, :created, :scheduled]) where(status: [:running, :preparing, :pending, :created, :scheduled])
......
...@@ -179,7 +179,7 @@ module RelativePositioning ...@@ -179,7 +179,7 @@ module RelativePositioning
relation = yield relation if block_given? relation = yield relation if block_given?
relation relation
.pluck(self.class.parent_column, "#{calculation}(relative_position) AS position") .pluck(self.class.parent_column, Arel.sql("#{calculation}(relative_position) AS position"))
.first&. .first&.
last last
end end
......
...@@ -46,7 +46,7 @@ module Routable ...@@ -46,7 +46,7 @@ module Routable
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/18603. Also note that # See https://gitlab.com/gitlab-org/gitlab-ce/issues/18603. Also note that
# our unique index is case-sensitive in Postgres. # our unique index is case-sensitive in Postgres.
binary = Gitlab::Database.mysql? ? 'BINARY' : '' binary = Gitlab::Database.mysql? ? 'BINARY' : ''
order_sql = "(CASE WHEN #{binary} routes.path = #{connection.quote(path)} THEN 0 ELSE 1 END)" order_sql = Arel.sql("(CASE WHEN #{binary} routes.path = #{connection.quote(path)} THEN 0 ELSE 1 END)")
found = where_full_path_in([path]).reorder(order_sql).take found = where_full_path_in([path]).reorder(order_sql).take
return found if found return found if found
......
...@@ -52,7 +52,7 @@ module TokenAuthenticatable ...@@ -52,7 +52,7 @@ module TokenAuthenticatable
mod.define_method("#{token_field}_matches?") do |other_token| mod.define_method("#{token_field}_matches?") do |other_token|
token = read_attribute(token_field) token = read_attribute(token_field)
token.present? && ActiveSupport::SecurityUtils.variable_size_secure_compare(other_token, token) token.present? && ActiveSupport::SecurityUtils.secure_compare(other_token, token)
end end
end end
......
...@@ -4,9 +4,8 @@ class Email < ApplicationRecord ...@@ -4,9 +4,8 @@ class Email < ApplicationRecord
include Sortable include Sortable
include Gitlab::SQL::Pattern include Gitlab::SQL::Pattern
belongs_to :user belongs_to :user, optional: false
validates :user_id, presence: true
validates :email, presence: true, uniqueness: true, devise_email: true validates :email, presence: true, uniqueness: true, devise_email: true
validate :unique_email, if: ->(email) { email.email_changed? } validate :unique_email, if: ->(email) { email.email_changed? }
......
...@@ -25,7 +25,7 @@ class MergeRequestsClosingIssues < ApplicationRecord ...@@ -25,7 +25,7 @@ class MergeRequestsClosingIssues < ApplicationRecord
class << self class << self
def count_for_collection(ids, current_user) def count_for_collection(ids, current_user)
closing_merge_requests(ids, current_user).group(:issue_id).pluck('issue_id', 'COUNT(*) as count') closing_merge_requests(ids, current_user).group(:issue_id).pluck('issue_id', Arel.sql('COUNT(*) as count'))
end end
def count_for_issue(id, current_user) def count_for_issue(id, current_user)
......
...@@ -357,7 +357,7 @@ class Project < ApplicationRecord ...@@ -357,7 +357,7 @@ class Project < ApplicationRecord
scope :with_unmigrated_storage, -> { where('storage_version < :version OR storage_version IS NULL', version: LATEST_STORAGE_VERSION) } scope :with_unmigrated_storage, -> { where('storage_version < :version OR storage_version IS NULL', version: LATEST_STORAGE_VERSION) }
# last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push # last_activity_at is throttled every minute, but last_repository_updated_at is updated with every push
scope :sorted_by_activity, -> { reorder("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC") } scope :sorted_by_activity, -> { reorder(Arel.sql("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC")) }
scope :sorted_by_stars_desc, -> { reorder(star_count: :desc) } scope :sorted_by_stars_desc, -> { reorder(star_count: :desc) }
scope :sorted_by_stars_asc, -> { reorder(star_count: :asc) } scope :sorted_by_stars_asc, -> { reorder(star_count: :asc) }
...@@ -612,7 +612,7 @@ class Project < ApplicationRecord ...@@ -612,7 +612,7 @@ class Project < ApplicationRecord
end end
end end
def initialize(attributes = {}) def initialize(attributes = nil)
# We can't use default_value_for because the database has a default # We can't use default_value_for because the database has a default
# value of 0 for visibility_level. If someone attempts to create a # value of 0 for visibility_level. If someone attempts to create a
# private project, default_value_for will assume that the # private project, default_value_for will assume that the
...@@ -622,6 +622,8 @@ class Project < ApplicationRecord ...@@ -622,6 +622,8 @@ class Project < ApplicationRecord
# #
# To fix the problem, we assign the actual default in the application if # To fix the problem, we assign the actual default in the application if
# no explicit visibility has been initialized. # no explicit visibility has been initialized.
attributes ||= {}
unless visibility_attribute_present?(attributes) unless visibility_attribute_present?(attributes)
attributes[:visibility_level] = Gitlab::CurrentSettings.default_project_visibility attributes[:visibility_level] = Gitlab::CurrentSettings.default_project_visibility
end end
...@@ -1557,7 +1559,7 @@ class Project < ApplicationRecord ...@@ -1557,7 +1559,7 @@ class Project < ApplicationRecord
end end
def valid_runners_token?(token) def valid_runners_token?(token)
self.runners_token && ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.runners_token) self.runners_token && ActiveSupport::SecurityUtils.secure_compare(token, self.runners_token)
end end
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
......
...@@ -7,7 +7,7 @@ class CiService < Service ...@@ -7,7 +7,7 @@ class CiService < Service
default_value_for :category, 'ci' default_value_for :category, 'ci'
def valid_token?(token) def valid_token?(token)
self.respond_to?(:token) && self.token.present? && ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.token) self.respond_to?(:token) && self.token.present? && ActiveSupport::SecurityUtils.secure_compare(token, self.token)
end end
def self.supported_events def self.supported_events
......
...@@ -12,7 +12,7 @@ class SlashCommandsService < Service ...@@ -12,7 +12,7 @@ class SlashCommandsService < Service
def valid_token?(token) def valid_token?(token)
self.respond_to?(:token) && self.respond_to?(:token) &&
self.token.present? && self.token.present? &&
ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.token) ActiveSupport::SecurityUtils.secure_compare(token, self.token)
end end
def self.supported_events def self.supported_events
......
...@@ -44,7 +44,7 @@ module Ci ...@@ -44,7 +44,7 @@ module Ci
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def stage_indexes_of_created_processables def stage_indexes_of_created_processables
created_processables.order(:stage_idx).pluck('distinct stage_idx') created_processables.order(:stage_idx).pluck(Arel.sql('DISTINCT stage_idx'))
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
...@@ -68,7 +68,7 @@ module Ci ...@@ -68,7 +68,7 @@ module Ci
latest_statuses = pipeline.statuses.latest latest_statuses = pipeline.statuses.latest
.group(:name) .group(:name)
.having('count(*) > 1') .having('count(*) > 1')
.pluck('max(id)', 'name') .pluck(Arel.sql('MAX(id)'), 'name')
# mark builds that are retried # mark builds that are retried
pipeline.statuses.latest pipeline.statuses.latest
......
...@@ -27,8 +27,7 @@ module Groups ...@@ -27,8 +27,7 @@ module Groups
@group.build_chat_team(name: response['name'], team_id: response['id']) @group.build_chat_team(name: response['name'], team_id: response['id'])
end end
@group.save @group.add_owner(current_user) if @group.save
@group.add_owner(current_user)
@group @group
end end
......
#!/usr/bin/env ruby #!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
load Gem.bin_path('bundler', 'bundle') load Gem.bin_path('bundler', 'bundle')
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'fileutils'
require "pathname" include FileUtils
# path to your application root. # path to your application root.
APP_ROOT = Pathname.new File.expand_path("../../", __FILE__) APP_ROOT = File.expand_path('..', __dir__)
def system!(*args) def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==") system(*args) || abort("\n== Command #{args} failed ==")
end end
Dir.chdir APP_ROOT do chdir APP_ROOT do
# This script is a starting point to set up your application. # This script is a starting point to setup your application.
# Add necessary setup steps to this file: # Add necessary setup steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
puts "== Installing dependencies ==" # Install JavaScript dependencies if using Yarn
system! "gem install bundler --conservative" # system('bin/yarn')
system("bundle check") || system!("bundle install")
# puts "\n== Copying sample files ==" # puts "\n== Copying sample files =="
# unless File.exist?("config/database.yml") # unless File.exist?('config/database.yml')
# cp "config/database.yml.sample", "config/database.yml" # cp 'config/database.yml.sample', 'config/database.yml'
# end # end
puts "\n== Preparing database ==" puts "\n== Preparing database =="
system! "bin/rails db:setup" system! 'bin/rails db:setup'
puts "\n== Removing old logs and tempfiles ==" puts "\n== Removing old logs and tempfiles =="
system! "bin/rails log:clear tmp:clear" system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server ==" puts "\n== Restarting application server =="
system! "bin/rails restart" system! 'bin/rails restart'
end end
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'pathname'
require 'fileutils' require 'fileutils'
include FileUtils include FileUtils
# path to your application root. # path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) APP_ROOT = File.expand_path('..', __dir__)
def system!(*args) def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==") system(*args) || abort("\n== Command #{args} failed ==")
...@@ -18,6 +17,9 @@ chdir APP_ROOT do ...@@ -18,6 +17,9 @@ chdir APP_ROOT do
system! 'gem install bundler --conservative' system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install') system('bundle check') || system!('bundle install')
# Install JavaScript dependencies if using Yarn
# system('bin/yarn')
puts "\n== Updating database ==" puts "\n== Updating database =="
system! 'bin/rails db:migrate' system! 'bin/rails db:migrate'
......
#!/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 @@ module Gitlab ...@@ -25,6 +31,8 @@ module Gitlab
# 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 @@ module Gitlab ...@@ -86,13 +94,6 @@ module Gitlab
# 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 @@ module Gitlab ...@@ -272,5 +273,10 @@ module Gitlab
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 @@ Rails.application.configure do ...@@ -7,6 +7,7 @@ Rails.application.configure do
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 @@ Rails.application.configure do ...@@ -23,6 +23,7 @@ Rails.application.configure do
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 @@ if Gitlab::Database.postgresql? ...@@ -22,7 +22,7 @@ if Gitlab::Database.postgresql?
# #
# 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 @@ elsif Gitlab::Database.mysql? ...@@ -51,7 +51,7 @@ elsif Gitlab::Database.mysql?
# #
# 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 @@ if Rails.env.test? ...@@ -2,17 +2,14 @@ if Rails.env.test?
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 @@ module ActiveRecord ...@@ -22,10 +22,11 @@ module ActiveRecord
# 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 @@ unless Sidekiq.server? ...@@ -18,7 +18,7 @@ unless Sidekiq.server?
.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 @@ if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) ...@@ -15,7 +15,6 @@ if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
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 @@ if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) ...@@ -24,12 +23,6 @@ if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
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 @@ module ActiveRecord ...@@ -94,8 +94,8 @@ module ActiveRecord
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 @@ module API ...@@ -205,7 +205,9 @@ module API
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 API ...@@ -7,8 +7,7 @@ module API
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 @@ module Gitlab ...@@ -45,7 +45,7 @@ module Gitlab
# 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 @@ module Gitlab ...@@ -128,7 +128,7 @@ module Gitlab
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 @@ module Gitlab ...@@ -142,7 +142,7 @@ module Gitlab
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 @@ module Gitlab ...@@ -24,7 +24,7 @@ module Gitlab
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 @@ describe Admin::RunnersController do ...@@ -23,10 +23,11 @@ describe Admin::RunnersController do
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 @@ describe AvatarsHelper do ...@@ -16,7 +16,7 @@ describe AvatarsHelper do
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
......
...@@ -103,7 +103,7 @@ describe EmailsHelper do ...@@ -103,7 +103,7 @@ describe EmailsHelper do
appearance = create :appearance, header_logo: fixture_file_upload('spec/fixtures/dk.png') appearance = create :appearance, header_logo: fixture_file_upload('spec/fixtures/dk.png')
expect(header_logo).to eq( expect(header_logo).to eq(
%{<img style="height: 50px" src="/uploads/-/system/appearance/header_logo/#{appearance.id}/dk.png" alt="Dk" />} %{<img style="height: 50px" src="/uploads/-/system/appearance/header_logo/#{appearance.id}/dk.png" />}
) )
end end
end end
......
...@@ -114,7 +114,7 @@ describe API::Helpers::Pagination do ...@@ -114,7 +114,7 @@ describe API::Helpers::Pagination do
expect(paginated_relation.order_values).to be_present expect(paginated_relation.order_values).to be_present
expect(paginated_relation.order_values.size).to eq(1) expect(paginated_relation.order_values.size).to eq(1)
expect(paginated_relation.order_values.first).to be_descending expect(paginated_relation.order_values.first).to be_descending
expect(paginated_relation.order_values.first.expr.name).to eq :id expect(paginated_relation.order_values.first.expr.name).to eq 'id'
end end
end end
...@@ -151,9 +151,9 @@ describe API::Helpers::Pagination do ...@@ -151,9 +151,9 @@ describe API::Helpers::Pagination do
expect(paginated_relation.order_values).to be_present expect(paginated_relation.order_values).to be_present
expect(paginated_relation.order_values.size).to eq(2) expect(paginated_relation.order_values.size).to eq(2)
expect(paginated_relation.order_values.first).to be_descending expect(paginated_relation.order_values.first).to be_descending
expect(paginated_relation.order_values.first.expr.name).to eq :name expect(paginated_relation.order_values.first.expr.name).to eq 'name'
expect(paginated_relation.order_values.second).to be_descending expect(paginated_relation.order_values.second).to be_descending
expect(paginated_relation.order_values.second.expr.name).to eq :id expect(paginated_relation.order_values.second.expr.name).to eq 'id'
end end
it 'returns the right records (first page)' do it 'returns the right records (first page)' do
...@@ -341,7 +341,7 @@ describe API::Helpers::Pagination do ...@@ -341,7 +341,7 @@ describe API::Helpers::Pagination do
expect(resource.order_values).to be_empty expect(resource.order_values).to be_empty
expect(paginated_relation.order_values).to be_present expect(paginated_relation.order_values).to be_present
expect(paginated_relation.order_values.first).to be_ascending expect(paginated_relation.order_values.first).to be_ascending
expect(paginated_relation.order_values.first.expr.name).to eq :id expect(paginated_relation.order_values.first.expr.name).to eq 'id'
end end
it 'is present it does not add anything' do it 'is present it does not add anything' do
...@@ -349,7 +349,7 @@ describe API::Helpers::Pagination do ...@@ -349,7 +349,7 @@ describe API::Helpers::Pagination do
expect(paginated_relation.order_values).to be_present expect(paginated_relation.order_values).to be_present
expect(paginated_relation.order_values.first).to be_descending expect(paginated_relation.order_values.first).to be_descending
expect(paginated_relation.order_values.first.expr.name).to eq :created_at expect(paginated_relation.order_values.first.expr.name).to eq 'created_at'
end end
end end
end end
......
...@@ -80,7 +80,7 @@ describe Gitlab::CurrentSettings do ...@@ -80,7 +80,7 @@ describe Gitlab::CurrentSettings do
# during the initialization phase of the test suite, so instead let's mock the internals of it # during the initialization phase of the test suite, so instead let's mock the internals of it
expect(ActiveRecord::Base.connection).not_to receive(:active?) expect(ActiveRecord::Base.connection).not_to receive(:active?)
expect(ActiveRecord::Base.connection).not_to receive(:cached_table_exists?) expect(ActiveRecord::Base.connection).not_to receive(:cached_table_exists?)
expect(ActiveRecord::Migrator).not_to receive(:needs_migration?) expect_any_instance_of(ActiveRecord::MigrationContext).not_to receive(:needs_migration?)
expect(ActiveRecord::QueryRecorder.new { described_class.current_application_settings }.count).to eq(0) expect(ActiveRecord::QueryRecorder.new { described_class.current_application_settings }.count).to eq(0)
end end
end end
...@@ -109,7 +109,7 @@ describe Gitlab::CurrentSettings do ...@@ -109,7 +109,7 @@ describe Gitlab::CurrentSettings do
context 'with pending migrations' do context 'with pending migrations' do
before do before do
expect(ActiveRecord::Migrator).to receive(:needs_migration?).and_return(true) expect_any_instance_of(ActiveRecord::MigrationContext).to receive(:needs_migration?).and_return(true)
end end
shared_examples 'a non-persisted ApplicationSetting object' do shared_examples 'a non-persisted ApplicationSetting object' do
......
...@@ -105,6 +105,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -105,6 +105,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do
context "when the issue could not be saved" do context "when the issue could not be saved" do
before do before do
allow_any_instance_of(Issue).to receive(:persisted?).and_return(false) allow_any_instance_of(Issue).to receive(:persisted?).and_return(false)
allow_any_instance_of(Issue).to receive(:ensure_metrics).and_return(nil)
end end
it "raises an InvalidIssueError" do it "raises an InvalidIssueError" do
......
...@@ -15,7 +15,7 @@ describe ActiveRecord::Schema do ...@@ -15,7 +15,7 @@ describe ActiveRecord::Schema do
it '> schema version equals last migration timestamp' do it '> schema version equals last migration timestamp' do
defined_schema_version = File.open(Rails.root.join('db', 'schema.rb')) do |file| defined_schema_version = File.open(Rails.root.join('db', 'schema.rb')) do |file|
file.find { |line| line =~ /ActiveRecord::Schema.define/ } file.find { |line| line =~ /ActiveRecord::Schema.define/ }
end.match(/(\d+)/)[0].to_i end.match(/(\d{4}_\d{2}_\d{2}_\d{6})/)[0].to_i
expect(defined_schema_version).to eq(latest_migration_timestamp) expect(defined_schema_version).to eq(latest_migration_timestamp)
end end
......
...@@ -24,7 +24,7 @@ describe 'CycleAnalytics#issue' do ...@@ -24,7 +24,7 @@ describe 'CycleAnalytics#issue' do
["list label added to issue", ["list label added to issue",
-> (context, data) do -> (context, data) do
if data[:issue].persisted? if data[:issue].persisted?
data[:issue].update(label_ids: [context.create(:label, lists: [context.create(:list)]).id]) data[:issue].update(label_ids: [context.create(:list).label_id])
end end
end]], end]],
post_fn: -> (context, data) do post_fn: -> (context, data) do
......
...@@ -25,7 +25,7 @@ describe 'CycleAnalytics#plan' do ...@@ -25,7 +25,7 @@ describe 'CycleAnalytics#plan' do
end], end],
["list label added to issue", ["list label added to issue",
-> (context, data) do -> (context, data) do
data[:issue].update(label_ids: [context.create(:label, lists: [context.create(:list)]).id]) data[:issue].update(label_ids: [context.create(:list).label_id])
end]], end]],
end_time_conditions: [["issue mentioned in a commit", end_time_conditions: [["issue mentioned in a commit",
-> (context, data) do -> (context, data) do
......
...@@ -32,7 +32,7 @@ describe Issue::Metrics do ...@@ -32,7 +32,7 @@ describe Issue::Metrics do
context "list labels" do context "list labels" do
it "records the first time an issue is associated with a list label" do it "records the first time an issue is associated with a list label" do
list_label = create(:label, lists: [create(:list)]) list_label = create(:list).label
time = Time.now time = Time.now
Timecop.freeze(time) { subject.update(label_ids: [list_label.id]) } Timecop.freeze(time) { subject.update(label_ids: [list_label.id]) }
metrics = subject.metrics metrics = subject.metrics
...@@ -43,9 +43,9 @@ describe Issue::Metrics do ...@@ -43,9 +43,9 @@ describe Issue::Metrics do
it "does not record the second time an issue is associated with a list label" do it "does not record the second time an issue is associated with a list label" do
time = Time.now time = Time.now
first_list_label = create(:label, lists: [create(:list)]) first_list_label = create(:list).label
Timecop.freeze(time) { subject.update(label_ids: [first_list_label.id]) } Timecop.freeze(time) { subject.update(label_ids: [first_list_label.id]) }
second_list_label = create(:label, lists: [create(:list)]) second_list_label = create(:list).label
Timecop.freeze(time + 5.hours) { subject.update(label_ids: [second_list_label.id]) } Timecop.freeze(time + 5.hours) { subject.update(label_ids: [second_list_label.id]) }
metrics = subject.metrics metrics = subject.metrics
......
...@@ -1844,7 +1844,7 @@ describe NotificationService, :mailer do ...@@ -1844,7 +1844,7 @@ describe NotificationService, :mailer do
describe 'ProjectMember' do describe 'ProjectMember' do
let(:project) { create(:project) } let(:project) { create(:project) }
set(:added_user) { create(:user) } let(:added_user) { create(:user) }
describe '#new_access_request' do describe '#new_access_request' do
context 'for a project in a user namespace' do context 'for a project in a user namespace' do
......
...@@ -18,8 +18,12 @@ module MigrationsHelpers ...@@ -18,8 +18,12 @@ module MigrationsHelpers
ActiveRecord::Migrator.migrations_paths ActiveRecord::Migrator.migrations_paths
end end
def migration_context
ActiveRecord::MigrationContext.new(migrations_paths)
end
def migrations def migrations
ActiveRecord::Migrator.migrations(migrations_paths) migration_context.migrations
end end
def clear_schema_cache! def clear_schema_cache!
...@@ -96,8 +100,7 @@ module MigrationsHelpers ...@@ -96,8 +100,7 @@ module MigrationsHelpers
def schema_migrate_down! def schema_migrate_down!
disable_migrations_output do disable_migrations_output do
ActiveRecord::Migrator.migrate(migrations_paths, migration_context.down(migration_schema_version)
migration_schema_version)
end end
reset_column_in_all_models reset_column_in_all_models
...@@ -107,7 +110,7 @@ module MigrationsHelpers ...@@ -107,7 +110,7 @@ module MigrationsHelpers
reset_column_in_all_models reset_column_in_all_models
disable_migrations_output do disable_migrations_output do
ActiveRecord::Migrator.migrate(migrations_paths) migration_context.up
end end
reset_column_in_all_models reset_column_in_all_models
...@@ -123,7 +126,7 @@ module MigrationsHelpers ...@@ -123,7 +126,7 @@ module MigrationsHelpers
end end
def migrate! def migrate!
ActiveRecord::Migrator.up(migrations_paths) do |migration| migration_context.up do |migration|
migration.name == described_class.name migration.name == described_class.name
end end
end end
......
...@@ -28,7 +28,7 @@ describe 'notify/pipeline_failed_email.html.haml' do ...@@ -28,7 +28,7 @@ describe 'notify/pipeline_failed_email.html.haml' do
expect(rendered).to have_content "Your pipeline has failed" expect(rendered).to have_content "Your pipeline has failed"
expect(rendered).to have_content pipeline.project.name expect(rendered).to have_content pipeline.project.name
expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ') expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}" expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content pipeline.user.name expect(rendered).to have_content pipeline.user.name
...@@ -45,7 +45,7 @@ describe 'notify/pipeline_failed_email.html.haml' do ...@@ -45,7 +45,7 @@ describe 'notify/pipeline_failed_email.html.haml' do
expect(rendered).to have_content "Your pipeline has failed" expect(rendered).to have_content "Your pipeline has failed"
expect(rendered).to have_content pipeline.project.name expect(rendered).to have_content pipeline.project.name
expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ') expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}" expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content "by API" expect(rendered).to have_content "by API"
......
...@@ -30,7 +30,7 @@ describe 'notify/pipeline_failed_email.text.erb' do ...@@ -30,7 +30,7 @@ describe 'notify/pipeline_failed_email.text.erb' do
expect(rendered).to have_content('Your pipeline has failed') expect(rendered).to have_content('Your pipeline has failed')
expect(rendered).to have_content(pipeline.project.name) expect(rendered).to have_content(pipeline.project.name)
expect(rendered).to have_content(pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ')) expect(rendered).to have_content(pipeline.git_commit_message.truncate(50).gsub(/\s+/, ' '))
expect(rendered).to have_content(pipeline.commit.author_name) expect(rendered).to have_content(pipeline.commit.author_name)
expect(rendered).to have_content("##{pipeline.id}") expect(rendered).to have_content("##{pipeline.id}")
expect(rendered).to have_content(pipeline.user.name) expect(rendered).to have_content(pipeline.user.name)
......
...@@ -28,7 +28,7 @@ describe 'notify/pipeline_success_email.html.haml' do ...@@ -28,7 +28,7 @@ describe 'notify/pipeline_success_email.html.haml' do
expect(rendered).to have_content "Your pipeline has passed" expect(rendered).to have_content "Your pipeline has passed"
expect(rendered).to have_content pipeline.project.name expect(rendered).to have_content pipeline.project.name
expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ') expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}" expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content pipeline.user.name expect(rendered).to have_content pipeline.user.name
...@@ -45,7 +45,7 @@ describe 'notify/pipeline_success_email.html.haml' do ...@@ -45,7 +45,7 @@ describe 'notify/pipeline_success_email.html.haml' do
expect(rendered).to have_content "Your pipeline has passed" expect(rendered).to have_content "Your pipeline has passed"
expect(rendered).to have_content pipeline.project.name expect(rendered).to have_content pipeline.project.name
expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub!(/\s+/, ' ') expect(rendered).to have_content pipeline.git_commit_message.truncate(50).gsub(/\s+/, ' ')
expect(rendered).to have_content pipeline.commit.author_name expect(rendered).to have_content pipeline.commit.author_name
expect(rendered).to have_content "##{pipeline.id}" expect(rendered).to have_content "##{pipeline.id}"
expect(rendered).to have_content "by API" expect(rendered).to have_content "by API"
......
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