Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-03-22 06:08:34 +00:00
parent b460d4a7c0
commit 7137270698
64 changed files with 1062 additions and 981 deletions

View File

@ -49,18 +49,6 @@ compile-production-assets:
after_script:
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
compile-production-assets-esbuild:
allow_failure: true
extends:
- .compile-assets-base
- .frontend:rules:compile-production-assets
variables:
NODE_ENV: "production"
RAILS_ENV: "production"
WEBPACK_USE_ESBUILD_LOADER: "true"
after_script:
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
compile-test-assets:
extends:
- .compile-assets-base
@ -73,14 +61,6 @@ compile-test-assets:
- "${WEBPACK_COMPILE_LOG_PATH}"
when: always
compile-test-assets-esbuild:
allow_failure: true
extends:
- .compile-assets-base
- .frontend:rules:compile-test-assets
variables:
WEBPACK_USE_ESBUILD_LOADER: "true"
compile-test-assets as-if-foss:
extends:
- compile-test-assets

View File

@ -532,17 +532,6 @@ Layout/ArgumentAlignment:
- 'app/models/ci/running_build.rb'
- 'app/models/ci/stage.rb'
- 'app/models/clusters/kubernetes_namespace.rb'
- 'app/models/concerns/bulk_member_access_load.rb'
- 'app/models/concerns/ci/metadatable.rb'
- 'app/models/concerns/discussion_on_diff.rb'
- 'app/models/concerns/group_descendant.rb'
- 'app/models/concerns/integrations/has_issue_tracker_fields.rb'
- 'app/models/concerns/issuable.rb'
- 'app/models/concerns/limitable.rb'
- 'app/models/concerns/mentionable/reference_regexes.rb'
- 'app/models/concerns/resolvable_discussion.rb'
- 'app/models/concerns/vulnerability_finding_helpers.rb'
- 'app/models/concerns/web_hooks/auto_disabling.rb'
- 'app/models/container_repository.rb'
- 'app/models/cycle_analytics/project_level_stage_adapter.rb'
- 'app/models/deployment.rb'
@ -1142,8 +1131,6 @@ Layout/ArgumentAlignment:
- 'ee/app/mailers/emails/namespace_storage_usage_mailer.rb'
- 'ee/app/models/approval_wrapped_rule.rb'
- 'ee/app/models/ci/minutes/notification.rb'
- 'ee/app/models/concerns/ee/protected_ref_access.rb'
- 'ee/app/models/concerns/geo/verifiable_replicator.rb'
- 'ee/app/models/dast/pre_scan_verification.rb'
- 'ee/app/models/deployments/approval.rb'
- 'ee/app/models/ee/application_setting.rb'
@ -1523,12 +1510,6 @@ Layout/ArgumentAlignment:
- 'ee/spec/models/approval_wrapped_code_owner_rule_spec.rb'
- 'ee/spec/models/ci/bridge_spec.rb'
- 'ee/spec/models/ci/build_spec.rb'
- 'ee/spec/models/concerns/elastic/issue_spec.rb'
- 'ee/spec/models/concerns/elastic/merge_request_spec.rb'
- 'ee/spec/models/concerns/elastic/note_spec.rb'
- 'ee/spec/models/concerns/elastic/project_spec.rb'
- 'ee/spec/models/concerns/elastic/repository_spec.rb'
- 'ee/spec/models/concerns/elastic/snippet_spec.rb'
- 'ee/spec/models/dast/pre_scan_verification_step_spec.rb'
- 'ee/spec/models/dast_site_profile_spec.rb'
- 'ee/spec/models/deployments/approval_summary_spec.rb'
@ -2611,13 +2592,6 @@ Layout/ArgumentAlignment:
- 'spec/models/clusters/kubernetes_namespace_spec.rb'
- 'spec/models/clusters/platforms/kubernetes_spec.rb'
- 'spec/models/commit_spec.rb'
- 'spec/models/concerns/ci/partitionable/switch_spec.rb'
- 'spec/models/concerns/ci/partitionable_spec.rb'
- 'spec/models/concerns/ci/track_environment_usage_spec.rb'
- 'spec/models/concerns/database_event_tracking_spec.rb'
- 'spec/models/concerns/deployment_platform_spec.rb'
- 'spec/models/concerns/issuable_spec.rb'
- 'spec/models/concerns/token_authenticatable_spec.rb'
- 'spec/models/container_repository_spec.rb'
- 'spec/models/deployment_spec.rb'
- 'spec/models/design_management/version_spec.rb'
@ -2995,11 +2969,6 @@ Layout/ArgumentAlignment:
- 'spec/support/shared_examples/lib/sentry/client_shared_examples.rb'
- 'spec/support/shared_examples/models/chat_integration_shared_examples.rb'
- 'spec/support/shared_examples/models/clusters/prometheus_client_shared.rb'
- 'spec/support/shared_examples/models/concerns/auto_disabling_hooks_shared_examples.rb'
- 'spec/support/shared_examples/models/concerns/cascading_namespace_setting_shared_examples.rb'
- 'spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb'
- 'spec/support/shared_examples/models/concerns/timebox_shared_examples.rb'
- 'spec/support/shared_examples/models/concerns/unstoppable_hooks_shared_examples.rb'
- 'spec/support/shared_examples/models/diff_note_after_commit_shared_examples.rb'
- 'spec/support/shared_examples/models/member_shared_examples.rb'
- 'spec/support/shared_examples/observability/csp_shared_examples.rb'

View File

@ -2318,7 +2318,6 @@ RSpec/ContextWording:
- 'spec/models/personal_access_token_spec.rb'
- 'spec/models/plan_limits_spec.rb'
- 'spec/models/preloaders/labels_preloader_spec.rb'
- 'spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/project_authorization_spec.rb'
- 'spec/models/project_feature_spec.rb'
- 'spec/models/project_feature_usage_spec.rb'

View File

@ -162,7 +162,6 @@ RSpec/DescribedClass:
- 'spec/models/performance_monitoring/prometheus_panel_spec.rb'
- 'spec/models/postgresql/detached_partition_spec.rb'
- 'spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/project_spec.rb'
- 'spec/models/projects/topic_spec.rb'
- 'spec/models/release_highlight_spec.rb'

View File

@ -5444,7 +5444,6 @@ RSpec/MissingFeatureCategory:
- 'spec/models/preloaders/project_root_ancestor_preloader_spec.rb'
- 'spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb'
- 'spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- 'spec/models/product_analytics_event_spec.rb'
- 'spec/models/programming_language_spec.rb'
- 'spec/models/project_authorization_spec.rb'

View File

@ -527,7 +527,7 @@ gem 'flipper', '~> 0.25.0'
gem 'flipper-active_record', '~> 0.25.0'
gem 'flipper-active_support_cache_store', '~> 0.25.0'
gem 'unleash', '~> 3.2.2'
gem 'gitlab-experiment', '~> 0.8.0'
gem 'gitlab-experiment', '~> 0.7.1'
# Structured logging
gem 'lograge', '~> 0.5'

View File

@ -206,7 +206,7 @@
{"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"},
{"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"},
{"name":"gitlab-dangerfiles","version":"3.8.0","platform":"ruby","checksum":"7ef0c3205faa38a2ada19ee5b8e4012ea696611aa02564a4a95eaf3fb26d1a7e"},
{"name":"gitlab-experiment","version":"0.8.0","platform":"ruby","checksum":"b4e2f73e0af19cdd899a745f5a846c1318d44054e068a8f4ac887f6b1017d3f9"},
{"name":"gitlab-experiment","version":"0.7.1","platform":"ruby","checksum":"166dddb3aa83428bcaa93c35684ed01dc4d61f321fd2ae40b020806dc54a7824"},
{"name":"gitlab-fog-azure-rm","version":"1.7.0","platform":"ruby","checksum":"969c67943c54ad4c259a6acd040493f13922fbdf2211bb4eca00e71505263dc2"},
{"name":"gitlab-labkit","version":"0.31.1","platform":"ruby","checksum":"3e3a39370966b5d2739c2d9d9005c0ea27541d32cb7292e856e8bd74c720bffb"},
{"name":"gitlab-license","version":"2.2.1","platform":"ruby","checksum":"39fcf6be8b2887df8afe01b5dcbae8d08b7c5d937ff56b0fb40484a8c4f02d30"},

View File

@ -590,7 +590,7 @@ GEM
danger (>= 8.4.5)
danger-gitlab (>= 8.0.0)
rake
gitlab-experiment (0.8.0)
gitlab-experiment (0.7.1)
activesupport (>= 3.0)
request_store (>= 1.0)
gitlab-fog-azure-rm (1.7.0)
@ -1718,7 +1718,7 @@ DEPENDENCIES
gitaly (~> 15.9.0.pre.rc3)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.8.0)
gitlab-experiment (~> 0.8.0)
gitlab-experiment (~> 0.7.1)
gitlab-fog-azure-rm (~> 1.7.0)
gitlab-labkit (~> 0.31.1)
gitlab-license (~> 2.2.1)

View File

@ -339,7 +339,6 @@ class Projects::PipelinesController < Projects::ApplicationController
return if helpers.has_gitlab_ci?(project)
experiment(:runners_availability_section, namespace: project.root_ancestor) do |e|
e.control {}
e.candidate {}
end
end

View File

@ -105,12 +105,10 @@ module Ci
}
experiment(:runners_availability_section, namespace: project.root_ancestor) do |e|
e.control {} # rubocop:disable Lint/EmptyBlock
e.candidate { data[:any_runners_available] = project.active_runners.exists?.to_s }
end
experiment(:ios_specific_templates, actor: current_user, project: project, sticky_to: project) do |e|
e.control {} # rubocop:disable Lint/EmptyBlock
e.candidate do
data[:registration_token] = project.runners_token if can?(current_user, :register_project_runners, project)
data[:ios_runners_available] = (project.shared_runners_available? && Gitlab.com?).to_s

View File

@ -72,7 +72,6 @@ module IdeHelper
def enable_environments_guidance?(project)
experiment(:in_product_guidance_environments_webide, project: project) do |e|
e.control { 'false' }
e.candidate { !has_dismissed_ide_environments_callout? }
e.run

View File

@ -5,16 +5,20 @@ module BulkMemberAccessLoad
included do
def merge_value_to_request_store(resource_klass, resource_id, value)
Gitlab::SafeRequestLoader.execute(resource_key: max_member_access_for_resource_key(resource_klass),
resource_ids: [resource_id],
default_value: Gitlab::Access::NO_ACCESS) do
Gitlab::SafeRequestLoader.execute(
resource_key: max_member_access_for_resource_key(resource_klass),
resource_ids: [resource_id],
default_value: Gitlab::Access::NO_ACCESS
) do
{ resource_id => value }
end
end
def purge_resource_id_from_request_store(resource_klass, resource_id)
Gitlab::SafeRequestPurger.execute(resource_key: max_member_access_for_resource_key(resource_klass),
resource_ids: [resource_id])
Gitlab::SafeRequestPurger.execute(
resource_key: max_member_access_for_resource_key(resource_klass),
resource_ids: [resource_id]
)
end
def max_member_access_for_resource_key(klass)

View File

