Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/gems
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-10-19 15:57:54 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-10-19 15:57:54 +0300
commit419c53ec62de6e97a517abd5fdd4cbde3a942a34 (patch)
tree1f43a548b46bca8a5fb8fe0c31cef1883d49c5b6 /gems
parent1da20d9135b3ad9e75e65b028bffc921aaf8deb7 (diff)
Add latest changes from gitlab-org/gitlab@16-5-stable-eev16.5.0-rc42
Diffstat (limited to 'gems')
-rw-r--r--gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning.rb5
-rw-r--r--gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning/base.rb8
-rw-r--r--gems/activerecord-gitlab/lib/active_record/gitlab_patches/rescue_from.rb11
-rw-r--r--gems/activerecord-gitlab/spec/active_record/gitlab_patches/partitioning/locking_spec.rb34
-rw-r--r--gems/activerecord-gitlab/spec/active_record/gitlab_patches/rescue_from_spec.rb18
-rw-r--r--gems/activerecord-gitlab/spec/support/database.rb8
-rw-r--r--gems/activerecord-gitlab/spec/support/models.rb11
-rw-r--r--gems/click_house-client/lib/click_house/client/formatter.rb3
-rw-r--r--gems/click_house-client/spec/click_house/client/formatter_spec.rb13
-rw-r--r--gems/config/rubocop.yml2
-rw-r--r--gems/csv_builder/lib/csv_builder/gzip.rb11
-rw-r--r--gems/gitlab-http/.rubocop.yml6
-rw-r--r--gems/gitlab-http/Gemfile.lock4
-rw-r--r--gems/gitlab-http/gitlab-http.gemspec4
-rw-r--r--gems/gitlab-http/lib/gitlab/http_v2/client.rb104
-rw-r--r--gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb8
-rw-r--r--gems/gitlab-http/lib/net_http/response_patch.rb11
-rw-r--r--gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb2
-rw-r--r--gems/gitlab-schema-validation/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter.rb2
-rw-r--r--gems/gitlab-schema-validation/lib/gitlab/schema/validation/sources/database.rb6
-rw-r--r--gems/gitlab-schema-validation/spec/fixtures/structure.sql3
-rw-r--r--gems/gitlab-schema-validation/spec/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter_spec.rb3
-rw-r--r--gems/gitlab-utils/.rubocop.yml3
-rw-r--r--gems/gitlab-utils/lib/gitlab/version_info.rb12
-rw-r--r--gems/gitlab-utils/spec/gitlab/version_info_spec.rb34
-rw-r--r--gems/rspec_flaky/.rubocop.yml3
-rw-r--r--gems/rspec_flaky/Gemfile.lock2
-rw-r--r--gems/rspec_flaky/rspec_flaky.gemspec2
28 files changed, 245 insertions, 88 deletions
diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning.rb
index cf0bd4849e2..2f3dde2a871 100644
--- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning.rb
+++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning.rb
@@ -34,9 +34,12 @@ module ActiveRecord
::ActiveRecord::Reflection::MacroReflection.prepend(
ActiveRecord::GitlabPatches::Partitioning::Reflection::MacroReflection
)
- ::ActiveRecord::Base.prepend(
+ ::ActiveRecord::Persistence.prepend(
ActiveRecord::GitlabPatches::Partitioning::Base
)
+ ::ActiveRecord::Persistence::ClassMethods.prepend(
+ ActiveRecord::GitlabPatches::Partitioning::Base::ClassMethods
+ )
end
end
end
diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning/base.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning/base.rb
index 0c8a248b984..c4b3528a526 100644
--- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning/base.rb
+++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/partitioning/base.rb
@@ -4,19 +4,18 @@ if ::ActiveRecord::VERSION::STRING >= "7.1"
raise 'New version of active-record detected, please remove or update this patch'
end
+# rubocop:disable Gitlab/ModuleWithInstanceVariables
module ActiveRecord
module GitlabPatches
module Partitioning
module Base
- extend ActiveSupport::Concern
-
def _query_constraints_hash
constraints_hash = super
return constraints_hash unless self.class.use_partition_id_filter?
if self.class.query_constraints_list.nil?
- { @primary_key => id_in_database } # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ { @primary_key => id_in_database }
else
self.class.query_constraints_list.index_with do |column_name|
attribute_in_database(column_name)
@@ -24,7 +23,7 @@ module ActiveRecord
end
end
- class_methods do
+ module ClassMethods
def use_partition_id_filter?
false
end
@@ -47,3 +46,4 @@ module ActiveRecord
end
end
end
+# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/rescue_from.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/rescue_from.rb
index faabddd2686..eaaa90ec52b 100644
--- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/rescue_from.rb
+++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/rescue_from.rb
@@ -7,6 +7,7 @@ module ActiveRecord
#
# - `ActiveRecord::Relation#load`, and other methods that call
# `ActiveRecord::Relation#exec_queries`.
+ # - `ActiveModel::UnknownAttributeError` as a result of `ActiveRecord::Base#assign_attributes`
#
# class ApplicationRecord < ActiveRecord::Base
# rescue_from MyException, with: :my_handler
@@ -29,13 +30,23 @@ module ActiveRecord
def exec_queries
super
rescue StandardError => e
+ # Method klass is defined in ActiveRecord gem lib/active_record/relation.rb
klass.rescue_with_handler(e) || raise
end
end
+
+ module AssignAttributesRescueWithHandler
+ def _assign_attributes(...)
+ super(...)
+ rescue StandardError => e
+ rescue_with_handler(e) || raise
+ end
+ end
end
end
ActiveSupport.on_load(:active_record) do
ActiveRecord::Relation.prepend(ActiveRecord::GitlabPatches::ExecQueriesRescueWithHandler)
+ ActiveRecord::Base.prepend(ActiveRecord::GitlabPatches::AssignAttributesRescueWithHandler)
ActiveRecord::Base.prepend(ActiveRecord::GitlabPatches::RescueFrom)
end
diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/partitioning/locking_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/partitioning/locking_spec.rb
new file mode 100644
index 00000000000..df9241e0983
--- /dev/null
+++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/partitioning/locking_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+RSpec.describe 'ActiveRecord::GitlabPatches::Partitioning::Associations::Locking', :partitioning do
+ let!(:job) { LockingJob.create!(partition_id: 100) }
+
+ describe 'optimistic locking' do
+ it 'does not use lock version on unrelated updates' do
+ update_statement = <<~SQL.squish
+ UPDATE "locking_jobs" SET "name" = 'test'
+ WHERE "locking_jobs"."id" = #{job.id} AND "locking_jobs"."partition_id" = #{job.partition_id}
+ SQL
+
+ result = QueryRecorder.log do
+ job.update!(name: 'test')
+ end
+
+ expect(result).to include(update_statement)
+ end
+
+ it 'uses lock version when status changes' do
+ update_statement = <<~SQL.squish
+ UPDATE "locking_jobs"
+ SET "status" = 1, "name" = 'test', "lock_version" = 1
+ WHERE "locking_jobs"."id" = 1 AND "locking_jobs"."partition_id" = 100 AND "locking_jobs"."lock_version" = 0
+ SQL
+
+ result = QueryRecorder.log do
+ job.update!(name: 'test', status: :completed)
+ end
+
+ expect(result).to include(update_statement)
+ end
+ end
+end
diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/rescue_from_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/rescue_from_spec.rb
index 22729edb014..0a70c4dddaf 100644
--- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/rescue_from_spec.rb
+++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/rescue_from_spec.rb
@@ -4,10 +4,13 @@ RSpec.describe ActiveRecord::GitlabPatches::RescueFrom do
let(:model_with_rescue_from) do
Class.new(Project) do
rescue_from ActiveRecord::StatementInvalid, with: :handle_exception
+ rescue_from ActiveRecord::UnknownAttributeError, with: :handle_attr_exception
class << self
def handle_exception(exception); end
end
+
+ def handle_attr_exception(exc); end
end
end
@@ -26,4 +29,19 @@ RSpec.describe ActiveRecord::GitlabPatches::RescueFrom do
expect { model_without_rescue_from.where('BADQUERY').load }.to raise_error(ActiveRecord::StatementInvalid)
end
end
+
+ context 'for errors from ActiveRecord::Base.assign_attributes' do
+ it 'triggers rescue_from' do
+ model_instance = model_with_rescue_from.new
+
+ expect(model_instance).to receive(:handle_attr_exception)
+
+ expect { model_instance.assign_attributes(nonexistent_column: "some value") }.not_to raise_error
+ end
+
+ it 'does not trigger rescue_from' do
+ expect { model_without_rescue_from.new.assign_attributes(nonexistent_column: "some value") }
+ .to raise_error(ActiveRecord::UnknownAttributeError)
+ end
+ end
end
diff --git a/gems/activerecord-gitlab/spec/support/database.rb b/gems/activerecord-gitlab/spec/support/database.rb
index 998d945c311..7b4de82312d 100644
--- a/gems/activerecord-gitlab/spec/support/database.rb
+++ b/gems/activerecord-gitlab/spec/support/database.rb
@@ -24,6 +24,14 @@ RSpec.configure do |config|
t.integer :partition_id
t.boolean :test_flag, default: false
end
+
+ create_table :locking_jobs, force: true do |t|
+ t.integer :pipeline_id
+ t.integer :partition_id
+ t.integer :lock_version, default: 0, null: false
+ t.integer :status, default: 0, null: false
+ t.string :name
+ end
end
end
end
diff --git a/gems/activerecord-gitlab/spec/support/models.rb b/gems/activerecord-gitlab/spec/support/models.rb
index c0017656ea8..445dc8b2ac2 100644
--- a/gems/activerecord-gitlab/spec/support/models.rb
+++ b/gems/activerecord-gitlab/spec/support/models.rb
@@ -48,3 +48,14 @@ class Metadata < PartitionedRecord
belongs_to :job,
->(metadata) { where(partition_id: metadata.partition_id) }
end
+
+class LockingJob < PartitionedRecord
+ self.table_name = :locking_jobs
+ query_constraints :id, :partition_id
+
+ enum status: { created: 0, completed: 1 }
+
+ def locking_enabled?
+ will_save_change_to_status?
+ end
+end
diff --git a/gems/click_house-client/lib/click_house/client/formatter.rb b/gems/click_house-client/lib/click_house/client/formatter.rb
index de7ae72bdf8..a19c55e3e3d 100644
--- a/gems/click_house-client/lib/click_house/client/formatter.rb
+++ b/gems/click_house-client/lib/click_house/client/formatter.rb
@@ -8,7 +8,8 @@ module ClickHouse
TYPE_CASTERS = {
'UInt64' => ->(value) { Integer(value) },
"DateTime64(6, 'UTC')" => ->(value) { ActiveSupport::TimeZone['UTC'].parse(value) },
- "IntervalSecond" => ->(value) { ActiveSupport::Duration.build(value.to_i) }
+ "IntervalSecond" => ->(value) { ActiveSupport::Duration.build(value.to_i) },
+ "IntervalMillisecond" => ->(value) { ActiveSupport::Duration.build(value.to_i / 1000.0) }
}.freeze
def self.format(result)
diff --git a/gems/click_house-client/spec/click_house/client/formatter_spec.rb b/gems/click_house-client/spec/click_house/client/formatter_spec.rb
index 0af3aa0bdbc..ca57187b098 100644
--- a/gems/click_house-client/spec/click_house/client/formatter_spec.rb
+++ b/gems/click_house-client/spec/click_house/client/formatter_spec.rb
@@ -8,7 +8,8 @@ RSpec.describe ClickHouse::Client::Formatter do
_query = <<~SQL.squish
SELECT toUInt64(1) as uint64,
toDateTime64('2016-06-15 23:00:00', 6, 'UTC') as datetime64_6,
- INTERVAL 1 second as interval_second
+ INTERVAL 1 second as interval_second,
+ INTERVAL 1 millisecond as interval_millisecond
SQL
response_json = <<~JSON
@@ -26,6 +27,10 @@ RSpec.describe ClickHouse::Client::Formatter do
{
"name": "interval_second",
"type": "IntervalSecond"
+ },
+ {
+ "name": "interval_millisecond",
+ "type": "IntervalMillisecond"
}
],
@@ -34,7 +39,8 @@ RSpec.describe ClickHouse::Client::Formatter do
{
"uint64": "1",
"datetime64_6": "2016-06-15 23:00:00.000000",
- "interval_second": "1"
+ "interval_second": "1",
+ "interval_millisecond": "1"
}
],
@@ -56,7 +62,8 @@ RSpec.describe ClickHouse::Client::Formatter do
eq(
[{ "uint64" => 1,
"datetime64_6" => ActiveSupport::TimeZone["UTC"].parse("2016-06-15 23:00:00"),
- "interval_second" => 1.second }]
+ "interval_second" => 1.second,
+ "interval_millisecond" => 0.001.seconds }]
)
)
end
diff --git a/gems/config/rubocop.yml b/gems/config/rubocop.yml
index 72b37aa60b5..d6139bef1b5 100644
--- a/gems/config/rubocop.yml
+++ b/gems/config/rubocop.yml
@@ -93,7 +93,7 @@ RSpec/ContextWording:
- 'if'
# This cop doesn't make sense in the context of gems
-RSpec/MissingFeatureCategory:
+RSpec/FeatureCategory:
Enabled: false
# Enable once we drop 3.0 support
diff --git a/gems/csv_builder/lib/csv_builder/gzip.rb b/gems/csv_builder/lib/csv_builder/gzip.rb
index f97c066705a..83a83970acd 100644
--- a/gems/csv_builder/lib/csv_builder/gzip.rb
+++ b/gems/csv_builder/lib/csv_builder/gzip.rb
@@ -12,12 +12,15 @@ module CsvBuilder
# > puts rows
# > end
def render
- Tempfile.open(['csv_builder_gzip', '.csv.gz']) do |tempfile|
- csv = CSV.new(Zlib::GzipWriter.open(tempfile.path))
+ Tempfile.create(['csv_builder_gzip', '.csv.gz']) do |tempfile|
+ Zlib::GzipWriter.open(tempfile.path) do |gz|
+ csv = CSV.new(gz)
- write_csv csv, until_condition: -> {} # truncation must be handled outside of the CsvBuilder
+ write_csv csv, until_condition: -> {} # truncation must be handled outside of the CsvBuilder
+
+ csv.close
+ end
- csv.close
yield tempfile, @rows_written
end
end
diff --git a/gems/gitlab-http/.rubocop.yml b/gems/gitlab-http/.rubocop.yml
index 73ea5f610b3..8bc6b6a4cfb 100644
--- a/gems/gitlab-http/.rubocop.yml
+++ b/gems/gitlab-http/.rubocop.yml
@@ -1,13 +1,13 @@
inherit_from:
- ../config/rubocop.yml
+Gemfile/MissingFeatureCategory:
+ Enabled: false
+
Naming/ClassAndModuleCamelCase:
AllowedNames:
- HTTP_V2
-Performance/RegexpMatch:
- Enabled: false
-
Style/SpecialGlobalVars:
Enabled: false
diff --git a/gems/gitlab-http/Gemfile.lock b/gems/gitlab-http/Gemfile.lock
index 4afa39ef750..c15bcd7cc18 100644
--- a/gems/gitlab-http/Gemfile.lock
+++ b/gems/gitlab-http/Gemfile.lock
@@ -19,11 +19,11 @@ PATH
remote: .
specs:
gitlab-http (0.1.0)
- activesupport (~> 7.0.6)
+ activesupport (~> 7)
httparty (~> 0.21.0)
ipaddress (~> 0.8.3)
nokogiri (~> 1.15.4)
- railties (~> 7.0.6)
+ railties (~> 7)
GEM
remote: https://rubygems.org/
diff --git a/gems/gitlab-http/gitlab-http.gemspec b/gems/gitlab-http/gitlab-http.gemspec
index 2653d4d4fb7..6146ba7f78b 100644
--- a/gems/gitlab-http/gitlab-http.gemspec
+++ b/gems/gitlab-http/gitlab-http.gemspec
@@ -19,11 +19,11 @@ Gem::Specification.new do |spec|
spec.test_files = Dir['spec/**/*']
spec.require_paths = ["lib"]
- spec.add_runtime_dependency 'activesupport', '~> 7.0.6'
+ spec.add_runtime_dependency 'activesupport', '~> 7'
spec.add_runtime_dependency 'httparty', '~> 0.21.0'
spec.add_runtime_dependency 'ipaddress', '~> 0.8.3'
spec.add_runtime_dependency 'nokogiri', '~> 1.15.4'
- spec.add_runtime_dependency "railties", "~> 7.0.6"
+ spec.add_runtime_dependency "railties", "~> 7"
spec.add_development_dependency 'gitlab-styles', '~> 10.1.0'
spec.add_development_dependency 'rspec-rails', '~> 6.0.3'
diff --git a/gems/gitlab-http/lib/gitlab/http_v2/client.rb b/gems/gitlab-http/lib/gitlab/http_v2/client.rb
index 8daf19d7351..c10197e0385 100644
--- a/gems/gitlab-http/lib/gitlab/http_v2/client.rb
+++ b/gems/gitlab-http/lib/gitlab/http_v2/client.rb
@@ -25,70 +25,74 @@ module Gitlab
include HTTParty # rubocop:disable Gitlab/HTTParty
- class << self
- alias_method :httparty_perform_request, :perform_request
- end
-
connection_adapter NewConnectionAdapter
- def self.perform_request(http_method, path, options, &block)
- raise_if_blocked_by_silent_mode(http_method) if options.delete(:silent_mode_enabled)
+ class << self
+ def try_get(path, options = {}, &block)
+ self.get(path, options, &block) # rubocop:disable Style/RedundantSelf
+ rescue *HTTP_ERRORS
+ nil
+ end
- log_info = options.delete(:extra_log_info)
- options_with_timeouts =
- if !options.has_key?(:timeout)
- options.with_defaults(DEFAULT_TIMEOUT_OPTIONS)
- else
- options
- end
+ def configuration
+ Gitlab::HTTP_V2.configuration
+ end
- if options[:stream_body]
- httparty_perform_request(http_method, path, options_with_timeouts, &block)
- else
- begin
- start_time = nil
- read_total_timeout = options.fetch(:timeout, DEFAULT_READ_TOTAL_TIMEOUT)
+ private
- httparty_perform_request(http_method, path, options_with_timeouts) do |fragment|
- start_time ||= system_monotonic_time
- elapsed = system_monotonic_time - start_time
+ alias_method :httparty_perform_request, :perform_request
- raise ReadTotalTimeout, "Request timed out after #{elapsed} seconds" if elapsed > read_total_timeout
+ # TODO: This overwrites a method implemented by `HTTPParty`
+ # The calls to `get/...` will call this method instead of `httparty_perform_request`
+ def perform_request(http_method, path, options, &block)
+ raise_if_blocked_by_silent_mode(http_method) if options.delete(:silent_mode_enabled)
+
+ log_info = options.delete(:extra_log_info)
+ options_with_timeouts =
+ if !options.has_key?(:timeout)
+ options.with_defaults(DEFAULT_TIMEOUT_OPTIONS)
+ else
+ options
+ end
- yield fragment if block
+ if options[:stream_body]
+ httparty_perform_request(http_method, path, options_with_timeouts, &block)
+ else
+ begin
+ start_time = nil
+ read_total_timeout = options.fetch(:timeout, DEFAULT_READ_TOTAL_TIMEOUT)
+
+ httparty_perform_request(http_method, path, options_with_timeouts) do |fragment|
+ start_time ||= system_monotonic_time
+ elapsed = system_monotonic_time - start_time
+
+ raise ReadTotalTimeout, "Request timed out after #{elapsed} seconds" if elapsed > read_total_timeout
+
+ yield fragment if block
+ end
+ rescue HTTParty::RedirectionTooDeep
+ raise RedirectionTooDeep
+ rescue *HTTP_ERRORS => e
+ extra_info = log_info || {}
+ extra_info = log_info.call(e, path, options) if log_info.respond_to?(:call)
+ configuration.log_exception(e, extra_info)
+
+ raise e
end
- rescue HTTParty::RedirectionTooDeep
- raise RedirectionTooDeep
- rescue *HTTP_ERRORS => e
- extra_info = log_info || {}
- extra_info = log_info.call(e, path, options) if log_info.respond_to?(:call)
- configuration.log_exception(e, extra_info)
-
- raise e
end
end
- end
-
- def self.try_get(path, options = {}, &block)
- self.get(path, options, &block) # rubocop:disable Style/RedundantSelf
- rescue *HTTP_ERRORS
- nil
- end
- def self.raise_if_blocked_by_silent_mode(http_method)
- return if SILENT_MODE_ALLOWED_METHODS.include?(http_method)
+ def raise_if_blocked_by_silent_mode(http_method)
+ return if SILENT_MODE_ALLOWED_METHODS.include?(http_method)
- configuration.silent_mode_log_info('Outbound HTTP request blocked', http_method.to_s)
+ configuration.silent_mode_log_info('Outbound HTTP request blocked', http_method.to_s)
- raise SilentModeBlockedError, 'only get, head, options, and trace methods are allowed in silent mode'
- end
-
- def self.system_monotonic_time
- Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
- end
+ raise SilentModeBlockedError, 'only get, head, options, and trace methods are allowed in silent mode'
+ end
- def self.configuration
- Gitlab::HTTP_V2.configuration
+ def system_monotonic_time
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
+ end
end
end
end
diff --git a/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb b/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb
index a794ab2f443..878daf42d8a 100644
--- a/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb
+++ b/gems/gitlab-http/lib/gitlab/http_v2/url_blocker.rb
@@ -188,7 +188,7 @@ module Gitlab
#
# @param uri [Addressable::URI]
#
- # @raise [Gitlab::UrlBlocker::BlockedUrlError, ArgumentError] - BlockedUrlError raised if host is too long.
+ # @raise [Gitlab::HTTP_V2::UrlBlocker::BlockedUrlError, ArgumentError] raised if host is too long.
#
# @return [Array<Addrinfo>]
def get_address_info(uri)
@@ -271,7 +271,7 @@ module Gitlab
def multiline_blocked?(parsed_url)
url = parsed_url.to_s
- return true if url =~ /\n|\r/
+ return true if /\n|\r/.match?(url)
# Google Cloud Storage uses a multi-line, encoded Signature query string
return false if %w[http https].include?(parsed_url.scheme&.downcase)
@@ -295,7 +295,7 @@ module Gitlab
def validate_user(value)
return if value.blank?
- return if value =~ /\A\p{Alnum}/
+ return if /\A\p{Alnum}/.match?(value)
raise BlockedUrlError, "Username needs to start with an alphanumeric character"
end
@@ -303,7 +303,7 @@ module Gitlab
def validate_hostname(value)
return if value.blank?
return if IPAddress.valid?(value)
- return if value =~ /\A\p{Alnum}/
+ return if /\A\p{Alnum}/.match?(value)
raise BlockedUrlError, "Hostname or IP address invalid"
end
diff --git a/gems/gitlab-http/lib/net_http/response_patch.rb b/gems/gitlab-http/lib/net_http/response_patch.rb
index e5477a31318..303d629b32e 100644
--- a/gems/gitlab-http/lib/net_http/response_patch.rb
+++ b/gems/gitlab-http/lib/net_http/response_patch.rb
@@ -20,11 +20,12 @@ module Net
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
key = value = nil
while true
- line = if sock.is_a?(Gitlab::HTTP_V2::BufferedIo)
- sock.readuntil("\n", true, start_time)
- else
- sock.readuntil("\n", true)
- end
+ uses_buffered_io = sock.is_a?(Gitlab::HTTP_V2::BufferedIo)
+
+ # TODO: Gitlab::BufferedIo is temporarily used for an easy migration.
+ uses_buffered_io ||= sock.is_a?(Gitlab::BufferedIo) if defined?(Gitlab::BufferedIo)
+
+ line = uses_buffered_io ? sock.readuntil("\n", true, start_time) : sock.readuntil("\n", true)
line = line.sub(/\s{0,10}\z/, '')
break if line.empty?
if line[0] == ?\s or line[0] == ?\t and value
diff --git a/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb b/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb
index b82646fb365..f34b0d98403 100644
--- a/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb
+++ b/gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'net/http'
-RSpec.describe 'Net::HTTP patch proxy user and password encoding' do
+RSpec.describe 'Net::HTTP patch proxy user and password encoding', feature_category: :shared do
let(:net_http) { Net::HTTP.new('hostname.example') }
before do
diff --git a/gems/gitlab-schema-validation/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter.rb b/gems/gitlab-schema-validation/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter.rb
index 62e501bf16b..5b6026a1f73 100644
--- a/gems/gitlab-schema-validation/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter.rb
+++ b/gems/gitlab-schema-validation/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter.rb
@@ -36,7 +36,7 @@ module Gitlab
value = parse_node(constraints.find { |node| node.constraint.contype == DEFAULT_CONSTR })
- return unless value
+ return if value.nil?
"DEFAULT #{value}"
end
diff --git a/gems/gitlab-schema-validation/lib/gitlab/schema/validation/sources/database.rb b/gems/gitlab-schema-validation/lib/gitlab/schema/validation/sources/database.rb
index 45ce4d8ebfe..3f62396c156 100644
--- a/gems/gitlab-schema-validation/lib/gitlab/schema/validation/sources/database.rb
+++ b/gems/gitlab-schema-validation/lib/gitlab/schema/validation/sources/database.rb
@@ -143,8 +143,10 @@ module Gitlab
# rubocop:disable Rails/SquishedSQLHeredocs
sql = <<~SQL
SELECT indexname, indexdef
- FROM pg_indexes
- WHERE indexname NOT LIKE '%_pkey' AND schemaname IN ($1, $2);
+ FROM pg_indexes i
+ LEFT JOIN pg_constraint AS c ON i.indexname = c.conname
+ WHERE i.indexname NOT LIKE '%_pkey' AND schemaname IN ($1, $2)
+ AND c.conname IS NULL;
SQL
# rubocop:enable Rails/SquishedSQLHeredocs
diff --git a/gems/gitlab-schema-validation/spec/fixtures/structure.sql b/gems/gitlab-schema-validation/spec/fixtures/structure.sql
index 421fb6c3593..7bb68734c72 100644
--- a/gems/gitlab-schema-validation/spec/fixtures/structure.sql
+++ b/gems/gitlab-schema-validation/spec/fixtures/structure.sql
@@ -19,7 +19,8 @@ CREATE TABLE test_table (
numeric_column numeric NOT NULL,
numeric_with_default_column numeric DEFAULT 1.0 NOT NULL,
boolean_colum boolean,
- boolean_with_default_colum boolean DEFAULT true NOT NULL,
+ boolean_with_default_column_true boolean DEFAULT true NOT NULL,
+ boolean_with_default_column_false boolean DEFAULT false NOT NULL,
double_precision_column double precision,
double_precision_with_default_column double precision DEFAULT 1.0,
varying_column character varying,
diff --git a/gems/gitlab-schema-validation/spec/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter_spec.rb b/gems/gitlab-schema-validation/spec/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter_spec.rb
index ae0d635e8ca..1c44db5286a 100644
--- a/gems/gitlab-schema-validation/spec/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter_spec.rb
+++ b/gems/gitlab-schema-validation/spec/lib/gitlab/schema/validation/adapters/column_structure_sql_adapter_spec.rb
@@ -21,7 +21,8 @@ RSpec.describe Gitlab::Schema::Validation::Adapters::ColumnStructureSqlAdapter,
['smallint_with_default_column', 'smallint', 'DEFAULT 0', 'NOT NULL', false],
['double_precision_with_default_column', 'double precision', 'DEFAULT 1.0', nil, false],
['numeric_with_default_column', 'numeric', 'DEFAULT 1.0', 'NOT NULL', false],
- ['boolean_with_default_colum', 'boolean', 'DEFAULT true', 'NOT NULL', false],
+ ['boolean_with_default_column_true', 'boolean', 'DEFAULT true', 'NOT NULL', false],
+ ['boolean_with_default_column_false', 'boolean', 'DEFAULT false', 'NOT NULL', false],
['varying_with_default_column', 'character varying', "DEFAULT 'DEFAULT'::character varying", 'NOT NULL', false],
['varying_with_limit_and_default_column', 'character varying(255)', "DEFAULT 'DEFAULT'::character varying",
nil, false],
diff --git a/gems/gitlab-utils/.rubocop.yml b/gems/gitlab-utils/.rubocop.yml
index eeafd850c9b..bea4262fa2b 100644
--- a/gems/gitlab-utils/.rubocop.yml
+++ b/gems/gitlab-utils/.rubocop.yml
@@ -1,6 +1,9 @@
inherit_from:
- ../config/rubocop.yml
+Gemfile/MissingFeatureCategory:
+ Enabled: false
+
RSpec/InstanceVariable:
Exclude:
- spec/**/*.rb
diff --git a/gems/gitlab-utils/lib/gitlab/version_info.rb b/gems/gitlab-utils/lib/gitlab/version_info.rb
index 00a9b4ddc6e..21478c46259 100644
--- a/gems/gitlab-utils/lib/gitlab/version_info.rb
+++ b/gems/gitlab-utils/lib/gitlab/version_info.rb
@@ -7,10 +7,22 @@ module Gitlab
attr_reader :major, :minor, :patch
VERSION_REGEX = /(\d+)\.(\d+)\.(\d+)/
+ MILESTONE_REGEX = /\A(\d+)\.(\d+)\z/
# To mitigate ReDoS, limit the length of the version string we're
# willing to check
MAX_VERSION_LENGTH = 128
+ InvalidMilestoneError = Class.new(StandardError)
+
+ def self.parse_from_milestone(str)
+ raise InvalidMilestoneError if str.length > MAX_VERSION_LENGTH
+
+ m = MILESTONE_REGEX.match(str)
+ raise InvalidMilestoneError if m.nil?
+
+ VersionInfo.new(m[1].to_i, m[2].to_i)
+ end
+
def self.parse(str, parse_suffix: false)
return str if str.is_a?(self)
diff --git a/gems/gitlab-utils/spec/gitlab/version_info_spec.rb b/gems/gitlab-utils/spec/gitlab/version_info_spec.rb
index 2b5f6bcb4c1..ca13a06b92c 100644
--- a/gems/gitlab-utils/spec/gitlab/version_info_spec.rb
+++ b/gems/gitlab-utils/spec/gitlab/version_info_spec.rb
@@ -130,6 +130,40 @@ RSpec.describe Gitlab::VersionInfo, feature_category: :shared do
end
end
+ describe '.parse_from_milestone' do
+ subject(:milestone) { described_class.parse_from_milestone(milestone_str) }
+
+ context 'when the milestone string is valid' do
+ let(:milestone_str) { '14.7' }
+
+ it "creates a #{described_class.class} with patch version zero" do
+ expect(milestone.major).to eq 14
+ expect(milestone.minor).to eq 7
+ expect(milestone.patch).to eq 0
+ end
+ end
+
+ context 'when the milestone string is not valid' do
+ let(:milestone_str) { 'foo' }
+
+ it 'raises InvalidMilestoneError' do
+ expect do
+ milestone
+ end.to raise_error "#{described_class}::InvalidMilestoneError".constantize
+ end
+ end
+
+ context 'when the milestone string is too long' do
+ let(:milestone_str) { 'a' * 129 }
+
+ it 'raises InvalidMilestoneError' do
+ expect do
+ milestone
+ end.to raise_error "#{described_class}::InvalidMilestoneError".constantize
+ end
+ end
+ end
+
describe '.to_s' do
it { expect(@v1_0_0.to_s).to eq("1.0.0") }
it { expect(@v1_0_1_rc1.to_s).to eq("1.0.1-rc1") }
diff --git a/gems/rspec_flaky/.rubocop.yml b/gems/rspec_flaky/.rubocop.yml
index 62cb8a982c5..66f8eb6e21c 100644
--- a/gems/rspec_flaky/.rubocop.yml
+++ b/gems/rspec_flaky/.rubocop.yml
@@ -1,6 +1,9 @@
inherit_from:
- ../config/rubocop.yml
+Gemfile/MissingFeatureCategory:
+ Enabled: false
+
# FIXME once Gitlab::Json is in a gem
Gitlab/Json:
Enabled: false
diff --git a/gems/rspec_flaky/Gemfile.lock b/gems/rspec_flaky/Gemfile.lock
index 547dc24e375..3f40a41483e 100644
--- a/gems/rspec_flaky/Gemfile.lock
+++ b/gems/rspec_flaky/Gemfile.lock
@@ -9,7 +9,7 @@ PATH
remote: .
specs:
rspec_flaky (0.1.0)
- activesupport (>= 6.1, < 7.1)
+ activesupport (>= 6.1, < 8)
rspec (~> 3.0)
GEM
diff --git a/gems/rspec_flaky/rspec_flaky.gemspec b/gems/rspec_flaky/rspec_flaky.gemspec
index 5c0a434218f..6ddbe4afd1e 100644
--- a/gems/rspec_flaky/rspec_flaky.gemspec
+++ b/gems/rspec_flaky/rspec_flaky.gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
spec.files = Dir["lib/**/*.rb"]
spec.require_paths = ["lib"]
- spec.add_runtime_dependency "activesupport", ">= 6.1", "< 7.1"
+ spec.add_runtime_dependency "activesupport", ">= 6.1", "< 8"
spec.add_runtime_dependency "rspec", "~> 3.0"
spec.add_development_dependency "gitlab-styles", "~> 10.1.0"