Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-06-11 18:09:50 +00:00
parent 5dffc9ad39
commit 8dbfb388b6
48 changed files with 566 additions and 668 deletions

View File

@ -83,6 +83,24 @@ compile-test-assets:
- "${WEBPACK_COMPILE_LOG_PATH}"
when: always
build-vite-prod:
extends:
- .production
- .default-retry
- .with-ci-node-image
- .frontend:rules:compile-production-assets
artifacts:
expire_in: 1h
paths:
- public/vite-dev/
stage: prepare
needs: []
script:
- source scripts/utils.sh
- yarn_install_script
- yarn vite-prod
allow_failure: true
gdk:compile-test-assets:
extends:
- compile-test-assets

View File

@ -376,6 +376,7 @@
- "{package.json,yarn.lock}"
- ".browserslistrc"
- "babel.config.js"
- "vite.config.js"
- "config/webpack.config.js"
- "config/**/*.js"
- "{,ee/,jh/}app/assets/**/*"
@ -388,6 +389,7 @@
- "{Gemfile.next,Gemfile.next.lock}"
- ".browserslistrc"
- "babel.config.js"
- "vite.config.js"
- "config/webpack.config.js"
- "*.js"
- "config/**/*.js"
@ -544,6 +546,7 @@
- "*_VERSION"
- "lib/gitlab/redis/*"
- "babel.config.js"
- "vite.config.js"
- "config.ru"
- "Dockerfile.assets"
- "jest.config.{base,integration,unit}.js"
@ -574,6 +577,7 @@
- "{package.json,yarn.lock}"
- "*_VERSION"
- "babel.config.js"
- "vite.config.js"
- "config.ru"
- "Dockerfile.assets"
- "jest.config.{base,integration,unit}.js"
@ -611,6 +615,7 @@
- "{package.json,yarn.lock}"
- "*_VERSION"
- "babel.config.js"
- "vite.config.js"
- "config.ru"
- "Dockerfile.assets"
- "jest.config.{base,integration,unit}.js"
@ -648,6 +653,7 @@
- "{package.json,yarn.lock}"
- "*_VERSION"
- "babel.config.js"
- "vite.config.js"
- "config.ru"
- "Dockerfile.assets"
- "jest.config.{base,integration,unit}.js"
@ -686,6 +692,7 @@
- "{package.json,yarn.lock}"
- ".browserslistrc"
- "babel.config.js"
- "vite.config.js"
- "jest.config.{base,integration,unit}.js"
- ".stylelintrc"
- "Dockerfile.assets"

View File

@ -65,7 +65,6 @@ Gitlab/RSpec/MisplacedEeSpecFile:
- 'ee/spec/graphql/types/gitlab_subscriptions/member_management/users_queued_for_role_promotion_type_spec.rb'
- 'ee/spec/graphql/types/issue_connection_type_spec.rb'
- 'ee/spec/graphql/types/issue_type_spec.rb'
- 'ee/spec/graphql/types/namespaces/user_level_permissions/group_namespace_user_level_permissions_type_spec.rb'
- 'ee/spec/graphql/types/permission_types/group_spec.rb'
- 'ee/spec/graphql/types/permission_types/namespaces/base_spec.rb'
- 'ee/spec/graphql/types/permission_types/project_spec.rb'

View File