@ -9,10 +9,11 @@ module Ci
extend ActiveSupport::Concern
included do
has_one :metadata, class_name: 'Ci::BuildMetadata',
foreign_key: :build_id,
inverse_of: :build,
autosave: true
has_one :metadata,
class_name: 'Ci::BuildMetadata',
foreign_key: :build_id,
inverse_of: :build,
autosave: true
accepts_nested_attributes_for :metadata

View File

@ -7,20 +7,20 @@ module DiscussionOnDiff
NUMBER_OF_TRUNCATED_DIFF_LINES = 16
included do
delegate :line_code,
:original_line_code,
:note_diff_file,
:diff_line,
:active?,
:created_at_diff?,
to: :first_note
delegate :line_code,
:original_line_code,
:note_diff_file,
:diff_line,
:active?,
:created_at_diff?,
to: :first_note
delegate :file_path,
:blob,
:highlighted_diff_lines,
:diff_lines,
to: :diff_file,
allow_nil: true
delegate :file_path,
:blob,
:highlighted_diff_lines,
:diff_lines,
to: :diff_file,
allow_nil: true
end
def diff_discussion?

View File

@ -60,10 +60,7 @@ module GroupDescendant
end
if parent && parent != hierarchy_top
expand_hierarchy_for_child(parent,
{ parent => hierarchy },
hierarchy_top,
preloaded)
expand_hierarchy_for_child(parent, { parent => hierarchy }, hierarchy_top, preloaded)
else
hierarchy
end

View File

@ -8,29 +8,29 @@ module Integrations
self.field_storage = :data_fields
field :project_url,
required: true,
title: -> { _('Project URL') },
help: -> do
s_('IssueTracker|The URL to the project in the external issue tracker.')
end
required: true,
title: -> { _('Project URL') },
help: -> do
s_('IssueTracker|The URL to the project in the external issue tracker.')
end
field :issues_url,
required: true,
title: -> { s_('IssueTracker|Issue URL') },
help: -> do
ERB::Util.html_escape(
s_('IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}.')
) % {
colon_id: '<code>:id</code>'.html_safe
}
end
required: true,
title: -> { s_('IssueTracker|Issue URL') },
help: -> do
ERB::Util.html_escape(
s_('IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}.')
) % {
colon_id: '<code>:id</code>'.html_safe
}
end
field :new_issue_url,
required: true,
title: -> { s_('IssueTracker|New issue URL') },
help: -> do
s_('IssueTracker|The URL to create an issue in the external issue tracker.')
end
required: true,
title: -> { s_('IssueTracker|New issue URL') },
help: -> do
s_('IssueTracker|The URL to create an issue in the external issue tracker.')
end
end
end
end

View File

@ -84,11 +84,11 @@ module Issuable
has_one :metrics, inverse_of: model_name.singular.to_sym, autosave: true
delegate :name,
:email,
:public_email,
to: :author,
allow_nil: true,
prefix: true
:email,
:public_email,
to: :author,
allow_nil: true,
prefix: true
validates :author, presence: true
validates :title, presence: true, length: { maximum: TITLE_LENGTH_MAX }
@ -345,8 +345,7 @@ module Issuable
order_milestone_due_asc
.order_labels_priority(excluded_labels: excluded_labels, extra_select_columns: [milestones_due_date])
.reorder(milestones_due_date_with_direction.nulls_last,
highest_priority_arel_with_direction.nulls_last)
.reorder(milestones_due_date_with_direction.nulls_last, highest_priority_arel_with_direction.nulls_last)
end
def order_labels_priority(direction = 'ASC', excluded_labels: [], extra_select_columns: [], with_cte: false)
@ -620,8 +619,10 @@ module Issuable
end
def updated_tasks
Taskable.get_updated_tasks(old_content: previous_changes['description'].first,
new_content: description)
Taskable.get_updated_tasks(
old_content: previous_changes['description'].first,
new_content: description
)
end
##

View File

@ -59,7 +59,10 @@ module Limitable
def check_plan_limit_not_exceeded(limits, relation)
return unless limits&.exceeded?(limit_name, relation)
errors.add(:base, _("Maximum number of %{name} (%{count}) exceeded") %
{ name: limit_name.humanize(capitalize: false), count: limits.public_send(limit_name) }) # rubocop:disable GitlabSecurity/PublicSend
errors.add(
:base,
_("Maximum number of %{name} (%{count}) exceeded") %
{ name: limit_name.humanize(capitalize: false), count: limits.public_send(limit_name) } # rubocop:disable GitlabSecurity/PublicSend
)
end
end

View File

@ -5,9 +5,7 @@ module Mentionable
extend Gitlab::Utils::StrongMemoize
def self.reference_pattern(link_patterns, issue_pattern)
Regexp.union(link_patterns,
issue_pattern,
*other_patterns)
Regexp.union(link_patterns, issue_pattern, *other_patterns)
end
def self.other_patterns

View File

@ -24,14 +24,14 @@ module ResolvableDiscussion
)
delegate :potentially_resolvable?,
:noteable_id,
:noteable_type,
to: :first_note
:noteable_id,
:noteable_type,
to: :first_note
delegate :resolved_at,
:resolved_by,
to: :last_resolved_note,
allow_nil: true
delegate :resolved_at,
:resolved_by,
to: :last_resolved_note,
allow_nil: true
end
def resolved_by_push?

View File

@ -47,8 +47,9 @@ module VulnerabilityFindingHelpers
report_finding = report_finding_for(security_finding)
return Vulnerabilities::Finding.new unless report_finding
finding_data = report_finding.to_hash.except(:compare_key, :identifiers, :location, :scanner, :links, :signatures,
:flags, :evidence)
finding_data = report_finding.to_hash.except(
:compare_key, :identifiers, :location, :scanner, :links, :signatures, :flags, :evidence
)
identifiers = report_finding.identifiers.uniq(&:fingerprint).map do |identifier|
Vulnerabilities::Identifier.new(identifier.to_hash.merge({ project: project }))
end

View File

@ -39,8 +39,11 @@ module WebHooks
scope :disabled, -> do
return none unless auto_disabling_enabled?
where('recent_failures > ? AND (disabled_until IS NULL OR disabled_until >= ?)',
FAILURE_THRESHOLD, Time.current)
where(
'recent_failures > ? AND (disabled_until IS NULL OR disabled_until >= ?)',
FAILURE_THRESHOLD,
Time.current
)
end
# A hook is executable if:
@ -52,8 +55,12 @@ module WebHooks
scope :executable, -> do
return all unless auto_disabling_enabled?
where('recent_failures <= ? OR (recent_failures > ? AND (disabled_until IS NOT NULL) AND (disabled_until < ?))',
FAILURE_THRESHOLD, FAILURE_THRESHOLD, Time.current)
where(
'recent_failures <= ? OR (recent_failures > ? AND (disabled_until IS NOT NULL) AND (disabled_until < ?))',
FAILURE_THRESHOLD,
FAILURE_THRESHOLD,
Time.current
)
end
end

View File

@ -0,0 +1,51 @@
# frozen_string_literal: true
module Preloaders
# This class preloads the max access level (role) for the users within the given projects and
# stores the values in requests store via the ProjectTeam class.
class UsersMaxAccessLevelByProjectPreloader
include Gitlab::Utils::StrongMemoize
def initialize(project_users:)
@project_users = project_users.transform_values { |users| Array.wrap(users) }
end
def execute
return unless @project_users.present?
all_users = @project_users.values.flatten.uniq
preload_users_namespace_bans(all_users)
@project_users.each do |project, users|
users.each do |user|
access_level = access_levels.fetch([project.id, user.id], Gitlab::Access::NO_ACCESS)
project.team.write_member_access_for_user_id(user.id, access_level)
end
end
end
private
def access_levels
query = ProjectAuthorization.none
@project_users.each do |project, users|
query = query.or(
ProjectAuthorization
.where(project_id: project.id, user_id: users.map(&:id))
)
end
query
.group(:project_id, :user_id)
.maximum(:access_level)
end
strong_memoize_attr :access_levels
def preload_users_namespace_bans(_users)
# overridden in EE
end
end
end
Preloaders::UsersMaxAccessLevelByProjectPreloader.prepend_mod

View File

@ -1,54 +0,0 @@
# frozen_string_literal: true
module Preloaders
# This class preloads the max access level (role) for the users within the given projects and
# stores the values in requests store via the ProjectTeam class.
class UsersMaxAccessLevelInProjectsPreloader
def initialize(projects:, users:)
@projects = projects
@users = users
end
def execute
return unless @projects.present? && @users.present?
preload_users_namespace_bans(@users)
access_levels.each do |(project_id, user_id), access_level|
project = projects_by_id[project_id]
project.team.write_member_access_for_user_id(user_id, access_level)
end
end
private
def access_levels
ProjectAuthorization
.where(project_id: project_ids, user_id: user_ids)
.group(:project_id, :user_id)
.maximum(:access_level)
end
# Use reselect to override the existing select to prevent
# the error `subquery has too many columns`
# NotificationsController passes in an Array so we need to check the type
def project_ids
@projects.is_a?(ActiveRecord::Relation) ? @projects.reselect(:id) : @projects
end
def user_ids
@users.is_a?(ActiveRecord::Relation) ? @users.reselect(:id) : @users
end
def projects_by_id
@projects_by_id ||= @projects.index_by(&:id)
end
def preload_users_namespace_bans(_users)
# overridden in EE
end
end
end
Preloaders::UsersMaxAccessLevelInProjectsPreloader.prepend_mod

View File

@ -130,6 +130,75 @@ class WorkItem < Issue
::Gitlab::WorkItems::WorkItemHierarchy.new(base, options: options)
end
override :allowed_work_item_type_change
def allowed_work_item_type_change
return unless work_item_type_id_changed?
child_links = WorkItems::ParentLink.for_parents(id)
parent_link = ::WorkItems::ParentLink.find_by(work_item: self)
validate_parent_restrictions(parent_link)
validate_child_restrictions(child_links)
validate_depth(parent_link, child_links)
end
def validate_parent_restrictions(parent_link)
return unless parent_link
parent_link.work_item.work_item_type_id = work_item_type_id
unless parent_link.valid?
errors.add(
:work_item_type_id,
format(
_('cannot be changed to %{new_type} with %{parent_type} as parent type.'),
new_type: work_item_type.name, parent_type: parent_link.work_item_parent.work_item_type.name
)
)
end
end
def validate_child_restrictions(child_links)
return if child_links.empty?
child_type_ids = child_links.joins(:work_item).select(self.class.arel_table[:work_item_type_id]).distinct
restrictions = ::WorkItems::HierarchyRestriction.where(
parent_type_id: work_item_type_id,
child_type_id: child_type_ids
)
# We expect a restriction for every child type
if restrictions.size < child_type_ids.size
errors.add(
:work_item_type_id,
format(_('cannot be changed to %{new_type} with these child item types.'), new_type: work_item_type.name)
)
end
end
def validate_depth(parent_link, child_links)
restriction = ::WorkItems::HierarchyRestriction.find_by_parent_type_id_and_child_type_id(
work_item_type_id,
work_item_type_id
)
return unless restriction&.maximum_depth
children_with_new_type = self.class.where(id: child_links.select(:work_item_id))
.where(work_item_type_id: work_item_type_id)
max_child_depth = ::Gitlab::WorkItems::WorkItemHierarchy.new(children_with_new_type).max_descendants_depth.to_i
ancestor_depth =
if parent_link&.work_item_parent && parent_link.work_item_parent.work_item_type_id == work_item_type_id
parent_link.work_item_parent.same_type_base_and_ancestors.count
else
0
end
if max_child_depth + ancestor_depth > restriction.maximum_depth - 1
errors.add(:work_item_type_id, _('reached maximum depth'))
end
end
end
WorkItem.prepend_mod

