Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b460d4a7c0
commit
7137270698
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
##
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
};
|
||||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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('|'),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
58d91bbad9896429a0b8d383a1d5ef47a7b017c65af7834c01091fbccb7f5221
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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') }
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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' }
|
||||
|
|
|
|||
|
|
@ -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'])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
155
yarn.lock
|
|
@ -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==
|
||||
|
|
|
|||
Loading…
Reference in New Issue