@ -130,7 +130,7 @@ export default {
<template #title>
<gl-button
variant="link"
class="!gl-text-subtle"
class="!gl-text-subtle !gl-no-underline"
:aria-expanded="isExpanded.toString()"
:aria-controls="$options.ariaControlsId"
data-testid="toggle-button"

View File

@ -301,11 +301,6 @@
"MergeRequestReviewer",
"UserCore"
],
"UserLevelPermissions": [
"GroupNamespaceUserLevelPermissions",
"ProjectNamespaceUserLevelPermissions",
"UserNamespaceUserLevelPermissions"
],
"VulnerabilityDetail": [
"VulnerabilityDetailBase",
"VulnerabilityDetailBoolean",

View File

@ -7,7 +7,7 @@ const SPLIT_REGEX = /\s*[\r\n]+\s*/;
* @param {string} - str
* @returns {string}
*/
module.exports = function ensureSingleLine(str) {
export function ensureSingleLine(str) {
// This guard makes the function significantly faster
if (str.includes('\n') || str.includes('\r')) {
return str
@ -16,4 +16,4 @@ module.exports = function ensureSingleLine(str) {
.join(' ');
}
return str;
};
}

View File

@ -1,5 +1,5 @@
import Jed from 'jed';
import ensureSingleLine from './ensure_single_line.cjs';
import { ensureSingleLine } from './ensure_single_line';
import sprintf from './sprintf';
const GITLAB_FALLBACK_LANGUAGE = 'en';

View File

@ -10,7 +10,11 @@
.expandable-card {
&.is-collapsed header {
border-bottom: 0;
border-radius: $gl-border-radius-base;
border-radius: $gl-border-radius-lg;
&:hover {
background-color: $gl-background-color-subtle;
}
}
.crud-body {

View File

@ -21,8 +21,8 @@ module Repositories
return render_lfs_not_found unless lfs_object&.file&.exists?
if Feature.enabled?(:validate_lfs_object_access, project) && !lfs_object.project_allowed_access?(project)
return render_lfs_not_found
if Feature.enabled?(:validate_lfs_object_access, project)
return render_lfs_not_found unless lfs_object.project_allowed_access?(project) # rubocop:disable Style/SoleNestedConditional -- Using unless for clearer logic when removing feature flag
end
send_upload(lfs_object.file, send_params: { content_type: "application/octet-stream" })

View File

@ -21,8 +21,7 @@ module Issues
# Since the CTE is used in access_to_parent_exists only if @related_groups is not null, we can skip the CTE if
# it's null
if Feature.enabled?(:use_cte_optimization_for_confidentiality_filter,
parent&.root_ancestor) && !@related_groups.nil?
unless @related_groups.nil?
issues = issues.with_accessible_sub_namespace_ids_cte(Group.groups_user_can(@related_groups,
current_user,
:read_confidential_issues,
@ -60,19 +59,9 @@ module Issues
return access_to_project_level_issue_exists if @related_groups.nil?
if Feature.enabled?(:use_cte_optimization_for_confidentiality_filter, parent&.root_ancestor)
access_to_project_level_issue_exists.project_level.or(
issues.group_level.in_namespaces(Group.in_accessible_sub_namespaces)
)
else
access_to_project_level_issue_exists.project_level.or(
issues.group_level.in_namespaces(
Group.id_in(
Group.groups_user_can(@related_groups, current_user, :read_confidential_issues, same_root: true)
)
)
)
end
access_to_project_level_issue_exists.project_level.or(
issues.group_level.in_namespaces(Group.in_accessible_sub_namespaces)
)
end
end
end

View File

@ -145,13 +145,6 @@ module Types
method: :itself,
experiment: { milestone: '18.1' }
field :user_level_permissions,
Types::Namespaces::UserLevelPermissions,
null: true,
description: 'User permissions on the namespace.',
method: :itself,
experiment: { milestone: '18.1' }
field :markdown_paths,
Types::Namespaces::MarkdownPaths,
null: true,

View File

@ -1,44 +0,0 @@
# frozen_string_literal: true
module Types
module Namespaces
module UserLevelPermissions
include ::Types::BaseInterface
include ::IssuablesHelper
graphql_name 'UserLevelPermissions'
# rubocop:disable Layout/LineLength -- Expected file length
TYPE_MAPPINGS = {
::Group => ::Types::Namespaces::UserLevelPermissions::GroupNamespaceUserLevelPermissionsType,
::Namespaces::ProjectNamespace => ::Types::Namespaces::UserLevelPermissions::ProjectNamespaceUserLevelPermissionsType,
::Namespaces::UserNamespace => ::Types::Namespaces::UserLevelPermissions::UserNamespaceUserLevelPermissionsType
}.freeze
# rubocop:enable Layout/LineLength
field :can_admin_label,
GraphQL::Types::Boolean,
null: true,
description: 'Whether the current user can admin labels in the namespace.',
fallback_value: false
field :can_create_projects,
GraphQL::Types::Boolean,
null: true,
description: 'Whether the current user can create projects in the namespace.',
fallback_value: false
def self.type_mappings
TYPE_MAPPINGS
end
def self.resolve_type(object, _context)
type_mappings[object.class] || raise("Unknown GraphQL type for namespace type #{object.class}")
end
orphan_types(*type_mappings.values)
end
end
end
::Types::Namespaces::UserLevelPermissions.prepend_mod

View File

@ -1,24 +0,0 @@
# frozen_string_literal: true
module Types
module Namespaces
module UserLevelPermissions
class GroupNamespaceUserLevelPermissionsType < BaseObject # rubocop:disable Graphql/AuthorizeTypes -- parent is already authorized
graphql_name 'GroupNamespaceUserLevelPermissions'
implements ::Types::Namespaces::UserLevelPermissions
alias_method :group, :object
def can_admin_label
can?(current_user, :admin_label, group)
end
def can_create_projects
can?(current_user, :create_projects, group)
end
end
end
end
end
::Types::Namespaces::UserLevelPermissions::GroupNamespaceUserLevelPermissionsType.prepend_mod

View File

@ -1,20 +0,0 @@
# frozen_string_literal: true
module Types
module Namespaces
module UserLevelPermissions
class ProjectNamespaceUserLevelPermissionsType < BaseObject # rubocop:disable Graphql/AuthorizeTypes -- parent is already authorized
graphql_name 'ProjectNamespaceUserLevelPermissions'
implements ::Types::Namespaces::UserLevelPermissions
alias_method :project, :object
def can_admin_label
can?(current_user, :admin_label, project)
end
end
end
end
end
::Types::Namespaces::UserLevelPermissions::ProjectNamespaceUserLevelPermissionsType.prepend_mod

View File

@ -1,14 +0,0 @@
# frozen_string_literal: true
module Types
module Namespaces
module UserLevelPermissions
class UserNamespaceUserLevelPermissionsType < BaseObject # rubocop:disable Graphql/AuthorizeTypes -- parent is already authorized
graphql_name 'UserNamespaceUserLevelPermissions'
implements ::Types::Namespaces::UserLevelPermissions
end
end
end
end
::Types::Namespaces::UserLevelPermissions::UserNamespaceUserLevelPermissionsType.prepend_mod

View File

@ -7,7 +7,7 @@ module Types
graphql_name 'NamespacePermissions'
abilities :admin_label, :admin_issue, :create_work_item,
:import_issues, :read_crm_contact, :read_crm_organization
:import_issues, :read_crm_contact, :read_crm_organization, :create_projects
ability_field :read_namespace
end

View File

@ -40,9 +40,5 @@ module Types
value 'UPDATED_ASC', 'Updated at ascending order.', value: :updated_asc
value 'CREATED_DESC', 'Created at descending order.', value: :created_desc
value 'CREATED_ASC', 'Created at ascending order.', value: :created_asc
def self.enum_values(context = {})
super.sort { |a, b| a.value.to_s <=> b.value.to_s }
end
end
end

View File

@ -1,9 +0,0 @@
---
name: summarize_merge_request_claude_3_7_sonnet
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/521400
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/182958
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/521699
milestone: '17.10'
group: group::code review
type: beta
default_enabled: true

View File

@ -1,10 +0,0 @@
---
name: use_cte_optimization_for_confidentiality_filter
description: Use a CTE to optimize confidentiality checks on Epic WorkItems List
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/548094
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/193857
rollout_issue_url:
milestone: '18.1'
group: group::product planning
type: gitlab_com_derisk
default_enabled: false

View File

@ -5,4 +5,4 @@ feature_category: importers
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180432
milestone: '17.9'
queued_migration_version: 20250205194215
finalized_by: # version of the migration that finalized this BBM
finalized_by: '20250610152411'

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
class AddAllowBypassPlaceholderConfirmationForEnterpriseToNamespaceSettings < Gitlab::Database::Migration[2.3]
milestone '18.1'
def change
add_column :namespace_settings, :allow_enterprise_bypass_placeholder_confirmation, :boolean,
default: false, null: false
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class ChangeIdxCiBuildReportResultsOnBuildIdPartitionId < Gitlab::Database::Migration[2.3]
milestone '18.1'
disable_ddl_transaction!
TABLE_NAME = :ci_build_report_results
OLD_INDEX_NAME = :index_ci_build_report_results_on_partition_id_build_id
OLD_COLUMNS = [:partition_id, :build_id]
NEW_INDEX_NAME = :index_ci_build_report_results_on_build_id_partition_id
NEW_COLUMNS = [:build_id, :partition_id]
def up
add_concurrent_index(TABLE_NAME, NEW_COLUMNS, unique: true, name: NEW_INDEX_NAME)
remove_concurrent_index_by_name(TABLE_NAME, OLD_INDEX_NAME)
end
def down
add_concurrent_index(TABLE_NAME, OLD_COLUMNS, unique: true, name: OLD_INDEX_NAME)
remove_concurrent_index_by_name(TABLE_NAME, NEW_INDEX_NAME)
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
class SwapPrimaryKeyForCiBuildReportResultsToIncludePartitionId < Gitlab::Database::Migration[2.3]
milestone '18.1'
disable_ddl_transaction!
TABLE_NAME = :ci_build_report_results
PRIMARY_KEY_NAME = :ci_build_report_results_pkey
OLD_INDEX_NAME = :index_ci_build_report_results_on_build_id
OLD_COLUMN = :build_id
NEW_INDEX_NAME = :index_ci_build_report_results_on_build_id_partition_id
NEW_COLUMNS = [:build_id, :partition_id]
def up
swap_primary_key(TABLE_NAME, PRIMARY_KEY_NAME, NEW_INDEX_NAME)
end
def down
add_concurrent_index(TABLE_NAME, OLD_COLUMN, unique: true, name: OLD_INDEX_NAME)
add_concurrent_index(TABLE_NAME, NEW_COLUMNS, unique: true, name: NEW_INDEX_NAME)
unswap_primary_key(TABLE_NAME, PRIMARY_KEY_NAME, OLD_INDEX_NAME)
end
end

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class FinalizeBackfillBulkImportExportBatchesProjectId < Gitlab::Database::Migration[2.3]
milestone '18.1'
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
def up
ensure_batched_background_migration_is_finished(
job_class_name: 'BackfillBulkImportExportBatchesProjectId',
table_name: :bulk_import_export_batches,
column_name: :id,
job_arguments: [:project_id, :bulk_import_exports, :project_id, :export_id],
finalize: true
)
end
def down; end
end

View File

@ -0,0 +1 @@
2244181d0870519e816e9f8735a44976b3740cc8a7d1a97f709b63d2acef0d7b

View File

@ -0,0 +1 @@
55a55ae9ebae8e196dcc7891ed79775ea84c2442cf6decba075e3c5d820dbb0f

View File

@ -0,0 +1 @@
9db1565e4a4fa99459fa40c0c52197ee1baa1c752758fe2a86b8b6eb8abc19d0

View File

@ -0,0 +1 @@
56d754cade87677af68273b3de4d1965f87d2cdc3fd8119942b130b1e040431f

View File

@ -18102,6 +18102,7 @@ CREATE TABLE namespace_settings (
disable_invite_members boolean DEFAULT false NOT NULL,
web_based_commit_signing_enabled boolean,
lock_web_based_commit_signing_enabled boolean DEFAULT false NOT NULL,
allow_enterprise_bypass_placeholder_confirmation boolean DEFAULT false NOT NULL,
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255)),
CONSTRAINT check_namespace_settings_security_policies_is_hash CHECK ((jsonb_typeof(security_policies) = 'object'::text)),
CONSTRAINT namespace_settings_unique_project_download_limit_alertlist_size CHECK ((cardinality(unique_project_download_limit_alertlist) <= 100)),
@ -29418,7 +29419,7 @@ ALTER TABLE ONLY ci_build_pending_states
ADD CONSTRAINT ci_build_pending_states_pkey PRIMARY KEY (id);
ALTER TABLE ONLY ci_build_report_results
ADD CONSTRAINT ci_build_report_results_pkey PRIMARY KEY (build_id);
ADD CONSTRAINT ci_build_report_results_pkey PRIMARY KEY (build_id, partition_id);
ALTER TABLE ONLY ci_build_trace_chunks
ADD CONSTRAINT ci_build_trace_chunks_pkey PRIMARY KEY (id);
@ -34462,8 +34463,6 @@ CREATE UNIQUE INDEX index_ci_build_pending_states_on_build_id ON ci_build_pendin
CREATE INDEX index_ci_build_pending_states_on_project_id ON ci_build_pending_states USING btree (project_id);
CREATE UNIQUE INDEX index_ci_build_report_results_on_partition_id_build_id ON ci_build_report_results USING btree (partition_id, build_id);
CREATE INDEX index_ci_build_report_results_on_project_id ON ci_build_report_results USING btree (project_id);
CREATE UNIQUE INDEX index_ci_build_trace_chunks_on_build_id_and_chunk_index ON ci_build_trace_chunks USING btree (build_id, chunk_index);

View File

@ -13,7 +13,15 @@ title: GitLab Dedicated maintenance and release schedule
{{< /details >}}
GitLab performs regular maintenance to your GitLab Dedicated instance. This page outlines the maintenance windows and release upgrade schedule.
Regular maintenance is performed on GitLab Dedicated instances according to scheduled maintenance windows and release upgrade timelines.
During scheduled maintenance windows, the following tasks might be performed:
- Application and operating system software patches and upgrades.
- Operating system restarts.
- Infrastructure upgrades.
- Activities needed to operate and enhance the availability or security of your tenant.
- Feature enhancements.
## Maintenance windows
@ -26,7 +34,8 @@ Maintenance is performed outside standard working hours:
| Americas (Option 1) | Tuesday | 07:00 - 11:00 |
| Americas (Option 2) | Sunday-Monday | 21:00 - 01:00 |
View your maintenance window in [Switchboard](tenant_overview.md#maintenance-windows), including upcoming and recent maintenance. You can postpone scheduled maintenance to another window in the same week by contacting your Customer Success Manager at least one week in advance.
View your maintenance window in [Switchboard](tenant_overview.md#maintenance-windows), including upcoming and recent maintenance.
You can postpone scheduled maintenance to another window in the same week by contacting your Customer Success Manager at least one week in advance.
{{< alert type="note" >}}
@ -64,7 +73,7 @@ For example, GitLab 16.9 released on 2024-02-15. Instances in the EMEA and Ameri
{{< alert type="note" >}}
If a production change lock (PCL) is active during a scheduled upgrade, GitLab defers the upgrade to the first maintenance window after the PCL ends.
If a production change lock (PCL) is active during a scheduled upgrade, GitLab defers the upgrade to the first maintenance window after the PCL ends.
A PCL for GitLab Dedicated is a complete pause on all production changes during periods of reduced team availability such as major holidays. During a PCL, the following is paused:

View File

@ -28244,7 +28244,6 @@ GPG signature for a signed commit.
| <a id="grouptotalrepositorysizeexcess"></a>`totalRepositorySizeExcess` | [`Float`](#float) | Total excess repository size of all projects in the root namespace in bytes. This only applies to namespaces under Project limit enforcement. |
| <a id="grouptwofactorgraceperiod"></a>`twoFactorGracePeriod` | [`Int`](#int) | Time before two-factor authentication is enforced. |
| <a id="groupupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp of when the group was last updated. |
| <a id="groupuserlevelpermissions"></a>`userLevelPermissions` {{< icon name="warning-solid" >}} | [`UserLevelPermissions`](#userlevelpermissions) | **Introduced** in GitLab 18.1. **Status**: Experiment. User permissions on the namespace. |
| <a id="groupuserpermissions"></a>`userPermissions` | [`GroupPermissions!`](#grouppermissions) | Permissions for the current user on the resource. |
| <a id="groupvaluestreamanalytics"></a>`valueStreamAnalytics` | [`ValueStreamAnalytics`](#valuestreamanalytics) | Information about Value Stream Analytics within the group. |
| <a id="groupvisibility"></a>`visibility` | [`String`](#string) | Visibility of the namespace. |
@ -30230,17 +30229,6 @@ Returns [`String`](#string).
| ---- | ---- | ----------- |
| <a id="groupnamespacemarkdownpathsmarkdownpreviewpathiid"></a>`iid` | [`String`](#string) | IID of the target item for markdown preview. |
### `GroupNamespaceUserLevelPermissions`
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="groupnamespaceuserlevelpermissionscanadminlabel"></a>`canAdminLabel` | [`Boolean`](#boolean) | Whether the current user can admin labels in the namespace. |
| <a id="groupnamespaceuserlevelpermissionscanbulkeditepics"></a>`canBulkEditEpics` | [`Boolean`](#boolean) | Whether the current user can bulk edit epics in the group. |
| <a id="groupnamespaceuserlevelpermissionscancreateepic"></a>`canCreateEpic` | [`Boolean`](#boolean) | Whether the current user can create epics in the group. |
| <a id="groupnamespaceuserlevelpermissionscancreateprojects"></a>`canCreateProjects` | [`Boolean`](#boolean) | Whether the current user can create projects in the namespace. |
### `GroupPermissions`
#### Fields
@ -33845,7 +33833,6 @@ Product analytics events for a specific month and year.
| <a id="namespacetimelogcategories"></a>`timelogCategories` {{< icon name="warning-solid" >}} | [`TimeTrackingTimelogCategoryConnection`](#timetrackingtimelogcategoryconnection) | **Introduced** in GitLab 15.3. **Status**: Experiment. Timelog categories for the namespace. |
| <a id="namespacetotalrepositorysize"></a>`totalRepositorySize` | [`Float`](#float) | Total repository size of all projects in the root namespace in bytes. |
| <a id="namespacetotalrepositorysizeexcess"></a>`totalRepositorySizeExcess` | [`Float`](#float) | Total excess repository size of all projects in the root namespace in bytes. This only applies to namespaces under Project limit enforcement. |
| <a id="namespaceuserlevelpermissions"></a>`userLevelPermissions` {{< icon name="warning-solid" >}} | [`UserLevelPermissions`](#userlevelpermissions) | **Introduced** in GitLab 18.1. **Status**: Experiment. User permissions on the namespace. |
| <a id="namespaceuserpermissions"></a>`userPermissions` | [`NamespacePermissions!`](#namespacepermissions) | Permissions for the current user on the resource. |
| <a id="namespacevisibility"></a>`visibility` | [`String`](#string) | Visibility of the namespace. |
| <a id="namespaceweburl"></a>`webUrl` | [`String`](#string) | URL of the object. |
@ -34383,6 +34370,9 @@ Represents a namespace-cluster-agent mapping.
| ---- | ---- | ----------- |
| <a id="namespacepermissionsadminissue"></a>`adminIssue` | [`Boolean!`](#boolean) | If `true`, the user can perform `admin_issue` on this resource. |
| <a id="namespacepermissionsadminlabel"></a>`adminLabel` | [`Boolean!`](#boolean) | If `true`, the user can perform `admin_label` on this resource. |
| <a id="namespacepermissionsbulkadminepic"></a>`bulkAdminEpic` | [`Boolean!`](#boolean) | If `true`, the user can perform `bulk_admin_epic` on this resource. |
| <a id="namespacepermissionscreateepic"></a>`createEpic` | [`Boolean!`](#boolean) | If `true`, the user can perform `create_epic` on this resource. |
| <a id="namespacepermissionscreateprojects"></a>`createProjects` | [`Boolean!`](#boolean) | If `true`, the user can perform `create_projects` on this resource. |
| <a id="namespacepermissionscreateworkitem"></a>`createWorkItem` | [`Boolean!`](#boolean) | If `true`, the user can perform `create_work_item` on this resource. |
| <a id="namespacepermissionsgeneratedescription"></a>`generateDescription` | [`Boolean!`](#boolean) | If `true`, the user can perform `generate_description` on this resource. |
| <a id="namespacepermissionsimportissues"></a>`importIssues` | [`Boolean!`](#boolean) | If `true`, the user can perform `import_issues` on this resource. |
@ -38457,17 +38447,6 @@ Returns [`String`](#string).
| ---- | ---- | ----------- |
| <a id="projectnamespacemarkdownpathsmarkdownpreviewpathiid"></a>`iid` | [`String`](#string) | IID of the target item for markdown preview. |
### `ProjectNamespaceUserLevelPermissions`
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectnamespaceuserlevelpermissionscanadminlabel"></a>`canAdminLabel` | [`Boolean`](#boolean) | Whether the current user can admin labels in the namespace. |
| <a id="projectnamespaceuserlevelpermissionscanbulkeditepics"></a>`canBulkEditEpics` | [`Boolean`](#boolean) | Whether the current user can bulk edit epics in the group. |
| <a id="projectnamespaceuserlevelpermissionscancreateepic"></a>`canCreateEpic` | [`Boolean`](#boolean) | Whether the current user can create epics in the group. |
| <a id="projectnamespaceuserlevelpermissionscancreateprojects"></a>`canCreateProjects` | [`Boolean`](#boolean) | Whether the current user can create projects in the namespace. |
### `ProjectPermissions`
#### Fields
@ -41330,17 +41309,6 @@ Returns [`String`](#string).
| ---- | ---- | ----------- |
| <a id="usernamespacemarkdownpathsmarkdownpreviewpathiid"></a>`iid` | [`String`](#string) | IID of the target item for markdown preview. |
### `UserNamespaceUserLevelPermissions`
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="usernamespaceuserlevelpermissionscanadminlabel"></a>`canAdminLabel` | [`Boolean`](#boolean) | Whether the current user can admin labels in the namespace. |
| <a id="usernamespaceuserlevelpermissionscanbulkeditepics"></a>`canBulkEditEpics` | [`Boolean`](#boolean) | Whether the current user can bulk edit epics in the group. |
| <a id="usernamespaceuserlevelpermissionscancreateepic"></a>`canCreateEpic` | [`Boolean`](#boolean) | Whether the current user can create epics in the group. |
| <a id="usernamespaceuserlevelpermissionscancreateprojects"></a>`canCreateProjects` | [`Boolean`](#boolean) | Whether the current user can create projects in the namespace. |
### `UserPermissions`
#### Fields
@ -50266,23 +50234,6 @@ four standard [pagination arguments](#pagination-arguments):
| ---- | ---- | ----------- |
| <a id="useruserachievementsincludehidden"></a>`includeHidden` | [`Boolean`](#boolean) | Indicates whether or not achievements hidden from the profile should be included in the result. |
#### `UserLevelPermissions`
Implementations:
- [`GroupNamespaceUserLevelPermissions`](#groupnamespaceuserlevelpermissions)
- [`ProjectNamespaceUserLevelPermissions`](#projectnamespaceuserlevelpermissions)
- [`UserNamespaceUserLevelPermissions`](#usernamespaceuserlevelpermissions)
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="userlevelpermissionscanadminlabel"></a>`canAdminLabel` | [`Boolean`](#boolean) | Whether the current user can admin labels in the namespace. |
| <a id="userlevelpermissionscanbulkeditepics"></a>`canBulkEditEpics` | [`Boolean`](#boolean) | Whether the current user can bulk edit epics in the group. |
| <a id="userlevelpermissionscancreateepic"></a>`canCreateEpic` | [`Boolean`](#boolean) | Whether the current user can create epics in the group. |
| <a id="userlevelpermissionscancreateprojects"></a>`canCreateProjects` | [`Boolean`](#boolean) | Whether the current user can create projects in the namespace. |
#### `VulnerabilityStatisticInterface`
Implementations:

View File

@ -2118,3 +2118,336 @@ Example response:
}
]
```
### Credentials inventory management
{{< details >}}
- Tier: Premium, Ultimate
- Offering: GitLab.com
{{< /details >}}
{{< history >}}
- [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/16343) in GitLab 18.1 [with a flag](../administration/feature_flags.md) named `manage_pat_by_group_owners_ready`. Disabled by default.
{{< /history >}}
The Credentials Inventory API allows top-level-group owners to view, revoke, and rotate the credentials of their enterprise users on GitLab.com.
Prerequisites:
- You must have the Owner role for the group.
#### List all personal access tokens for a group
Lists all personal access tokens associated with enterprise users in a top-level-group.
```plaintext
GET /groups/:id/manage/personal_access_tokens
```
| Attribute | Type | Required | Description |
| ------------------ | ------------------- | -------- | ----------- |
| `id` | integer or string | Yes | The ID or [URL-encoded path](rest/_index.md#namespaced-paths) of a group. |
| `created_after` | datetime (ISO 8601) | No | If defined, returns tokens created after the specified time. |
| `created_before` | datetime (ISO 8601) | No | If defined, returns tokens created before the specified time. |
| `last_used_after` | datetime (ISO 8601) | No | If defined, returns tokens last used after the specified time. |
| `last_used_before` | datetime (ISO 8601) | No | If defined, returns tokens last used before the specified time. |
| `revoked` | boolean | No | If `true`, only returns revoked tokens. |
| `search` | string | No | If defined, returns tokens that include the specified value in the name. |
| `state` | string | No | If defined, returns tokens with the specified state. Possible values: `active` and `inactive`. |
| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `expires_asc`, `expires_desc`, `last_used_asc`, `last_used_desc`, `name_asc`, `name_desc`. |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <group_owner_token>" "https://gitlab.example.com/api/v4/groups/1/manage/personal_access_tokens"
```
Example response:
```json
[
{
"id": 1,
"name": "Test Token",
"revoked": false,
"created_at": "2020-07-23T14:31:47.729Z",
"description": "Test Token description",
"scopes": [
"api"
],
"user_id": 3,
"last_used_at": "2021-10-06T17:58:37.550Z",
"active": true,
"expires_at": 2025-11-08
}
]
```
#### List all group and project access tokens for a group
Lists all group and project access tokens associated with a top-level-group.
```plaintext
GET /groups/:id/manage/resource_access_tokens
```
| Attribute | Type | Required | Description |
| ------------------ | ------------------- | -------- | ----------- |
| `id` | integer or string | Yes | The ID or [URL-encoded path](rest/_index.md#namespaced-paths) of a group. |
| `created_after` | datetime (ISO 8601) | No | If defined, returns tokens created after the specified time. |
| `created_before` | datetime (ISO 8601) | No | If defined, returns tokens created before the specified time. |
| `last_used_after` | datetime (ISO 8601) | No | If defined, returns tokens last used after the specified time. |
| `last_used_before` | datetime (ISO 8601) | No | If defined, returns tokens last used before the specified time. |
| `revoked` | boolean | No | If `true`, only returns revoked tokens. |
| `search` | string | No | If defined, returns tokens that include the specified value in the name. |
| `state` | string | No | If defined, returns tokens with the specified state. Possible values: `active` and `inactive`. |
| `sort` | string | No | If defined, sorts the results by the specified value. Possible values: `created_asc`, `created_desc`, `expires_asc`, `expires_desc`, `last_used_asc`, `last_used_desc`, `name_asc`, `name_desc`. |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <group_owner_token>" "https://gitlab.example.com/api/v4/groups/1/manage/resource_access_tokens"
```
Example response:
```json
[
{
"id": 12767703,
"name": "Test Group Token",
"revoked": false,
"created_at": "2025-01-07T00:25:02.128Z",
"description": "",
"scopes": [
"read_registry"
],
"user_id": 25365147,
"last_used_at": null,
"active": true,
"expires_at": "2025-06-19",
"access_level": 10,
"resource_type": "group",
"resource_id": 77449520
}
]
```
#### List all SSH keys for a group
Lists all SSH public keys associated with enterprise users in a top-level-group.
```plaintext
GET /groups/:id/manage/ssh_keys
```
| Attribute | Type | Required | Description |
| ---------------- | ------------------- | -------- | ----------- |
| `id` | integer or string | Yes | The ID or [URL-encoded path](rest/_index.md#namespaced-paths) of a group. |
| `created_after` | datetime (ISO 8601) | No | If defined, returns SSH keys created after the specified time. |
| `created_before` | datetime (ISO 8601) | No | If defined, returns SSH keys created before the specified time. |
| `expires_before` | datetime (ISO 8601) | No | If defined, returns SSH keys that expire before the specified time. |
| `expires_after` | datetime (ISO 8601) | No | If defined, returns SSH keys that expire after the specified time. |
```shell
curl --header "PRIVATE-TOKEN: <group_owner_token>" "https://gitlab.example.com/api/v4/groups/1/manage/ssh_keys"
```
Example response:
```json
[
{
"id":3,
"title":"Sample key 3",
"created_at":"2024-12-23T05:40:11.891Z",
"expires_at":null,
"last_used_at":"2024-13-23T05:40:11.891Z",
"usage_type":"auth_and_signing",
"user_id":3
}
]
```
#### Revoke a personal access token for an enterprise user
Revokes a specified personal access token for an enterprise user.
```plaintext
DELETE groups/:id/manage/personal_access_tokens/:id
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| `id` | integer or string | yes | ID of a personal access token or the keyword `self`. |
```shell
curl --request DELETE \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/groups/1/personal_access_tokens/<personal_access_token_id>"
```
If successful, returns `204: No Content`.
Other possible responses:
- `400: Bad Request` if not revoked successfully.
- `401: Unauthorized` if the access token is invalid.
- `403: Forbidden` if the access token does not have the required permissions.
#### Revoke a group or project access token for an enterprise user
Revokes a specified group or project access token for an enterprise user associated with the top-level group.
```plaintext
DELETE groups/:id/manage/resource_access_tokens/:id
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| `id` | integer or string | yes | ID of a resource access token or the keyword `self`. |
```shell
curl --request DELETE \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/groups/1/resource_access_tokens/<personal_access_token_id>"
```
If successful, returns `204: No Content`.
Other possible responses:
- `400: Bad Request` if not revoked successfully.
- `401: Unauthorized` if the access token is invalid.
- `403: Forbidden` if the access token does not have the required permissions.
## Delete an SSH key for a user
## Delete an SSH key for an enterprise user
Deletes a specified SSH public key for an enterprise user associated with the top-level group.
```plaintext
DELETE /groups/:id/manage/keys/:key_id
```
Supported attributes:
| Attribute | Type | Required | Description |
|:----------|:--------|:---------|:------------|
| `key_id` | integer | yes | ID of existing key |
If successful, returns `204: No Content`.
Other possible responses:
- `400: Bad Request` if SSH Key is not deleted successfully.
- `401: Unauthorized` if the SSH Key is invalid.
- `403: Forbidden` if the user does not have the required permissions.
## Rotate a personal access token for an enterprise user
Rotates a specified personal access token for an enterprise user associated with the top-level group. This revokes the previous token and creates a new token
that expires after one week.
```plaintext
POST groups/:id/manage/personal_access_tokens/:id/rotate
```
| Attribute | Type | Required | Description |
|-----------|-----------|----------|---------------------|
| `id` | integer or string | yes | ID of a personal access token or the keyword `self`. |
| `expires_at` | date | no | Expiration date of the access token in ISO format (`YYYY-MM-DD`). The date must be one year or less from the rotation date. If undefined, the token expires after one week. |
```shell
curl --request POST \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/groups/:id/managepersonal_access_tokens/<personal_access_token_id>/rotate"
```
Example response:
```json
{
"id": 42,
"name": "Rotated Token",
"revoked": false,
"created_at": "2023-08-01T15:00:00.000Z",
"description": "Test Token description",
"scopes": ["api"],
"user_id": 1337,
"last_used_at": null,
"active": true,
"expires_at": "2023-08-15",
"token": "s3cr3t"
}
```
If successful, returns `200: OK`.
Other possible responses:
- `400: Bad Request` if not rotated successfully.
- `401: Unauthorized` if any of the following conditions are true:
- The token does not exist.
- The token has expired.
- The token was revoked.
- You do not have access to the specified token.
- `403: Forbidden` if the token is not allowed to rotate itself.
- `404: Not Found` if the user is an group owner but the token does not exist.
- `405: Method Not Allowed` if the token is not a personal access token.
## Rotate a group or project access token for an enterprise user
Rotates a specified group or project access token for an enterprise user associated with the top-level group. This revokes the previous token and creates a new token
that expires after one week.
```plaintext
POST groups/:id/manage/resource_access_tokens/:id/rotate
```
| Attribute | Type | Required | Description |
|-----------|-----------|----------|---------------------|
| `id` | integer or string | yes | ID of a personal access token or the keyword `self`. |
| `expires_at` | date | no | Expiration date of the access token in ISO format (`YYYY-MM-DD`). The date must be one year or less from the rotation date. If undefined, the token expires after one week. |
```shell
curl --request POST \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/groups/:id/manage/resource_access_tokens/<resource_access_token_id>/rotate"
```
Example response:
```json
{
"id": 42,
"name": "Rotated Token",
"revoked": false,
"created_at": "2023-08-01T15:00:00.000Z",
"description": "Test Token description",
"scopes": ["api"],
"user_id": 1337,
"last_used_at": null,
"active": true,
"expires_at": "2023-08-15",
"token": "s3cr3t"
}
```
If successful, returns `200: OK`.
Other possible responses:
- `400: Bad Request` if not rotated successfully.
- `401: Unauthorized` if any of the following conditions are true:
- The token does not exist.
- The token has expired.
- The token was revoked.
- You do not have access to the specified token.
- `403: Forbidden` if the token is not allowed to rotate itself or token is not a bot user token.
- `404: Not Found` if the user is a group owner but the token does not exist.

View File

@ -59,18 +59,25 @@ glab mr merge
- [`glab cluster`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/cluster)
- [`glab completion`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/completion)
- [`glab config`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/config)
- [`glab deploy-key`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/deploy-key)
- [`glab duo`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/duo)
- [`glab incident`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/incident)
- [`glab issue`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/issue)
- [`glab iteration`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/iteration)
- [`glab job`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/job)
- [`glab label`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/label)
- [`glab mr`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/mr)
- [`glab release`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/release)
- [`glab repo`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/repo)
- [`glab schedule`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/schedule)
- [`glab securefile`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/securefile)
- [`glab snippet`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/snippet)
- [`glab ssh-key`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/ssh-key)
- [`glab stack`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/stack)
- [`glab token`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/token)
- [`glab user`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/user)
- [`glab variable`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/variable)
- [`glab version`](https://gitlab.com/gitlab-org/cli/-/tree/main/docs/source/version)
## GitLab Duo for the CLI

View File

@ -37980,7 +37980,13 @@ msgstr ""
msgid "MemberRole|This role is available by default and cannot be changed."
msgstr ""
msgid "MemberRole|To delete custom role, remove role from all users."
msgid "MemberRole|To delete custom admin role, remove role from all users."
msgstr ""
msgid "MemberRole|To delete custom member role, remove role from all group and project members."
msgstr ""
msgid "MemberRole|To delete custom member role, remove role from the following security policies:"
msgstr ""
msgid "MemberRole|Unable to export role report. Contact support if this error persists."
@ -38004,12 +38010,6 @@ msgstr ""
msgid "MemberRole|View permissions"
msgstr ""
msgid "MemberRole|You can't delete this custom role until you remove it from all group members."
msgstr ""
msgid "MemberRole|You can't delete this custom role until you remove it from all security policies:"
msgstr ""
msgid "MemberRole|You must fill out all required fields."
msgstr ""

View File

@ -60,7 +60,7 @@
"@gitlab/application-sdk-browser": "^0.3.4",
"@gitlab/at.js": "1.5.7",
"@gitlab/cluster-client": "^3.0.0",
"@gitlab/duo-ui": "^8.15.0",
"@gitlab/duo-ui": "^8.18.0",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/fonts": "^1.3.0",
"@gitlab/query-language-rust": "0.8.4",
@ -73,6 +73,7 @@
"@mattiasbuelens/web-streams-adapter": "^0.1.0",
"@rails/actioncable": "7.1.501",
"@rails/ujs": "7.1.501",
"@rollup/plugin-graphql": "^2.0.5",
"@sentry/browser": "9.27.0",
"@snowplow/browser-plugin-client-hints": "^3.24.2",
"@snowplow/browser-plugin-form-tracking": "^3.24.2",
@ -117,6 +118,7 @@
"@tiptap/pm": "^2.14.0",
"@tiptap/suggestion": "^2.14.0",
"@tiptap/vue-2": "^2.14.0",
"@vitejs/plugin-vue2": "^2.3.3",
"@vue/apollo-components": "^4.0.0-beta.4",
"@vue/apollo-option": "^4.0.0-beta.4",
"apollo-upload-client": "15.0.0",
@ -129,6 +131,7 @@
"browserslist": "^4.21.3",
"cache-loader": "^4.1.0",
"canvas-confetti": "^1.4.0",
"chokidar": "^3.5.3",
"clipboard": "^2.0.8",
"colord": "^2.9.3",
"commander": "^14.0.0",
@ -154,6 +157,7 @@
"file-loader": "^6.2.0",
"fuzzaldrin-plus": "^0.6.0",
"gettext-parser": "^6.0.0",
"globby": "^11.0.1",
"graphiql": "^3.7.1",
"graphql": "16.11.0",
"graphql-tag": "^2.11.0",
@ -225,6 +229,8 @@
"url-loader": "^4.1.1",
"uuid": "8.1.0",
"visibilityjs": "^1.2.4",
"vite": "^6.3.5",
"vite-plugin-ruby": "^5.1.1",
"vue": "2.7.16",
"vue-apollo": "^3.0.7",
"vue-loader": "15.11.1",
@ -252,13 +258,10 @@
"@gitlab/noop": "^1.0.1",
"@gitlab/stylelint-config": "6.2.2",
"@graphql-eslint/eslint-plugin": "4.4.0",
"@originjs/vite-plugin-commonjs": "^1.0.3",
"@pinia/testing": "^0.1.5",
"@rollup/plugin-graphql": "^2.0.5",
"@testing-library/dom": "^7.16.2",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.197",
"@vitejs/plugin-vue2": "^2.3.3",
"@vue/compat": "^3.5.13",
"@vue/compiler-sfc": "^3.5.13",
"@vue/server-renderer": "^3.5.13",
@ -272,7 +275,6 @@
"babel-jest": "^29.7.0",
"babel-plugin-istanbul": "^7.0.0",
"chalk": "^2.4.1",
"chokidar": "^3.5.3",
"crypto": "^1.0.1",
"custom-jquery-matchers": "^2.1.0",
"dependency-cruiser": "^16.9.0",
@ -288,7 +290,6 @@
"gettext-extractor": "^3.7.0",
"gettext-extractor-vue": "^5.1.0",
"glob": "^7.1.6",
"globby": "^11.0.1",
"jest": "^29.7.0",
"jest-canvas-mock": "^2.4.0",
"jest-diff": "^29.7.0",
@ -306,8 +307,6 @@
"swagger-cli": "^4.0.4",
"tailwindcss": "^3.4.1",
"timezone-mock": "^1.0.8",
"vite": "^6.3.5",
"vite-plugin-ruby": "^5.1.1",
"vue-loader-vue3": "npm:vue-loader@17.4.2",
"vue-test-utils-compat": "0.0.14",
"vuex-mock-store": "^0.1.0",

View File

@ -6,7 +6,6 @@ const {
decorateExtractorWithHelpers,
} = require('gettext-extractor-vue');
const vue2TemplateCompiler = require('vue-template-compiler');
const ensureSingleLine = require('../../app/assets/javascripts/locale/ensure_single_line.cjs');
program
.option('-f, --file <file>', 'Extract message from one single file')
@ -17,6 +16,17 @@ const args = program.opts();
const extractor = decorateExtractorWithHelpers(new GettextExtractor());
function ensureSingleLine(str) {
// This guard makes the function significantly faster
if (str.includes('\n') || str.includes('\r')) {
return str
.split(/\s*[\r\n]+\s*/)
.filter((s) => s !== '')
.join(' ');
}
return str;
}
extractor.addMessageTransformFunction(ensureSingleLine);
const jsParser = extractor.createJsParser([

View File

@ -78,7 +78,6 @@ spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js
spec/frontend/ci_settings_pipeline_triggers/components/edit_trigger_modal_spec.js
spec/frontend/clusters/agents/components/activity_history_item_spec.js
spec/frontend/clusters/agents/components/revoke_token_button_spec.js
spec/frontend/clusters/agents/components/show_spec.js
spec/frontend/clusters/components/new_cluster_spec.js
spec/frontend/clusters/components/remove_cluster_confirmation_spec.js
spec/frontend/clusters_list/components/delete_agent_button_spec.js

View File

@ -147,4 +147,14 @@ RSpec.describe 'CI configuration validation - branch pipelines', feature_categor
it_behaves_like 'merge train pipeline'
end
end
context 'when MR changes vite.config.js and pipeline is tier 3' do
let(:mr_labels) { ['pipeline::tier-3'] }
let(:source_branch) { 'vite-change' }
let(:changed_files) { ['vite.config.js'] }
where(expected_job_name: %w[compile-production-assets build-vite-prod])
with_them { it_behaves_like 'merge request pipeline' }
end
end

View File

@ -1,6 +1,6 @@
import { GlAlert, GlKeysetPagination, GlLoadingIcon, GlSprintf, GlTab, GlButton } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@ -17,8 +17,7 @@ import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { MAX_LIST_COUNT } from '~/clusters/agents/constants';
import { CONNECT_MODAL_ID } from '~/clusters_list/constants';
const localVue = createLocalVue();
localVue.use(VueApollo);
Vue.use(VueApollo);
describe('ClusterAgentShow', () => {
let wrapper;
@ -58,7 +57,6 @@ describe('ClusterAgentShow', () => {
wrapper = extendedWrapper(
shallowMount(ClusterAgentShow, {
localVue,
apolloProvider,
provide,
stubs: { GlSprintf, TimeAgoTooltip, GlTab },
@ -69,13 +67,22 @@ describe('ClusterAgentShow', () => {
);
};
const createWrapperWithoutApollo = ({ clusterAgent, loading = false, slots = {} }) => {
const $apollo = { queries: { clusterAgent: { loading } } };
const createWrapperForLoading = ({ clusterAgent, loading = false, slots = {} }) => {
let queryResponse;
if (loading) {
queryResponse = jest.fn().mockReturnValue(new Promise(() => {}));
} else {
queryResponse = jest
.fn()
.mockResolvedValue({ data: { project: { id: 'project-1', clusterAgent } } });
}
const apolloProvider = createMockApollo([[getAgentQuery, queryResponse]]);
wrapper = extendedWrapper(
shallowMount(ClusterAgentShow, {
apolloProvider,
provide,
mocks: { $apollo, clusterAgent },
slots,
stubs: { GlTab },
}),
@ -245,12 +252,12 @@ describe('ClusterAgentShow', () => {
describe('when the clusterAgent is present', () => {
beforeEach(() => {
createWrapperWithoutApollo({ clusterAgent: defaultClusterAgent, loading: true });
createWrapperForLoading({ clusterAgent: defaultClusterAgent, loading: true });
});
it('displays a loading icon and token tab', () => {
it('displays a loading icon and no token tab', () => {
expect(findLoadingIcon().exists()).toBe(true);
expect(wrapper.text()).toContain(ClusterAgentShow.i18n.tokens);
expect(wrapper.text()).not.toContain(ClusterAgentShow.i18n.tokens);
});
});
});
@ -269,38 +276,38 @@ describe('ClusterAgentShow', () => {
describe('ee-security-tab slot', () => {
it('does not display when a slot is not passed in', async () => {
createWrapperWithoutApollo({ clusterAgent: defaultClusterAgent });
await nextTick();
createWrapperForLoading({ clusterAgent: defaultClusterAgent });
await waitForPromises();
expect(findEESecurityTabSlot().exists()).toBe(false);
});
it('does display when a slot is passed in', async () => {
createWrapperWithoutApollo({
createWrapperForLoading({
clusterAgent: defaultClusterAgent,
slots: {
'ee-security-tab': `<gl-tab data-testid="ee-security-tab">Security Tab!</gl-tab>`,
},
});
await nextTick();
await waitForPromises();
expect(findEESecurityTabSlot().exists()).toBe(true);
});
});
describe('ee-workspaces-tab slot', () => {
it('does not display when a slot is not passed in', async () => {
createWrapperWithoutApollo({ clusterAgent: defaultClusterAgent });
await nextTick();
createWrapperForLoading({ clusterAgent: defaultClusterAgent });
await waitForPromises();
expect(findEEWorkspacesTabSlot().exists()).toBe(false);
});
it('does display when a slot is passed in', async () => {
createWrapperWithoutApollo({
createWrapperForLoading({
clusterAgent: defaultClusterAgent,
slots: {
'ee-workspaces-tab': `<gl-tab data-testid="ee-workspaces-tab">Workspaces Tab!</gl-tab>`,
},
});
await nextTick();
await waitForPromises();
expect(findEEWorkspacesTabSlot().exists()).toBe(true);
});
});

View File

@ -1,4 +1,4 @@
import ensureSingleLine from '~/locale/ensure_single_line.cjs';
import { ensureSingleLine } from '~/locale/ensure_single_line';
describe('locale', () => {
describe('ensureSingleLine', () => {

View File

@ -1,107 +0,0 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe Types::Namespaces::UserLevelPermissions::GroupNamespaceUserLevelPermissionsType, feature_category: :shared do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
let_it_be(:user) { create(:user) }
subject(:type) { described_class.resolve_type(group, {}) }
it_behaves_like 'expose all user permissions fields for the namespace'
describe "permission values" do
let_it_be(:non_member) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:developer) { create(:user) }
let_it_be(:maintainer) { create(:user) }
let_it_be(:owner) { create(:user) }
let_it_be(:group) do
create(
:group,
:private,
guests: [guest],
developers: [developer],
maintainers: [maintainer],
owners: [owner]
)
end
context "for can_admin_label permission" do
where(:user_role, :expected) do
:non_member | false
:guest | false
:developer | true
:maintainer | true
:owner | true
end
with_them do
let(:current_user) { send(user_role) }
it "returns the correct permission value" do
actual = resolve_field(:can_admin_label, group, current_user: current_user)
expect(actual).to eq(expected)
end
end
end
context "for can_create_projects permission" do
where(:user_role, :expected) do
:non_member | false
:guest | false
:developer | false
:maintainer | true
:owner | true
end
with_them do
let(:current_user) { send(user_role) }
it "returns the correct permission value" do
actual = resolve_field(:can_create_projects, group, current_user: current_user)
expect(actual).to eq(expected)
end
end
end
end
context "when group settings restrict permissions" do
let_it_be(:group) { create(:group, :private) }
let_it_be(:developer) { create(:user) }
let_it_be(:owner) { create(:user) }
before_all do
group.add_developer(developer)
group.add_owner(owner)
end
context "when create project is restricted" do
before do
allow_next_instance_of(Ability) do |instance|
allow(instance).to receive(:can?).with(:create_projects, group).and_return(false)
end
end
it "returns false" do
expect(resolve_field(:can_create_projects, group, current_user: user)).to be(false)
end
end
context "when label administration is restricted" do
before do
allow_next_instance_of(Ability) do |instance|
allow(instance).to receive(:can?).with(:admin_label, group).and_return(false)
end
end
it "returns false" do
expect(resolve_field(:can_admin_label, group, current_user: user)).to be(false)
end
end
end
end

View File

@ -1,85 +0,0 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe Types::Namespaces::UserLevelPermissions::ProjectNamespaceUserLevelPermissionsType, feature_category: :shared do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:project_namespace) { project.project_namespace }
subject(:type) { described_class.resolve_type(project_namespace, {}) }
it_behaves_like 'expose all user permissions fields for the namespace'
describe "permission values" do
let_it_be(:non_member) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:developer) { create(:user) }
let_it_be(:maintainer) { create(:user) }
let_it_be(:owner) { create(:user) }
before_all do
project.add_guest(guest)
project.add_developer(developer)
project.add_maintainer(maintainer)
project.add_owner(owner)
end
# Test the implemented method that returns actual permission values
context "for can_admin_label permission" do
where(:user_role, :expected) do
:non_member | false
:guest | false
:developer | true
:maintainer | true
:owner | true
end
with_them do
let(:current_user) { send(user_role) }
it "returns the correct permission value" do
actual = resolve_field(:can_admin_label, project_namespace, current_user: current_user)
expect(actual).to eq(expected)
end
end
end
# Unified test for all non-implemented permissions that return nil
context "for non-implemented permissions" do
let(:current_user) { maintainer }
it "returns nil for can_create_projects" do
expect(resolve_field(:can_create_projects, project_namespace, current_user: current_user)).to be(false)
end
if Gitlab.ee?
it "returns nil for can_bulk_edit_epics" do
expect(resolve_field(:can_bulk_edit_epics, project_namespace, current_user: current_user)).to be(false)
end
it "returns nil for can_create_epic" do
expect(resolve_field(:can_create_epic, project_namespace, current_user: current_user)).to be(false)
end
end
end
end
context "when project settings restrict permissions" do
context "when label administration is restricted" do
before do
allow_next_instance_of(Ability) do |instance|
allow(instance).to receive(:can?).with(:admin_label, project).and_return(false)
end
end
it "returns false" do
expect(resolve_field(:can_admin_label, project_namespace, current_user: user)).to be(false)
end
end
end
end

View File

@ -1,7 +0,0 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe Types::Namespaces::UserLevelPermissions::UserNamespaceUserLevelPermissionsType, feature_category: :shared do
it_behaves_like 'expose all user permissions fields for the namespace'
end

View File

@ -1,39 +0,0 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe Types::Namespaces::UserLevelPermissions, feature_category: :shared do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
where(:namespace_class, :namespace_type_name) do
::Group | ::Types::Namespaces::UserLevelPermissions::GroupNamespaceUserLevelPermissionsType
::Namespaces::ProjectNamespace | ::Types::Namespaces::UserLevelPermissions::ProjectNamespaceUserLevelPermissionsType
end
with_them do
describe ".resolve_type" do
it "knows the correct type for objects" do
namespace = namespace_class.new
expect(described_class.resolve_type(namespace, {}))
.to eq(namespace_type_name)
end
end
describe ".orphan_types" do
it "includes the type" do
expect(described_class.orphan_types).to include(namespace_type_name)
end
end
end
it "raises an error for an unknown type" do
namespace = build(:project)
expect { described_class.resolve_type(namespace, {}) }
.to raise_error("Unknown GraphQL type for namespace type #{namespace.class}")
end
it_behaves_like "expose all user permissions fields for the namespace"
end

View File

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Types::PermissionTypes::Namespaces::Base, feature_category: :groups_and_projects do
specify do
expected_permissions = [:admin_label, :read_namespace, :admin_issue, :create_work_item,
:import_issues, :read_crm_contact, :read_crm_organization]
:import_issues, :read_crm_contact, :read_crm_organization, :create_projects]
expected_permissions.each do |permission|
expect(described_class).to have_graphql_field(permission)

View File

@ -1,23 +0,0 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.shared_examples "expose all user permissions fields for the namespace" do
include GraphqlHelpers
specify do
expected_fields = %i[
canAdminLabel
canCreateProjects
]
if Gitlab.ee?
expected_fields.push(*%i[
canCreateEpic
canBulkEditEpics
])
end
expect(described_class).to have_graphql_fields(*expected_fields)
end
end

View File

@ -4,7 +4,6 @@ import path from 'node:path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue2';
import graphql from '@rollup/plugin-graphql';
import { viteCommonjs } from '@originjs/vite-plugin-commonjs';
import webpackConfig from './config/webpack.config';
import {
IS_EE,
@ -108,9 +107,6 @@ export default defineConfig({
},
}),
graphql(),
viteCommonjs({
include: [path.resolve(javascriptsPath, 'locale/ensure_single_line.cjs')],
}),
CrossOriginWorkerPlugin(),
],
define: {
@ -168,4 +164,12 @@ export default defineConfig({
worker: {
format: 'es',
},
build: {
// speed up build in CI by disabling sourcemaps and compression
// TODO: allow sourcemaps and compression when we are ready for Vite in production
sourcemap: false,
minify: false,
cssMinify: false,
reportCompressedSize: false,
},
});

155
yarn.lock
View File

@ -1190,11 +1190,6 @@
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz#3e0736fcfab16cff042dec806247e2c76e109e19"
integrity sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==
"@esbuild/linux-loong64@0.14.54":
version "0.14.54"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028"
integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==
"@esbuild/linux-loong64@0.25.0":
version "0.25.0"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz#ea2bf730883cddb9dfb85124232b5a875b8020c7"
@ -1387,10 +1382,10 @@
core-js "^3.29.1"
mitt "^3.0.1"
"@gitlab/duo-ui@^8.15.0":
version "8.15.0"
resolved "https://registry.yarnpkg.com/@gitlab/duo-ui/-/duo-ui-8.15.0.tgz#159eb511f715d0bf7a3475bc275584e4ef534094"
integrity sha512-/awVYyObIQ4xJaO3OcGNHvzlPFcX+PkrWe0HupHpOoG0MmFndl0XpLtQG+DOCrnyVVs39IMYjEagejOOg2uvEQ==
"@gitlab/duo-ui@^8.18.0":
version "8.18.0"
resolved "https://registry.yarnpkg.com/@gitlab/duo-ui/-/duo-ui-8.18.0.tgz#ced9368e5f069cb162bb14a9602b45bf9bed6de9"
integrity sha512-FFmQJ8O3I9xoQgALjCfsf4Xy04GQLqEycpc0jkQgUzBuml49Van8Rh3Ig/ZnB6QR40Y+dMDteBE0g3+CpcqlDw==
dependencies:
"@floating-ui/dom" "1.7.0"
echarts "^5.3.2"
@ -1430,8 +1425,7 @@
resolved "https://registry.yarnpkg.com/@gitlab/fonts/-/fonts-1.3.0.tgz#df89c1bb6714e4a8a5d3272568aa4de7fb337267"
integrity sha512-DoMUIN3DqjEn7wvcxBg/b7Ite5fTdF5EmuOZoBRo2j0UBGweDXmNBi+9HrTZs4cBU660dOxcf1hATFcG3npbPg==
"@gitlab/noop@^1.0.1", jackspeak@^3.1.2, "jackspeak@npm:@gitlab/noop@1.0.1":
name jackspeak
"@gitlab/noop@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@gitlab/noop/-/noop-1.0.1.tgz#71a831146ee02732b4a61d2d3c11204564753454"
integrity sha512-s++4wjMYeDvBp9IO59DBrWjy8SE/gFkjTDO5ck2W0S6Vv7OlqgErwL7pHngAnrSmTJAzyUG8wHGqo0ViS4jn5Q==
@ -2165,13 +2159,6 @@
resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323"
integrity sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==
"@originjs/vite-plugin-commonjs@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@originjs/vite-plugin-commonjs/-/vite-plugin-commonjs-1.0.3.tgz#2e3fb11ec78847da9422b79c103953f94d667f09"
integrity sha512-KuEXeGPptM2lyxdIEJ4R11+5ztipHoE7hy8ClZt3PYaOVQ/pyngd2alaSrPnwyFeOW1UagRBaQ752aA1dTMdOQ==
dependencies:
esbuild "^0.14.14"
"@pinia/testing@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@pinia/testing/-/testing-0.1.5.tgz#3d43de8b0fea102e4bd6188f219ebe4d241a29e5"
@ -7218,133 +7205,6 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
esbuild-android-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be"
integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==
esbuild-android-arm64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771"
integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==
esbuild-darwin-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25"
integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==
esbuild-darwin-arm64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73"
integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==
esbuild-freebsd-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d"
integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==
esbuild-freebsd-arm64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48"
integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==
esbuild-linux-32@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5"
integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==
esbuild-linux-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652"
integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==
esbuild-linux-arm64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b"
integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==
esbuild-linux-arm@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59"
integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==
esbuild-linux-mips64le@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34"
integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==
esbuild-linux-ppc64le@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e"
integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==
esbuild-linux-riscv64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8"
integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==
esbuild-linux-s390x@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6"
integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==
esbuild-netbsd-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81"
integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==
esbuild-openbsd-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b"
integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==
esbuild-sunos-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da"
integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==
esbuild-windows-32@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31"
integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==
esbuild-windows-64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4"
integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==
esbuild-windows-arm64@0.14.54:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982"
integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==
esbuild@^0.14.14:
version "0.14.54"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2"
integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==
optionalDependencies:
"@esbuild/linux-loong64" "0.14.54"
esbuild-android-64 "0.14.54"
esbuild-android-arm64 "0.14.54"
esbuild-darwin-64 "0.14.54"
esbuild-darwin-arm64 "0.14.54"
esbuild-freebsd-64 "0.14.54"
esbuild-freebsd-arm64 "0.14.54"
esbuild-linux-32 "0.14.54"
esbuild-linux-64 "0.14.54"
esbuild-linux-arm "0.14.54"
esbuild-linux-arm64 "0.14.54"
esbuild-linux-mips64le "0.14.54"
esbuild-linux-ppc64le "0.14.54"
esbuild-linux-riscv64 "0.14.54"
esbuild-linux-s390x "0.14.54"
esbuild-netbsd-64 "0.14.54"
esbuild-openbsd-64 "0.14.54"
esbuild-sunos-64 "0.14.54"
esbuild-windows-32 "0.14.54"
esbuild-windows-64 "0.14.54"
esbuild-windows-arm64 "0.14.54"
esbuild@^0.25.0:
version "0.25.0"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.0.tgz#0de1787a77206c5a79eeb634a623d39b5006ce92"
@ -9504,6 +9364,11 @@ istanbul-reports@^3.1.3:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
jackspeak@^3.1.2, "jackspeak@npm:@gitlab/noop@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@gitlab/noop/-/noop-1.0.1.tgz#71a831146ee02732b4a61d2d3c11204564753454"
integrity sha512-s++4wjMYeDvBp9IO59DBrWjy8SE/gFkjTDO5ck2W0S6Vv7OlqgErwL7pHngAnrSmTJAzyUG8wHGqo0ViS4jn5Q==
jed@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"