View File

@ -1,65 +0,0 @@
const browserslist = require('browserslist');
const esbuild = require('esbuild');
const ESBUILD_SUPPORTED_TARGETS = new Set([
'chrome',
'edge',
'firefox',
'hermes',
'ie',
'ios',
'node',
'opera',
'rhino',
'safari',
]);
const parseBrowserslist = (browserslistResult) => {
return browserslistResult.map((browsers) => {
const [family, version] = browsers.split(' ');
let normalizedVersion = version;
// browserslist can return a range: safari15.2-15.4
if (version.indexOf('-') >= -1) {
// we take the lowest version
[normalizedVersion] = version.split('-');
}
return {
family,
version: normalizedVersion,
};
});
};
const mapBrowserslistToESBuildTarget = (browsersList) => {
return parseBrowserslist(browsersList)
.filter(({ family, version }) => {
if (!ESBUILD_SUPPORTED_TARGETS.has(family)) {
console.warning('Unknown ESBuild target %s, version %s', family, version);
return false;
}
return true;
})
.map(({ family, version }) => {
return `${family}${version}`;
});
};
module.exports = {
target: mapBrowserslistToESBuildTarget(browserslist()),
supported: {
'optional-chain': false,
'nullish-coalescing': false,
'class-static-field': false,
'class-field': false,
},
implementation: esbuild,
/**
* It's necessary to tell esbuild to use the 'js' loader
* because esbuild cannot auto-detect which loader to use
* based on the .vue extension.
*/
loader: 'js',
};

View File

