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/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-23 12:14:52 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-23 12:14:52 +0300
commit347bf09d6ecf4871da234c06ca8ee541e27b5105 (patch)
tree2ad6943e0c681c22acc8850d1debc6a983b0e006 /lib
parent0a51be0866d33273070f535257626a9eb2e10700 (diff)
Add latest changes from gitlab-org/gitlab@13-10-stable-eev13.10.0-rc20210223090520
Diffstat (limited to 'lib')
-rw-r--r--lib/api/api.rb2
-rw-r--r--lib/api/concerns/packages/npm_endpoints.rb14
-rw-r--r--lib/api/helpers/packages/npm.rb23
-rw-r--r--lib/api/lint.rb2
-rw-r--r--lib/api/nuget_project_packages.rb5
-rw-r--r--lib/api/rubygem_packages.rb39
-rw-r--r--lib/backup/repositories.rb7
-rw-r--r--lib/banzai/filter/video_link_filter.rb2
-rw-r--r--lib/bulk_imports/common/loaders/entity_loader.rb15
-rw-r--r--lib/bulk_imports/common/transformers/award_emoji_transformer.rb2
-rw-r--r--lib/bulk_imports/common/transformers/prohibited_attributes_transformer.rb4
-rw-r--r--lib/bulk_imports/groups/extractors/subgroups_extractor.rb2
-rw-r--r--lib/bulk_imports/groups/graphql/get_labels_query.rb4
-rw-r--r--lib/bulk_imports/groups/loaders/group_loader.rb4
-rw-r--r--lib/bulk_imports/groups/loaders/labels_loader.rb15
-rw-r--r--lib/bulk_imports/groups/loaders/members_loader.rb17
-rw-r--r--lib/bulk_imports/groups/pipelines/labels_pipeline.rb4
-rw-r--r--lib/bulk_imports/groups/pipelines/members_pipeline.rb6
-rw-r--r--lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline.rb5
-rw-r--r--lib/bulk_imports/groups/transformers/group_attributes_transformer.rb13
-rw-r--r--lib/bulk_imports/groups/transformers/member_attributes_transformer.rb2
-rw-r--r--lib/bulk_imports/groups/transformers/subgroup_to_entity_transformer.rb2
-rw-r--r--lib/bulk_imports/pipeline.rb74
-rw-r--r--lib/csv_builder.rb5
-rw-r--r--lib/gitlab/analytics/cycle_analytics/average.rb48
-rw-r--r--lib/gitlab/analytics/cycle_analytics/data_collector.rb6
-rw-r--r--lib/gitlab/analytics/usage_trends/workers_argument_builder.rb (renamed from lib/gitlab/analytics/instance_statistics/workers_argument_builder.rb)6
-rw-r--r--lib/gitlab/application_rate_limiter.rb2
-rw-r--r--lib/gitlab/auth/o_auth/provider.rb11
-rw-r--r--lib/gitlab/background_migration/set_default_iteration_cadences.rb57
-rw-r--r--lib/gitlab/ci/jwt.rb6
-rw-r--r--lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml17
-rw-r--r--lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml8
-rw-r--r--lib/gitlab/current_settings.rb4
-rw-r--r--lib/gitlab/database/migrations/observation.rb3
-rw-r--r--lib/gitlab/database/migrations/observers.rb3
-rw-r--r--lib/gitlab/database/migrations/observers/query_statistics.rb38
-rw-r--r--lib/gitlab/email/handler/service_desk_handler.rb8
-rw-r--r--lib/gitlab/experimentation.rb6
-rw-r--r--lib/gitlab/gitaly_client.rb4
-rw-r--r--lib/gitlab/gitaly_client/storage_settings.rb3
-rw-r--r--lib/gitlab/graphql/docs/helper.rb20
-rw-r--r--lib/gitlab/graphql/docs/templates/default.md.haml18
-rw-r--r--lib/gitlab/import_export/repo_restorer.rb2
-rw-r--r--lib/gitlab/marginalia.rb9
-rw-r--r--lib/gitlab/marginalia/active_record_instrumentation.rb12
-rw-r--r--lib/gitlab/metrics/samplers/ruby_sampler.rb2
-rw-r--r--lib/gitlab/metrics/subscribers/active_record.rb3
-rw-r--r--lib/gitlab/performance_bar/redis_adapter_when_peek_enabled.rb8
-rw-r--r--lib/gitlab/regex.rb4
-rw-r--r--lib/gitlab/template/base_template.rb6
-rw-r--r--lib/gitlab/template/issue_template.rb6
-rw-r--r--lib/gitlab/template/merge_request_template.rb6
-rw-r--r--lib/gitlab/tracking/standard_context.rb8
-rw-r--r--lib/gitlab/usage/docs/helper.rb4
-rw-r--r--lib/gitlab/usage/docs/value_formatter.rb4
-rw-r--r--lib/gitlab/usage_data_counters/aggregated_metrics/code_review.yml89
-rw-r--r--lib/gitlab/usage_data_counters/counter_events/package_events.yml3
-rw-r--r--lib/gitlab/usage_data_counters/known_events/package_events.yml10
-rw-r--r--lib/tasks/eslint.rake2
-rw-r--r--lib/tasks/gitlab/graphql.rake16
-rw-r--r--lib/tasks/lint.rake1
-rw-r--r--lib/tasks/scss-lint.rake12
64 files changed, 533 insertions, 212 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 0598f03c7ab..bf4b031cb9f 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -147,7 +147,7 @@ module API
# Only overwrite `text/plain+deprecated`
if content_types[api_format] == 'text/plain+deprecated'
- if Feature.enabled?(:api_always_use_application_json)
+ if Feature.enabled?(:api_always_use_application_json, default_enabled: :yaml)
content_type 'application/json'
else
content_type 'text/plain'
diff --git a/lib/api/concerns/packages/npm_endpoints.rb b/lib/api/concerns/packages/npm_endpoints.rb
index 833288c6013..d6e006df976 100644
--- a/lib/api/concerns/packages/npm_endpoints.rb
+++ b/lib/api/concerns/packages/npm_endpoints.rb
@@ -41,8 +41,8 @@ module API
authorize_read_package!(project)
- packages = ::Packages::Npm::PackageFinder.new(project, package_name)
- .execute
+ packages = ::Packages::Npm::PackageFinder.new(package_name, project: project)
+ .execute
not_found! if packages.empty?
@@ -68,9 +68,8 @@ module API
authorize_create_package!(project)
- package = ::Packages::Npm::PackageFinder
- .new(project, package_name)
- .find_by_version(version)
+ package = ::Packages::Npm::PackageFinder.new(package_name, project: project)
+ .find_by_version(version)
not_found!('Package') unless package
::Packages::Npm::CreateTagService.new(package, tag).execute
@@ -112,9 +111,8 @@ module API
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
get '*package_name', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
package_name = params[:package_name]
-
- packages = ::Packages::Npm::PackageFinder.new(project_or_nil, package_name)
- .execute
+ packages = ::Packages::Npm::PackageFinder.new(package_name, project: project_or_nil)
+ .execute
redirect_request = project_or_nil.blank? || packages.empty?
diff --git a/lib/api/helpers/packages/npm.rb b/lib/api/helpers/packages/npm.rb
index c1f6a001201..2d556f889bf 100644
--- a/lib/api/helpers/packages/npm.rb
+++ b/lib/api/helpers/packages/npm.rb
@@ -49,13 +49,28 @@ module API
when :project
params[:id]
when :instance
- ::Packages::Package.npm
- .with_name(params[:package_name])
- .first
- &.project_id
+ namespace_path = namespace_path_from_package_name
+ next unless namespace_path
+
+ namespace = Namespace.top_most
+ .by_path(namespace_path)
+ next unless namespace
+
+ finder = ::Packages::Npm::PackageFinder.new(params[:package_name], namespace: namespace)
+
+ finder.last&.project_id
end
end
end
+
+ # from "@scope/package-name" return "scope" or nil
+ def namespace_path_from_package_name
+ package_name = params[:package_name]
+ return unless package_name.starts_with?('@')
+ return unless package_name.include?('/')
+
+ package_name.match(Gitlab::Regex.npm_package_name_regex)&.captures&.first
+ end
end
end
end
diff --git a/lib/api/lint.rb b/lib/api/lint.rb
index 2d30754a36d..e0806674c6a 100644
--- a/lib/api/lint.rb
+++ b/lib/api/lint.rb
@@ -11,7 +11,7 @@ module API
optional :include_merged_yaml, type: Boolean, desc: 'Whether or not to include merged CI config yaml in the response'
end
post '/lint' do
- unauthorized! unless Gitlab::CurrentSettings.signup_enabled? && current_user
+ unauthorized! if Gitlab::CurrentSettings.signup_disabled? && current_user.nil?
result = Gitlab::Ci::YamlProcessor.new(params[:content], user: current_user).execute
diff --git a/lib/api/nuget_project_packages.rb b/lib/api/nuget_project_packages.rb
index e071b6bd68f..73ecc140959 100644
--- a/lib/api/nuget_project_packages.rb
+++ b/lib/api/nuget_project_packages.rb
@@ -62,8 +62,9 @@ module API
file_name: PACKAGE_FILENAME
)
- package = ::Packages::Nuget::CreatePackageService.new(project_or_group, current_user, declared_params.merge(build: current_authenticated_job))
- .execute
+ package = ::Packages::CreateTemporaryPackageService.new(
+ project_or_group, current_user, declared_params.merge(build: current_authenticated_job)
+ ).execute(:nuget, name: ::Packages::Nuget::TEMPORARY_PACKAGE_NAME)
package_file = ::Packages::CreatePackageFileService.new(package, file_params.merge(build: current_authenticated_job))
.execute
diff --git a/lib/api/rubygem_packages.rb b/lib/api/rubygem_packages.rb
index 7819aab879c..5bacf9b122d 100644
--- a/lib/api/rubygem_packages.rb
+++ b/lib/api/rubygem_packages.rb
@@ -12,7 +12,7 @@ module API
# The Marshal version can be found by "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
# Updating the version should require a GitLab API version change.
MARSHAL_VERSION = '4.8'
-
+ PACKAGE_FILENAME = 'package.gem'
FILE_NAME_REQUIREMENTS = {
file_name: API::NO_SLASH_URL_PART_REGEX
}.freeze
@@ -73,16 +73,45 @@ module API
detail 'This feature was introduced in GitLab 13.9'
end
post 'gems/authorize' do
- # To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299263
- not_found!
+ authorize_workhorse!(
+ subject: user_project,
+ has_length: false,
+ maximum_size: user_project.actual_limits.rubygems_max_file_size
+ )
end
desc 'Upload a gem' do
detail 'This feature was introduced in GitLab 13.9'
end
+ params do
+ requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)'
+ end
post 'gems' do
- # To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299263
- not_found!
+ authorize_upload!(user_project)
+ bad_request!('File is too large') if user_project.actual_limits.exceeded?(:rubygems_max_file_size, params[:file].size)
+
+ track_package_event('push_package', :rubygems)
+
+ ActiveRecord::Base.transaction do
+ package = ::Packages::CreateTemporaryPackageService.new(
+ user_project, current_user, declared_params.merge(build: current_authenticated_job)
+ ).execute(:rubygems, name: ::Packages::Rubygems::TEMPORARY_PACKAGE_NAME)
+
+ file_params = {
+ file: params[:file],
+ file_name: PACKAGE_FILENAME
+ }
+
+ ::Packages::CreatePackageFileService.new(
+ package, file_params.merge(build: current_authenticated_job)
+ ).execute
+ end
+
+ created!
+ rescue ObjectStorage::RemoteStoreError => e
+ Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: user_project.id })
+
+ forbidden!
end
desc 'Fetch a list of dependencies' do
diff --git a/lib/backup/repositories.rb b/lib/backup/repositories.rb
index d15114a72a3..79b7b2c61f2 100644
--- a/lib/backup/repositories.rb
+++ b/lib/backup/repositories.rb
@@ -201,7 +201,12 @@ module Backup
PoolRepository.includes(:source_project).find_each do |pool|
progress.puts " - Object pool #{pool.disk_path}..."
- pool.source_project ||= pool.member_projects.first.root_of_fork_network
+ pool.source_project ||= pool.member_projects.first&.root_of_fork_network
+ unless pool.source_project
+ progress.puts " - Object pool #{pool.disk_path}... " + "[SKIPPED]".color(:cyan)
+ next
+ end
+
pool.state = 'none'
pool.save
diff --git a/lib/banzai/filter/video_link_filter.rb b/lib/banzai/filter/video_link_filter.rb
index 98987ee2019..3789a215dd8 100644
--- a/lib/banzai/filter/video_link_filter.rb
+++ b/lib/banzai/filter/video_link_filter.rb
@@ -15,7 +15,7 @@ module Banzai
end
def extra_element_attrs
- { width: "400" }
+ { width: "400", preload: "metadata" }
end
end
end
diff --git a/lib/bulk_imports/common/loaders/entity_loader.rb b/lib/bulk_imports/common/loaders/entity_loader.rb
deleted file mode 100644
index 8644f3c9dcb..00000000000
--- a/lib/bulk_imports/common/loaders/entity_loader.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-module BulkImports
- module Common
- module Loaders
- class EntityLoader
- def initialize(*args); end
-
- def load(context, entity)
- context.bulk_import.entities.create!(entity)
- end
- end
- end
- end
-end
diff --git a/lib/bulk_imports/common/transformers/award_emoji_transformer.rb b/lib/bulk_imports/common/transformers/award_emoji_transformer.rb
index 260b47ab917..676c71f1316 100644
--- a/lib/bulk_imports/common/transformers/award_emoji_transformer.rb
+++ b/lib/bulk_imports/common/transformers/award_emoji_transformer.rb
@@ -4,8 +4,6 @@ module BulkImports
module Common
module Transformers
class AwardEmojiTransformer
- def initialize(*args); end
-
def transform(context, data)
user = find_user(context, data&.dig('user', 'public_email')) || context.current_user
diff --git a/lib/bulk_imports/common/transformers/prohibited_attributes_transformer.rb b/lib/bulk_imports/common/transformers/prohibited_attributes_transformer.rb
index 858c4c8976b..37b64923d56 100644
--- a/lib/bulk_imports/common/transformers/prohibited_attributes_transformer.rb
+++ b/lib/bulk_imports/common/transformers/prohibited_attributes_transformer.rb
@@ -14,10 +14,6 @@ module BulkImports
/\Aremote_\w+_(url|urls|request_header)\Z/ # carrierwave automatically creates these attribute methods for uploads
).freeze
- def initialize(options = {})
- @options = options
- end
-
def transform(context, data)
data.each_with_object({}) do |(key, value), result|
prohibited = prohibited_key?(key)
diff --git a/lib/bulk_imports/groups/extractors/subgroups_extractor.rb b/lib/bulk_imports/groups/extractors/subgroups_extractor.rb
index b01fb6f68ac..e5e2b9fdbd4 100644
--- a/lib/bulk_imports/groups/extractors/subgroups_extractor.rb
+++ b/lib/bulk_imports/groups/extractors/subgroups_extractor.rb
@@ -4,8 +4,6 @@ module BulkImports
module Groups
module Extractors
class SubgroupsExtractor
- def initialize(*args); end
-
def extract(context)
encoded_parent_path = ERB::Util.url_encode(context.entity.source_full_path)
diff --git a/lib/bulk_imports/groups/graphql/get_labels_query.rb b/lib/bulk_imports/groups/graphql/get_labels_query.rb
index d1fe791c2ce..23efbc33581 100644
--- a/lib/bulk_imports/groups/graphql/get_labels_query.rb
+++ b/lib/bulk_imports/groups/graphql/get_labels_query.rb
@@ -10,7 +10,7 @@ module BulkImports
<<-'GRAPHQL'
query ($full_path: ID!, $cursor: String) {
group(fullPath: $full_path) {
- labels(first: 100, after: $cursor) {
+ labels(first: 100, after: $cursor, onlyGroupLabels: true) {
page_info: pageInfo {
end_cursor: endCursor
has_next_page: hasNextPage
@@ -19,6 +19,8 @@ module BulkImports
title
description
color
+ created_at: createdAt
+ updated_at: updatedAt
}
}
}
diff --git a/lib/bulk_imports/groups/loaders/group_loader.rb b/lib/bulk_imports/groups/loaders/group_loader.rb
index 386fc695182..a631685c2ad 100644
--- a/lib/bulk_imports/groups/loaders/group_loader.rb
+++ b/lib/bulk_imports/groups/loaders/group_loader.rb
@@ -4,10 +4,6 @@ module BulkImports
module Groups
module Loaders
class GroupLoader
- def initialize(options = {})
- @options = options
- end
-
def load(context, data)
return unless user_can_create_group?(context.current_user, data)
diff --git a/lib/bulk_imports/groups/loaders/labels_loader.rb b/lib/bulk_imports/groups/loaders/labels_loader.rb
deleted file mode 100644
index b8c9ba9609c..00000000000
--- a/lib/bulk_imports/groups/loaders/labels_loader.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-module BulkImports
- module Groups
- module Loaders
- class LabelsLoader
- def initialize(*); end
-
- def load(context, data)
- Labels::CreateService.new(data).execute(group: context.group)
- end
- end
- end
- end
-end
diff --git a/lib/bulk_imports/groups/loaders/members_loader.rb b/lib/bulk_imports/groups/loaders/members_loader.rb
deleted file mode 100644
index ccf44b31aee..00000000000
--- a/lib/bulk_imports/groups/loaders/members_loader.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-module BulkImports
- module Groups
- module Loaders
- class MembersLoader
- def initialize(*); end
-
- def load(context, data)
- return unless data
-
- context.group.members.create!(data)
- end
- end
- end
- end
-end
diff --git a/lib/bulk_imports/groups/pipelines/labels_pipeline.rb b/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
index 40dab9b444c..9f8b8682751 100644
--- a/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
+++ b/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
@@ -11,7 +11,9 @@ module BulkImports
transformer Common::Transformers::ProhibitedAttributesTransformer
- loader BulkImports::Groups::Loaders::LabelsLoader
+ def load(context, data)
+ Labels::CreateService.new(data).execute(group: context.group)
+ end
def after_run(extracted_data)
context.entity.update_tracker_for(
diff --git a/lib/bulk_imports/groups/pipelines/members_pipeline.rb b/lib/bulk_imports/groups/pipelines/members_pipeline.rb
index b00c4c1a659..32fc931e8c3 100644
--- a/lib/bulk_imports/groups/pipelines/members_pipeline.rb
+++ b/lib/bulk_imports/groups/pipelines/members_pipeline.rb
@@ -12,7 +12,11 @@ module BulkImports
transformer Common::Transformers::ProhibitedAttributesTransformer
transformer BulkImports::Groups::Transformers::MemberAttributesTransformer
- loader BulkImports::Groups::Loaders::MembersLoader
+ def load(context, data)
+ return unless data
+
+ context.group.members.create!(data)
+ end
def after_run(extracted_data)
context.entity.update_tracker_for(
diff --git a/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline.rb b/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline.rb
index d7e1a118d0b..c47a8bd1daa 100644
--- a/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline.rb
+++ b/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline.rb
@@ -9,7 +9,10 @@ module BulkImports
extractor BulkImports::Groups::Extractors::SubgroupsExtractor
transformer Common::Transformers::ProhibitedAttributesTransformer
transformer BulkImports::Groups::Transformers::SubgroupToEntityTransformer
- loader BulkImports::Common::Loaders::EntityLoader
+
+ def load(context, data)
+ context.bulk_import.entities.create!(data)
+ end
end
end
end
diff --git a/lib/bulk_imports/groups/transformers/group_attributes_transformer.rb b/lib/bulk_imports/groups/transformers/group_attributes_transformer.rb
index 7de9a430421..23e898a7bb2 100644
--- a/lib/bulk_imports/groups/transformers/group_attributes_transformer.rb
+++ b/lib/bulk_imports/groups/transformers/group_attributes_transformer.rb
@@ -4,10 +4,6 @@ module BulkImports
module Groups
module Transformers
class GroupAttributesTransformer
- def initialize(options = {})
- @options = options
- end
-
def transform(context, data)
import_entity = context.entity
@@ -39,12 +35,11 @@ module BulkImports
end
def transform_parent(context, import_entity, data)
- current_user = context.current_user
- namespace = Namespace.find_by_full_path(import_entity.destination_namespace)
-
- return data if namespace == current_user.namespace
+ unless import_entity.destination_namespace.blank?
+ namespace = Namespace.find_by_full_path(import_entity.destination_namespace)
+ data['parent_id'] = namespace.id
+ end
- data['parent_id'] = namespace.id
data
end
diff --git a/lib/bulk_imports/groups/transformers/member_attributes_transformer.rb b/lib/bulk_imports/groups/transformers/member_attributes_transformer.rb
index 622f5b60ffe..e92c898171a 100644
--- a/lib/bulk_imports/groups/transformers/member_attributes_transformer.rb
+++ b/lib/bulk_imports/groups/transformers/member_attributes_transformer.rb
@@ -4,8 +4,6 @@ module BulkImports
module Groups
module Transformers
class MemberAttributesTransformer
- def initialize(*); end
-
def transform(context, data)
data
.then { |data| add_user(data) }
diff --git a/lib/bulk_imports/groups/transformers/subgroup_to_entity_transformer.rb b/lib/bulk_imports/groups/transformers/subgroup_to_entity_transformer.rb
index 6c3c299c2d2..676a6ca8d2a 100644
--- a/lib/bulk_imports/groups/transformers/subgroup_to_entity_transformer.rb
+++ b/lib/bulk_imports/groups/transformers/subgroup_to_entity_transformer.rb
@@ -4,8 +4,6 @@ module BulkImports
module Groups
module Transformers
class SubgroupToEntityTransformer
- def initialize(*args); end
-
def transform(context, entry)
{
source_type: :group_entity,
diff --git a/lib/bulk_imports/pipeline.rb b/lib/bulk_imports/pipeline.rb
index 1d55ad95887..254ae0e792e 100644
--- a/lib/bulk_imports/pipeline.rb
+++ b/lib/bulk_imports/pipeline.rb
@@ -15,16 +15,78 @@ module BulkImports
attr_reader :context
+ # Fetch pipeline extractor.
+ # An extractor is defined either by instance `#extract(context)` method
+ # or by using `extractor` DSL.
+ #
+ # @example
+ # class MyPipeline
+ # extractor MyExtractor, foo: :bar
+ # end
+ #
+ # class MyPipeline
+ # def extract(context)
+ # puts 'Fetch some data'
+ # end
+ # end
+ #
+ # If pipeline implements instance method `extract` - use it
+ # and ignore class `extractor` method implementation.
def extractor
- @extractor ||= instantiate(self.class.get_extractor)
+ @extractor ||= self.respond_to?(:extract) ? self : instantiate(self.class.get_extractor)
end
+ # Fetch pipeline transformers.
+ #
+ # A transformer can be defined using:
+ # - `transformer` class method
+ # - `transform` instance method
+ #
+ # Multiple transformers can be defined within a single
+ # pipeline and run sequentially for each record in the
+ # following order:
+ # - Transformers defined using `transformer` class method
+ # - Instance method `transform`
+ #
+ # Instance method `transform` is always the last to run.
+ #
+ # @example
+ # class MyPipeline
+ # transformer MyTransformerOne, foo: :bar
+ # transformer MyTransformerTwo, foo: :bar
+ #
+ # def transform(context, data)
+ # # perform transformation here
+ # end
+ # end
+ #
+ # In the example above `MyTransformerOne` is the first to run and
+ # the instance `#transform` method is the last.
def transformers
@transformers ||= self.class.transformers.map(&method(:instantiate))
+ @transformers << self if respond_to?(:transform) && @transformers.exclude?(self)
+ @transformers
end
+ # Fetch pipeline loader.
+ # A loader is defined either by instance method `#load(context, data)`
+ # or by using `loader` DSL.
+ #
+ # @example
+ # class MyPipeline
+ # loader MyLoader, foo: :bar
+ # end
+ #
+ # class MyPipeline
+ # def load(context, data)
+ # puts 'Load some data'
+ # end
+ # end
+ #
+ # If pipeline implements instance method `load` - use it
+ # and ignore class `loader` method implementation.
def loader
- @loaders ||= instantiate(self.class.get_loader)
+ @loader ||= self.respond_to?(:load) ? self : instantiate(self.class.get_loader)
end
def pipeline
@@ -32,7 +94,13 @@ module BulkImports
end
def instantiate(class_config)
- class_config[:klass].new(class_config[:options])
+ options = class_config[:options]
+
+ if options
+ class_config[:klass].new(class_config[:options])
+ else
+ class_config[:klass].new
+ end
end
def abort_on_failure?
diff --git a/lib/csv_builder.rb b/lib/csv_builder.rb
index a9ef5a83ae8..6116009f171 100644
--- a/lib/csv_builder.rb
+++ b/lib/csv_builder.rb
@@ -16,6 +16,7 @@
class CsvBuilder
DEFAULT_ORDER_BY = 'id'.freeze
DEFAULT_BATCH_SIZE = 1000
+ PREFIX_REGEX = /^[=\+\-@;]/.freeze
attr_reader :rows_written
@@ -114,8 +115,8 @@ class CsvBuilder
def excel_sanitize(line)
return if line.nil?
+ return line unless line.is_a?(String) && line.match?(PREFIX_REGEX)
- line = ["'", line].join if line =~ /^[=\+\-@;]/
- line
+ ["'", line].join
end
end
diff --git a/lib/gitlab/analytics/cycle_analytics/average.rb b/lib/gitlab/analytics/cycle_analytics/average.rb
new file mode 100644
index 00000000000..a449b71b165
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/average.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ class Average
+ include Gitlab::Utils::StrongMemoize
+ include StageQueryHelpers
+
+ def initialize(stage:, query:)
+ @stage = stage
+ @query = query
+ end
+
+ def seconds
+ select_average ? select_average['average'] : nil
+ end
+
+ def days
+ seconds ? seconds.fdiv(1.day) : nil
+ end
+
+ private
+
+ attr_reader :stage
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def select_average
+ strong_memoize(:select_average) do
+ execute_query(@query.select(average_in_seconds.as('average')).reorder(nil)).first
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def average
+ Arel::Nodes::NamedFunction.new(
+ 'AVG',
+ [duration]
+ )
+ end
+
+ def average_in_seconds
+ Arel::Nodes::Extract.new(average, :epoch)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/data_collector.rb b/lib/gitlab/analytics/cycle_analytics/data_collector.rb
index 5eca364a697..10a008a76d5 100644
--- a/lib/gitlab/analytics/cycle_analytics/data_collector.rb
+++ b/lib/gitlab/analytics/cycle_analytics/data_collector.rb
@@ -31,6 +31,12 @@ module Gitlab
end
end
+ def average
+ strong_memoize(:average) do
+ Average.new(stage: stage, query: query)
+ end
+ end
+
private
attr_reader :stage, :params
diff --git a/lib/gitlab/analytics/instance_statistics/workers_argument_builder.rb b/lib/gitlab/analytics/usage_trends/workers_argument_builder.rb
index 54b3bbb3ce6..a502f46287d 100644
--- a/lib/gitlab/analytics/instance_statistics/workers_argument_builder.rb
+++ b/lib/gitlab/analytics/usage_trends/workers_argument_builder.rb
@@ -2,7 +2,7 @@
module Gitlab
module Analytics
- module InstanceStatistics
+ module UsageTrends
class WorkersArgumentBuilder
def initialize(measurement_identifiers: [], recorded_at: Time.zone.now)
@measurement_identifiers = measurement_identifiers
@@ -35,11 +35,11 @@ module Gitlab
end
def custom_min_max_queries
- ::Analytics::InstanceStatistics::Measurement.identifier_min_max_queries
+ ::Analytics::UsageTrends::Measurement.identifier_min_max_queries
end
def query_mappings
- ::Analytics::InstanceStatistics::Measurement.identifier_query_mapping
+ ::Analytics::UsageTrends::Measurement.identifier_query_mapping
end
end
end
diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb
index 0a69a9c503d..f74edf2b767 100644
--- a/lib/gitlab/application_rate_limiter.rb
+++ b/lib/gitlab/application_rate_limiter.rb
@@ -47,7 +47,7 @@ module Gitlab
# @option scope [Array<ActiveRecord>] Array of ActiveRecord models to scope throttling to a specific request (e.g. per user per project)
# @option threshold [Integer] Optional threshold value to override default one registered in `.rate_limits`
# @option interval [Integer] Optional interval value to override default one registered in `.rate_limits`
- # @option users_allowlist [Array<String>] Optional list of usernames to excepted from the limit. This param will only be functional if Scope includes a current user.
+ # @option users_allowlist [Array<String>] Optional list of usernames to exclude from the limit. This param will only be functional if Scope includes a current user.
#
# @return [Boolean] Whether or not a request should be throttled
def throttled?(key, **options)
diff --git a/lib/gitlab/auth/o_auth/provider.rb b/lib/gitlab/auth/o_auth/provider.rb
index 57ff3fcd1f0..ab6ac815601 100644
--- a/lib/gitlab/auth/o_auth/provider.rb
+++ b/lib/gitlab/auth/o_auth/provider.rb
@@ -5,11 +5,12 @@ module Gitlab
module OAuth
class Provider
LABELS = {
- "github" => "GitHub",
- "gitlab" => "GitLab.com",
- "google_oauth2" => "Google",
- "azure_oauth2" => "Azure AD",
- 'atlassian_oauth2' => 'Atlassian'
+ "github" => "GitHub",
+ "gitlab" => "GitLab.com",
+ "google_oauth2" => "Google",
+ "azure_oauth2" => "Azure AD",
+ "azure_activedirectory_v2" => "Azure AD v2",
+ 'atlassian_oauth2' => 'Atlassian'
}.freeze
def self.authentication(user, provider)
diff --git a/lib/gitlab/background_migration/set_default_iteration_cadences.rb b/lib/gitlab/background_migration/set_default_iteration_cadences.rb
new file mode 100644
index 00000000000..530608144aa
--- /dev/null
+++ b/lib/gitlab/background_migration/set_default_iteration_cadences.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # rubocop:disable Style/Documentation
+ class SetDefaultIterationCadences
+ class Iteration < ApplicationRecord
+ self.table_name = 'sprints'
+ end
+
+ class IterationCadence < ApplicationRecord
+ self.table_name = 'iterations_cadences'
+
+ include BulkInsertSafe
+ end
+
+ class Group < ApplicationRecord
+ self.table_name = 'namespaces'
+ end
+
+ def perform(*group_ids)
+ create_iterations_cadences(group_ids)
+ assign_iterations_cadences(group_ids)
+ end
+
+ private
+
+ def create_iterations_cadences(group_ids)
+ groups_with_cadence = IterationCadence.select(:group_id)
+ new_cadences = Group.where(id: group_ids).where.not(id: groups_with_cadence).map do |group|
+ last_iteration = Iteration.where(group_id: group.id).order(:start_date)&.last
+
+ next unless last_iteration
+
+ time = Time.now
+ IterationCadence.new(
+ group_id: group.id,
+ title: "#{group.name} Iterations",
+ start_date: last_iteration.start_date,
+ last_run_date: last_iteration.start_date,
+ automatic: false,
+ created_at: time,
+ updated_at: time
+ )
+ end
+
+ IterationCadence.bulk_insert!(new_cadences.compact)
+ end
+
+ def assign_iterations_cadences(group_ids)
+ IterationCadence.where(group_id: group_ids).each do |cadence|
+ Iteration.where(iterations_cadence_id: nil).where(group_id: cadence.group_id).update_all(iterations_cadence_id: cadence.id)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/jwt.rb b/lib/gitlab/ci/jwt.rb
index 0870c74053a..af06e124736 100644
--- a/lib/gitlab/ci/jwt.rb
+++ b/lib/gitlab/ci/jwt.rb
@@ -60,7 +60,7 @@ module Gitlab
ref_protected: build.protected.to_s
}
- if include_environment_claims?
+ if environment.present?
fields.merge!(
environment: environment.name,
environment_protected: environment_protected?.to_s
@@ -119,10 +119,6 @@ module Gitlab
def environment_protected?
false # Overridden in EE
end
-
- def include_environment_claims?
- Feature.enabled?(:ci_jwt_include_environment) && environment.present?
- end
end
end
end
diff --git a/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml b/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml
index a4aed36889e..e4ed7fadfaa 100644
--- a/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/LaTeX.gitlab-ci.yml
@@ -1,11 +1,20 @@
-# use docker image with latex preinstalled
-# since there is no official latex image, use https://github.com/blang/latex-docker
-# possible alternative: https://github.com/natlownes/docker-latex
-image: blang/latex
+---
+variables:
+ # Feel free to choose the image that suits you best.
+ # blang/latex:latest ... Former image used in this template. No longer maintained by author.
+ # listx/texlive:2020 ... The default, referring to TexLive 2020. Current at least to 2021-02-02.
+
+ # Additional alternatives with high Docker pull counts:
+ # thomasweise/docker-texlive-full
+ # thomasweise/texlive
+ # adnrv/texlive
+ LATEX_IMAGE: listx/texlive:2020
build:
+ image: $LATEX_IMAGE
script:
- latexmk -pdf
+
artifacts:
paths:
- "*.pdf"
diff --git a/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
index 135f0df99fe..460cb84460a 100644
--- a/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
@@ -172,6 +172,7 @@ apifuzzer_fuzz_dnd:
-e FUZZAPI_HAR \
-e FUZZAPI_OPENAPI \
-e FUZZAPI_POSTMAN_COLLECTION \
+ -e FUZZAPI_POSTMAN_COLLECTION_VARIABLES \
-e FUZZAPI_TARGET_URL \
-e FUZZAPI_OVERRIDES_FILE \
-e FUZZAPI_OVERRIDES_ENV \
@@ -214,6 +215,7 @@ apifuzzer_fuzz_dnd:
-e FUZZAPI_HAR \
-e FUZZAPI_OPENAPI \
-e FUZZAPI_POSTMAN_COLLECTION \
+ -e FUZZAPI_POSTMAN_COLLECTION_VARIABLES \
-e FUZZAPI_TARGET_URL \
-e FUZZAPI_OVERRIDES_FILE \
-e FUZZAPI_OVERRIDES_ENV \
diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
index 828352743b4..3b166505e0a 100644
--- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
@@ -140,7 +140,9 @@ gosec-sast:
mobsf-android-sast:
extends: .sast-analyzer
services:
- - name: opensecurity/mobile-security-framework-mobsf:latest
+ # this version must match with analyzer version mentioned in: https://gitlab.com/gitlab-org/security-products/analyzers/mobsf/-/blob/master/Dockerfile
+ # Unfortunately, we need to keep track of mobsf version in 2 different places for now.
+ - name: opensecurity/mobile-security-framework-mobsf:v3.2.9
alias: mobsf
image:
name: "$SAST_ANALYZER_IMAGE"
@@ -161,7 +163,9 @@ mobsf-android-sast:
mobsf-ios-sast:
extends: .sast-analyzer
services:
- - name: opensecurity/mobile-security-framework-mobsf:latest
+ # this version must match with analyzer version mentioned in: https://gitlab.com/gitlab-org/security-products/analyzers/mobsf/-/blob/master/Dockerfile
+ # Unfortunately, we need to keep track of mobsf version in 2 different places for now.
+ - name: opensecurity/mobile-security-framework-mobsf:v3.2.9
alias: mobsf
image:
name: "$SAST_ANALYZER_IMAGE"
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 0bf41f9dc0d..55f381fcb64 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -3,6 +3,10 @@
module Gitlab
module CurrentSettings
class << self
+ def signup_disabled?
+ !signup_enabled?
+ end
+
def current_application_settings
Gitlab::SafeRequestStore.fetch(:current_application_settings) { ensure_application_settings! }
end
diff --git a/lib/gitlab/database/migrations/observation.rb b/lib/gitlab/database/migrations/observation.rb
index 518c2c560d2..046843824a4 100644
--- a/lib/gitlab/database/migrations/observation.rb
+++ b/lib/gitlab/database/migrations/observation.rb
@@ -7,7 +7,8 @@ module Gitlab
:migration,
:walltime,
:success,
- :total_database_size_change
+ :total_database_size_change,
+ :query_statistics
)
end
end
diff --git a/lib/gitlab/database/migrations/observers.rb b/lib/gitlab/database/migrations/observers.rb
index 4b931d3c19c..592993aeac5 100644
--- a/lib/gitlab/database/migrations/observers.rb
+++ b/lib/gitlab/database/migrations/observers.rb
@@ -6,7 +6,8 @@ module Gitlab
module Observers
def self.all_observers
[
- TotalDatabaseSizeChange.new
+ TotalDatabaseSizeChange.new,
+ QueryStatistics.new
]
end
end
diff --git a/lib/gitlab/database/migrations/observers/query_statistics.rb b/lib/gitlab/database/migrations/observers/query_statistics.rb
new file mode 100644
index 00000000000..466f4724256
--- /dev/null
+++ b/lib/gitlab/database/migrations/observers/query_statistics.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module Migrations
+ module Observers
+ # This observer gathers statistics from the pg_stat_statements extension.
+ # Notice that this extension is not installed by default. In case it cannot
+ # be found, the observer does nothing and doesn't throw an error.
+ class QueryStatistics < MigrationObserver
+ include Gitlab::Database::SchemaHelpers
+
+ def before
+ return unless enabled?
+
+ connection.execute('select pg_stat_statements_reset()')
+ end
+
+ def record(observation)
+ return unless enabled?
+
+ observation.query_statistics = connection.execute(<<~SQL)
+ SELECT query, calls, total_time, max_time, mean_time, rows
+ FROM pg_stat_statements
+ ORDER BY total_time DESC
+ SQL
+ end
+
+ private
+
+ def enabled?
+ function_exists?(:pg_stat_statements_reset) && connection.view_exists?(:pg_stat_statements)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/handler/service_desk_handler.rb b/lib/gitlab/email/handler/service_desk_handler.rb
index d1dd616385d..80e8b726099 100644
--- a/lib/gitlab/email/handler/service_desk_handler.rb
+++ b/lib/gitlab/email/handler/service_desk_handler.rb
@@ -79,7 +79,7 @@ module Gitlab
@issue = Issues::CreateService.new(
project,
User.support_bot,
- title: issue_title,
+ title: mail.subject,
description: message_including_template,
confidential: true,
external_author: from_address
@@ -137,12 +137,6 @@ module Gitlab
(mail.reply_to || []).first || mail.from.first || mail.sender
end
- def issue_title
- from = "(from #{from_address})" if from_address
-
- "Service Desk #{from}: #{mail.subject}"
- end
-
def can_handle_legacy_format?
project_path && project_path.include?('/') && !mail_key.include?('+')
end
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 423f238a0a2..337c28f3179 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -58,10 +58,6 @@ module Gitlab
tracking_category: 'Growth::Conversion::Experiment::ContactSalesInApp',
use_backwards_compatible_subject_index: true
},
- customize_homepage: {
- tracking_category: 'Growth::Expansion::Experiment::CustomizeHomepage',
- use_backwards_compatible_subject_index: true
- },
group_only_trials: {
tracking_category: 'Growth::Conversion::Experiment::GroupOnlyTrials',
use_backwards_compatible_subject_index: true
@@ -81,7 +77,7 @@ module Gitlab
trial_during_signup: {
tracking_category: 'Growth::Conversion::Experiment::TrialDuringSignup'
},
- ci_syntax_templates: {
+ ci_syntax_templates_b: {
tracking_category: 'Growth::Activation::Experiment::CiSyntaxTemplates',
rollout_strategy: :user
},
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 3c7fa88977e..e3788814dd5 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -246,9 +246,7 @@ module Gitlab
def self.route_to_primary
return {} unless Gitlab::SafeRequestStore.active?
- return {} unless Gitlab::SafeRequestStore[:gitlab_git_env]
-
- return {} if Gitlab::SafeRequestStore[:gitlab_git_env].empty?
+ return {} if Gitlab::SafeRequestStore[:gitlab_git_env].blank?
{ 'gitaly-route-repository-accessor-policy' => 'primary-only' }
end
diff --git a/lib/gitlab/gitaly_client/storage_settings.rb b/lib/gitlab/gitaly_client/storage_settings.rb
index 5e50ac72965..7edd42f9ef7 100644
--- a/lib/gitlab/gitaly_client/storage_settings.rb
+++ b/lib/gitlab/gitaly_client/storage_settings.rb
@@ -60,7 +60,8 @@ module Gitlab
end
def legacy_disk_path
- if self.class.disk_access_denied?
+ # Do not use self.class due to Spring reloading issues
+ if Gitlab::GitalyClient::StorageSettings.disk_access_denied?
raise DirectPathAccessError, "git disk access denied"
end
diff --git a/lib/gitlab/graphql/docs/helper.rb b/lib/gitlab/graphql/docs/helper.rb
index ad9e08e189c..155602740c4 100644
--- a/lib/gitlab/graphql/docs/helper.rb
+++ b/lib/gitlab/graphql/docs/helper.rb
@@ -28,16 +28,20 @@ module Gitlab
end
def render_name_and_description(object)
- content = "### #{object[:name]}\n"
+ content = "### #{object[:name].camelcase}\n"
if object[:description].present?
- content += "\n#{object[:description]}.\n"
+ content += "\n#{object[:description]}"
+ content += '.' unless object[:description].ends_with?('.')
+ content += "\n"
end
content
end
def sorted_by_name(objects)
+ return [] unless objects.present?
+
objects.sort_by { |o| o[:name] }
end
@@ -49,6 +53,14 @@ module Gitlab
]
end
+ def render_argument(argument)
+ '| %s | %s | %s |' % [
+ render_name(argument),
+ render_description(argument),
+ render_field_type(argument[:type][:info])
+ ]
+ end
+
def render_enum_value(value)
'| %s | %s |' % [
render_name(value),
@@ -98,6 +110,10 @@ module Gitlab
end
end
+ def queries
+ graphql_operation_types.find { |type| type[:name] == 'Query' }.to_h[:fields]
+ end
+
# We ignore the built-in enum types.
def enums
graphql_enum_types.select do |enum_type|
diff --git a/lib/gitlab/graphql/docs/templates/default.md.haml b/lib/gitlab/graphql/docs/templates/default.md.haml
index 9dfb9b090a8..1df1c3a3e58 100644
--- a/lib/gitlab/graphql/docs/templates/default.md.haml
+++ b/lib/gitlab/graphql/docs/templates/default.md.haml
@@ -21,6 +21,24 @@
\
:plain
+ ## Queries
+
+ Queries are used to get the resources, filter or query them.
+
+ For more information, visit [Queries and Mutations](https://graphql.org/learn/queries/).
+\
+
+- sorted_by_name(queries).each do |query|
+
+ = render_name_and_description(query)
+ - unless query[:arguments].empty?
+ ~ "| Name | Description | Type |"
+ ~ "| ----- | ---- | ----------- |"
+ - sorted_by_name(query[:arguments]).each do |argument|
+ = render_argument(argument)
+ \
+
+:plain
## Object types
Object types represent the resources that the GitLab GraphQL API can return.
diff --git a/lib/gitlab/import_export/repo_restorer.rb b/lib/gitlab/import_export/repo_restorer.rb
index 8af7b68d78e..998da3e4afb 100644
--- a/lib/gitlab/import_export/repo_restorer.rb
+++ b/lib/gitlab/import_export/repo_restorer.rb
@@ -42,7 +42,7 @@ module Gitlab
def ensure_repository_does_not_exist!
if repository.exists?
shared.logger.info(
- message: %Q{Deleting existing "#{repository.path}" to re-import it.}
+ message: %Q{Deleting existing "#{repository.disk_path}" to re-import it.}
)
Repositories::DestroyService.new(repository).execute
diff --git a/lib/gitlab/marginalia.rb b/lib/gitlab/marginalia.rb
index 325a8c5c325..c99cf113638 100644
--- a/lib/gitlab/marginalia.rb
+++ b/lib/gitlab/marginalia.rb
@@ -2,8 +2,6 @@
module Gitlab
module Marginalia
- cattr_accessor :enabled, default: false
-
def self.set_application_name
::Marginalia.application_name = Gitlab.process_name
end
@@ -13,12 +11,5 @@ module Gitlab
::Marginalia::SidekiqInstrumentation.enable!
end
end
-
- def self.set_enabled_from_feature_flag
- # During db:create and db:bootstrap skip feature query as DB is not available yet.
- return false unless Gitlab::Database.cached_table_exists?('features')
-
- self.enabled = Feature.enabled?(:marginalia, type: :ops)
- end
end
end
diff --git a/lib/gitlab/marginalia/active_record_instrumentation.rb b/lib/gitlab/marginalia/active_record_instrumentation.rb
deleted file mode 100644
index 452f472bf6a..00000000000
--- a/lib/gitlab/marginalia/active_record_instrumentation.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-# Patch to annotate sql only when the feature is enabled.
-module Gitlab
- module Marginalia
- module ActiveRecordInstrumentation
- def annotate_sql(sql)
- Gitlab::Marginalia.enabled ? super(sql) : sql
- end
- end
- end
-end
diff --git a/lib/gitlab/metrics/samplers/ruby_sampler.rb b/lib/gitlab/metrics/samplers/ruby_sampler.rb
index 76175b465e4..3d29d38fa1f 100644
--- a/lib/gitlab/metrics/samplers/ruby_sampler.rb
+++ b/lib/gitlab/metrics/samplers/ruby_sampler.rb
@@ -7,7 +7,7 @@ module Gitlab
module Samplers
class RubySampler < BaseSampler
DEFAULT_SAMPLING_INTERVAL_SECONDS = 60
- GC_REPORT_BUCKETS = [0.005, 0.01, 0.02, 0.04, 0.07, 0.1, 0.5].freeze
+ GC_REPORT_BUCKETS = [0.01, 0.05, 0.1, 0.2, 0.3, 0.5, 1].freeze
def initialize(*)
GC::Profiler.clear
diff --git a/lib/gitlab/metrics/subscribers/active_record.rb b/lib/gitlab/metrics/subscribers/active_record.rb
index d725d8d7b29..111aa2cab48 100644
--- a/lib/gitlab/metrics/subscribers/active_record.rb
+++ b/lib/gitlab/metrics/subscribers/active_record.rb
@@ -9,6 +9,7 @@ module Gitlab
IGNORABLE_SQL = %w{BEGIN COMMIT}.freeze
DB_COUNTERS = %i{db_count db_write_count db_cached_count}.freeze
+ SQL_COMMANDS_WITH_COMMENTS_REGEX = /\A(\/\*.*\*\/\s)?((?!(.*[^\w'"](DELETE|UPDATE|INSERT INTO)[^\w'"])))(WITH.*)?(SELECT)((?!(FOR UPDATE|FOR SHARE)).)*$/i.freeze
def sql(event)
# Mark this thread as requiring a database connection. This is used
@@ -37,7 +38,7 @@ module Gitlab
private
def select_sql_command?(payload)
- payload[:sql].match(/\A((?!(.*[^\w'"](DELETE|UPDATE|INSERT INTO)[^\w'"])))(WITH.*)?(SELECT)((?!(FOR UPDATE|FOR SHARE)).)*$/i)
+ payload[:sql].match(SQL_COMMANDS_WITH_COMMENTS_REGEX)
end
def increment_db_counters(payload)
diff --git a/lib/gitlab/performance_bar/redis_adapter_when_peek_enabled.rb b/lib/gitlab/performance_bar/redis_adapter_when_peek_enabled.rb
index 133d777fc32..ac5c907465e 100644
--- a/lib/gitlab/performance_bar/redis_adapter_when_peek_enabled.rb
+++ b/lib/gitlab/performance_bar/redis_adapter_when_peek_enabled.rb
@@ -17,7 +17,7 @@ module Gitlab
# to a structured log
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def enqueue_stats_job(request_id)
- return unless gather_stats?
+ return unless Feature.enabled?(:performance_bar_stats)
@client.sadd(GitlabPerformanceBarStatsWorker::STATS_KEY, request_id)
@@ -43,12 +43,6 @@ module Gitlab
)
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
-
- def gather_stats?
- return unless Feature.enabled?(:performance_bar_stats)
-
- Gitlab.com? || Gitlab.staging? || !Rails.env.production?
- end
end
end
end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index 96f2b7570b3..00739c05386 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -61,6 +61,10 @@ module Gitlab
maven_app_name_regex
end
+ def npm_package_name_regex
+ @npm_package_name_regex ||= %r{\A(?:@(#{Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX})/)?[-+\.\_a-zA-Z0-9]+\z}
+ end
+
def nuget_package_name_regex
@nuget_package_name_regex ||= %r{\A[-+\.\_a-zA-Z0-9]+\z}.freeze
end
diff --git a/lib/gitlab/template/base_template.rb b/lib/gitlab/template/base_template.rb
index 0f933a61598..dc006877129 100644
--- a/lib/gitlab/template/base_template.rb
+++ b/lib/gitlab/template/base_template.rb
@@ -87,11 +87,11 @@ module Gitlab
raise NotImplementedError
end
- def by_category(category, project = nil)
+ def by_category(category, project = nil, empty_category_title: nil)
directory = category_directory(category)
files = finder(project).list_files_for(directory)
- files.map { |f| new(f, project, category: category) }.sort
+ files.map { |f| new(f, project, category: category.presence || empty_category_title) }.sort
end
def category_directory(category)
@@ -108,7 +108,7 @@ module Gitlab
# Gitaly the actual template names within a given project's repository for all file templates
# other than `issue` and `merge request` description templates, which would instead
# overwrite the `template_names` method to return a redis cached version, by reading cached values
- # from `repository.issue_template_names_by_category` and `repository.merge_request_template_names_by_category`
+ # from `repository.issue_template_names_hash` and `repository.merge_request_template_names_hash`
# methods.
def repository_template_names(project)
template_names_by_category(self.all(project))
diff --git a/lib/gitlab/template/issue_template.rb b/lib/gitlab/template/issue_template.rb
index 3049f43b322..6e579018e45 100644
--- a/lib/gitlab/template/issue_template.rb
+++ b/lib/gitlab/template/issue_template.rb
@@ -23,7 +23,11 @@ module Gitlab
# own caching mechanism to avoid the back and forth call jumps between finder and model.
#
# follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300279
- project.repository.issue_template_names_by_category
+ project.repository.issue_template_names_hash
+ end
+
+ def by_category(category, project = nil, empty_category_title: nil)
+ super(category, project, empty_category_title: _('Project Templates'))
end
end
end
diff --git a/lib/gitlab/template/merge_request_template.rb b/lib/gitlab/template/merge_request_template.rb
index 9442f3b13fb..241a823d870 100644
--- a/lib/gitlab/template/merge_request_template.rb
+++ b/lib/gitlab/template/merge_request_template.rb
@@ -23,7 +23,11 @@ module Gitlab
# own caching mechanism to avoid the back and forth call jumps between finder and model.
#
# follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300279
- project.repository.merge_request_template_names_by_category
+ project.repository.merge_request_template_names_hash
+ end
+
+ def by_category(category, project = nil, empty_category_title: nil)
+ super(category, project, empty_category_title: _('Project Templates'))
end
end
end
diff --git a/lib/gitlab/tracking/standard_context.rb b/lib/gitlab/tracking/standard_context.rb
index 92fdd008249..8ce16c11267 100644
--- a/lib/gitlab/tracking/standard_context.rb
+++ b/lib/gitlab/tracking/standard_context.rb
@@ -15,10 +15,14 @@ module Gitlab
end
def environment
- return 'production' if Gitlab.com_and_canary?
-
return 'staging' if Gitlab.staging?
+ return 'production' if Gitlab.com?
+
+ return 'org' if Gitlab.org?
+
+ return 'self-managed' if Rails.env.production?
+
'development'
end
diff --git a/lib/gitlab/usage/docs/helper.rb b/lib/gitlab/usage/docs/helper.rb
index 8483334800b..e090eb65b4b 100644
--- a/lib/gitlab/usage/docs/helper.rb
+++ b/lib/gitlab/usage/docs/helper.rb
@@ -31,7 +31,9 @@ module Gitlab
end
def render_description(object)
- object.description
+ return 'Missing description' unless object.attributes[:description].present?
+
+ object.attributes[:description]
end
def render_attribute_row(key, value)
diff --git a/lib/gitlab/usage/docs/value_formatter.rb b/lib/gitlab/usage/docs/value_formatter.rb
index a2dc9b081f8..22c5c13fc0f 100644
--- a/lib/gitlab/usage/docs/value_formatter.rb
+++ b/lib/gitlab/usage/docs/value_formatter.rb
@@ -5,12 +5,14 @@ module Gitlab
module Docs
class ValueFormatter
def self.format(key, value)
+ return '' unless value.present?
+
case key
when :key_path
"**`#{value}`**"
when :data_source
value.to_s.capitalize
- when :product_group
+ when :product_group, :product_category
"`#{value}`"
when :introduced_by_url
"[Introduced by](#{value})"
diff --git a/lib/gitlab/usage_data_counters/aggregated_metrics/code_review.yml b/lib/gitlab/usage_data_counters/aggregated_metrics/code_review.yml
new file mode 100644
index 00000000000..4f86d500164
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/aggregated_metrics/code_review.yml
@@ -0,0 +1,89 @@
+# code_review_extension_category_monthly_active_users
+# This is only metrics related to the VS Code Extension for now.
+#
+# code_review_category_monthly_active_users
+# This is the user based metrics. These should only be user based metrics and only be related to the Code Review things inside of GitLab.
+#
+# code_review_group_monthly_active_users
+# This is an aggregation of both of the above aggregations. It's intended to represent all users who interact with our group across all of our categories.
+---
+- name: code_review_group_monthly_active_users
+ operator: OR
+ feature_flag: usage_data_code_review_aggregation
+ source: redis
+ events: [
+ 'i_code_review_user_single_file_diffs',
+ 'i_code_review_user_create_mr',
+ 'i_code_review_user_close_mr',
+ 'i_code_review_user_reopen_mr',
+ 'i_code_review_user_resolve_thread',
+ 'i_code_review_user_unresolve_thread',
+ 'i_code_review_edit_mr_title',
+ 'i_code_review_edit_mr_desc',
+ 'i_code_review_user_merge_mr',
+ 'i_code_review_user_create_mr_comment',
+ 'i_code_review_user_edit_mr_comment',
+ 'i_code_review_user_remove_mr_comment',
+ 'i_code_review_user_create_review_note',
+ 'i_code_review_user_publish_review',
+ 'i_code_review_user_create_multiline_mr_comment',
+ 'i_code_review_user_edit_multiline_mr_comment',
+ 'i_code_review_user_remove_multiline_mr_comment',
+ 'i_code_review_user_add_suggestion',
+ 'i_code_review_user_apply_suggestion',
+ 'i_code_review_user_assigned',
+ 'i_code_review_user_review_requested',
+ 'i_code_review_user_approve_mr',
+ 'i_code_review_user_unapprove_mr',
+ 'i_code_review_user_marked_as_draft',
+ 'i_code_review_user_unmarked_as_draft',
+ 'i_code_review_user_approval_rule_added',
+ 'i_code_review_user_approval_rule_deleted',
+ 'i_code_review_user_approval_rule_edited',
+ 'i_code_review_user_vs_code_api_request',
+ 'i_code_review_user_toggled_task_item_status',
+ 'i_code_review_user_create_mr_from_issue'
+ ]
+- name: code_review_category_monthly_active_users
+ operator: OR
+ feature_flag: usage_data_code_review_aggregation
+ source: redis
+ events: [
+ 'i_code_review_user_single_file_diffs',
+ 'i_code_review_user_create_mr',
+ 'i_code_review_user_close_mr',
+ 'i_code_review_user_reopen_mr',
+ 'i_code_review_user_resolve_thread',
+ 'i_code_review_user_unresolve_thread',
+ 'i_code_review_edit_mr_title',
+ 'i_code_review_edit_mr_desc',
+ 'i_code_review_user_merge_mr',
+ 'i_code_review_user_create_mr_comment',
+ 'i_code_review_user_edit_mr_comment',
+ 'i_code_review_user_remove_mr_comment',
+ 'i_code_review_user_create_review_note',
+ 'i_code_review_user_publish_review',
+ 'i_code_review_user_create_multiline_mr_comment',
+ 'i_code_review_user_edit_multiline_mr_comment',
+ 'i_code_review_user_remove_multiline_mr_comment',
+ 'i_code_review_user_add_suggestion',
+ 'i_code_review_user_apply_suggestion',
+ 'i_code_review_user_assigned',
+ 'i_code_review_user_review_requested',
+ 'i_code_review_user_approve_mr',
+ 'i_code_review_user_unapprove_mr',
+ 'i_code_review_user_marked_as_draft',
+ 'i_code_review_user_unmarked_as_draft',
+ 'i_code_review_user_approval_rule_added',
+ 'i_code_review_user_approval_rule_deleted',
+ 'i_code_review_user_approval_rule_edited',
+ 'i_code_review_user_toggled_task_item_status',
+ 'i_code_review_user_create_mr_from_issue'
+ ]
+- name: code_review_extension_category_monthly_active_users
+ operator: OR
+ feature_flag: usage_data_code_review_aggregation
+ source: redis
+ events: [
+ 'i_code_review_user_vs_code_api_request'
+ ]
diff --git a/lib/gitlab/usage_data_counters/counter_events/package_events.yml b/lib/gitlab/usage_data_counters/counter_events/package_events.yml
index f6bddabdd44..e1648245f3f 100644
--- a/lib/gitlab/usage_data_counters/counter_events/package_events.yml
+++ b/lib/gitlab/usage_data_counters/counter_events/package_events.yml
@@ -41,6 +41,9 @@
- i_package_pypi_delete_package
- i_package_pypi_pull_package
- i_package_pypi_push_package
+- i_package_rubygems_delete_package
+- i_package_rubygems_pull_package
+- i_package_rubygems_push_package
- i_package_tag_delete_package
- i_package_tag_pull_package
- i_package_tag_push_package
diff --git a/lib/gitlab/usage_data_counters/known_events/package_events.yml b/lib/gitlab/usage_data_counters/known_events/package_events.yml
index 78a2a587b34..6cf31ba4db7 100644
--- a/lib/gitlab/usage_data_counters/known_events/package_events.yml
+++ b/lib/gitlab/usage_data_counters/known_events/package_events.yml
@@ -99,6 +99,16 @@
aggregation: weekly
redis_slot: package
feature_flag: collect_package_events_redis
+- name: i_package_rubygems_deploy_token
+ category: deploy_token_packages
+ aggregation: weekly
+ redis_slot: package
+ feature_flag: collect_package_events_redis
+- name: i_package_rubygems_user
+ category: user_packages
+ aggregation: weekly
+ redis_slot: package
+ feature_flag: collect_package_events_redis
- name: i_package_tag_deploy_token
category: deploy_token_packages
aggregation: weekly
diff --git a/lib/tasks/eslint.rake b/lib/tasks/eslint.rake
index ad63de66c81..35c3e834258 100644
--- a/lib/tasks/eslint.rake
+++ b/lib/tasks/eslint.rake
@@ -3,7 +3,7 @@
unless Rails.env.production?
desc "GitLab | Run ESLint"
task eslint: ['yarn:check'] do
- unless system('yarn run eslint')
+ unless system('yarn run lint:eslint')
abort('rake eslint failed')
end
end
diff --git a/lib/tasks/gitlab/graphql.rake b/lib/tasks/gitlab/graphql.rake
index e4eb4604138..caf5879a154 100644
--- a/lib/tasks/gitlab/graphql.rake
+++ b/lib/tasks/gitlab/graphql.rake
@@ -6,6 +6,7 @@ require 'graphql/rake_task'
namespace :gitlab do
OUTPUT_DIR = Rails.root.join("doc/api/graphql/reference")
+ TEMP_SCHEMA_DIR = Rails.root.join('tmp/tests/graphql')
TEMPLATES_DIR = 'lib/gitlab/graphql/docs/templates/'
# Make all feature flags enabled so that all feature flag
@@ -27,7 +28,7 @@ namespace :gitlab do
GraphQL::RakeTask.new(
schema_name: 'GitlabSchema',
dependencies: [:environment, :enable_feature_flags],
- directory: OUTPUT_DIR,
+ directory: TEMP_SCHEMA_DIR,
idl_outfile: "gitlab_schema.graphql",
json_outfile: "gitlab_schema.json"
)
@@ -129,19 +130,6 @@ namespace :gitlab do
abort
end
end
-
- desc 'GitLab | GraphQL | Check if GraphQL schemas are up to date'
- task check_schema: [:environment, :enable_feature_flags] do
- idl_doc = File.read(Rails.root.join(OUTPUT_DIR, 'gitlab_schema.graphql'))
- json_doc = File.read(Rails.root.join(OUTPUT_DIR, 'gitlab_schema.json'))
-
- if idl_doc == GitlabSchema.to_definition && json_doc == GitlabSchema.to_json
- puts "GraphQL schema is up to date"
- else
- format_output('GraphQL schema is outdated! Please update it by running `bundle exec rake gitlab:graphql:schema:dump`.')
- abort
- end
- end
end
end
diff --git a/lib/tasks/lint.rake b/lib/tasks/lint.rake
index 5d60bc41f21..976ec089011 100644
--- a/lib/tasks/lint.rake
+++ b/lib/tasks/lint.rake
@@ -33,7 +33,6 @@ unless Rails.env.production?
tasks = %w[
config_lint
lint:haml
- scss_lint
gettext:lint
lint:static_verification
gitlab:sidekiq:all_queues_yml:check
diff --git a/lib/tasks/scss-lint.rake b/lib/tasks/scss-lint.rake
deleted file mode 100644
index 8a4809f80fd..00000000000
--- a/lib/tasks/scss-lint.rake
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-unless Rails.env.production?
- require 'scss_lint/rake_task'
-
- SCSSLint::RakeTask.new do |t|
- t.config = '.scss-lint.yml'
- # See https://github.com/brigade/scss-lint/issues/726
- # Hack, otherwise linter won't respect scss_files option in config file.
- t.files = []
- end
-end