@ -31,14 +31,11 @@ const { VueLoaderPlugin } = require(VUE_LOADER_MODULE);
const VUE_LOADER_VERSION = require(`${VUE_LOADER_MODULE}/package.json`).version;
const VUE_VERSION = require('vue/package.json').version;
const { EsbuildPlugin } = require('esbuild-loader');
const webpack = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { StatsWriterPlugin } = require('webpack-stats-plugin');
const WEBPACK_VERSION = require('webpack/package.json').version;
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const esbuildConfiguration = require('./esbuild.config');
const createIncrementalWebpackCompiler = require('./helpers/incremental_webpack_compiler');
const IS_EE = require('./helpers/is_ee_env');
@ -58,8 +55,6 @@ const VENDOR_DLL = process.env.WEBPACK_VENDOR_DLL && process.env.WEBPACK_VENDOR_
const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache');
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
const IS_DEV_SERVER = process.env.WEBPACK_SERVE === 'true';
const WEBPACK_USE_ESBUILD_LOADER =
process.env.WEBPACK_USE_ESBUILD_LOADER && process.env.WEBPACK_USE_ESBUILD_LOADER !== 'false';
const { DEV_SERVER_HOST, DEV_SERVER_PUBLIC_ADDR } = process.env;
const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10);
@ -69,11 +64,9 @@ const DEV_SERVER_LIVERELOAD = IS_DEV_SERVER && process.env.DEV_SERVER_LIVERELOAD
const INCREMENTAL_COMPILER_ENABLED =
IS_DEV_SERVER &&
process.env.DEV_SERVER_INCREMENTAL &&
process.env.DEV_SERVER_INCREMENTAL !== 'false' &&
!WEBPACK_USE_ESBUILD_LOADER;
process.env.DEV_SERVER_INCREMENTAL !== 'false';
const INCREMENTAL_COMPILER_TTL = Number(process.env.DEV_SERVER_INCREMENTAL_TTL) || Infinity;
const INCREMENTAL_COMPILER_RECORD_HISTORY =
IS_DEV_SERVER && !process.env.CI && !WEBPACK_USE_ESBUILD_LOADER;
const INCREMENTAL_COMPILER_RECORD_HISTORY = IS_DEV_SERVER && !process.env.CI;
const WEBPACK_REPORT = process.env.WEBPACK_REPORT && process.env.WEBPACK_REPORT !== 'false';
const WEBPACK_MEMORY_TEST =
process.env.WEBPACK_MEMORY_TEST && process.env.WEBPACK_MEMORY_TEST !== 'false';
@ -294,10 +287,6 @@ const defaultJsOptions = {
cacheCompression: false,
};
if (WEBPACK_USE_ESBUILD_LOADER) {
console.log('esbuild-loader is active');
}
const vueLoaderOptions = {
ident: 'vue-loader-options',
@ -374,13 +363,7 @@ module.exports = {
include: /node_modules/,
loader: 'babel-loader',
},
WEBPACK_USE_ESBUILD_LOADER && {
test: /\.(js|cjs)$/,
exclude: shouldExcludeFromCompliling,
loader: 'esbuild-loader',
options: esbuildConfiguration,
},
!WEBPACK_USE_ESBUILD_LOADER && {
{
test: /\.(js|cjs)$/,
exclude: shouldExcludeFromCompliling,
use: [
@ -399,16 +382,7 @@ module.exports = {
},
],
},
WEBPACK_USE_ESBUILD_LOADER && {
test: /\.(js|cjs)$/,
include: (modulePath) =>
/node_modules\/(monaco-worker-manager|monaco-marker-data-provider)\/index\.js/.test(
modulePath,
) || /node_modules\/yaml/.test(modulePath),
loader: 'esbuild-loader',
options: esbuildConfiguration,
},
!WEBPACK_USE_ESBUILD_LOADER && {
{
test: /\.(js|cjs)$/,
include: (modulePath) =>
/node_modules\/(monaco-worker-manager|monaco-marker-data-provider)\/index\.js/.test(
@ -586,7 +560,6 @@ module.exports = {
},
},
},
...(WEBPACK_USE_ESBUILD_LOADER ? { minimizer: [new EsbuildPlugin(esbuildConfiguration)] } : {}),
},
plugins: [

View File

@ -76,8 +76,6 @@ module.exports = {
https://gitlab.com/gitlab-org/gitlab/-/issues/219353
*/
'chokidar',
// We are ignoring esbuild as we want to force a newer version than what esbuild-loader provides
'esbuild',
// We are ignoring ts-jest, because we force a newer version, compatible with our current jest version
'ts-jest',
].join('|'),

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddIndexToNamespaceDetails < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
INDEX_NAME = 'index_fuc_over_limit_notified_at'
TABLE_NAME = 'namespace_details'
COLUMN_NAME = 'free_user_cap_over_limit_notified_at'
def up
add_concurrent_index TABLE_NAME, COLUMN_NAME, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, name: INDEX_NAME
end
end

View File

@ -0,0 +1 @@
58d91bbad9896429a0b8d383a1d5ef47a7b017c65af7834c01091fbccb7f5221

View File

@ -30335,6 +30335,8 @@ CREATE UNIQUE INDEX index_fork_network_members_on_project_id ON fork_network_mem
CREATE UNIQUE INDEX index_fork_networks_on_root_project_id ON fork_networks USING btree (root_project_id);
CREATE INDEX index_fuc_over_limit_notified_at ON namespace_details USING btree (free_user_cap_over_limit_notified_at);
CREATE INDEX index_geo_event_log_on_cache_invalidation_event_id ON geo_event_log USING btree (cache_invalidation_event_id) WHERE (cache_invalidation_event_id IS NOT NULL);
CREATE INDEX index_geo_event_log_on_geo_event_id ON geo_event_log USING btree (geo_event_id) WHERE (geo_event_id IS NOT NULL);

View File

@ -8,6 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/121) in GitLab 12.4.
> - [Author Email added to the response body](https://gitlab.com/gitlab-org/gitlab/-/issues/386322) in GitLab 15.9.
> - Support for keyset pagination [added](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.11.
## Instance Audit Events **(PREMIUM SELF)**
@ -29,8 +30,8 @@ GET /audit_events
| `entity_type` | string | no | Return audit events for the given entity type. Valid values are: `User`, `Group`, or `Project`. |
| `entity_id` | integer | no | Return audit events for the given entity ID. Requires `entity_type` attribute to be present. |
By default, `GET` requests return 20 results at a time because the API results
are paginated.
This endpoint supports both offset-based and [keyset-based](rest/index.md#keyset-based-pagination) pagination. You should use keyset-based
pagination when requesting consecutive pages of results.
Read more on [pagination](rest/index.md#pagination).

View File

@ -483,13 +483,14 @@ pagination headers.
Keyset-based pagination is supported only for selected resources and ordering
options:
| Resource | Options | Availability |
|:----------------------------------------------------------------|:---------------------------------|:--------------------------------------------------------------------------------------------------------------|
| [Projects](../projects.md) | `order_by=id` only | Authenticated and unauthenticated users |
| [Groups](../groups.md) | `order_by=name`, `sort=asc` only | Unauthenticated users only |
| [Group audit events](../audit_events.md#group-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/333968) in GitLab 15.2) |
| [Project audit events](../audit_events.md#project-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.10) |
| [Jobs](../jobs.md) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362172) in GitLab 15.9) |
| Resource | Options | Availability |
|:------------------------------------------------------------------|:---------------------------------|:--------------------------------------------------------------------------------------------------------------|
| [Projects](../projects.md) | `order_by=id` only | Authenticated and unauthenticated users |
| [Groups](../groups.md) | `order_by=name`, `sort=asc` only | Unauthenticated users only |
| [Instance audit events](../audit_events.md#instance-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.11) |
| [Group audit events](../audit_events.md#group-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/333968) in GitLab 15.2) |
| [Project audit events](../audit_events.md#project-audit-events) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367528) in GitLab 15.10) |
| [Jobs](../jobs.md) | `order_by=id`, `sort=desc` only | Authenticated users only ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362172) in GitLab 15.9) |
### Pagination response headers

View File

@ -12,9 +12,12 @@ module Gitlab
def preload_authorizations(dast_profiles)
return unless dast_profiles
projects = dast_profiles.map(&:project)
users = dast_profiles.filter_map { |dast_profile| dast_profile.dast_profile_schedule&.owner }
Preloaders::UsersMaxAccessLevelInProjectsPreloader.new(projects: projects, users: users).execute
project_users = dast_profiles.group_by(&:project).transform_values do |project_profiles|
project_profiles
.filter_map { |profile| profile.dast_profile_schedule&.owner }
.uniq
end
Preloaders::UsersMaxAccessLevelByProjectPreloader.new(project_users: project_users).execute
end
end
end

View File

@ -50896,6 +50896,9 @@ msgstr ""
msgid "can not be changed to %{new_type}"
msgstr ""
msgid "can not be changed when assigned to an epic"
msgstr ""
msgid "can not be set for this resource"
msgstr ""
@ -50959,6 +50962,12 @@ msgstr ""
msgid "cannot be changed since member is associated with a custom role"
msgstr ""
msgid "cannot be changed to %{new_type} with %{parent_type} as parent type."
msgstr ""
msgid "cannot be changed to %{new_type} with these child item types."
msgstr ""
msgid "cannot be enabled"
msgstr ""

View File

@ -126,8 +126,6 @@
"dropzone": "^4.2.0",
"editorconfig": "^0.15.3",
"emoji-regex": "^10.0.0",
"esbuild": "0.17.11",
"esbuild-loader": "^3.0.1",
"fast-mersenne-twister": "1.0.2",
"file-loader": "^6.2.0",
"fuzzaldrin-plus": "^0.6.0",

View File

@ -211,7 +211,7 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
application_experiment.variant(:variant1) {}
application_experiment.variant(:variant2) {}
expect(application_experiment.assigned.name).to eq(:variant2)
expect(application_experiment.assigned.name).to eq('variant2')
end
end
@ -248,7 +248,7 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
end
it "caches the variant determined by the variant resolver" do
expect(application_experiment.assigned.name).to eq(:candidate) # we should be in the experiment
expect(application_experiment.assigned.name).to eq('candidate') # we should be in the experiment
application_experiment.run
@ -263,7 +263,7 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
# the control.
stub_feature_flags(namespaced_stub: false) # simulate being not rolled out
expect(application_experiment.assigned.name).to eq(:control) # if we ask, it should be control
expect(application_experiment.assigned.name).to eq('control') # if we ask, it should be control
application_experiment.run
@ -299,4 +299,29 @@ RSpec.describe ApplicationExperiment, :experiment, feature_category: :experiment
end
end
end
context "with deprecation warnings" do
before do
Gitlab::Experiment::Configuration.instance_variable_set(:@__dep_versions, nil) # clear the internal memoization
allow(ActiveSupport::Deprecation).to receive(:new).and_call_original
end
it "doesn't warn on non dev/test environments" do
allow(Gitlab).to receive(:dev_or_test_env?).and_return(false)
expect { experiment(:example) { |e| e.use {} } }.not_to raise_error
expect(ActiveSupport::Deprecation).not_to have_received(:new).with(anything, 'Gitlab::Experiment')
end
it "warns on dev and test environments" do
allow(Gitlab).to receive(:dev_or_test_env?).and_return(true)
# This will eventually raise an ActiveSupport::Deprecation exception,
# it's ok to change it when that happens.
expect { experiment(:example) { |e| e.use {} } }.not_to raise_error
expect(ActiveSupport::Deprecation).to have_received(:new).with(anything, 'Gitlab::Experiment')
end
end
end

View File

@ -4,6 +4,6 @@ require 'spec_helper'
RSpec.describe SecurityReportsMrWidgetPromptExperiment do
it "defines a control and candidate" do
expect(subject.behaviors.keys).to match_array(%i[control candidate])
expect(subject.behaviors.keys).to match_array(%w[control candidate])
end
end

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::Experiment::Rollout::Feature, :experiment do
subject { described_class.new(subject_experiment) }
subject { described_class.new.for(subject_experiment) }
let(:subject_experiment) { experiment('namespaced/stub') }

View File

@ -59,13 +59,14 @@ RSpec.describe Ci::Partitionable::Switch, :aggregate_failures do
model.include(Ci::Partitionable)
model.partitionable scope: ->(r) { 1 },
through: { table: :_test_p_ci_jobs_metadata, flag: table_rollout_flag }
through: { table: :_test_p_ci_jobs_metadata, flag: table_rollout_flag }
model.belongs_to :job, anonymous_class: jobs_model
jobs_model.has_one :metadata, anonymous_class: model,
foreign_key: :job_id, inverse_of: :job,
dependent: :destroy
jobs_model.has_one :metadata,
anonymous_class: model,
foreign_key: :job_id, inverse_of: :job,
dependent: :destroy
allow(Feature::Definition).to receive(:get).and_call_original
allow(Feature::Definition).to receive(:get).with(table_rollout_flag)

View File

@ -31,7 +31,7 @@ RSpec.describe Ci::Partitionable do
ci_model.include(described_class)
ci_model.partitionable scope: ->(r) { 1 },
through: { table: :_test_table_name, flag: :some_flag }
through: { table: :_test_table_name, flag: :some_flag }
end
it { expect(ci_model.routing_table_name).to eq(:_test_table_name) }

View File

@ -8,10 +8,12 @@ RSpec.describe Ci::TrackEnvironmentUsage do
context 'when build is the verify action for the environment' do
let(:build) do
build_stubbed(:ci_build,
ref: 'master',
environment: 'staging',
options: { environment: { action: 'verify' } })
build_stubbed(
:ci_build,
ref: 'master',
environment: 'staging',
options: { environment: { action: 'verify' } }
)
end
it { is_expected.to be_truthy }
@ -19,10 +21,12 @@ RSpec.describe Ci::TrackEnvironmentUsage do
context 'when build is not the verify action for the environment' do
let(:build) do
build_stubbed(:ci_build,
ref: 'master',
environment: 'staging',
options: { environment: { action: 'start' } })
build_stubbed(
:ci_build,
ref: 'master',
environment: 'staging',
options: { environment: { action: 'start' } }
)
end
it { is_expected.to be_falsey }

View File

@ -46,24 +46,42 @@ RSpec.describe DatabaseEventTracking, :snowplow do
it 'when created' do
create_test_class_record
expect_snowplow_event(category: category, action: "#{event}_create", label: 'application_setting_terms',
property: 'create', namespace: nil, "id" => 1)
expect_snowplow_event(
category: category,
action: "#{event}_create",
label: 'application_setting_terms',
property: 'create',
namespace: nil,
"id" => 1
)
end
it 'when updated' do
create_test_class_record
test_class.first.update!(id: 3)
expect_snowplow_event(category: category, action: "#{event}_update", label: 'application_setting_terms',
property: 'update', namespace: nil, "id" => 3)
expect_snowplow_event(
category: category,
action: "#{event}_update",
label: 'application_setting_terms',
property: 'update',
namespace: nil,
"id" => 3
)
end
it 'when destroyed' do
create_test_class_record
test_class.first.destroy!
expect_snowplow_event(category: category, action: "#{event}_destroy", label: 'application_setting_terms',
property: 'destroy', namespace: nil, "id" => 1)
expect_snowplow_event(
category: category,
action: "#{event}_destroy",
label: 'application_setting_terms',
property: 'destroy',
namespace: nil,
"id" => 1
)
end
end
end

View File

@ -56,13 +56,23 @@ RSpec.describe DeploymentPlatform do
context 'when project does not have a cluster but has group clusters' do
let!(:default_cluster) do
create(:cluster, :provided_by_user,
cluster_type: :group_type, groups: [group], environment_scope: '*')
create(
:cluster,
:provided_by_user,
cluster_type: :group_type,
groups: [group],
environment_scope: '*'
)
end
let!(:cluster) do
create(:cluster, :provided_by_user,
cluster_type: :group_type, environment_scope: 'review/*', groups: [group])
create(
:cluster,
:provided_by_user,
cluster_type: :group_type,
environment_scope: 'review/*',
groups: [group]
)
end
let(:environment) { 'review/name' }
@ -99,8 +109,13 @@ RSpec.describe DeploymentPlatform do
context 'when parent_group has a cluster with default scope' do
let!(:parent_group_cluster) do
create(:cluster, :provided_by_user,
cluster_type: :group_type, environment_scope: '*', groups: [parent_group])
create(
:cluster,
:provided_by_user,
cluster_type: :group_type,
environment_scope: '*',
groups: [parent_group]
)
end
it_behaves_like 'matching environment scope'
@ -108,8 +123,13 @@ RSpec.describe DeploymentPlatform do
context 'when parent_group has a cluster that is an exact match' do
let!(:parent_group_cluster) do
create(:cluster, :provided_by_user,
cluster_type: :group_type, environment_scope: 'review/name', groups: [parent_group])
create(
:cluster,
:provided_by_user,
cluster_type: :group_type,
environment_scope: 'review/name',
groups: [parent_group]
)
end
it_behaves_like 'matching environment scope'
@ -160,8 +180,13 @@ RSpec.describe DeploymentPlatform do
let!(:cluster) { create(:cluster, :provided_by_user, environment_scope: 'review/*', projects: [project]) }
let!(:group_default_cluster) do
create(:cluster, :provided_by_user,
cluster_type: :group_type, groups: [group], environment_scope: '*')
create(
:cluster,
:provided_by_user,
cluster_type: :group_type,
groups: [group],
environment_scope: '*'
)
end
let(:environment) { 'review/name' }

View File

@ -150,8 +150,10 @@ RSpec.describe Issuable do
end
it 'gives preference to state_id if present' do
issuable = MergeRequest.new('state' => 'opened',
'state_id' => described_class::STATE_ID_MAP['merged'])
issuable = MergeRequest.new(
'state' => 'opened',
'state_id' => described_class::STATE_ID_MAP['merged']
)
expect(issuable.state).to eq('merged')
expect(issuable.state_id).to eq(described_class::STATE_ID_MAP['merged'])

View File

@ -130,10 +130,7 @@ RSpec.describe PersonalAccessToken, 'TokenAuthenticatable' do
let(:token_digest) { Gitlab::CryptoHelper.sha256(token_value) }
let(:user) { create(:user) }
let(:personal_access_token) do
described_class.new(name: 'test-pat-01',
user_id: user.id,
scopes: [:api],
token_digest: token_digest)
described_class.new(name: 'test-pat-01', user_id: user.id, scopes: [:api], token_digest: token_digest)
end
before do

View File

@ -0,0 +1,61 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Preloaders::UsersMaxAccessLevelByProjectPreloader, feature_category: :projects do
let_it_be(:user_1) { create(:user) }
let_it_be(:user_2) { create(:user) }
let_it_be(:user_with_no_access) { create(:user) } # ensures we correctly cache NO_ACCESS
let_it_be(:project_1) { create(:project) }
let_it_be(:project_2) { create(:project) }
let_it_be(:project_3) { create(:project) }
before do
project_1.add_developer(user_1)
project_1.add_developer(user_2)
project_2.add_developer(user_1)
project_2.add_developer(user_2)
project_3.add_developer(user_1)
project_3.add_developer(user_2)
end
describe '#execute', :request_store do
let(:project_users) do
{
project_1 => [user_1, user_with_no_access],
project_2 => user_2
}
end
it 'avoids N+1 queries' do
control_input = project_users
control = ActiveRecord::QueryRecorder.new do
described_class.new(project_users: control_input).execute
end
sample_input = control_input.merge(project_3 => user_2)
sample = ActiveRecord::QueryRecorder.new do
described_class.new(project_users: sample_input).execute
end
expect(sample).not_to exceed_query_limit(control)
end
it 'preloads the max access level used by project policies' do
described_class.new(project_users: project_users).execute
policy_queries = ActiveRecord::QueryRecorder.new do
project_users.each do |project, users|
Array.wrap(users).each do |user|
user.can?(:read_project, project)
end
end
end
expect(policy_queries).not_to exceed_query_limit(0)
end
end
end

View File

@ -1,51 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Preloaders::UsersMaxAccessLevelInProjectsPreloader do
let_it_be(:user1) { create(:user) }
let_it_be(:user2) { create(:user) }
let_it_be(:project_1) { create(:project) }
let_it_be(:project_2) { create(:project) }
let_it_be(:project_3) { create(:project) }
let(:projects) { [project_1, project_2, project_3] }
let(:users) { [user1, user2] }
before do
project_1.add_developer(user1)
project_1.add_developer(user2)
project_2.add_developer(user1)
project_2.add_developer(user2)
project_3.add_developer(user1)
project_3.add_developer(user2)
end
context 'preload maximum access level to avoid querying project_authorizations', :request_store do
it 'avoids N+1 queries', :request_store do
Preloaders::UsersMaxAccessLevelInProjectsPreloader.new(projects: projects, users: users).execute
expect(count_queries).to eq(0)
end
it 'runs N queries without preloading' do
query_count_without_preload = count_queries
Preloaders::UsersMaxAccessLevelInProjectsPreloader.new(projects: projects, users: users).execute
count_queries_with_preload = count_queries
expect(count_queries_with_preload).to be < query_count_without_preload
end
end
def count_queries
ActiveRecord::QueryRecorder.new do
projects.each do |project|
user1.can?(:read_project, project)
user2.can?(:read_project, project)
end
end.count
end
end

View File

@ -368,4 +368,179 @@ RSpec.describe WorkItem, feature_category: :portfolio_management do
end
end
end
describe '#allowed_work_item_type_change' do
let_it_be(:all_types) { WorkItems::Type::BASE_TYPES.keys }
it 'is possible to change between all types', :aggregate_failures do
all_types.each do |type|
work_item = build(:work_item, type, project: reusable_project)
(all_types - [type]).each do |new_type|
work_item.work_item_type_id = WorkItems::Type.default_by_type(new_type).id
expect(work_item).to be_valid, "#{type} to #{new_type}"
end
end
end
context 'with ParentLink relation' do
let_it_be(:old_type) { create(:work_item_type) }
let_it_be(:new_type) { create(:work_item_type) }
context 'with hierarchy restrictions' do
let_it_be(:child_type) { create(:work_item_type) }
let_it_be_with_reload(:parent) { create(:work_item, work_item_type: old_type, project: reusable_project) }
let_it_be_with_reload(:child) { create(:work_item, work_item_type: child_type, project: reusable_project) }
let_it_be(:hierarchy_restriction) do
create(:hierarchy_restriction, parent_type: old_type, child_type: child_type)
end
let_it_be(:link) { create(:parent_link, work_item_parent: parent, work_item: child) }
context 'when child items restrict the type change' do
before do
parent.work_item_type = new_type
end
context 'when child items are compatible with the new type' do
let_it_be(:hierarchy_restriction_new_type) do
create(:hierarchy_restriction, parent_type: new_type, child_type: child_type)
end
it 'allows to change types' do
expect(parent).to be_valid
expect(parent.errors).to be_empty
end
end
context 'when child items are not compatible with the new type' do
it 'does not allow to change types' do
expect(parent).not_to be_valid
expect(parent.errors[:work_item_type_id])
.to include("cannot be changed to #{new_type.name} with these child item types.")
end
end
end
context 'when the parent restricts the type change' do
before do
child.work_item_type = new_type
end
it 'does not allow to change types' do
expect(child.valid?).to eq(false)
expect(child.errors[:work_item_type_id])
.to include("cannot be changed to #{new_type.name} with #{parent.work_item_type.name} as parent type.")
end
end
end
context 'with hierarchy depth restriction' do
let_it_be_with_reload(:item1) { create(:work_item, work_item_type: new_type, project: reusable_project) }
let_it_be_with_reload(:item2) { create(:work_item, work_item_type: new_type, project: reusable_project) }
let_it_be_with_reload(:item3) { create(:work_item, work_item_type: new_type, project: reusable_project) }
let_it_be_with_reload(:item4) { create(:work_item, work_item_type: new_type, project: reusable_project) }
let_it_be(:hierarchy_restriction1) do
create(:hierarchy_restriction, parent_type: old_type, child_type: new_type)
end
let_it_be(:hierarchy_restriction2) do
create(:hierarchy_restriction, parent_type: new_type, child_type: old_type)
end
let_it_be_with_reload(:hierarchy_restriction3) do
create(:hierarchy_restriction, parent_type: new_type, child_type: new_type, maximum_depth: 4)
end
let_it_be(:link1) { create(:parent_link, work_item_parent: item1, work_item: item2) }
let_it_be(:link2) { create(:parent_link, work_item_parent: item2, work_item: item3) }
let_it_be(:link3) { create(:parent_link, work_item_parent: item3, work_item: item4) }
before do
hierarchy_restriction3.update!(maximum_depth: maximum_depth)
end
shared_examples 'validates the depth correctly' do
before do
work_item.update!(work_item_type: old_type)
end
context 'when it is valid' do
let(:maximum_depth) { 4 }
it 'allows to change types' do
work_item.work_item_type = new_type
expect(work_item).to be_valid
end
end
context 'when it is not valid' do
let(:maximum_depth) { 3 }
it 'does not allow to change types' do
work_item.work_item_type = new_type
expect(work_item).not_to be_valid
expect(work_item.errors[:work_item_type_id]).to include("reached maximum depth")
end
end
end
context 'with the highest ancestor' do
let_it_be_with_reload(:work_item) { item1 }
it_behaves_like 'validates the depth correctly'
end
context 'with a child item' do
let_it_be_with_reload(:work_item) { item2 }
it_behaves_like 'validates the depth correctly'
end
context 'with the last child item' do
let_it_be_with_reload(:work_item) { item4 }
it_behaves_like 'validates the depth correctly'
end
context 'when ancestor is still the old type' do
let_it_be(:hierarchy_restriction4) do
create(:hierarchy_restriction, parent_type: old_type, child_type: old_type)
end
before do
item1.update!(work_item_type: old_type)
item2.update!(work_item_type: old_type)
end
context 'when it exceeds maximum depth' do
let(:maximum_depth) { 2 }
it 'does not allow to change types' do
item2.work_item_type = new_type
expect(item2).not_to be_valid
expect(item2.errors[:work_item_type_id]).to include("reached maximum depth")
end
end
context 'when it does not exceed maximum depth' do
let(:maximum_depth) { 3 }
it 'does allow to change types' do
item2.work_item_type = new_type
expect(item2).to be_valid
end
end
end
end
end
end
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -70,7 +70,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
describe "GET /projects/:id/noteable/:noteable_id/notes" do
context "current user cannot view the notes" do
it "returns an empty array" do
it "returns an empty array", :aggregate_failures do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", user)
expect(response).to have_gitlab_http_status(:ok)
@ -93,7 +93,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
end
context "current user can view the note" do
it "returns a non-empty array" do
it "returns a non-empty array", :aggregate_failures do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", private_user)
expect(response).to have_gitlab_http_status(:ok)
@ -114,7 +114,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
let(:test_url) { "/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes" }
shared_examples 'a notes request' do
it 'is a note array response' do
it 'is a note array response', :aggregate_failures do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@ -164,7 +164,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
it_behaves_like 'a notes request'
it "properly filters the returned notables" do
it "properly filters the returned notables", :aggregate_failures do
expect(json_response.count).to eq(count)
expect(json_response.first["system"]).to be system_notable
end
@ -195,7 +195,7 @@ RSpec.describe API::Notes, feature_category: :team_planning do
end
context "current user can view the note" do
it "returns an issue note by id" do
it "returns an issue note by id", :aggregate_failures do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes/#{cross_reference_note.id}", private_user)
expect(response).to have_gitlab_http_status(:ok)

View File

@ -12,7 +12,7 @@ RSpec.describe API::PersonalAccessTokens::SelfInformation, feature_category: :sy
subject(:delete_token) { delete api(path, personal_access_token: token) }
shared_examples 'revoking token succeeds' do
it 'revokes token' do
it 'revokes token', :aggregate_failures do
delete_token
expect(response).to have_gitlab_http_status(:no_content)
@ -72,7 +72,7 @@ RSpec.describe API::PersonalAccessTokens::SelfInformation, feature_category: :sy
context "with a '#{scope}' scoped token" do
let(:token) { create(:personal_access_token, scopes: [scope], user: current_user) }
it 'shows token info' do
it 'shows token info', :aggregate_failures do
get api(path, personal_access_token: token)
expect(response).to have_gitlab_http_status(:ok)

View File

@ -15,7 +15,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
shared_examples 'response as expected' do |params|
subject { get api(path, personal_access_token: current_users_token), params: params }
it "status, count and result as expected" do
it "status, count and result as expected", :aggregate_failures do
subject
case status
@ -32,9 +32,9 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
context 'logged in as an Administrator' do
let_it_be(:current_user) { create(:admin) }
let_it_be(:current_users_token) { create(:personal_access_token, user: current_user) }
let_it_be(:current_users_token) { create(:personal_access_token, :admin_mode, user: current_user) }
it 'returns all PATs by default' do
it 'returns all PATs by default', :aggregate_failures do
get api(path, current_user)
expect(response).to have_gitlab_http_status(:ok)
@ -45,8 +45,8 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
let_it_be(:token) { create(:personal_access_token) }
let_it_be(:token_impersonated) { create(:personal_access_token, impersonation: true, user: token.user) }
it 'returns only PATs belonging to that user' do
get api(path, current_user), params: { user_id: token.user.id }
it 'returns only PATs belonging to that user', :aggregate_failures do
get api(path, current_user, admin_mode: true), params: { user_id: token.user.id }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.count).to eq(2)
@ -243,7 +243,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
let_it_be(:current_user) { create(:user) }
let_it_be(:current_users_token) { create(:personal_access_token, user: current_user) }
it 'returns all PATs belonging to the signed-in user' do
it 'returns all PATs belonging to the signed-in user', :aggregate_failures do
get api(path, personal_access_token: current_users_token)
expect(response).to have_gitlab_http_status(:ok)
@ -255,7 +255,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
context 'filtered with user_id parameter' do
let_it_be(:user) { create(:user) }
it 'returns PATs belonging to the specific user' do
it 'returns PATs belonging to the specific user', :aggregate_failures do
get api(path, current_user, personal_access_token: current_users_token), params: { user_id: current_user.id }
expect(response).to have_gitlab_http_status(:ok)
@ -393,14 +393,14 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
let_it_be(:admin_token) { create(:personal_access_token, user: admin_user) }
let_it_be(:admin_path) { "/personal_access_tokens/#{admin_token.id}" }
it 'returns admins own PAT by id' do
it 'returns admins own PAT by id', :aggregate_failures do
get api(admin_path, admin_user)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq(admin_token.id)
end
it 'returns a different users PAT by id' do
it 'returns a different users PAT by id', :aggregate_failures do
get api(user_token_path, admin_user)
expect(response).to have_gitlab_http_status(:ok)
@ -417,7 +417,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
context 'when current_user is not an administrator' do
let_it_be(:other_users_path) { "/personal_access_tokens/#{token1.id}" }
it 'returns users own PAT by id' do
it 'returns users own PAT by id', :aggregate_failures do
get api(user_token_path, current_user)
expect(response).to have_gitlab_http_status(:ok)
@ -458,7 +458,7 @@ RSpec.describe API::PersonalAccessTokens, feature_category: :system_access do
create(:personal_access_token, scopes: ['read_repository'], user: admin_user)
end
it 'revokes a different users token' do
it 'revokes a different users token', :aggregate_failures do
delete api(path, admin_user)
expect(response).to have_gitlab_http_status(:no_content)

View File

@ -50,7 +50,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
it 'returns releases ordered by released_at' do
it 'returns releases ordered by released_at', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.count).to eq(2)
@ -113,7 +113,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to match_response_schema('public_api/v4/releases')
end
it 'returns rendered helper paths' do
it 'returns rendered helper paths', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.first['commit_path']).to eq("/#{release_2.project.full_path}/-/commit/#{release_2.commit.id}")
@ -132,7 +132,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
end
it 'returns an upcoming_release status for a future release' do
it 'returns an upcoming_release status for a future release', :aggregate_failures do
tomorrow = Time.now.utc + 1.day
create(:release, project: project, tag: 'v0.1', author: maintainer, released_at: tomorrow)
@ -142,7 +142,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(json_response.first['upcoming_release']).to eq(true)
end
it 'returns an upcoming_release status for a past release' do
it 'returns an upcoming_release status for a past release', :aggregate_failures do
yesterday = Time.now.utc - 1.day
create(:release, project: project, tag: 'v0.1', author: maintainer, released_at: yesterday)
@ -152,7 +152,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(json_response.first['upcoming_release']).to eq(false)
end
it 'avoids N+1 queries', :use_sql_query_cache do
it 'avoids N+1 queries', :aggregate_failures, :use_sql_query_cache do
create(:release, :with_evidence, project: project, tag: 'v0.1', author: maintainer)
create(:release_link, release: project.releases.first)
@ -211,7 +211,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag does not exist in git repository' do
let!(:release) { create(:release, project: project, tag: 'v1.1.5') }
it 'returns the tag' do
it 'returns the tag', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(json_response.count).to eq(1)
@ -223,7 +223,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag contains a slash' do
let!(:release) { create(:release, project: project, tag: 'debian/2.4.0-1', description: "debian/2.4.0-1") }
it 'returns 200 HTTP status' do
it 'returns 200 HTTP status', :aggregate_failures do
get api("/projects/#{project.id}/releases", maintainer)
expect(response).to have_gitlab_http_status(:ok)
@ -246,7 +246,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
it "does not expose tag, commit, source code or helper paths" do
it "does not expose tag, commit, source code or helper paths", :aggregate_failures do
get api("/projects/#{project.id}/releases", guest)
expect(response).to match_response_schema('public_api/v4/release/releases_for_guest')
@ -264,7 +264,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
it "exposes tag, commit, source code and helper paths" do
it "exposes tag, commit, source code and helper paths", :aggregate_failures do
get api("/projects/#{project.id}/releases", guest)
expect(response).to match_response_schema('public_api/v4/releases')
@ -296,7 +296,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when releases are public and request user is absent' do
let(:project) { create(:project, :repository, :public) }
it 'returns the releases' do
it 'returns the releases', :aggregate_failures do
create(:release, project: project, tag: 'v0.1')
get api("/projects/#{project.id}/releases")
@ -333,7 +333,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:ok)
end
it 'returns a release entry' do
it 'returns a release entry', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(json_response['tag_name']).to eq(release.tag)
@ -351,7 +351,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to match_response_schema('public_api/v4/release')
end
it 'contains source information as assets' do
it 'contains source information as assets', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(json_response['assets']['sources'].map { |h| h['format'] })
@ -413,7 +413,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:url) { 'https://my-external-hosting.example.com/scrambled-url/app.zip' }
it 'contains link information as assets' do
it 'contains link information as assets', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1", maintainer)
expect(json_response['assets']['links'].count).to eq(1)
@ -480,14 +480,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when specified tag is not found in the project' do
it 'returns 404 for maintater' do
it 'returns 404 for maintater', :aggregate_failures do
get api("/projects/#{project.id}/releases/non_exist_tag", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not Found')
end
it 'returns project not found for no user' do
it 'returns project not found for no user', :aggregate_failures do
get api("/projects/#{project.id}/releases/non_exist_tag", nil)
expect(response).to have_gitlab_http_status(:not_found)
@ -538,7 +538,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(json_response['milestones'].first['title']).to eq(milestone.title)
end
it 'returns issue stats for milestone' do
it 'returns issue stats for milestone', :aggregate_failures do
create_list(:issue, 2, milestone: milestone, project: project)
create_list(:issue, 3, :closed, milestone: milestone, project: project)
@ -580,14 +580,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:url) { 'https://google.com/-/jobs/140463678/artifacts/download' }
context 'with an invalid release tag' do
it 'returns 404 for maintater' do
it 'returns 404 for maintater', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.2/downloads#{filepath}", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not Found')
end
it 'returns project not found for no user' do
it 'returns project not found for no user', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.2/downloads#{filepath}", nil)
expect(response).to have_gitlab_http_status(:not_found)
@ -648,14 +648,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when filepath does not exists' do
it 'returns 404 for maintater' do
it 'returns 404 for maintater', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1/downloads/bin/not_existing.exe", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 Not found')
end
it 'returns project not found for no user' do
it 'returns project not found for no user', :aggregate_failures do
get api("/projects/#{project.id}/releases/v0.1/downloads/bin/not_existing.exe", nil)
expect(response).to have_gitlab_http_status(:not_found)
@ -728,7 +728,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
released_at: 2.days.ago)
end
it 'redirects to the latest release tag' do
it 'redirects to the latest release tag', :aggregate_failures do
get api("/projects/#{project.id}/releases/permalink/latest", maintainer)
uri = URI(response.header["Location"])
@ -737,7 +737,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(uri.path).to eq("/api/v4/projects/#{project.id}/releases/#{release_b.tag}")
end
it 'redirects to the latest release tag when using JOB-TOKEN auth' do
it 'redirects to the latest release tag when using JOB-TOKEN auth', :aggregate_failures do
job = create(:ci_build, :running, project: project, user: maintainer)
get api("/projects/#{project.id}/releases/permalink/latest"), params: { job_token: job.token }
@ -748,7 +748,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(uri.path).to eq("/api/v4/projects/#{project.id}/releases/#{release_b.tag}")
end
context 'when there are query parameters present' do
context 'when there are query parameters present', :aggregate_failures do
it 'includes the query params on the redirection' do
get api("/projects/#{project.id}/releases/permalink/latest", maintainer), params: { include_html_description: true, other_param: "aaa" }
@ -763,7 +763,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
})
end
it 'discards the `order_by` query param' do
it 'discards the `order_by` query param', :aggregate_failures do
get api("/projects/#{project.id}/releases/permalink/latest", maintainer), params: { order_by: 'something', other_param: "aaa" }
uri = URI(response.header["Location"])
@ -781,7 +781,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when downloading a release asset' do
it 'redirects to the right endpoint keeping the suffix_path' do
it 'redirects to the right endpoint keeping the suffix_path', :aggregate_failures do
get api("/projects/#{project.id}/releases/permalink/latest/downloads/bin/example.exe", maintainer)
uri = URI(response.header["Location"])
@ -830,7 +830,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:created)
end
it 'creates a new release' do
it 'creates a new release', :aggregate_failures do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
@ -848,7 +848,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
end
it 'creates a new release without description' do
it 'creates a new release without description', :aggregate_failures do
params = {
name: 'New release without description',
tag_name: 'v0.1',
@ -926,7 +926,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
params[:direct_asset_path] = params.delete(:filepath)
end
it 'creates a new release successfully' do
it 'creates a new release successfully', :aggregate_failures do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
@ -1010,7 +1010,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(response).to have_gitlab_http_status(:created)
end
it 'creates an asset with specified parameters' do
it 'creates an asset with specified parameters', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(json_response['assets']['links'].count).to eq(1)
@ -1038,7 +1038,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
})
end
it 'creates two assets with specified parameters' do
it 'creates two assets with specified parameters', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(json_response['assets']['links'].count).to eq(2)
@ -1099,7 +1099,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
context 'when a valid token is provided' do
it 'creates the release for a running job' do
it 'creates the release for a running job', :aggregate_failures do
job.update!(status: :running, project: project)
post api("/projects/#{project.id}/releases"), params: params.merge(job_token: job.token)
@ -1139,7 +1139,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
.to eq(project.repository.commit('master').id)
end
it 'creates a new release' do
it 'creates a new release', :aggregate_failures do
expect do
post api("/projects/#{project.id}/releases", maintainer), params: params
end.to change { Release.count }.by(1)
@ -1155,7 +1155,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag name is HEAD' do
let(:tag_name) { 'HEAD' }
it 'returns a 400 error as failure on tag creation' do
it 'returns a 400 error as failure on tag creation', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:bad_request)
@ -1166,7 +1166,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'when tag name is empty' do
let(:tag_name) { '' }
it 'returns a 400 error as failure on tag creation' do
it 'returns a 400 error as failure on tag creation', :aggregate_failures do
post api("/projects/#{project.id}/releases", maintainer), params: params
expect(response).to have_gitlab_http_status(:bad_request)
@ -1216,7 +1216,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with a project milestone' do
shared_examples 'adds milestone' do
it 'adds the milestone' do
it 'adds the milestone', :aggregate_failures do
expect(response).to have_gitlab_http_status(:created)
expect(returned_milestones).to match_array(['v1.0'])
end
@ -1239,7 +1239,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:milestone2) { create(:milestone, project: project, title: 'm2') }
let(:milestone_params) { { milestones: [milestone.title, milestone2.title] } }
it 'adds all milestones' do
it 'adds all milestones', :aggregate_failures do
expect(response).to have_gitlab_http_status(:created)
expect(returned_milestones).to match_array(['v1.0', 'm2'])
end
@ -1248,7 +1248,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with an empty milestone' do
let(:milestone_params) { { milestones: [] } }
it 'removes all milestones' do
it 'removes all milestones', :aggregate_failures do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['milestones']).to be_nil
end
@ -1257,7 +1257,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with a non-existant milestone' do
let(:milestone_params) { { milestones: ['xyz'] } }
it 'returns a 400 error as milestone not found' do
it 'returns a 400 error as milestone not found', :aggregate_failures do
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq("Milestone(s) not found: xyz")
end
@ -1267,7 +1267,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let(:milestone) { create(:milestone, title: 'v1.0') }
let(:milestone_params) { { milestones: [milestone.title] } }
it 'returns a 400 error as milestone not found' do
it 'returns a 400 error as milestone not found', :aggregate_failures do
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq("Milestone(s) not found: v1.0")
end
@ -1311,7 +1311,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
expect(project.releases.last.description).to eq('Best release ever!')
end
it 'does not change other attributes' do
it 'does not change other attributes', :aggregate_failures do
put api("/projects/#{project.id}/releases/v0.1", maintainer), params: params
expect(project.releases.last.tag).to eq('v0.1')
@ -1427,7 +1427,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
end
shared_examples 'updates milestone' do
it 'updates the milestone' do
it 'updates the milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@ -1461,7 +1461,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'an empty milestone' do
let(:params) { { milestones: [] } }
it 'removes the milestone' do
it 'removes the milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@ -1472,7 +1472,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'without milestones parameter' do
let(:params) { { name: 'some new name' } }
it 'does not change the milestone' do
it 'does not change the milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@ -1485,7 +1485,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let!(:milestone2) { create(:milestone, project: project, title: 'milestone2') }
let(:params) { { milestones: [milestone.title, milestone2.title] } }
it 'adds the new milestone' do
it 'adds the new milestone', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@ -1498,7 +1498,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let!(:milestone3) { create(:milestone, project: project, title: 'milestone3') }
shared_examples 'update milestones' do
it 'replaces the milestones' do
it 'replaces the milestones', :aggregate_failures do
subject
expect(response).to have_gitlab_http_status(:ok)
@ -1665,8 +1665,8 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
let_it_be(:release2) { create(:release, project: project2) }
let_it_be(:release3) { create(:release, project: project3) }
context 'when authenticated as owner' do
it 'gets releases from all projects in the group' do
context 'when authenticated as owner', :enable_admin_mode do
it 'gets releases from all projects in the group', :aggregate_failures do
get api("/groups/#{group1.id}/releases", admin)
expect(response).to have_gitlab_http_status(:ok)
@ -1700,7 +1700,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
group1.add_guest(guest)
end
it "does not expose tag, commit, source code or helper paths" do
it "does not expose tag, commit, source code or helper paths", :aggregate_failures do
get api("/groups/#{group1.id}/releases", guest)
expect(response).to match_response_schema('public_api/v4/release/releases_for_guest')
@ -1715,9 +1715,14 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
context 'with subgroups' do
let(:group) { create(:group) }
it 'include_subgroups avoids N+1 queries' do
subject { get api("/groups/#{group.id}/releases", admin, admin_mode: true), params: query_params.merge({ include_subgroups: true }) }
it 'include_subgroups avoids N+1 queries', :aggregate_failures, :use_sql_query_cache do
subject
expect(response).to have_gitlab_http_status(:ok)
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
get api("/groups/#{group.id}/releases", admin), params: query_params.merge({ include_subgroups: true })
subject
end.count
subgroups = create_list(:group, 10, parent: group1)
@ -1725,7 +1730,7 @@ RSpec.describe API::Releases, feature_category: :release_orchestration do
create_list(:release, 10, project: projects[0], author: admin)
expect do
get api("/groups/#{group.id}/releases", admin), params: query_params.merge({ include_subgroups: true })
subject
end.not_to exceed_all_query_limit(control_count)
end
end

View File

@ -6,8 +6,8 @@ RSpec.describe API::SidekiqMetrics, feature_category: :shared do
let(:admin) { create(:user, :admin) }
describe 'GET sidekiq/*' do
it 'defines the `queue_metrics` endpoint' do
get api('/sidekiq/queue_metrics', admin)
it 'defines the `queue_metrics` endpoint', :aggregate_failures do
get api('/sidekiq/queue_metrics', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to match a_hash_including(
@ -24,15 +24,15 @@ RSpec.describe API::SidekiqMetrics, feature_category: :shared do
)
end
it 'defines the `process_metrics` endpoint' do
get api('/sidekiq/process_metrics', admin)
it 'defines the `process_metrics` endpoint', :aggregate_failures do
get api('/sidekiq/process_metrics', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['processes']).to be_an Array
end
it 'defines the `job_stats` endpoint' do
get api('/sidekiq/job_stats', admin)
it 'defines the `job_stats` endpoint', :aggregate_failures do
get api('/sidekiq/job_stats', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash
@ -42,8 +42,8 @@ RSpec.describe API::SidekiqMetrics, feature_category: :shared do
expect(json_response['jobs'].values).to all(be_an(Integer))
end
it 'defines the `compound_metrics` endpoint' do
get api('/sidekiq/compound_metrics', admin)
it 'defines the `compound_metrics` endpoint', :aggregate_failures do
get api('/sidekiq/compound_metrics', admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash

View File

@ -360,21 +360,13 @@ RSpec.configure do |config|
./spec/requests/api/broadcast_messages_spec.rb
./spec/requests/api/deploy_keys_spec.rb
./spec/requests/api/deploy_tokens_spec.rb
./spec/requests/api/groups_spec.rb
./spec/requests/api/keys_spec.rb
./spec/requests/api/merge_requests_spec.rb
./spec/requests/api/namespaces_spec.rb
./spec/requests/api/notes_spec.rb
./spec/requests/api/personal_access_tokens/self_information_spec.rb
./spec/requests/api/personal_access_tokens_spec.rb
./spec/requests/api/project_export_spec.rb
./spec/requests/api/project_repository_storage_moves_spec.rb
./spec/requests/api/project_snapshots_spec.rb
./spec/requests/api/project_snippets_spec.rb
./spec/requests/api/projects_spec.rb
./spec/requests/api/releases_spec.rb
./spec/requests/api/sidekiq_metrics_spec.rb
./spec/requests/api/snippet_repository_storage_moves_spec.rb
./spec/requests/api/snippets_spec.rb
./spec/requests/api/statistics_spec.rb
./spec/requests/api/system_hooks_spec.rb

View File

@ -8231,7 +8231,6 @@
- './spec/models/preloaders/merge_request_diff_preloader_spec.rb'
- './spec/models/preloaders/user_max_access_level_in_groups_preloader_spec.rb'
- './spec/models/preloaders/user_max_access_level_in_projects_preloader_spec.rb'
- './spec/models/preloaders/users_max_access_level_in_projects_preloader_spec.rb'
- './spec/models/product_analytics_event_spec.rb'
- './spec/models/programming_language_spec.rb'
- './spec/models/project_authorization_spec.rb'

View File

@ -17,8 +17,12 @@ RSpec.shared_examples 'a hook that gets automatically disabled on failure' do
[4, 1.second.from_now], # Exceeded the grace period, set by #backoff!
[4, Time.current] # Exceeded the grace period, set by #backoff!, edge-case
].map do |(recent_failures, disabled_until)|
create(hook_factory, **default_factory_arguments, recent_failures: recent_failures,
disabled_until: disabled_until)
create(
hook_factory,
**default_factory_arguments,
recent_failures: recent_failures,
disabled_until: disabled_until
)
end
end
@ -45,8 +49,12 @@ disabled_until: disabled_until)
[0, suspended],
[0, expired]
].map do |(recent_failures, disabled_until)|
create(hook_factory, **default_factory_arguments, recent_failures: recent_failures,
disabled_until: disabled_until)
create(
hook_factory,
**default_factory_arguments,
recent_failures: recent_failures,
disabled_until: disabled_until
)
end
end

View File

@ -112,9 +112,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the local value to be saved' do
subgroup_settings.send("#{settings_attribute_name}=", nil)
expect { subgroup_settings.save! }
.to raise_error(ActiveRecord::RecordInvalid,
/cannot be changed because it is locked by an ancestor/)
expect { subgroup_settings.save! }.to raise_error(
ActiveRecord::RecordInvalid,
/cannot be changed because it is locked by an ancestor/
)
end
end
@ -321,9 +322,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the attribute to be saved' do
subgroup_settings.send("lock_#{settings_attribute_name}=", true)
expect { subgroup_settings.save! }
.to raise_error(ActiveRecord::RecordInvalid,
/cannot be changed because it is locked by an ancestor/)
expect { subgroup_settings.save! }.to raise_error(
ActiveRecord::RecordInvalid,
/cannot be changed because it is locked by an ancestor/
)
end
end
@ -343,9 +345,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the lock to be saved when the attribute is nil' do
subgroup_settings.send("#{settings_attribute_name}=", nil)
expect { subgroup_settings.save! }
.to raise_error(ActiveRecord::RecordInvalid,
/cannot be nil when locking the attribute/)
expect { subgroup_settings.save! }.to raise_error(
ActiveRecord::RecordInvalid,
/cannot be nil when locking the attribute/
)
end
it 'copies the cascaded value when locking the attribute if the local value is nil', :aggregate_failures do
@ -364,9 +367,10 @@ RSpec.shared_examples 'a cascading namespace setting boolean attribute' do
it 'does not allow the attribute to be saved' do
subgroup_settings.send("lock_#{settings_attribute_name}=", true)
expect { subgroup_settings.save! }
.to raise_error(ActiveRecord::RecordInvalid,
/cannot be changed because it is locked by an ancestor/)
expect { subgroup_settings.save! }.to raise_error(
ActiveRecord::RecordInvalid,
/cannot be changed because it is locked by an ancestor/
)
end
end

View File

@ -465,10 +465,13 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when commit comment event executed' do
let(:commit_note) do
create(:note_on_commit, author: user,
project: project,
commit_id: project.repository.commit.id,
note: 'a comment on a commit')
create(
:note_on_commit,
author: user,
project: project,
commit_id: project.repository.commit.id,
note: 'a comment on a commit'
)
end
let(:data) do
@ -480,8 +483,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when merge request comment event executed' do
let(:merge_request_note) do
create(:note_on_merge_request, project: project,
note: 'a comment on a merge request')
create(:note_on_merge_request, project: project, note: 'a comment on a merge request')
end
let(:data) do
@ -493,8 +495,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when issue comment event executed' do
let(:issue_note) do
create(:note_on_issue, project: project,
note: 'a comment on an issue')
create(:note_on_issue, project: project, note: 'a comment on an issue')
end
let(:data) do
@ -506,8 +507,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'when snippet comment event executed' do
let(:snippet_note) do
create(:note_on_project_snippet, project: project,
note: 'a comment on a snippet')
create(:note_on_project_snippet, project: project, note: 'a comment on a snippet')
end
let(:data) do
@ -522,9 +522,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
let_it_be(:user) { create(:user) }
let_it_be_with_refind(:project) { create(:project, :repository, creator: user) }
let(:pipeline) do
create(:ci_pipeline,
project: project, status: status,
sha: project.commit.sha, ref: project.default_branch)
create(:ci_pipeline, project: project, status: status, sha: project.commit.sha, ref: project.default_branch)
end
before do
@ -557,9 +555,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'with failed pipeline' do
context 'on default branch' do
let(:pipeline) do
create(:ci_pipeline,
project: project, status: :failed,
sha: project.commit.sha, ref: project.default_branch)
create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: project.default_branch)
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
@ -587,9 +583,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
end
let(:pipeline) do
create(:ci_pipeline,
project: project, status: :failed,
sha: project.commit.sha, ref: 'a-protected-branch')
create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: 'a-protected-branch')
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
@ -617,9 +611,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
end
let(:pipeline) do
create(:ci_pipeline,
project: project, status: :failed,
sha: project.commit.sha, ref: '1-stable')
create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: '1-stable')
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }
@ -643,9 +635,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'on a neither protected nor default branch' do
let(:pipeline) do
create(:ci_pipeline,
project: project, status: :failed,
sha: project.commit.sha, ref: 'a-random-branch')
create(:ci_pipeline, project: project, status: :failed, sha: project.commit.sha, ref: 'a-random-branch')
end
let(:data) { Gitlab::DataBuilder::Pipeline.build(pipeline) }

View File

@ -84,9 +84,12 @@ RSpec.shared_examples 'a timebox' do |timebox_type|
let(:max_date) { mid_point + 10.days }
def box(from, to)
create(factory, *timebox_args,
start_date: from || open_on_left,
due_date: to || open_on_right)
create(
factory,
*timebox_args,
start_date: from || open_on_left,
due_date: to || open_on_right
)
end
it 'can find overlapping timeboxes' do

View File

@ -18,8 +18,12 @@ RSpec.shared_examples 'a hook that does not get automatically disabled on failur
[3, nil],
[3, 1.day.ago]
].map do |(recent_failures, disabled_until)|
create(hook_factory, **default_factory_arguments, recent_failures: recent_failures,
disabled_until: disabled_until)
create(
hook_factory,
**default_factory_arguments,
recent_failures: recent_failures,
disabled_until: disabled_until
)
end
end

155
yarn.lock
View File

@ -1048,116 +1048,6 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==
"@esbuild/android-arm64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.11.tgz#52c3e6cabc19c5e4c1c0c01cb58f0442338e1c14"
integrity sha512-QnK4d/zhVTuV4/pRM4HUjcsbl43POALU2zvBynmrrqZt9LPcLA3x1fTZPBg2RRguBQnJcnU059yKr+bydkntjg==
"@esbuild/android-arm@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.11.tgz#f3fc768235aecbeb840d0049fdf13cd28592105f"
integrity sha512-CdyX6sRVh1NzFCsf5vw3kULwlAhfy9wVt8SZlrhQ7eL2qBjGbFhRBWkkAzuZm9IIEOCKJw4DXA6R85g+qc8RDw==
"@esbuild/android-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.11.tgz#443ed47771a7e917e4282469ba350d117473550c"
integrity sha512-3PL3HKtsDIXGQcSCKtWD/dy+mgc4p2Tvo2qKgKHj9Yf+eniwFnuoQ0OUhlSfAEpKAFzF9N21Nwgnap6zy3L3MQ==
"@esbuild/darwin-arm64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.11.tgz#0e8c78d94d5759a48521dbfd83189d2ed3499a16"
integrity sha512-pJ950bNKgzhkGNO3Z9TeHzIFtEyC2GDQL3wxkMApDEghYx5Qers84UTNc1bAxWbRkuJOgmOha5V0WUeh8G+YGw==
"@esbuild/darwin-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.11.tgz#2405cfdf70eb961c7cf973463ca7263dc2004c88"
integrity sha512-iB0dQkIHXyczK3BZtzw1tqegf0F0Ab5texX2TvMQjiJIWXAfM4FQl7D909YfXWnB92OQz4ivBYQ2RlxBJrMJOw==
"@esbuild/freebsd-arm64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.11.tgz#d5138e873e15f87bd4564c024dfa00ef37e623fd"
integrity sha512-7EFzUADmI1jCHeDRGKgbnF5sDIceZsQGapoO6dmw7r/ZBEKX7CCDnIz8m9yEclzr7mFsd+DyasHzpjfJnmBB1Q==
"@esbuild/freebsd-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.11.tgz#e850b58b8fabf8e9ef0e125af3c25229ad2d6c38"
integrity sha512-iPgenptC8i8pdvkHQvXJFzc1eVMR7W2lBPrTE6GbhR54sLcF42mk3zBOjKPOodezzuAz/KSu8CPyFSjcBMkE9g==
"@esbuild/linux-arm64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.11.tgz#2bfb93d0809ec2357c12ebb27736b750c9ae0aa5"
integrity sha512-Qxth3gsWWGKz2/qG2d5DsW/57SeA2AmpSMhdg9TSB5Svn2KDob3qxfQSkdnWjSd42kqoxIPy3EJFs+6w1+6Qjg==
"@esbuild/linux-arm@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.11.tgz#e56fb3b76828317a704f4a167c5bd790fe5314e7"
integrity sha512-M9iK/d4lgZH0U5M1R2p2gqhPV/7JPJcRz+8O8GBKVgqndTzydQ7B2XGDbxtbvFkvIs53uXTobOhv+RyaqhUiMg==
"@esbuild/linux-ia32@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.11.tgz#59fa1c49b271793d14eb5effc757e8c0d0cb2cab"
integrity sha512-dB1nGaVWtUlb/rRDHmuDQhfqazWE0LMro/AIbT2lWM3CDMHJNpLckH+gCddQyhhcLac2OYw69ikUMO34JLt3wA==
"@esbuild/linux-loong64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.11.tgz#89575bc189099c03a36daa54f3f481780c7fd502"
integrity sha512-aCWlq70Q7Nc9WDnormntGS1ar6ZFvUpqr8gXtO+HRejRYPweAFQN615PcgaSJkZjhHp61+MNLhzyVALSF2/Q0g==
"@esbuild/linux-mips64el@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.11.tgz#0e18ca039dc7e4645efd8edc1b10952933eb6b1b"
integrity sha512-cGeGNdQxqY8qJwlYH1BP6rjIIiEcrM05H7k3tR7WxOLmD1ZxRMd6/QIOWMb8mD2s2YJFNRuNQ+wjMhgEL2oCEw==
"@esbuild/linux-ppc64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.11.tgz#2d152cb3a253afb8c100a165ad132dc96f36cb11"
integrity sha512-BdlziJQPW/bNe0E8eYsHB40mYOluS+jULPCjlWiHzDgr+ZBRXPtgMV1nkLEGdpjrwgmtkZHEGEPaKdS/8faLDA==
"@esbuild/linux-riscv64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.11.tgz#c6ac494a81221d53d65b33e665c7df1747952d3c"
integrity sha512-MDLwQbtF+83oJCI1Cixn68Et/ME6gelmhssPebC40RdJaect+IM+l7o/CuG0ZlDs6tZTEIoxUe53H3GmMn8oMA==
"@esbuild/linux-s390x@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.11.tgz#4bad33894bc7415cea4be8fa90fe456226a424ad"
integrity sha512-4N5EMESvws0Ozr2J94VoUD8HIRi7X0uvUv4c0wpTHZyZY9qpaaN7THjosdiW56irQ4qnJ6Lsc+i+5zGWnyqWqQ==
"@esbuild/linux-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.11.tgz#903fda743459f530a16a6c6ee8d2c0f6c1a12fc7"
integrity sha512-rM/v8UlluxpytFSmVdbCe1yyKQd/e+FmIJE2oPJvbBo+D0XVWi1y/NQ4iTNx+436WmDHQBjVLrbnAQLQ6U7wlw==
"@esbuild/netbsd-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.11.tgz#b589239fe7d9b16ee03c5e191f3f5b640f1518a1"
integrity sha512-4WaAhuz5f91h3/g43VBGdto1Q+X7VEZfpcWGtOFXnggEuLvjV+cP6DyLRU15IjiU9fKLLk41OoJfBFN5DhPvag==
"@esbuild/openbsd-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.11.tgz#b355019754116bef39ec688f8fd2fe6471b9779b"
integrity sha512-UBj135Nx4FpnvtE+C8TWGp98oUgBcmNmdYgl5ToKc0mBHxVVqVE7FUS5/ELMImOp205qDAittL6Ezhasc2Ev/w==
"@esbuild/sunos-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.11.tgz#2ea47fb592e68406e5025a7696dc714fc6a115dc"
integrity sha512-1/gxTifDC9aXbV2xOfCbOceh5AlIidUrPsMpivgzo8P8zUtczlq1ncFpeN1ZyQJ9lVs2hILy1PG5KPp+w8QPPg==
"@esbuild/win32-arm64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.11.tgz#47e6fdab17c4c52e6e0d606dd9cb843b29826325"
integrity sha512-vtSfyx5yRdpiOW9yp6Ax0zyNOv9HjOAw8WaZg3dF5djEHKKm3UnoohftVvIJtRh0Ec7Hso0RIdTqZvPXJ7FdvQ==
"@esbuild/win32-ia32@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.11.tgz#a97273aa3164c8d8f501899f55cc75a4a79599a3"
integrity sha512-GFPSLEGQr4wHFTiIUJQrnJKZhZjjq4Sphf+mM76nQR6WkQn73vm7IsacmBRPkALfpOCHsopSvLgqdd4iUW2mYw==
"@esbuild/win32-x64@0.17.11":
version "0.17.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.11.tgz#9be796d93ae27b636da32d960899a4912bca27a1"
integrity sha512-N9vXqLP3eRL8BqSy8yn4Y98cZI2pZ8fyuHx6lKjiG2WABpT2l01TXdzq5Ma2ZUBzfB7tx5dXVhge8X9u0S70ZQ==
"@eslint-community/eslint-utils@^4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz#a831e6e468b4b2b5ae42bf658bea015bf10bc518"
@ -5512,44 +5402,6 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
esbuild-loader@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/esbuild-loader/-/esbuild-loader-3.0.1.tgz#9871c0e8817c4c11b6249d1916832e75272e6c7e"
integrity sha512-aZfGybqTeuyCd4AsVvWOOfkhIuN+wfZFjMyh3gyQEU1Uvsl8L6vye9HqP93iRa0iTA+6Jclap514PJIC3cLnMA==
dependencies:
esbuild "^0.17.6"
get-tsconfig "^4.4.0"
loader-utils "^2.0.4"
webpack-sources "^1.4.3"
esbuild@0.17.11, esbuild@^0.17.6:
version "0.17.11"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.11.tgz#9f3122643b21d7e7731e42f18576c10bfa28152b"
integrity sha512-pAMImyokbWDtnA/ufPxjQg0fYo2DDuzAlqwnDvbXqHLphe+m80eF++perYKVm8LeTuj2zUuFXC+xgSVxyoHUdg==
optionalDependencies:
"@esbuild/android-arm" "0.17.11"
"@esbuild/android-arm64" "0.17.11"
"@esbuild/android-x64" "0.17.11"
"@esbuild/darwin-arm64" "0.17.11"
"@esbuild/darwin-x64" "0.17.11"
"@esbuild/freebsd-arm64" "0.17.11"
"@esbuild/freebsd-x64" "0.17.11"
"@esbuild/linux-arm" "0.17.11"
"@esbuild/linux-arm64" "0.17.11"
"@esbuild/linux-ia32" "0.17.11"
"@esbuild/linux-loong64" "0.17.11"
"@esbuild/linux-mips64el" "0.17.11"
"@esbuild/linux-ppc64" "0.17.11"
"@esbuild/linux-riscv64" "0.17.11"
"@esbuild/linux-s390x" "0.17.11"
"@esbuild/linux-x64" "0.17.11"
"@esbuild/netbsd-x64" "0.17.11"
"@esbuild/openbsd-x64" "0.17.11"
"@esbuild/sunos-x64" "0.17.11"
"@esbuild/win32-arm64" "0.17.11"
"@esbuild/win32-ia32" "0.17.11"
"@esbuild/win32-x64" "0.17.11"
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@ -6422,11 +6274,6 @@ get-symbol-description@^1.0.0:
call-bind "^1.0.2"
get-intrinsic "^1.1.1"
get-tsconfig@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.4.0.tgz#64eee64596668a81b8fce18403f94f245ee0d4e5"
integrity sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@ -8252,7 +8099,7 @@ loader-utils@^1.0.0, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2
emojis-list "^3.0.0"
json5 "^1.0.1"
loader-utils@^2.0.0, loader-utils@^2.0.4:
loader-utils@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==