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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-04-13 03:19:10 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-13 03:19:10 +0300
commitfa1b90364dc73f27dc78b9d27114e4a197f2cfcb (patch)
treef72d9e2a7355687d977bfe0c01bdb42238e98d27
parentac48f7c24110a7a1e0a0aa49fc7838ab03c28374 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_todo/gitlab/no_code_coverage_comment.yml1
-rw-r--r--.rubocop_todo/naming/heredoc_delimiter_naming.yml1
-rw-r--r--.rubocop_todo/rspec/expect_in_hook.yml1
-rw-r--r--.rubocop_todo/sidekiq_load_balancing/worker_data_consistency.yml1
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/ci/runner/components/runner_create_form.vue3
-rw-r--r--app/assets/javascripts/members/components/table/role_dropdown.vue23
-rw-r--r--app/assets/javascripts/repository/components/blob_content_viewer.vue14
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue2
-rw-r--r--app/controllers/projects/tree_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/graphql/mutations/ci/runner/common_mutation_arguments.rb5
-rw-r--r--app/graphql/mutations/ci/runner/create.rb79
-rw-r--r--app/graphql/mutations/ci/runner/update.rb5
-rw-r--r--app/policies/global_policy.rb4
-rw-r--r--app/policies/group_policy.rb6
-rw-r--r--app/policies/project_policy.rb6
-rw-r--r--app/services/ci/runners/create_runner_service.rb23
-rw-r--r--app/services/ci/runners/runner_creation_strategies/group_runner_strategy.rb38
-rw-r--r--app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb15
-rw-r--r--app/services/ci/runners/runner_creation_strategies/project_runner_strategy.rb38
-rw-r--r--config/feature_flags/development/reduce_sub_batch_size_on_timeouts.yml8
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--doc/api/graphql/reference/index.md182
-rw-r--r--doc/api/projects.md11
-rw-r--r--doc/user/group/compliance_frameworks.md50
-rw-r--r--lib/gitlab/database/background_migration/batched_job.rb2
-rw-r--r--lib/gitlab/graphql/deprecations/deprecation.rb4
-rw-r--r--locale/gitlab.pot6
-rw-r--r--qa/qa/page/project/import/github.rb2
-rw-r--r--spec/frontend/ci/runner/components/runner_create_form_spec.js3
-rw-r--r--spec/frontend/fixtures/runner.rb19
-rw-r--r--spec/frontend/members/components/table/role_dropdown_spec.js86
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_job_spec.rb36
-rw-r--r--spec/lib/gitlab/graphql/deprecations/deprecation_spec.rb2
-rw-r--r--spec/policies/global_policy_spec.rb30
-rw-r--r--spec/policies/group_policy_spec.rb46
-rw-r--r--spec/policies/project_policy_spec.rb58
-rw-r--r--spec/requests/api/graphql/mutations/ci/runner/create_spec.rb275
-rw-r--r--spec/services/ci/runners/create_runner_service_spec.rb149
-rw-r--r--spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb6
-rw-r--r--spec/tooling/graphql/docs/renderer_spec.rb8
42 files changed, 906 insertions, 350 deletions
diff --git a/.rubocop_todo/gitlab/no_code_coverage_comment.yml b/.rubocop_todo/gitlab/no_code_coverage_comment.yml
index e37a9702094..e97974a4738 100644
--- a/.rubocop_todo/gitlab/no_code_coverage_comment.yml
+++ b/.rubocop_todo/gitlab/no_code_coverage_comment.yml
@@ -4,7 +4,6 @@ Gitlab/NoCodeCoverageComment:
- 'app/models/integration.rb'
- 'app/services/ci/job_artifacts/destroy_batch_service.rb'
- 'app/workers/database/batched_background_migration/single_database_worker.rb'
- - 'config/initializers/net_http_response_patch.rb'
- 'ee/app/models/concerns/geo/replicable_model.rb'
- 'ee/lib/gitlab/geo/replicator.rb'
- 'lib/gitlab/auth/o_auth/session.rb'
diff --git a/.rubocop_todo/naming/heredoc_delimiter_naming.yml b/.rubocop_todo/naming/heredoc_delimiter_naming.yml
index b4586ecf414..76144801438 100644
--- a/.rubocop_todo/naming/heredoc_delimiter_naming.yml
+++ b/.rubocop_todo/naming/heredoc_delimiter_naming.yml
@@ -57,7 +57,6 @@ Naming/HeredocDelimiterNaming:
- 'spec/features/projects/commit/user_comments_on_commit_spec.rb'
- 'spec/features/task_lists_spec.rb'
- 'spec/initializers/100_patch_omniauth_oauth2_spec.rb'
- - 'spec/initializers/net_http_response_patch_spec.rb'
- 'spec/initializers/rack_multipart_patch_spec.rb'
- 'spec/initializers/secret_token_spec.rb'
- 'spec/initializers/validate_database_config_spec.rb'
diff --git a/.rubocop_todo/rspec/expect_in_hook.yml b/.rubocop_todo/rspec/expect_in_hook.yml
index d3dc36a7475..8d36ed7520c 100644
--- a/.rubocop_todo/rspec/expect_in_hook.yml
+++ b/.rubocop_todo/rspec/expect_in_hook.yml
@@ -164,7 +164,6 @@ RSpec/ExpectInHook:
- 'spec/helpers/projects_helper_spec.rb'
- 'spec/helpers/search_helper_spec.rb'
- 'spec/helpers/users_helper_spec.rb'
- - 'spec/initializers/net_http_response_patch_spec.rb'
- 'spec/initializers/validate_database_config_spec.rb'
- 'spec/lib/api/entities/merge_request_changes_spec.rb'
- 'spec/lib/api/helpers/variables_helpers_spec.rb'
diff --git a/.rubocop_todo/sidekiq_load_balancing/worker_data_consistency.yml b/.rubocop_todo/sidekiq_load_balancing/worker_data_consistency.yml
index e821ee19001..efd7db7ad2c 100644
--- a/.rubocop_todo/sidekiq_load_balancing/worker_data_consistency.yml
+++ b/.rubocop_todo/sidekiq_load_balancing/worker_data_consistency.yml
@@ -416,6 +416,7 @@ SidekiqLoadBalancing/WorkerDataConsistency:
- 'ee/app/workers/merge_request_reset_approvals_worker.rb'
- 'ee/app/workers/merge_requests/capture_suggested_reviewers_accepted_worker.rb'
- 'ee/app/workers/merge_requests/fetch_suggested_reviewers_worker.rb'
+ - 'ee/app/workers/merge_requests/llm/summarize_merge_request_worker.rb'
- 'ee/app/workers/merge_requests/sync_code_owner_approval_rules_worker.rb'
- 'ee/app/workers/merge_trains/refresh_worker.rb'
- 'ee/app/workers/namespaces/free_user_cap/backfill_notification_clearing_jobs_worker.rb'
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 3d5723f0c07..f98a9af7b30 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-08d6ba069ecf285bab9fe3162884ffe3c5b243d0
+81e439b712f147dc54bf0659857c4a038e9999b3
diff --git a/app/assets/javascripts/ci/runner/components/runner_create_form.vue b/app/assets/javascripts/ci/runner/components/runner_create_form.vue
index 5d2a3c53842..2bad08b4f48 100644
--- a/app/assets/javascripts/ci/runner/components/runner_create_form.vue
+++ b/app/assets/javascripts/ci/runner/components/runner_create_form.vue
@@ -4,7 +4,7 @@ import RunnerFormFields from '~/ci/runner/components/runner_form_fields.vue';
import runnerCreateMutation from '~/ci/runner/graphql/new/runner_create.mutation.graphql';
import { modelToUpdateMutationVariables } from 'ee_else_ce/ci/runner/runner_update_form_utils';
import { captureException } from '../sentry_utils';
-import { DEFAULT_ACCESS_LEVEL } from '../constants';
+import { DEFAULT_ACCESS_LEVEL, INSTANCE_TYPE } from '../constants';
export default {
name: 'RunnerCreateForm',
@@ -17,6 +17,7 @@ export default {
return {
saving: false,
runner: {
+ runnerType: INSTANCE_TYPE,
description: '',
maintenanceNote: '',
paused: false,
diff --git a/app/assets/javascripts/members/components/table/role_dropdown.vue b/app/assets/javascripts/members/components/table/role_dropdown.vue
index e066b023fbb..a85bb09e17b 100644
--- a/app/assets/javascripts/members/components/table/role_dropdown.vue
+++ b/app/assets/javascripts/members/components/table/role_dropdown.vue
@@ -81,19 +81,18 @@ export default {
return;
}
- this.updateMemberRole({
- memberId: this.member.id,
- accessLevel: { integerValue: newRoleValue, stringValue: newRoleName },
- })
- .then(() => {
- this.$toast.show(s__('Members|Role updated successfully.'));
- })
- .catch((error) => {
- Sentry.captureException(error);
- })
- .finally(() => {
- this.busy = false;
+ try {
+ await this.updateMemberRole({
+ memberId: this.member.id,
+ accessLevel: { integerValue: newRoleValue, stringValue: newRoleName },
});
+
+ this.$toast.show(s__('Members|Role updated successfully.'));
+ } catch (error) {
+ Sentry.captureException(error);
+ } finally {
+ this.busy = false;
+ }
},
},
};
diff --git a/app/assets/javascripts/repository/components/blob_content_viewer.vue b/app/assets/javascripts/repository/components/blob_content_viewer.vue
index 236351005e7..60df042529a 100644
--- a/app/assets/javascripts/repository/components/blob_content_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_content_viewer.vue
@@ -34,6 +34,7 @@ export default {
ForkSuggestion,
WebIdeLink,
CodeIntelligence,
+ AiGenie: () => import('ee_component/ai/components/ai_genie.vue'),
},
mixins: [getRefMixin, glFeatureFlagMixin()],
inject: {
@@ -142,6 +143,9 @@ export default {
};
},
computed: {
+ shouldRenderGenie() {
+ return this.glFeatures.explainCode && this.glFeatures.explainCodeSnippet;
+ },
isLoggedIn() {
return isLoggedIn();
},
@@ -316,9 +320,9 @@ export default {
</script>
<template>
- <div>
+ <div class="gl-relative">
<gl-loading-icon v-if="isLoading" size="sm" />
- <div v-if="blobInfo && !isLoading" class="file-holder">
+ <div v-if="blobInfo && !isLoading" id="fileHolder" class="file-holder">
<blob-header
:blob="blobInfo"
:hide-viewer-switcher="!hasRichViewer || isBinaryFileType || isUsingLfs"
@@ -393,5 +397,11 @@ export default {
:wrap-text-nodes="glFeatures.highlightJs"
/>
</div>
+ <ai-genie
+ v-if="shouldRenderGenie"
+ container-id="fileHolder"
+ :file-path="path"
+ class="gl-ml-7"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue b/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue
index 1690e666d3c..f121e84e1de 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue
@@ -38,7 +38,7 @@ export default {
class="gl-p-0! gl-absolute gl-z-index-3 diff-line-num gl-border-r gl-display-flex line-links line-numbers"
>
<a
- class="gl-user-select-none gl-shadow-none! file-line-blame"
+ class="gl-user-select-none gl-shadow-none! file-line-blame gl-mx-n2 gl-flex-grow-1"
:href="`${blamePath}${pageSearchString}#L${number}`"
></a>
<a
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 0631c02355e..367417ba840 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -19,6 +19,8 @@ class Projects::TreeController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
push_frontend_feature_flag(:synchronize_fork, @project.fork_source)
+ push_frontend_feature_flag(:explain_code_snippet, current_user)
+ push_licensed_feature(:explain_code, @project) if @project.licensed_feature_available?(:explain_code)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index a6bc754d09e..be30255ec4e 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -39,8 +39,10 @@ class ProjectsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
push_frontend_feature_flag(:synchronize_fork, @project&.fork_source)
+ push_frontend_feature_flag(:explain_code_snippet, current_user)
push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks)
push_licensed_feature(:security_orchestration_policies) if @project.present? && @project.licensed_feature_available?(:security_orchestration_policies)
+ push_licensed_feature(:explain_code, @project) if @project.present? && @project.licensed_feature_available?(:explain_code)
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc, @project&.work_items_mvc_feature_flag_enabled?)
push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?)
diff --git a/app/graphql/mutations/ci/runner/common_mutation_arguments.rb b/app/graphql/mutations/ci/runner/common_mutation_arguments.rb
index bfeed4881c6..f4fbd0a38c7 100644
--- a/app/graphql/mutations/ci/runner/common_mutation_arguments.rb
+++ b/app/graphql/mutations/ci/runner/common_mutation_arguments.rb
@@ -38,11 +38,6 @@ module Mutations
argument :tag_list, [GraphQL::Types::String],
required: false,
description: 'Tags associated with the runner.'
-
- argument :associated_projects, [::Types::GlobalIDType[::Project]],
- required: false,
- description: 'Projects associated with the runner. Available only for project runners.',
- prepare: ->(global_ids, _ctx) { global_ids&.filter_map { |gid| gid.model_id.to_i } }
end
end
end
diff --git a/app/graphql/mutations/ci/runner/create.rb b/app/graphql/mutations/ci/runner/create.rb
index 98300ee4c38..7eca6c27d10 100644
--- a/app/graphql/mutations/ci/runner/create.rb
+++ b/app/graphql/mutations/ci/runner/create.rb
@@ -10,25 +10,49 @@ module Mutations
include Mutations::Ci::Runner::CommonMutationArguments
+ argument :runner_type, ::Types::Ci::RunnerTypeEnum,
+ required: true,
+ description: 'Type of the runner to create.'
+
+ argument :group_id, ::Types::GlobalIDType[Group],
+ required: false,
+ description: 'Global ID of the group that the runner is created in (valid only for group runner).'
+
+ argument :project_id, ::Types::GlobalIDType[Project],
+ required: false,
+ description: 'Global ID of the project that the runner is created in (valid only for project runner).'
+
field :runner,
Types::Ci::RunnerType,
null: true,
description: 'Runner after mutation.'
- def resolve(**args)
- if Feature.disabled?(:create_runner_workflow_for_admin, current_user)
- raise Gitlab::Graphql::Errors::ResourceNotAvailable,
- '`create_runner_workflow_for_admin` feature flag is disabled.'
+ def ready?(**args)
+ case args[:runner_type]
+ when 'group_type'
+ raise Gitlab::Graphql::Errors::ArgumentError, '`group_id` is missing' unless args[:group_id].present?
+ when 'project_type'
+ raise Gitlab::Graphql::Errors::ArgumentError, '`project_id` is missing' unless args[:project_id].present?
end
- create_runner(args)
+ parse_gid(**args)
+
+ check_feature_flag(**args)
+
+ super
end
- private
+ def resolve(**args)
+ case args[:runner_type]
+ when 'group_type', 'project_type'
+ args[:scope] = authorized_find!(**args)
+ args.except!(:group_id, :project_id)
+ else
+ raise_resource_not_available_error! unless current_user.can?(:create_instance_runner)
+ end
- def create_runner(params)
response = { runner: nil, errors: [] }
- result = ::Ci::Runners::CreateRunnerService.new(user: current_user, type: nil, params: params).execute
+ result = ::Ci::Runners::CreateRunnerService.new(user: current_user, params: args).execute
if result.success?
response[:runner] = result.payload[:runner]
@@ -38,6 +62,45 @@ module Mutations
response
end
+
+ private
+
+ def find_object(**args)
+ obj = parse_gid(**args)
+
+ GitlabSchema.find_by_gid(obj) if obj
+ end
+
+ def parse_gid(runner_type:, **args)
+ case runner_type
+ when 'group_type'
+ GitlabSchema.parse_gid(args[:group_id], expected_type: ::Group)
+ when 'project_type'
+ GitlabSchema.parse_gid(args[:project_id], expected_type: ::Project)
+ end
+ end
+
+ def check_feature_flag(**args)
+ case args[:runner_type]
+ when 'instance_type'
+ if Feature.disabled?(:create_runner_workflow_for_admin, current_user)
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable,
+ '`create_runner_workflow_for_admin` feature flag is disabled.'
+ end
+ when 'group_type'
+ namespace = find_object(**args).sync
+ if Feature.disabled?(:create_runner_workflow_for_namespace, namespace)
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable,
+ '`create_runner_workflow_for_namespace` feature flag is disabled.'
+ end
+ when 'project_type'
+ project = find_object(**args).sync
+ if project && Feature.disabled?(:create_runner_workflow_for_namespace, project.namespace)
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable,
+ '`create_runner_workflow_for_namespace` feature flag is disabled.'
+ end
+ end
+ end
end
end
end
diff --git a/app/graphql/mutations/ci/runner/update.rb b/app/graphql/mutations/ci/runner/update.rb
index 00865b177a8..da28397bb71 100644
--- a/app/graphql/mutations/ci/runner/update.rb
+++ b/app/graphql/mutations/ci/runner/update.rb
@@ -21,6 +21,11 @@ module Mutations
description: 'Indicates the runner is allowed to receive jobs.',
deprecated: { reason: :renamed, replacement: 'paused', milestone: '14.8' }
+ argument :associated_projects, [::Types::GlobalIDType[::Project]],
+ required: false,
+ description: 'Projects associated with the runner. Available only for project runners.',
+ prepare: ->(global_ids, _ctx) { global_ids&.filter_map { |gid| gid.model_id.to_i } }
+
field :runner,
Types::Ci::RunnerType,
null: true,
diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb
index b64e7e16433..09e41e0bfbf 100644
--- a/app/policies/global_policy.rb
+++ b/app/policies/global_policy.rb
@@ -121,11 +121,11 @@ class GlobalPolicy < BasePolicy
enable :approve_user
enable :reject_user
enable :read_usage_trends_measurement
- enable :create_instance_runners
+ enable :create_instance_runner
end
rule { ~create_runner_workflow_enabled }.policy do
- prevent :create_instance_runners
+ prevent :create_instance_runner
end
# We can't use `read_statistics` because the user may have different permissions for different projects
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 5d4f8478377..a285a8e361b 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -214,7 +214,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_group_runners
enable :admin_group_runners
enable :register_group_runners
- enable :create_group_runners
+ enable :create_runner
enable :set_note_created_at
enable :set_emails_disabled
@@ -325,7 +325,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
rule { ~admin & ~group_runner_registration_allowed }.policy do
prevent :register_group_runners
- prevent :create_group_runners
+ prevent :create_runner
end
rule { migration_bot }.policy do
@@ -342,7 +342,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
end
rule { ~create_runner_workflow_enabled }.policy do
- prevent :create_group_runners
+ prevent :create_runner
end
# Should be matched with ProjectPolicy#read_internal_note
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 95cdbd65055..5f743f3713e 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -535,7 +535,7 @@ class ProjectPolicy < BasePolicy
enable :destroy_freeze_period
enable :admin_feature_flags_client
enable :register_project_runners
- enable :create_project_runners
+ enable :create_runner
enable :admin_project_runners
enable :read_project_runners
enable :update_runners_registration_token
@@ -844,7 +844,7 @@ class ProjectPolicy < BasePolicy
rule { ~admin & ~project_runner_registration_allowed }.policy do
prevent :register_project_runners
- prevent :create_project_runners
+ prevent :create_runner
end
rule { can?(:admin_project_member) }.policy do
@@ -870,7 +870,7 @@ class ProjectPolicy < BasePolicy
end
rule { ~create_runner_workflow_enabled }.policy do
- prevent :create_project_runners
+ prevent :create_runner
end
# Should be matched with GroupPolicy#read_internal_note
diff --git a/app/services/ci/runners/create_runner_service.rb b/app/services/ci/runners/create_runner_service.rb
index 5906cdce99d..fcb664500a9 100644
--- a/app/services/ci/runners/create_runner_service.rb
+++ b/app/services/ci/runners/create_runner_service.rb
@@ -5,23 +5,25 @@ module Ci
class CreateRunnerService
RUNNER_CLASS_MAPPING = {
'instance_type' => Ci::Runners::RunnerCreationStrategies::InstanceRunnerStrategy,
- nil => Ci::Runners::RunnerCreationStrategies::InstanceRunnerStrategy
+ 'group_type' => Ci::Runners::RunnerCreationStrategies::GroupRunnerStrategy,
+ 'project_type' => Ci::Runners::RunnerCreationStrategies::ProjectRunnerStrategy
}.freeze
- attr_accessor :user, :type, :params, :strategy
-
- def initialize(user:, type:, params:)
+ def initialize(user:, params:)
@user = user
- @type = type
@params = params
- @strategy = RUNNER_CLASS_MAPPING[type].new(user: user, type: type, params: params)
+ @strategy = RUNNER_CLASS_MAPPING[params[:runner_type]].new(user: user, params: params)
end
def execute
normalize_params
- return ServiceResponse.error(message: 'Validation error') unless strategy.validate_params
- return ServiceResponse.error(message: 'Insufficient permissions') unless strategy.authorized_user?
+ error = strategy.validate_params
+ return ServiceResponse.error(message: error, reason: :validation_error) if error
+
+ unless strategy.authorized_user?
+ return ServiceResponse.error(message: _('Insufficient permissions'), reason: :forbidden)
+ end
runner = ::Ci::Runner.new(params)
@@ -32,12 +34,15 @@ module Ci
def normalize_params
params[:registration_type] = :authenticated_user
- params[:runner_type] = type
params[:active] = !params.delete(:paused) if params.key?(:paused)
params[:creator] = user
strategy.normalize_params
end
+
+ private
+
+ attr_reader :user, :params, :strategy
end
end
end
diff --git a/app/services/ci/runners/runner_creation_strategies/group_runner_strategy.rb b/app/services/ci/runners/runner_creation_strategies/group_runner_strategy.rb
new file mode 100644
index 00000000000..2eae5069046
--- /dev/null
+++ b/app/services/ci/runners/runner_creation_strategies/group_runner_strategy.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ module RunnerCreationStrategies
+ class GroupRunnerStrategy
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(user:, params:)
+ @user = user
+ @params = params
+ end
+
+ def normalize_params
+ params[:runner_type] = 'group_type'
+ params[:groups] = [scope]
+ end
+
+ def validate_params
+ _('Missing/invalid scope') unless scope.present?
+ end
+
+ def authorized_user?
+ user.present? && user.can?(:create_runner, scope)
+ end
+
+ private
+
+ attr_reader :user, :params
+
+ def scope
+ params.delete(:scope)
+ end
+ strong_memoize_attr :scope
+ end
+ end
+ end
+end
diff --git a/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb b/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb
index f195c3e88f9..39719ad806f 100644
--- a/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb
+++ b/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb
@@ -4,25 +4,26 @@ module Ci
module Runners
module RunnerCreationStrategies
class InstanceRunnerStrategy
- attr_accessor :user, :type, :params
-
- def initialize(user:, type:, params:)
+ def initialize(user:, params:)
@user = user
- @type = type
@params = params
end
def normalize_params
- params[:runner_type] = :instance_type
+ params[:runner_type] = 'instance_type'
end
def validate_params
- true
+ _('Unexpected scope') if params[:scope]
end
def authorized_user?
- user.present? && user.can?(:create_instance_runners)
+ user.present? && user.can?(:create_instance_runner)
end
+
+ private
+
+ attr_reader :user, :params
end
end
end
diff --git a/app/services/ci/runners/runner_creation_strategies/project_runner_strategy.rb b/app/services/ci/runners/runner_creation_strategies/project_runner_strategy.rb
new file mode 100644
index 00000000000..487da996513
--- /dev/null
+++ b/app/services/ci/runners/runner_creation_strategies/project_runner_strategy.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ module RunnerCreationStrategies
+ class ProjectRunnerStrategy
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(user:, params:)
+ @user = user
+ @params = params
+ end
+
+ def normalize_params
+ params[:runner_type] = 'project_type'
+ params[:projects] = [scope]
+ end
+
+ def validate_params
+ _('Missing/invalid scope') unless scope.present?
+ end
+
+ def authorized_user?
+ user.present? && user.can?(:create_runner, scope)
+ end
+
+ private
+
+ attr_reader :user, :params
+
+ def scope
+ params.delete(:scope)
+ end
+ strong_memoize_attr :scope
+ end
+ end
+ end
+end
diff --git a/config/feature_flags/development/reduce_sub_batch_size_on_timeouts.yml b/config/feature_flags/development/reduce_sub_batch_size_on_timeouts.yml
deleted file mode 100644
index 507fce9cfe5..00000000000
--- a/config/feature_flags/development/reduce_sub_batch_size_on_timeouts.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: reduce_sub_batch_size_on_timeouts
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109354
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/393556
-milestone: '15.10'
-type: development
-group: group::database
-default_enabled: false
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index e4b1162a21d..ee8d137aca5 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -327,6 +327,8 @@
- 1
- - merge_requests_handle_assignees_change
- 1
+- - merge_requests_llm_summarize_merge_request
+ - 1
- - merge_requests_resolve_todos
- 1
- - merge_requests_resolve_todos_after_approval
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 96ba07025ff..c97f920af3d 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -61,7 +61,7 @@ CI Catalog resources visible to the current user.
WARNING:
**Introduced** in 15.11.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`CiCatalogResourceConnection`](#cicatalogresourceconnection).
@@ -263,7 +263,7 @@ Find issues visible to the current user. At least one filter must be provided.
WARNING:
**Introduced** in 15.6.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`IssueConnection`](#issueconnection).
@@ -395,7 +395,7 @@ Find a note.
WARNING:
**Introduced** in 15.9.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`Note`](#note).
@@ -563,7 +563,7 @@ Find a synthetic note.
WARNING:
**Introduced** in 15.9.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`Note`](#note).
@@ -738,7 +738,7 @@ Find a work item.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`WorkItem`](#workitem).
@@ -771,7 +771,7 @@ mutation($id: NoteableID!, $body: String!) {
WARNING:
**Introduced** in 15.10.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `AchievementsAwardInput`
@@ -795,7 +795,7 @@ Input type: `AchievementsAwardInput`
WARNING:
**Introduced** in 15.8.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `AchievementsCreateInput`
@@ -821,7 +821,7 @@ Input type: `AchievementsCreateInput`
WARNING:
**Introduced** in 15.11.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `AchievementsDeleteInput`
@@ -844,7 +844,7 @@ Input type: `AchievementsDeleteInput`
WARNING:
**Introduced** in 15.10.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `AchievementsRevokeInput`
@@ -867,7 +867,7 @@ Input type: `AchievementsRevokeInput`
WARNING:
**Introduced** in 15.11.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `AchievementsUpdateInput`
@@ -950,7 +950,7 @@ Input type: `AdminSidekiqQueuesDeleteJobsInput`
WARNING:
**Introduced** in 15.11.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `AiActionInput`
@@ -1317,7 +1317,7 @@ Input type: `BoardListUpdateLimitMetricsInput`
WARNING:
**Introduced** in 15.10.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `BulkDestroyJobArtifactsInput`
@@ -1364,7 +1364,7 @@ Input type: `BulkEnableDevopsAdoptionNamespacesInput`
WARNING:
**Introduced** in 15.3.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `BulkRunnerDeleteInput`
@@ -1388,7 +1388,7 @@ Input type: `BulkRunnerDeleteInput`
WARNING:
**Introduced** in 15.11.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `CatalogResourcesCreateInput`
@@ -1844,7 +1844,7 @@ Input type: `CreateComplianceFrameworkInput`
WARNING:
**Introduced** in 13.6.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `CreateCustomEmojiInput`
@@ -2734,7 +2734,7 @@ Input type: `DestroyContainerRepositoryTagsInput`
WARNING:
**Introduced** in 13.6.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `DestroyCustomEmojiInput`
@@ -3853,7 +3853,7 @@ Allows updating several properties for a set of issues. Does nothing if the `bul
WARNING:
**Introduced** in 15.9.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `IssuesBulkUpdateInput`
@@ -4949,7 +4949,7 @@ Input type: `ProjectSetLockedInput`
WARNING:
**Introduced** in 15.9.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `ProjectSyncForkInput`
@@ -5233,7 +5233,7 @@ Input type: `RepositionImageDiffNoteInput`
WARNING:
**Introduced** in 15.10.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `RunnerCreateInput`
@@ -5242,14 +5242,16 @@ Input type: `RunnerCreateInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationrunnercreateaccesslevel"></a>`accessLevel` | [`CiRunnerAccessLevel`](#cirunneraccesslevel) | Access level of the runner. |
-| <a id="mutationrunnercreateassociatedprojects"></a>`associatedProjects` | [`[ProjectID!]`](#projectid) | Projects associated with the runner. Available only for project runners. |
| <a id="mutationrunnercreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationrunnercreatedescription"></a>`description` | [`String`](#string) | Description of the runner. |
+| <a id="mutationrunnercreategroupid"></a>`groupId` | [`GroupID`](#groupid) | Global ID of the group that the runner is created in (valid only for group runner). |
| <a id="mutationrunnercreatelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates the runner is locked. |
| <a id="mutationrunnercreatemaintenancenote"></a>`maintenanceNote` | [`String`](#string) | Runner's maintenance notes. |
| <a id="mutationrunnercreatemaximumtimeout"></a>`maximumTimeout` | [`Int`](#int) | Maximum timeout (in seconds) for jobs processed by the runner. |
| <a id="mutationrunnercreatepaused"></a>`paused` | [`Boolean`](#boolean) | Indicates the runner is not allowed to receive jobs. |
+| <a id="mutationrunnercreateprojectid"></a>`projectId` | [`ProjectID`](#projectid) | Global ID of the project that the runner is created in (valid only for project runner). |
| <a id="mutationrunnercreaterununtagged"></a>`runUntagged` | [`Boolean`](#boolean) | Indicates the runner is able to run untagged jobs. |
+| <a id="mutationrunnercreaterunnertype"></a>`runnerType` | [`CiRunnerType!`](#cirunnertype) | Type of the runner to create. |
| <a id="mutationrunnercreatetaglist"></a>`tagList` | [`[String!]`](#string) | Tags associated with the runner. |
#### Fields
@@ -5639,7 +5641,7 @@ Input type: `TerraformStateUnlockInput`
WARNING:
**Introduced** in 15.6.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `TimelineEventCreateInput`
@@ -6567,7 +6569,7 @@ Converts the work item to a new type.
WARNING:
**Introduced** in 15.11.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemConvertInput`
@@ -6593,7 +6595,7 @@ Creates a work item.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemCreateInput`
@@ -6626,7 +6628,7 @@ Creates a work item from a task in another work item's description.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemCreateFromTaskInput`
@@ -6653,7 +6655,7 @@ Deletes a work item.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemDeleteInput`
@@ -6678,7 +6680,7 @@ Deletes a task in a work item's description.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemDeleteTaskInput`
@@ -6703,7 +6705,7 @@ Input type: `WorkItemDeleteTaskInput`
WARNING:
**Introduced** in 15.10.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemExportInput`
@@ -6711,7 +6713,7 @@ Input type: `WorkItemExportInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="mutationworkitemexportauthorusername"></a>`authorUsername` **{warning-solid}** | [`String`](#string) | **Deprecated:** This feature is in Alpha. It can be changed or removed at any time. Introduced in 15.9. |
+| <a id="mutationworkitemexportauthorusername"></a>`authorUsername` **{warning-solid}** | [`String`](#string) | **Deprecated:** This feature is an Experiment. It can be changed or removed at any time. Introduced in 15.9. |
| <a id="mutationworkitemexportclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationworkitemexportiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of work items. For example, `["1", "2"]`. |
| <a id="mutationworkitemexportin"></a>`in` | [`[IssuableSearchableField!]`](#issuablesearchablefield) | Specify the fields to perform the search in. Defaults to `[TITLE, DESCRIPTION]`. Requires the `search` argument.'. |
@@ -6734,7 +6736,7 @@ Updates a work item by Global ID.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemUpdateInput`
@@ -6775,7 +6777,7 @@ Updates a work item's task by Global ID.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Input type: `WorkItemUpdateTaskInput`
@@ -11114,7 +11116,7 @@ Representation of a GitLab user.
| <a id="achievementname"></a>`name` | [`String!`](#string) | Name of the achievement. |
| <a id="achievementnamespace"></a>`namespace` | [`Namespace!`](#namespace) | Namespace of the achievement. |
| <a id="achievementupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp the achievement was last updated. |
-| <a id="achievementuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Recipients for the achievement. |
+| <a id="achievementuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Recipients for the achievement. |
### `AgentConfiguration`
@@ -11578,7 +11580,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="boardepicancestorsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
| <a id="boardepicancestorsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
| <a id="boardepicancestorsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
-| <a id="boardepicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
+| <a id="boardepicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
| <a id="boardepicancestorssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
| <a id="boardepicancestorssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
| <a id="boardepicancestorsstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
@@ -11617,7 +11619,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="boardepicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
| <a id="boardepicchildrenmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
| <a id="boardepicchildrennot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
-| <a id="boardepicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
+| <a id="boardepicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
| <a id="boardepicchildrensearch"></a>`search` | [`String`](#string) | Search query for title or description. |
| <a id="boardepicchildrensort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
| <a id="boardepicchildrenstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
@@ -11784,10 +11786,10 @@ Represents the total number of issues and their weights for a particular day.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="cicatalogresourcedescription"></a>`description` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.11. This feature is in Alpha. It can be changed or removed at any time. Description of the catalog resource. |
-| <a id="cicatalogresourceicon"></a>`icon` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.11. This feature is in Alpha. It can be changed or removed at any time. Icon for the catalog resource. |
-| <a id="cicatalogresourceid"></a>`id` **{warning-solid}** | [`ID!`](#id) | **Introduced** in 15.11. This feature is in Alpha. It can be changed or removed at any time. ID of the catalog resource. |
-| <a id="cicatalogresourcename"></a>`name` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.11. This feature is in Alpha. It can be changed or removed at any time. Name of the catalog resource. |
+| <a id="cicatalogresourcedescription"></a>`description` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.11. This feature is an Experiment. It can be changed or removed at any time. Description of the catalog resource. |
+| <a id="cicatalogresourceicon"></a>`icon` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.11. This feature is an Experiment. It can be changed or removed at any time. Icon for the catalog resource. |
+| <a id="cicatalogresourceid"></a>`id` **{warning-solid}** | [`ID!`](#id) | **Introduced** in 15.11. This feature is an Experiment. It can be changed or removed at any time. ID of the catalog resource. |
+| <a id="cicatalogresourcename"></a>`name` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.11. This feature is an Experiment. It can be changed or removed at any time. Name of the catalog resource. |
### `CiConfig`
@@ -11983,7 +11985,7 @@ CI/CD variables for a GitLab instance.
| <a id="cijobrefpath"></a>`refPath` | [`String`](#string) | Path to the ref. |
| <a id="cijobretried"></a>`retried` | [`Boolean`](#boolean) | Indicates that the job has been retried. |
| <a id="cijobretryable"></a>`retryable` | [`Boolean!`](#boolean) | Indicates the job can be retried. |
-| <a id="cijobrunnermanager"></a>`runnerManager` **{warning-solid}** | [`CiRunnerManager`](#cirunnermanager) | **Introduced** in 15.11. This feature is in Alpha. It can be changed or removed at any time. Runner manager assigned to the job. |
+| <a id="cijobrunnermanager"></a>`runnerManager` **{warning-solid}** | [`CiRunnerManager`](#cirunnermanager) | **Introduced** in 15.11. This feature is an Experiment. It can be changed or removed at any time. Runner manager assigned to the job. |
| <a id="cijobscheduled"></a>`scheduled` | [`Boolean!`](#boolean) | Indicates the job is scheduled. |
| <a id="cijobscheduledat"></a>`scheduledAt` | [`Time`](#time) | Schedule for the build. |
| <a id="cijobschedulingtype"></a>`schedulingType` | [`String`](#string) | Type of job scheduling. Value is `dag` if the job uses the `needs` keyword, and `stage` otherwise. |
@@ -12027,7 +12029,7 @@ CI/CD variables for a GitLab instance.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="cijobtracehtmlsummary"></a>`htmlSummary` **{warning-solid}** | [`String!`](#string) | **Introduced** in 15.11. This feature is in Alpha. It can be changed or removed at any time. HTML summary containing the last 10 lines of the trace. |
+| <a id="cijobtracehtmlsummary"></a>`htmlSummary` **{warning-solid}** | [`String!`](#string) | **Introduced** in 15.11. This feature is an Experiment. It can be changed or removed at any time. HTML summary containing the last 10 lines of the trace. |
### `CiJobsDurationStatistics`
@@ -12037,11 +12039,11 @@ Representation of duration statistics for a group of CI jobs.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="cijobsdurationstatisticsp50"></a>`p50` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. 50th percentile. 50% of the durations are lower than this value. |
-| <a id="cijobsdurationstatisticsp75"></a>`p75` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. 75th percentile. 75% of the durations are lower than this value. |
-| <a id="cijobsdurationstatisticsp90"></a>`p90` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. 90th percentile. 90% of the durations are lower than this value. |
-| <a id="cijobsdurationstatisticsp95"></a>`p95` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. 95th percentile. 95% of the durations are lower than this value. |
-| <a id="cijobsdurationstatisticsp99"></a>`p99` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. 99th percentile. 99% of the durations are lower than this value. |
+| <a id="cijobsdurationstatisticsp50"></a>`p50` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. 50th percentile. 50% of the durations are lower than this value. |
+| <a id="cijobsdurationstatisticsp75"></a>`p75` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. 75th percentile. 75% of the durations are lower than this value. |
+| <a id="cijobsdurationstatisticsp90"></a>`p90` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. 90th percentile. 90% of the durations are lower than this value. |
+| <a id="cijobsdurationstatisticsp95"></a>`p95` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. 95th percentile. 95% of the durations are lower than this value. |
+| <a id="cijobsdurationstatisticsp99"></a>`p99` **{warning-solid}** | [`Duration`](#duration) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. 99th percentile. 99% of the durations are lower than this value. |
### `CiJobsStatistics`
@@ -12051,7 +12053,7 @@ Statistics for a group of CI jobs.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="cijobsstatisticsqueuedduration"></a>`queuedDuration` **{warning-solid}** | [`CiJobsDurationStatistics`](#cijobsdurationstatistics) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. Statistics for amount of time that jobs were waiting to be picked up. The calculation is performed based on the most recent 100 jobs executed by the 5000 most recently created runners in context. If no filter is applied to runners, the calculation is performed based on the most recent 100 jobs globally. |
+| <a id="cijobsstatisticsqueuedduration"></a>`queuedDuration` **{warning-solid}** | [`CiJobsDurationStatistics`](#cijobsdurationstatistics) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. Statistics for amount of time that jobs were waiting to be picked up. The calculation is performed based on the most recent 100 jobs executed by the 5000 most recently created runners in context. If no filter is applied to runners, the calculation is performed based on the most recent 100 jobs globally. |
### `CiManualVariable`
@@ -12123,17 +12125,17 @@ CI/CD variables for a project.
| <a id="cirunnercreatedby"></a>`createdBy` | [`UserCore`](#usercore) | User that created this runner. |
| <a id="cirunnerdescription"></a>`description` | [`String`](#string) | Description of the runner. |
| <a id="cirunnereditadminurl"></a>`editAdminUrl` | [`String`](#string) | Admin form URL of the runner. Only available for administrators. |
-| <a id="cirunnerephemeralauthenticationtoken"></a>`ephemeralAuthenticationToken` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. Ephemeral authentication token used for runner manager registration. Only available for the creator of the runner for a limited time during registration. |
+| <a id="cirunnerephemeralauthenticationtoken"></a>`ephemeralAuthenticationToken` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. Ephemeral authentication token used for runner manager registration. Only available for the creator of the runner for a limited time during registration. |
| <a id="cirunnerexecutorname"></a>`executorName` | [`String`](#string) | Executor last advertised by the runner. |
| <a id="cirunnergroups"></a>`groups` | [`GroupConnection`](#groupconnection) | Groups the runner is associated with. For group runners only. (see [Connections](#connections)) |
| <a id="cirunnerid"></a>`id` | [`CiRunnerID!`](#cirunnerid) | ID of the runner. |
| <a id="cirunneripaddress"></a>`ipAddress` | [`String`](#string) | IP address of the runner. |
| <a id="cirunnerjobcount"></a>`jobCount` | [`Int`](#int) | Number of jobs processed by the runner (limited to 1000, plus one to indicate that more items exist). |
-| <a id="cirunnerjobexecutionstatus"></a>`jobExecutionStatus` **{warning-solid}** | [`CiRunnerJobExecutionStatus`](#cirunnerjobexecutionstatus) | **Introduced** in 15.7. This feature is in Alpha. It can be changed or removed at any time. Job execution status of the runner. |
+| <a id="cirunnerjobexecutionstatus"></a>`jobExecutionStatus` **{warning-solid}** | [`CiRunnerJobExecutionStatus`](#cirunnerjobexecutionstatus) | **Introduced** in 15.7. This feature is an Experiment. It can be changed or removed at any time. Job execution status of the runner. |
| <a id="cirunnerlocked"></a>`locked` | [`Boolean`](#boolean) | Indicates the runner is locked. |
| <a id="cirunnermaintenancenote"></a>`maintenanceNote` | [`String`](#string) | Runner's maintenance notes. |
| <a id="cirunnermaintenancenotehtml"></a>`maintenanceNoteHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of `maintenance_note`. |
-| <a id="cirunnermanagers"></a>`managers` **{warning-solid}** | [`CiRunnerManagerConnection`](#cirunnermanagerconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Machines associated with the runner configuration. |
+| <a id="cirunnermanagers"></a>`managers` **{warning-solid}** | [`CiRunnerManagerConnection`](#cirunnermanagerconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Machines associated with the runner configuration. |
| <a id="cirunnermaximumtimeout"></a>`maximumTimeout` | [`Int`](#int) | Maximum timeout (in seconds) for jobs processed by the runner. |
| <a id="cirunnerownerproject"></a>`ownerProject` | [`Project`](#project) | Project that owns the runner. For project runners only. |
| <a id="cirunnerpaused"></a>`paused` | [`Boolean!`](#boolean) | Indicates the runner is paused and not available to run jobs. |
@@ -12148,7 +12150,7 @@ CI/CD variables for a project.
| <a id="cirunnershortsha"></a>`shortSha` | [`String`](#string) | First eight characters of the runner's token used to authenticate new job requests. Used as the runner's unique ID. |
| <a id="cirunnertaglist"></a>`tagList` | [`[String!]`](#string) | Tags associated with the runner. |
| <a id="cirunnertokenexpiresat"></a>`tokenExpiresAt` | [`Time`](#time) | Runner token expiration time. |
-| <a id="cirunnerupgradestatus"></a>`upgradeStatus` **{warning-solid}** | [`CiRunnerUpgradeStatus`](#cirunnerupgradestatus) | **Introduced** in 14.10. This feature is in Alpha. It can be changed or removed at any time. Availability of upgrades for the runner. |
+| <a id="cirunnerupgradestatus"></a>`upgradeStatus` **{warning-solid}** | [`CiRunnerUpgradeStatus`](#cirunnerupgradestatus) | **Introduced** in 14.10. This feature is an Experiment. It can be changed or removed at any time. Availability of upgrades for the runner. |
| <a id="cirunneruserpermissions"></a>`userPermissions` | [`RunnerPermissions!`](#runnerpermissions) | Permissions for the current user on the resource. |
| <a id="cirunnerversion"></a>`version` | [`String`](#string) | Version of the runner. |
@@ -13760,7 +13762,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="epicancestorsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
| <a id="epicancestorsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
| <a id="epicancestorsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
-| <a id="epicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
+| <a id="epicancestorsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
| <a id="epicancestorssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
| <a id="epicancestorssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
| <a id="epicancestorsstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
@@ -13799,7 +13801,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="epicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
| <a id="epicchildrenmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
| <a id="epicchildrennot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
-| <a id="epicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
+| <a id="epicchildrenor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
| <a id="epicchildrensearch"></a>`search` | [`String`](#string) | Search query for title or description. |
| <a id="epicchildrensort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
| <a id="epicchildrenstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
@@ -14096,7 +14098,7 @@ Represents epic board list metadata.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="epiclistmetadataepicscount"></a>`epicsCount` | [`Int`](#int) | Count of epics in the list. |
-| <a id="epiclistmetadatatotalweight"></a>`totalWeight` **{warning-solid}** | [`Int`](#int) | **Introduced** in 14.7. This feature is in Alpha. It can be changed or removed at any time. Total weight of all issues in the list. |
+| <a id="epiclistmetadatatotalweight"></a>`totalWeight` **{warning-solid}** | [`Int`](#int) | **Introduced** in 14.7. This feature is an Experiment. It can be changed or removed at any time. Total weight of all issues in the list. |
### `EpicPermissions`
@@ -14290,7 +14292,7 @@ Find Dependency Proxy Blob registries on this Geo node.
WARNING:
**Introduced** in 15.6.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`DependencyProxyBlobRegistryConnection`](#dependencyproxyblobregistryconnection).
@@ -14465,7 +14467,7 @@ Find Project Wiki Repository registries on this Geo node. Ignored if `geo_projec
WARNING:
**Introduced** in 15.10.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`ProjectWikiRepositoryRegistryConnection`](#projectwikirepositoryregistryconnection).
@@ -14573,7 +14575,7 @@ GPG signature for a signed commit.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="groupachievements"></a>`achievements` **{warning-solid}** | [`AchievementConnection`](#achievementconnection) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. Achievements for the namespace. Returns `null` if the `achievements` feature flag is disabled. |
+| <a id="groupachievements"></a>`achievements` **{warning-solid}** | [`AchievementConnection`](#achievementconnection) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. Achievements for the namespace. Returns `null` if the `achievements` feature flag is disabled. |
| <a id="groupactualrepositorysizelimit"></a>`actualRepositorySizeLimit` | [`Float`](#float) | Size limit for repositories in the namespace in bytes. |
| <a id="groupadditionalpurchasedstoragesize"></a>`additionalPurchasedStorageSize` | [`Float`](#float) | Additional storage purchased for the root namespace in bytes. |
| <a id="groupallowstalerunnerpruning"></a>`allowStaleRunnerPruning` | [`Boolean!`](#boolean) | Indicates whether to regularly prune stale group runners. Defaults to false. |
@@ -14582,7 +14584,7 @@ GPG signature for a signed commit.
| <a id="groupcontainerrepositoriescount"></a>`containerRepositoriesCount` | [`Int!`](#int) | Number of container repositories in the group. |
| <a id="groupcontainslockedprojects"></a>`containsLockedProjects` | [`Boolean!`](#boolean) | Includes at least one project where the repository size exceeds the limit. |
| <a id="groupcrossprojectpipelineavailable"></a>`crossProjectPipelineAvailable` | [`Boolean!`](#boolean) | Indicates if the cross_project_pipeline feature is available for the namespace. |
-| <a id="groupcustomemoji"></a>`customEmoji` **{warning-solid}** | [`CustomEmojiConnection`](#customemojiconnection) | **Introduced** in 13.6. This feature is in Alpha. It can be changed or removed at any time. Custom emoji within this namespace. |
+| <a id="groupcustomemoji"></a>`customEmoji` **{warning-solid}** | [`CustomEmojiConnection`](#customemojiconnection) | **Introduced** in 13.6. This feature is an Experiment. It can be changed or removed at any time. Custom emoji within this namespace. |
| <a id="groupdependencyproxyblobcount"></a>`dependencyProxyBlobCount` | [`Int!`](#int) | Number of dependency proxy blobs cached in the group. |
| <a id="groupdependencyproxyblobs"></a>`dependencyProxyBlobs` | [`DependencyProxyBlobConnection`](#dependencyproxyblobconnection) | Dependency Proxy blobs. (see [Connections](#connections)) |
| <a id="groupdependencyproxyimagecount"></a>`dependencyProxyImageCount` | [`Int!`](#int) | Number of dependency proxy images cached in the group. |
@@ -14599,7 +14601,7 @@ GPG signature for a signed commit.
| <a id="groupepicboards"></a>`epicBoards` | [`EpicBoardConnection`](#epicboardconnection) | Find epic boards. (see [Connections](#connections)) |
| <a id="groupepicsenabled"></a>`epicsEnabled` | [`Boolean`](#boolean) | Indicates if Epics are enabled for namespace. |
| <a id="groupexternalauditeventdestinations"></a>`externalAuditEventDestinations` | [`ExternalAuditEventDestinationConnection`](#externalauditeventdestinationconnection) | External locations that receive audit events belonging to the group. (see [Connections](#connections)) |
-| <a id="groupflowmetrics"></a>`flowMetrics` **{warning-solid}** | [`GroupValueStreamAnalyticsFlowMetrics`](#groupvaluestreamanalyticsflowmetrics) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Flow metrics for value stream analytics. |
+| <a id="groupflowmetrics"></a>`flowMetrics` **{warning-solid}** | [`GroupValueStreamAnalyticsFlowMetrics`](#groupvaluestreamanalyticsflowmetrics) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Flow metrics for value stream analytics. |
| <a id="groupfullname"></a>`fullName` | [`String!`](#string) | Full name of the namespace. |
| <a id="groupfullpath"></a>`fullPath` | [`ID!`](#id) | Full path of the namespace. |
| <a id="groupid"></a>`id` | [`ID!`](#id) | ID of the namespace. |
@@ -14622,7 +14624,7 @@ GPG signature for a signed commit.
| <a id="groupstoragesizelimit"></a>`storageSizeLimit` | [`Float`](#float) | Total storage limit of the root namespace in bytes. |
| <a id="groupsubgroupcreationlevel"></a>`subgroupCreationLevel` | [`String`](#string) | Permission level required to create subgroups within the group. |
| <a id="grouptemporarystorageincreaseendson"></a>`temporaryStorageIncreaseEndsOn` | [`Time`](#time) | Date until the temporary storage increase is active. |
-| <a id="grouptimelogcategories"></a>`timelogCategories` **{warning-solid}** | [`TimeTrackingTimelogCategoryConnection`](#timetrackingtimelogcategoryconnection) | **Introduced** in 15.3. This feature is in Alpha. It can be changed or removed at any time. Timelog categories for the namespace. |
+| <a id="grouptimelogcategories"></a>`timelogCategories` **{warning-solid}** | [`TimeTrackingTimelogCategoryConnection`](#timetrackingtimelogcategoryconnection) | **Introduced** in 15.3. This feature is an Experiment. It can be changed or removed at any time. Timelog categories for the namespace. |
| <a id="grouptotalrepositorysize"></a>`totalRepositorySize` | [`Float`](#float) | Total repository size of all projects in the root namespace in bytes. |
| <a id="grouptotalrepositorysizeexcess"></a>`totalRepositorySizeExcess` | [`Float`](#float) | Total excess repository size of all projects in the root namespace in bytes. |
| <a id="grouptwofactorgraceperiod"></a>`twoFactorGracePeriod` | [`Int`](#int) | Time before two-factor authentication is enforced. |
@@ -14859,7 +14861,7 @@ Returns [`Epic`](#epic).
| <a id="groupepicmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
| <a id="groupepicmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
| <a id="groupepicnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
-| <a id="groupepicor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
+| <a id="groupepicor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
| <a id="groupepicsearch"></a>`search` | [`String`](#string) | Search query for title or description. |
| <a id="groupepicsort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
| <a id="groupepicstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
@@ -14910,7 +14912,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupepicsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
| <a id="groupepicsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. |
| <a id="groupepicsnot"></a>`not` | [`NegatedEpicFilterInput`](#negatedepicfilterinput) | Negated epic arguments. |
-| <a id="groupepicsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
+| <a id="groupepicsor"></a>`or` **{warning-solid}** | [`UnionedEpicFilterInput`](#unionedepicfilterinput) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. List of arguments with inclusive OR. Ignored unless `or_issuable_queries` flag is enabled. |
| <a id="groupepicssearch"></a>`search` | [`String`](#string) | Search query for title or description. |
| <a id="groupepicssort"></a>`sort` | [`EpicSort`](#epicsort) | List epics by sort order. |
| <a id="groupepicsstartdate"></a>`startDate` **{warning-solid}** | [`Time`](#time) | **Deprecated** in 13.5. Use timeframe.start. |
@@ -16297,7 +16299,7 @@ Defines which user roles, users, or groups can merge into a protected branch.
| <a id="mergerequestsquashonmerge"></a>`squashOnMerge` | [`Boolean!`](#boolean) | Indicates if the merge request will be squashed when merged. |
| <a id="mergerequeststate"></a>`state` | [`MergeRequestState!`](#mergerequeststate) | State of the merge request. |
| <a id="mergerequestsubscribed"></a>`subscribed` | [`Boolean!`](#boolean) | Indicates if the currently logged in user is subscribed to this merge request. |
-| <a id="mergerequestsuggestedreviewers"></a>`suggestedReviewers` **{warning-solid}** | [`SuggestedReviewersType`](#suggestedreviewerstype) | **Introduced** in 15.4. This feature is in Alpha. It can be changed or removed at any time. Suggested reviewers for merge request. Returns `null` if `suggested_reviewers` feature flag is disabled. This flag is disabled by default and only available on GitLab.com because the feature is experimental and is subject to change without notice. |
+| <a id="mergerequestsuggestedreviewers"></a>`suggestedReviewers` **{warning-solid}** | [`SuggestedReviewersType`](#suggestedreviewerstype) | **Introduced** in 15.4. This feature is an Experiment. It can be changed or removed at any time. Suggested reviewers for merge request. Returns `null` if `suggested_reviewers` feature flag is disabled. This flag is disabled by default and only available on GitLab.com because the feature is experimental and is subject to change without notice. |
| <a id="mergerequesttargetbranch"></a>`targetBranch` | [`String!`](#string) | Target branch of the merge request. |
| <a id="mergerequesttargetbranchexists"></a>`targetBranchExists` | [`Boolean!`](#boolean) | Indicates if the target branch of the merge request exists. |
| <a id="mergerequesttargetproject"></a>`targetProject` | [`Project!`](#project) | Target project of the merge request. |
@@ -16423,7 +16425,7 @@ A user assigned to a merge request.
| <a id="mergerequestassigneesavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. Will not return saved replies if `saved_replies` feature flag is disabled. (see [Connections](#connections)) |
| <a id="mergerequestassigneestate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="mergerequestassigneestatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
-| <a id="mergerequestassigneeuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
+| <a id="mergerequestassigneeuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
| <a id="mergerequestassigneeuserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
| <a id="mergerequestassigneeusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
| <a id="mergerequestassigneewebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
@@ -16673,7 +16675,7 @@ The author of the merge request.
| <a id="mergerequestauthorsavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. Will not return saved replies if `saved_replies` feature flag is disabled. (see [Connections](#connections)) |
| <a id="mergerequestauthorstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="mergerequestauthorstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
-| <a id="mergerequestauthoruserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
+| <a id="mergerequestauthoruserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
| <a id="mergerequestauthoruserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
| <a id="mergerequestauthorusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
| <a id="mergerequestauthorwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
@@ -16942,7 +16944,7 @@ A user participating in a merge request.
| <a id="mergerequestparticipantsavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. Will not return saved replies if `saved_replies` feature flag is disabled. (see [Connections](#connections)) |
| <a id="mergerequestparticipantstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="mergerequestparticipantstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
-| <a id="mergerequestparticipantuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
+| <a id="mergerequestparticipantuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
| <a id="mergerequestparticipantuserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
| <a id="mergerequestparticipantusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
| <a id="mergerequestparticipantwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
@@ -17211,7 +17213,7 @@ A user assigned to a merge request as a reviewer.
| <a id="mergerequestreviewersavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. Will not return saved replies if `saved_replies` feature flag is disabled. (see [Connections](#connections)) |
| <a id="mergerequestreviewerstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="mergerequestreviewerstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
-| <a id="mergerequestrevieweruserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
+| <a id="mergerequestrevieweruserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
| <a id="mergerequestrevieweruserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
| <a id="mergerequestreviewerusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
| <a id="mergerequestreviewerwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
@@ -17552,7 +17554,7 @@ Contains statistics about a milestone.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="namespaceachievements"></a>`achievements` **{warning-solid}** | [`AchievementConnection`](#achievementconnection) | **Introduced** in 15.8. This feature is in Alpha. It can be changed or removed at any time. Achievements for the namespace. Returns `null` if the `achievements` feature flag is disabled. |
+| <a id="namespaceachievements"></a>`achievements` **{warning-solid}** | [`AchievementConnection`](#achievementconnection) | **Introduced** in 15.8. This feature is an Experiment. It can be changed or removed at any time. Achievements for the namespace. Returns `null` if the `achievements` feature flag is disabled. |
| <a id="namespaceactualrepositorysizelimit"></a>`actualRepositorySizeLimit` | [`Float`](#float) | Size limit for repositories in the namespace in bytes. |
| <a id="namespaceadditionalpurchasedstoragesize"></a>`additionalPurchasedStorageSize` | [`Float`](#float) | Additional storage purchased for the root namespace in bytes. |
| <a id="namespacecontainslockedprojects"></a>`containsLockedProjects` | [`Boolean!`](#boolean) | Includes at least one project where the repository size exceeds the limit. |
@@ -17573,7 +17575,7 @@ Contains statistics about a milestone.
| <a id="namespacesharedrunnerssetting"></a>`sharedRunnersSetting` | [`SharedRunnersSetting`](#sharedrunnerssetting) | Shared runners availability for the namespace and its descendants. |
| <a id="namespacestoragesizelimit"></a>`storageSizeLimit` | [`Float`](#float) | Total storage limit of the root namespace in bytes. |
| <a id="namespacetemporarystorageincreaseendson"></a>`temporaryStorageIncreaseEndsOn` | [`Time`](#time) | Date until the temporary storage increase is active. |
-| <a id="namespacetimelogcategories"></a>`timelogCategories` **{warning-solid}** | [`TimeTrackingTimelogCategoryConnection`](#timetrackingtimelogcategoryconnection) | **Introduced** in 15.3. This feature is in Alpha. It can be changed or removed at any time. Timelog categories for the namespace. |
+| <a id="namespacetimelogcategories"></a>`timelogCategories` **{warning-solid}** | [`TimeTrackingTimelogCategoryConnection`](#timetrackingtimelogcategoryconnection) | **Introduced** in 15.3. This feature is an Experiment. It can be changed or removed at any time. 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. |
| <a id="namespacevisibility"></a>`visibility` | [`String`](#string) | Visibility of the namespace. |
@@ -18489,11 +18491,11 @@ Represents a product analytics dashboard visualization.
| <a id="projectcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of the project creation. |
| <a id="projectdastscannerprofiles"></a>`dastScannerProfiles` | [`DastScannerProfileConnection`](#dastscannerprofileconnection) | DAST scanner profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdastsiteprofiles"></a>`dastSiteProfiles` | [`DastSiteProfileConnection`](#dastsiteprofileconnection) | DAST Site Profiles associated with the project. (see [Connections](#connections)) |
-| <a id="projectdependencies"></a>`dependencies` **{warning-solid}** | [`DependencyConnection`](#dependencyconnection) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. Software dependencies used by the project. |
+| <a id="projectdependencies"></a>`dependencies` **{warning-solid}** | [`DependencyConnection`](#dependencyconnection) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. Software dependencies used by the project. |
| <a id="projectdescription"></a>`description` | [`String`](#string) | Short description of the project. |
| <a id="projectdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of `description`. |
| <a id="projectdora"></a>`dora` | [`Dora`](#dora) | Project's DORA metrics. |
-| <a id="projectflowmetrics"></a>`flowMetrics` **{warning-solid}** | [`ProjectValueStreamAnalyticsFlowMetrics`](#projectvaluestreamanalyticsflowmetrics) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Flow metrics for value stream analytics. |
+| <a id="projectflowmetrics"></a>`flowMetrics` **{warning-solid}** | [`ProjectValueStreamAnalyticsFlowMetrics`](#projectvaluestreamanalyticsflowmetrics) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Flow metrics for value stream analytics. |
| <a id="projectforkscount"></a>`forksCount` | [`Int!`](#int) | Number of times the project has been forked. |
| <a id="projectfullpath"></a>`fullPath` | [`ID!`](#id) | Full path of the project. |
| <a id="projectgrafanaintegration"></a>`grafanaIntegration` | [`GrafanaIntegration`](#grafanaintegration) | Grafana integration details for the project. |
@@ -18502,11 +18504,11 @@ Represents a product analytics dashboard visualization.
| <a id="projectid"></a>`id` | [`ID!`](#id) | ID of the project. |
| <a id="projectimportstatus"></a>`importStatus` | [`String`](#string) | Status of import background job of the project. |
| <a id="projectincidentmanagementtimelineeventtags"></a>`incidentManagementTimelineEventTags` | [`[TimelineEventTagType!]`](#timelineeventtagtype) | Timeline event tags for the project. |
-| <a id="projectiscatalogresource"></a>`isCatalogResource` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in 15.11. This feature is in Alpha. It can be changed or removed at any time. Indicates if a project is a catalog resource. |
+| <a id="projectiscatalogresource"></a>`isCatalogResource` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in 15.11. This feature is an Experiment. It can be changed or removed at any time. Indicates if a project is a catalog resource. |
| <a id="projectissuesenabled"></a>`issuesEnabled` | [`Boolean`](#boolean) | Indicates if Issues are enabled for the current user. |
| <a id="projectjiraimportstatus"></a>`jiraImportStatus` | [`String`](#string) | Status of Jira import background job of the project. |
| <a id="projectjiraimports"></a>`jiraImports` | [`JiraImportConnection`](#jiraimportconnection) | Jira imports into the project. (see [Connections](#connections)) |
-| <a id="projectjitsukey"></a>`jitsuKey` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.7. This feature is in Alpha. It can be changed or removed at any time. Jitsu key assigned to the project. |
+| <a id="projectjitsukey"></a>`jitsuKey` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.7. This feature is an Experiment. It can be changed or removed at any time. Jitsu key assigned to the project. |
| <a id="projectjobsenabled"></a>`jobsEnabled` | [`Boolean`](#boolean) | Indicates if CI/CD pipeline jobs are enabled for the current user. |
| <a id="projectlanguages"></a>`languages` | [`[RepositoryLanguage!]`](#repositorylanguage) | Programming languages used in the project. |
| <a id="projectlastactivityat"></a>`lastActivityAt` | [`Time`](#time) | Timestamp of the project last activity. |
@@ -18527,7 +18529,7 @@ Represents a product analytics dashboard visualization.
| <a id="projectpathlocks"></a>`pathLocks` | [`PathLockConnection`](#pathlockconnection) | The project's path locks. (see [Connections](#connections)) |
| <a id="projectpipelineanalytics"></a>`pipelineAnalytics` | [`PipelineAnalytics`](#pipelineanalytics) | Pipeline analytics. |
| <a id="projectprintingmergerequestlinkenabled"></a>`printingMergeRequestLinkEnabled` | [`Boolean`](#boolean) | Indicates if a link to create or view a merge request should display after a push to Git repositories of the project from the command line. |
-| <a id="projectproductanalyticsstate"></a>`productAnalyticsState` **{warning-solid}** | [`ProductAnalyticsState`](#productanalyticsstate) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Current state of the product analytics stack for this project.Can only be called for one project in a single request. |
+| <a id="projectproductanalyticsstate"></a>`productAnalyticsState` **{warning-solid}** | [`ProductAnalyticsState`](#productanalyticsstate) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Current state of the product analytics stack for this project.Can only be called for one project in a single request. |
| <a id="projectpublicjobs"></a>`publicJobs` | [`Boolean`](#boolean) | Indicates if there is public access to pipelines and job details of the project, including output logs and artifacts. |
| <a id="projectpushrules"></a>`pushRules` | [`PushRules`](#pushrules) | Project's push rules settings. |
| <a id="projectrecentissueboards"></a>`recentIssueBoards` | [`BoardConnection`](#boardconnection) | List of recently visited boards of the project. Maximum size is 4. (see [Connections](#connections)) |
@@ -18552,7 +18554,7 @@ Represents a product analytics dashboard visualization.
| <a id="projectsuggestioncommitmessage"></a>`suggestionCommitMessage` | [`String`](#string) | Commit message used to apply merge request suggestions. |
| <a id="projecttaglist"></a>`tagList` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.12. Use `topics`. |
| <a id="projectterraformstates"></a>`terraformStates` | [`TerraformStateConnection`](#terraformstateconnection) | Terraform states associated with the project. (see [Connections](#connections)) |
-| <a id="projecttimelogcategories"></a>`timelogCategories` **{warning-solid}** | [`TimeTrackingTimelogCategoryConnection`](#timetrackingtimelogcategoryconnection) | **Introduced** in 15.3. This feature is in Alpha. It can be changed or removed at any time. Timelog categories for the project. |
+| <a id="projecttimelogcategories"></a>`timelogCategories` **{warning-solid}** | [`TimeTrackingTimelogCategoryConnection`](#timetrackingtimelogcategoryconnection) | **Introduced** in 15.3. This feature is an Experiment. It can be changed or removed at any time. Timelog categories for the project. |
| <a id="projecttopics"></a>`topics` | [`[String!]`](#string) | List of project topics. |
| <a id="projectuserpermissions"></a>`userPermissions` | [`ProjectPermissions!`](#projectpermissions) | Permissions for the current user on the resource. |
| <a id="projectvisibility"></a>`visibility` | [`String`](#string) | Visibility of the project. |
@@ -18692,7 +18694,7 @@ CI/CD config variable.
WARNING:
**Introduced** in 15.3.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`[CiConfigVariable!]`](#ciconfigvariable).
@@ -18899,7 +18901,7 @@ Details of the fork project compared to its upstream project.
WARNING:
**Introduced** in 15.7.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`ForkDetails`](#forkdetails).
@@ -19462,7 +19464,7 @@ Product Analytics dashboards of the project.
WARNING:
**Introduced** in 15.6.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`ProductAnalyticsDashboardConnection`](#productanalyticsdashboardconnection).
@@ -19738,7 +19740,7 @@ Visible forks of the project.
WARNING:
**Introduced** in 15.10.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`ProjectConnection`](#projectconnection).
@@ -19839,7 +19841,7 @@ Work items of the project.
WARNING:
**Introduced** in 15.1.
-This feature is in Alpha. It can be changed or removed at any time.
+This feature is an Experiment. It can be changed or removed at any time.
Returns [`WorkItemConnection`](#workitemconnection).
@@ -19851,7 +19853,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="projectworkitemsauthorusername"></a>`authorUsername` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. Filter work items by author username. |
+| <a id="projectworkitemsauthorusername"></a>`authorUsername` **{warning-solid}** | [`String`](#string) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. Filter work items by author username. |
| <a id="projectworkitemsiid"></a>`iid` | [`String`](#string) | IID of the work item. For example, "1". |
| <a id="projectworkitemsiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of work items. For example, `["1", "2"]`. |
| <a id="projectworkitemsin"></a>`in` | [`[IssuableSearchableField!]`](#issuablesearchablefield) | Specify the fields to perform the search in. Defaults to `[TITLE, DESCRIPTION]`. Requires the `search` argument.'. |
@@ -21563,7 +21565,7 @@ Core represention of a GitLab user.
| <a id="usercoresavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. Will not return saved replies if `saved_replies` feature flag is disabled. (see [Connections](#connections)) |
| <a id="usercorestate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="usercorestatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
-| <a id="usercoreuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
+| <a id="usercoreuserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
| <a id="usercoreuserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
| <a id="usercoreusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
| <a id="usercorewebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
@@ -22489,7 +22491,7 @@ Represents vulnerability letter grades with associated projects.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="workitemauthor"></a>`author` **{warning-solid}** | [`UserCore`](#usercore) | **Introduced** in 15.9. This feature is in Alpha. It can be changed or removed at any time. User that created the work item. |
+| <a id="workitemauthor"></a>`author` **{warning-solid}** | [`UserCore`](#usercore) | **Introduced** in 15.9. This feature is an Experiment. It can be changed or removed at any time. User that created the work item. |
| <a id="workitemclosedat"></a>`closedAt` | [`Time`](#time) | Timestamp of when the work item was closed. |
| <a id="workitemconfidential"></a>`confidential` | [`Boolean!`](#boolean) | Indicates the work item is confidential. |
| <a id="workitemcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the work item was created. |
@@ -22498,8 +22500,8 @@ Represents vulnerability letter grades with associated projects.
| <a id="workitemid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
| <a id="workitemiid"></a>`iid` | [`ID!`](#id) | Internal ID of the work item. |
| <a id="workitemlockversion"></a>`lockVersion` | [`Int!`](#int) | Lock version of the work item. Incremented each time the work item is updated. |
-| <a id="workitemnamespace"></a>`namespace` **{warning-solid}** | [`Namespace`](#namespace) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Namespace the work item belongs to. |
-| <a id="workitemproject"></a>`project` **{warning-solid}** | [`Project`](#project) | **Introduced** in 15.3. This feature is in Alpha. It can be changed or removed at any time. Project the work item belongs to. |
+| <a id="workitemnamespace"></a>`namespace` **{warning-solid}** | [`Namespace`](#namespace) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Namespace the work item belongs to. |
+| <a id="workitemproject"></a>`project` **{warning-solid}** | [`Project`](#project) | **Introduced** in 15.3. This feature is an Experiment. It can be changed or removed at any time. Project the work item belongs to. |
| <a id="workitemstate"></a>`state` | [`WorkItemState!`](#workitemstate) | State of the work item. |
| <a id="workitemtitle"></a>`title` | [`String!`](#string) | Title of the work item. |
| <a id="workitemtitlehtml"></a>`titleHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of `title`. |
@@ -23079,8 +23081,8 @@ Direction of access.
| Value | Description |
| ----- | ----------- |
-| <a id="cirunnerjobexecutionstatusidle"></a>`IDLE` **{warning-solid}** | **Introduced** in 15.7. This feature is in Alpha. It can be changed or removed at any time. Runner is idle. |
-| <a id="cirunnerjobexecutionstatusrunning"></a>`RUNNING` **{warning-solid}** | **Introduced** in 15.7. This feature is in Alpha. It can be changed or removed at any time. Runner is executing jobs. |
+| <a id="cirunnerjobexecutionstatusidle"></a>`IDLE` **{warning-solid}** | **Introduced** in 15.7. This feature is an Experiment. It can be changed or removed at any time. Runner is idle. |
+| <a id="cirunnerjobexecutionstatusrunning"></a>`RUNNING` **{warning-solid}** | **Introduced** in 15.7. This feature is an Experiment. It can be changed or removed at any time. Runner is executing jobs. |
### `CiRunnerMembershipFilter`
@@ -23088,7 +23090,7 @@ Values for filtering runners in namespaces. The previous type name `RunnerMember
| Value | Description |
| ----- | ----------- |
-| <a id="cirunnermembershipfilterall_available"></a>`ALL_AVAILABLE` **{warning-solid}** | **Introduced** in 15.5. This feature is in Alpha. It can be changed or removed at any time. Include all runners. This list includes runners for all projects in the group and subgroups, as well as for the parent groups and instance. |
+| <a id="cirunnermembershipfilterall_available"></a>`ALL_AVAILABLE` **{warning-solid}** | **Introduced** in 15.5. This feature is an Experiment. It can be changed or removed at any time. Include all runners. This list includes runners for all projects in the group and subgroups, as well as for the parent groups and instance. |
| <a id="cirunnermembershipfilterdescendants"></a>`DESCENDANTS` | Include runners that have either a direct or inherited relationship. These runners can be specific to a project or a group. |
| <a id="cirunnermembershipfilterdirect"></a>`DIRECT` | Include runners that have a direct relationship. |
@@ -23888,10 +23890,10 @@ Issue type.
| ----- | ----------- |
| <a id="issuetypeincident"></a>`INCIDENT` | Incident issue type. |
| <a id="issuetypeissue"></a>`ISSUE` | Issue issue type. |
-| <a id="issuetypekey_result"></a>`KEY_RESULT` **{warning-solid}** | **Introduced** in 15.7. This feature is in Alpha. It can be changed or removed at any time. Key Result issue type. Available only when feature flag `okrs_mvc` is enabled. |
-| <a id="issuetypeobjective"></a>`OBJECTIVE` **{warning-solid}** | **Introduced** in 15.6. This feature is in Alpha. It can be changed or removed at any time. Objective issue type. Available only when feature flag `okrs_mvc` is enabled. |
+| <a id="issuetypekey_result"></a>`KEY_RESULT` **{warning-solid}** | **Introduced** in 15.7. This feature is an Experiment. It can be changed or removed at any time. Key Result issue type. Available only when feature flag `okrs_mvc` is enabled. |
+| <a id="issuetypeobjective"></a>`OBJECTIVE` **{warning-solid}** | **Introduced** in 15.6. This feature is an Experiment. It can be changed or removed at any time. Objective issue type. Available only when feature flag `okrs_mvc` is enabled. |
| <a id="issuetyperequirement"></a>`REQUIREMENT` | Requirement issue type. |
-| <a id="issuetypetask"></a>`TASK` **{warning-solid}** | **Introduced** in 15.2. This feature is in Alpha. It can be changed or removed at any time. Task issue type. |
+| <a id="issuetypetask"></a>`TASK` **{warning-solid}** | **Introduced** in 15.2. This feature is an Experiment. It can be changed or removed at any time. Task issue type. |
| <a id="issuetypetest_case"></a>`TEST_CASE` | Test Case issue type. |
### `IterationSearchableField`
@@ -26222,7 +26224,7 @@ Implementations:
| <a id="usersavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. Will not return saved replies if `saved_replies` feature flag is disabled. (see [Connections](#connections)) |
| <a id="userstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="userstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
-| <a id="useruserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is in Alpha. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
+| <a id="useruserachievements"></a>`userAchievements` **{warning-solid}** | [`UserAchievementConnection`](#userachievementconnection) | **Introduced** in 15.10. This feature is an Experiment. It can be changed or removed at any time. Achievements for the user. Only returns for namespaces where the `achievements` feature flag is enabled. |
| <a id="useruserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
| <a id="userusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
| <a id="userwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 16b3bf95bd7..35400b0d540 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -2223,6 +2223,9 @@ This endpoint:
projects within a group to be deleted after a delayed period. When enabled,
actual deletion happens after the number of days specified in the
[default deletion delay](../user/admin_area/settings/visibility_and_access_controls.md#deletion-protection).
+- From [GitLab 15.11](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) on
+ [Premium or higher](https://about.gitlab.com/pricing/) tiers, deletes a project immediately if the project is already
+ marked for deletion, and the `permanently_remove` and `full_path` parameters are passed.
WARNING:
The default behavior of [Delayed Project deletion](https://gitlab.com/gitlab-org/gitlab/-/issues/32935)
@@ -2233,9 +2236,11 @@ in GitLab 13.2, as discussed in [Enable delayed project deletion](../user/group/
DELETE /projects/:id
```
-| Attribute | Type | Required | Description |
-|-----------|----------------|------------------------|-------------|
-| `id` | integer or string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| Attribute | Type | Required | Description |
+|------------------------------------|-------------------|------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `permanently_remove` **(PREMIUM)** | boolean/string | no | Immediately deletes a project if it is marked for deletion. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) in GitLab 15.11 |
+| `full_path` **(PREMIUM)** | string | no | Full path of project to use with `permanently_remove`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/396500) in GitLab 15.11. To find the project path, use `path_with_namespace` from [get single project](projects.md#get-single-project) |
## Restore project marked for deletion **(PREMIUM)**
diff --git a/doc/user/group/compliance_frameworks.md b/doc/user/group/compliance_frameworks.md
index 9675fe411cd..69642833d8a 100644
--- a/doc/user/group/compliance_frameworks.md
+++ b/doc/user/group/compliance_frameworks.md
@@ -347,3 +347,53 @@ mutation {
}
}
```
+
+### Compliance jobs are overwritten by target repository
+
+If you use the `extends` statement in a compliance pipeline configuration, compliance jobs are overwritten by the target repository job. For example,
+you could have the following `.compliance-gitlab-ci.yml` configuration:
+
+```yaml
+"compliance job":
+ extends:
+ - .compliance_template
+ stage: build
+
+.compliance_template:
+ script:
+ - echo "take compliance action"
+```
+
+You could also have the following `.gitlab-ci.yml` configuration:
+
+```yaml
+"compliance job":
+ stage: test
+ script:
+ - echo "overwriting compliance action"
+```
+
+This configuration results in the target repository pipeline overwriting the compliance pipeline, and you get the following message:
+`overwriting compliance action`.
+
+To avoid overwriting a compliance job, don't use the `extends` keyword in compliance pipeline configuration. For example,
+you could have the following `.compliance-gitlab-ci.yml` configuration:
+
+```yaml
+"compliance job":
+ stage: build
+ script:
+ - echo "take compliance action"
+```
+
+You could also have the following `.gitlab-ci.yml` configuration:
+
+```yaml
+"compliance job":
+ stage: test
+ script:
+ - echo "overwriting compliance action"
+```
+
+This configuration doesn't overwrite the compliance pipeline and you get the following message:
+`take compliance action`.
diff --git a/lib/gitlab/database/background_migration/batched_job.rb b/lib/gitlab/database/background_migration/batched_job.rb
index 5147ea92291..523ab2a9f27 100644
--- a/lib/gitlab/database/background_migration/batched_job.rb
+++ b/lib/gitlab/database/background_migration/batched_job.rb
@@ -130,8 +130,6 @@ module Gitlab
end
def can_reduce_sub_batch_size?
- return false unless Feature.enabled?(:reduce_sub_batch_size_on_timeouts)
-
still_retryable? && within_batch_size_boundaries?
end
diff --git a/lib/gitlab/graphql/deprecations/deprecation.rb b/lib/gitlab/graphql/deprecations/deprecation.rb
index 7f4cea7c635..dfcca5ee75b 100644
--- a/lib/gitlab/graphql/deprecations/deprecation.rb
+++ b/lib/gitlab/graphql/deprecations/deprecation.rb
@@ -9,7 +9,7 @@ module Gitlab
REASONS = {
REASON_RENAMED => 'This was renamed.',
- REASON_ALPHA => 'This feature is in Alpha. It can be changed or removed at any time.'
+ REASON_ALPHA => 'This feature is an Experiment. It can be changed or removed at any time.'
}.freeze
include ActiveModel::Validations
@@ -27,7 +27,7 @@ module Gitlab
return unless options
if alpha
- raise ArgumentError, '`alpha` and `deprecated` arguments cannot be passed at the same time' \
+ raise ArgumentError, '`experiment` and `deprecated` arguments cannot be passed at the same time' \
if deprecated
options[:reason] = :alpha
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 935fbe0700f..72013a5caaf 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -28169,6 +28169,9 @@ msgstr ""
msgid "Missing commit signatures endpoint!"
msgstr ""
+msgid "Missing/invalid scope"
+msgstr ""
+
msgid "MissingSSHKeyWarningLink|Add SSH key"
msgstr ""
@@ -46859,6 +46862,9 @@ msgstr ""
msgid "Unexpected error"
msgstr ""
+msgid "Unexpected scope"
+msgstr ""
+
msgid "Unfollow"
msgstr ""
diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb
index 6248af98a78..759729f0abf 100644
--- a/qa/qa/page/project/import/github.rb
+++ b/qa/qa/page/project/import/github.rb
@@ -32,6 +32,8 @@ module QA
# In this case skip this step and proceed to import project row
return unless has_element?(:personal_access_token_field)
+ raise ArgumentError, "No personal access token was provided" if personal_access_token.empty?
+
fill_element(:personal_access_token_field, personal_access_token)
click_element(:authenticate_button)
finished_loading?
diff --git a/spec/frontend/ci/runner/components/runner_create_form_spec.js b/spec/frontend/ci/runner/components/runner_create_form_spec.js
index 052b9d209c1..45d1f79cb68 100644
--- a/spec/frontend/ci/runner/components/runner_create_form_spec.js
+++ b/spec/frontend/ci/runner/components/runner_create_form_spec.js
@@ -6,7 +6,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import RunnerCreateForm from '~/ci/runner/components/runner_create_form.vue';
import RunnerFormFields from '~/ci/runner/components/runner_form_fields.vue';
-import { DEFAULT_ACCESS_LEVEL } from '~/ci/runner/constants';
+import { DEFAULT_ACCESS_LEVEL, INSTANCE_TYPE } from '~/ci/runner/constants';
import runnerCreateMutation from '~/ci/runner/graphql/new/runner_create.mutation.graphql';
import { captureException } from '~/ci/runner/sentry_utils';
import { runnerCreateResult } from '../mock_data';
@@ -16,6 +16,7 @@ jest.mock('~/ci/runner/sentry_utils');
const mockCreatedRunner = runnerCreateResult.data.runnerCreate.runner;
const defaultRunnerModel = {
+ runnerType: INSTANCE_TYPE,
description: '',
accessLevel: DEFAULT_ACCESS_LEVEL,
paused: false,
diff --git a/spec/frontend/fixtures/runner.rb b/spec/frontend/fixtures/runner.rb
index 1581bc58289..dae210d990d 100644
--- a/spec/frontend/fixtures/runner.rb
+++ b/spec/frontend/fixtures/runner.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Runner (JavaScript fixtures)' do
+RSpec.describe 'Runner (JavaScript fixtures)', feature_category: :runner_fleet do
include AdminModeHelper
include ApiHelpers
include JavaScriptFixturesHelpers
@@ -169,14 +169,17 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
get_graphql_query_as_string("#{query_path}#{runner_create_mutation}")
end
- it "#{fixtures_path}#{runner_create_mutation}.json" do
- post_graphql(query, current_user: admin, variables: {
- input: {
- description: 'My dummy runner'
- }
- })
+ context 'with runnerType set to INSTANCE_TYPE' do
+ it "#{fixtures_path}#{runner_create_mutation}.json" do
+ post_graphql(query, current_user: admin, variables: {
+ input: {
+ runnerType: 'INSTANCE_TYPE',
+ description: 'My dummy runner'
+ }
+ })
- expect_graphql_errors_to_be_empty
+ expect_graphql_errors_to_be_empty
+ end
end
end
end
diff --git a/spec/frontend/members/components/table/role_dropdown_spec.js b/spec/frontend/members/components/table/role_dropdown_spec.js
index d6e63b1930f..1045e3f9849 100644
--- a/spec/frontend/members/components/table/role_dropdown_spec.js
+++ b/spec/frontend/members/components/table/role_dropdown_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
+import * as Sentry from '@sentry/browser';
import { within } from '@testing-library/dom';
import { mount, createWrapper } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
@@ -12,6 +13,7 @@ import { member } from '../../mock_data';
Vue.use(Vuex);
jest.mock('ee_else_ce/members/guest_overage_confirm_action');
+jest.mock('@sentry/browser');
describe('RoleDropdown', () => {
let wrapper;
@@ -20,9 +22,9 @@ describe('RoleDropdown', () => {
show: jest.fn(),
};
- const createStore = () => {
+ const createStore = ({ updateMemberRoleReturn = Promise.resolve() } = {}) => {
actions = {
- updateMemberRole: jest.fn(() => Promise.resolve()),
+ updateMemberRole: jest.fn(() => updateMemberRoleReturn),
};
return new Vuex.Store({
@@ -32,7 +34,7 @@ describe('RoleDropdown', () => {
});
};
- const createComponent = (propsData = {}) => {
+ const createComponent = (propsData = {}, store = createStore()) => {
wrapper = mount(RoleDropdown, {
provide: {
namespace: MEMBER_TYPES.user,
@@ -46,7 +48,7 @@ describe('RoleDropdown', () => {
permissions: {},
...propsData,
},
- store: createStore(),
+ store,
mocks: {
$toast,
},
@@ -75,11 +77,11 @@ describe('RoleDropdown', () => {
});
describe('when dropdown is open', () => {
- beforeEach(() => {
+ beforeEach(async () => {
guestOverageConfirmAction.mockReturnValue(true);
createComponent();
- return findDropdownToggle().trigger('click');
+ await findDropdownToggle().trigger('click');
});
it('renders all valid roles', () => {
@@ -113,26 +115,74 @@ describe('RoleDropdown', () => {
});
});
- it('displays toast when successful', async () => {
- await getDropdownItemByText('Developer').trigger('click');
+ describe('when updateMemberRole is successful', () => {
+ it('displays toast', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
- await nextTick();
+ await nextTick();
- expect($toast.show).toHaveBeenCalledWith('Role updated successfully.');
- });
+ expect($toast.show).toHaveBeenCalledWith('Role updated successfully.');
+ });
- it('puts dropdown in loading state while waiting for `updateMemberRole` to resolve', async () => {
- await getDropdownItemByText('Developer').trigger('click');
+ it('puts dropdown in loading state while waiting for `updateMemberRole` to resolve', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
+
+ expect(findDropdown().props('loading')).toBe(true);
+ });
+
+ it('enables dropdown after `updateMemberRole` resolves', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
- expect(findDropdown().props('loading')).toBe(true);
+ await waitForPromises();
+
+ expect(findDropdown().props('disabled')).toBe(false);
+ });
+
+ it('does not log error to Sentry', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
+
+ await waitForPromises();
+
+ expect(Sentry.captureException).not.toHaveBeenCalled();
+ });
});
- it('enables dropdown after `updateMemberRole` resolves', async () => {
- await getDropdownItemByText('Developer').trigger('click');
+ describe('when updateMemberRole is not successful', () => {
+ const reason = 'Rejected ☹️';
- await waitForPromises();
+ beforeEach(() => {
+ createComponent({}, createStore({ updateMemberRoleReturn: Promise.reject(reason) }));
+ });
+
+ it('does not display toast', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
+
+ await nextTick();
+
+ expect($toast.show).not.toHaveBeenCalled();
+ });
+
+ it('puts dropdown in loading state while waiting for `updateMemberRole` to resolve', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
+
+ expect(findDropdown().props('loading')).toBe(true);
+ });
- expect(findDropdown().props('disabled')).toBe(false);
+ it('enables dropdown after `updateMemberRole` resolves', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
+
+ await waitForPromises();
+
+ expect(findDropdown().props('disabled')).toBe(false);
+ });
+
+ it('logs error to Sentry', async () => {
+ await getDropdownItemByText('Developer').trigger('click');
+
+ await waitForPromises();
+
+ expect(Sentry.captureException).toHaveBeenCalledWith(reason);
+ });
});
});
});
diff --git a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb
index 073a30e7839..d9b81a2be30 100644
--- a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb
@@ -378,41 +378,27 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d
let(:attempts) { 0 }
let(:batch_size) { 10 }
let(:sub_batch_size) { 6 }
- let(:feature_flag) { :reduce_sub_batch_size_on_timeouts }
let(:job) do
create(:batched_background_migration_job, attempts: attempts,
batch_size: batch_size, sub_batch_size: sub_batch_size)
end
- where(:feature_flag_state, :within_boundaries, :outside_boundaries, :limit_reached) do
- [
- [true, true, false, false],
- [false, false, false, false]
- ]
- end
-
- with_them do
- before do
- stub_feature_flags(feature_flag => feature_flag_state)
- end
+ context 'when the number of attempts is lower than the limit and batch size are within boundaries' do
+ let(:attempts) { 1 }
- context 'when the number of attempts is lower than the limit and batch size are within boundaries' do
- let(:attempts) { 1 }
-
- it { expect(job.can_reduce_sub_batch_size?).to be(within_boundaries) }
- end
+ it { expect(job.can_reduce_sub_batch_size?).to be(true) }
+ end
- context 'when the number of attempts is lower than the limit and batch size are outside boundaries' do
- let(:batch_size) { 1 }
+ context 'when the number of attempts is lower than the limit and batch size are outside boundaries' do
+ let(:batch_size) { 1 }
- it { expect(job.can_reduce_sub_batch_size?).to be(outside_boundaries) }
- end
+ it { expect(job.can_reduce_sub_batch_size?).to be(false) }
+ end
- context 'when the number of attempts is greater than the limit and batch size are within boundaries' do
- let(:attempts) { 3 }
+ context 'when the number of attempts is greater than the limit and batch size are within boundaries' do
+ let(:attempts) { 3 }
- it { expect(job.can_reduce_sub_batch_size?).to be(limit_reached) }
- end
+ it { expect(job.can_reduce_sub_batch_size?).to be(false) }
end
end
diff --git a/spec/lib/gitlab/graphql/deprecations/deprecation_spec.rb b/spec/lib/gitlab/graphql/deprecations/deprecation_spec.rb
index 55650b0480e..172872fd7eb 100644
--- a/spec/lib/gitlab/graphql/deprecations/deprecation_spec.rb
+++ b/spec/lib/gitlab/graphql/deprecations/deprecation_spec.rb
@@ -55,7 +55,7 @@ RSpec.describe ::Gitlab::Graphql::Deprecations::Deprecation, feature_category: :
it 'raises an error' do
expect { parsed_deprecation }.to raise_error(ArgumentError,
- '`alpha` and `deprecated` arguments cannot be passed at the same time'
+ '`experiment` and `deprecated` arguments cannot be passed at the same time'
)
end
end
diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb
index 3d6d95bb122..2949320c571 100644
--- a/spec/policies/global_policy_spec.rb
+++ b/spec/policies/global_policy_spec.rb
@@ -626,47 +626,47 @@ RSpec.describe GlobalPolicy, feature_category: :shared do
end
end
- describe 'create_instance_runners' do
+ describe 'create_instance_runner' do
context 'admin' do
let(:current_user) { admin_user }
context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_allowed(:create_instance_runners) }
+ it { is_expected.to be_allowed(:create_instance_runner) }
end
context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
end
context 'with project_bot' do
let(:current_user) { project_bot }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with migration_bot' do
let(:current_user) { migration_bot }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with security_bot' do
let(:current_user) { security_bot }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with regular user' do
let(:current_user) { user }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with anonymous' do
let(:current_user) { nil }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'create_runner_workflow_for_admin flag disabled' do
@@ -678,42 +678,42 @@ RSpec.describe GlobalPolicy, feature_category: :shared do
let(:current_user) { admin_user }
context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
end
context 'with project_bot' do
let(:current_user) { project_bot }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with migration_bot' do
let(:current_user) { migration_bot }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with security_bot' do
let(:current_user) { security_bot }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with regular user' do
let(:current_user) { user }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
context 'with anonymous' do
let(:current_user) { nil }
- it { is_expected.to be_disallowed(:create_instance_runners) }
+ it { is_expected.to be_disallowed(:create_instance_runner) }
end
end
end
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 1103ea4eaad..bd1e90b839c 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -1272,7 +1272,7 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
end
end
- describe 'create_group_runners' do
+ describe 'create_runner' do
shared_examples 'disallowed when group runner registration disabled' do
context 'with group runner registration disabled' do
before do
@@ -1283,13 +1283,13 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
context 'with specific group runner registration enabled' do
let(:runner_registration_enabled) { true }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with specific group runner registration disabled' do
let(:runner_registration_enabled) { false }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
end
@@ -1303,14 +1303,14 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_allowed(:create_group_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
context 'with specific group runner registration disabled' do
before do
group.runner_registration_enabled = false
end
- it { is_expected.to be_allowed(:create_group_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
context 'with group runner registration disabled' do
@@ -1322,26 +1322,26 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
context 'with specific group runner registration enabled' do
let(:runner_registration_enabled) { true }
- it { is_expected.to be_allowed(:create_group_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
context 'with specific group runner registration disabled' do
let(:runner_registration_enabled) { false }
- it { is_expected.to be_allowed(:create_group_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
end
end
context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'with owner' do
let(:current_user) { owner }
- it { is_expected.to be_allowed(:create_group_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
it_behaves_like 'disallowed when group runner registration disabled'
end
@@ -1349,31 +1349,31 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
context 'with maintainer' do
let(:current_user) { maintainer }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with reporter' do
let(:current_user) { reporter }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with guest' do
let(:current_user) { guest }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with developer' do
let(:current_user) { developer }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with anonymous' do
let(:current_user) { nil }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
@@ -1388,28 +1388,28 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
context 'with specific group runner registration disabled' do
before do
group.runner_registration_enabled = false
end
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
it_behaves_like 'disallowed when group runner registration disabled'
end
context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'with owner' do
let(:current_user) { owner }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
it_behaves_like 'disallowed when group runner registration disabled'
end
@@ -1417,31 +1417,31 @@ RSpec.describe GroupPolicy, feature_category: :system_access do
context 'with maintainer' do
let(:current_user) { maintainer }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with reporter' do
let(:current_user) { reporter }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with guest' do
let(:current_user) { guest }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with developer' do
let(:current_user) { developer }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with anonymous' do
let(:current_user) { nil }
- it { is_expected.to be_disallowed(:create_group_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index cc1029358ae..0ebe997f16f 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -2862,7 +2862,7 @@ RSpec.describe ProjectPolicy, feature_category: :system_access do
end
end
- describe 'create_project_runners' do
+ describe 'create_runner' do
context 'create_runner_workflow_for_namespace flag enabled' do
before do
stub_feature_flags(create_runner_workflow_for_namespace: [project.namespace])
@@ -2872,64 +2872,64 @@ RSpec.describe ProjectPolicy, feature_category: :system_access do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_allowed(:create_project_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
context 'with project runner registration disabled' do
before do
stub_application_setting(valid_runner_registrars: ['group'])
end
- it { is_expected.to be_allowed(:create_project_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
end
context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'with owner' do
let(:current_user) { owner }
- it { is_expected.to be_allowed(:create_project_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
context 'with project runner registration disabled' do
before do
stub_application_setting(valid_runner_registrars: ['group'])
end
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'with maintainer' do
let(:current_user) { maintainer }
- it { is_expected.to be_allowed(:create_project_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
context 'with reporter' do
let(:current_user) { reporter }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with guest' do
let(:current_user) { guest }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with developer' do
let(:current_user) { developer }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with anonymous' do
let(:current_user) { nil }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
@@ -2942,64 +2942,64 @@ RSpec.describe ProjectPolicy, feature_category: :system_access do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
context 'with project runner registration disabled' do
before do
stub_application_setting(valid_runner_registrars: ['group'])
end
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'with owner' do
let(:current_user) { owner }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
context 'with project runner registration disabled' do
before do
stub_application_setting(valid_runner_registrars: ['group'])
end
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'with maintainer' do
let(:current_user) { maintainer }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with reporter' do
let(:current_user) { reporter }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with guest' do
let(:current_user) { guest }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with developer' do
let(:current_user) { developer }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with anonymous' do
let(:current_user) { nil }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
end
@@ -3009,48 +3009,48 @@ RSpec.describe ProjectPolicy, feature_category: :system_access do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_allowed(:create_project_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
context 'with owner' do
let(:current_user) { owner }
- it { is_expected.to be_allowed(:create_project_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
context 'with maintainer' do
let(:current_user) { maintainer }
- it { is_expected.to be_allowed(:create_project_runners) }
+ it { is_expected.to be_allowed(:create_runner) }
end
context 'with reporter' do
let(:current_user) { reporter }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with guest' do
let(:current_user) { guest }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with developer' do
let(:current_user) { developer }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
context 'with anonymous' do
let(:current_user) { nil }
- it { is_expected.to be_disallowed(:create_project_runners) }
+ it { is_expected.to be_disallowed(:create_runner) }
end
end
diff --git a/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb b/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb
index f39f6f84c99..f592a2a3fe3 100644
--- a/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/runner/create_spec.rb
@@ -6,8 +6,12 @@ RSpec.describe 'RunnerCreate', feature_category: :runner_fleet do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
+ let_it_be(:group_owner) { create(:user) }
let_it_be(:admin) { create(:admin) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:other_group) { create(:group) }
+
let(:mutation_params) do
{
description: 'create description',
@@ -17,7 +21,7 @@ RSpec.describe 'RunnerCreate', feature_category: :runner_fleet do
paused: true,
run_untagged: false,
tag_list: %w[tag1 tag2]
- }
+ }.deep_merge(mutation_scope_params)
end
let(:mutation) do
@@ -49,72 +53,263 @@ RSpec.describe 'RunnerCreate', feature_category: :runner_fleet do
let(:mutation_response) { graphql_mutation_response(:runner_create) }
- context 'when user does not have permissions' do
+ before do
+ group.add_owner(group_owner)
+ end
+
+ shared_context 'when model is invalid returns error' do
+ let(:mutation_params) do
+ {
+ description: '',
+ maintenanceNote: '',
+ paused: true,
+ accessLevel: 'NOT_PROTECTED',
+ runUntagged: false,
+ tagList: [],
+ maximumTimeout: 1
+ }.deep_merge(mutation_scope_params)
+ end
+
+ it do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+
+ expect(mutation_response['errors']).to contain_exactly(
+ 'Tags list can not be empty when runner is not allowed to pick untagged jobs',
+ 'Maximum timeout needs to be at least 10 minutes'
+ )
+ end
+ end
+
+ shared_context 'when user does not have permissions' do
let(:current_user) { user }
it 'returns an error' do
post_graphql_mutation(mutation, current_user: current_user)
- expect(mutation_response['errors']).to contain_exactly "Insufficient permissions"
+ expect_graphql_errors_to_include(
+ 'The resource that you are attempting to access does not exist ' \
+ "or you don't have permission to perform this action"
+ )
end
end
- context 'when user has permissions', :enable_admin_mode do
- let(:current_user) { admin }
+ shared_context 'when :create_runner_workflow_for_namespace feature flag is disabled' do
+ before do
+ stub_feature_flags(create_runner_workflow_for_namespace: [other_group])
+ end
- context 'when :create_runner_workflow_for_admin feature flag is disabled' do
- before do
- stub_feature_flags(create_runner_workflow_for_admin: false)
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include('`create_runner_workflow_for_namespace` feature flag is disabled.')
+ end
+ end
+
+ shared_context 'when runner is created successfully' do
+ before do
+ stub_feature_flags(create_runner_workflow_for_namespace: [group])
+ end
+
+ it do
+ expected_args = { user: current_user, params: anything }
+ expect_next_instance_of(::Ci::Runners::CreateRunnerService, expected_args) do |service|
+ expect(service).to receive(:execute).and_call_original
end
- it 'returns an error' do
- post_graphql_mutation(mutation, current_user: current_user)
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
- expect(graphql_errors).not_to be_empty
- expect(graphql_errors[0]['message'])
- .to eq("`create_runner_workflow_for_admin` feature flag is disabled.")
+ expect(mutation_response['errors']).to eq([])
+ expect(mutation_response['runner']).not_to be_nil
+ mutation_params.except(:group_id, :project_id).each_key do |key|
+ expect(mutation_response['runner'][key.to_s.camelize(:lower)]).to eq mutation_params[key]
end
+
+ expect(mutation_response['runner']['ephemeralAuthenticationToken'])
+ .to start_with Ci::Runner::CREATED_RUNNER_TOKEN_PREFIX
+ end
+ end
+
+ context 'when runnerType is INSTANCE_TYPE' do
+ let(:mutation_scope_params) do
+ { runner_type: 'INSTANCE_TYPE' }
end
- context 'when success' do
- it do
- post_graphql_mutation(mutation, current_user: current_user)
+ it_behaves_like 'when user does not have permissions'
- expect(response).to have_gitlab_http_status(:success)
+ context 'when user has permissions', :enable_admin_mode do
+ let(:current_user) { admin }
- mutation_params.each_key do |key|
- expect(mutation_response['runner'][key.to_s.camelize(:lower)]).to eq mutation_params[key]
+ context 'when :create_runner_workflow_for_admin feature flag is disabled' do
+ before do
+ stub_feature_flags(create_runner_workflow_for_admin: false)
end
- expect(mutation_response['runner']['ephemeralAuthenticationToken']).to start_with 'glrt'
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
- expect(mutation_response['errors']).to eq([])
+ expect_graphql_errors_to_include('`create_runner_workflow_for_admin` feature flag is disabled.')
+ end
end
+
+ it_behaves_like 'when runner is created successfully'
+ it_behaves_like 'when model is invalid returns error'
end
+ end
- context 'when failure' do
- let(:mutation_params) do
- {
- description: "",
- maintenanceNote: "",
- paused: true,
- accessLevel: "NOT_PROTECTED",
- runUntagged: false,
- tagList:
- [],
- maximumTimeout: 1
- }
+ context 'when runnerType is GROUP_TYPE' do
+ let(:mutation_scope_params) do
+ {
+ runner_type: 'GROUP_TYPE',
+ group_id: group.to_global_id
+ }
+ end
+
+ it_behaves_like 'when user does not have permissions'
+
+ context 'when user has permissions' do
+ context 'when user is group owner' do
+ let(:current_user) { group_owner }
+
+ it_behaves_like 'when :create_runner_workflow_for_namespace feature flag is disabled'
+ it_behaves_like 'when runner is created successfully'
+ it_behaves_like 'when model is invalid returns error'
+
+ context 'when group_id is missing' do
+ let(:mutation_scope_params) do
+ { runner_type: 'GROUP_TYPE' }
+ end
+
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include('`group_id` is missing')
+ end
+ end
+
+ context 'when group_id is malformed' do
+ let(:mutation_scope_params) do
+ {
+ runner_type: 'GROUP_TYPE',
+ group_id: ''
+ }
+ end
+
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(
+ "RunnerCreateInput! was provided invalid value for groupId"
+ )
+ end
+ end
+
+ context 'when group_id does not exist' do
+ let(:mutation_scope_params) do
+ {
+ runner_type: 'GROUP_TYPE',
+ group_id: "gid://gitlab/Group/#{non_existing_record_id}"
+ }
+ end
+
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(
+ 'The resource that you are attempting to access does not exist ' \
+ "or you don't have permission to perform this action"
+ )
+ end
+ end
end
- it do
- post_graphql_mutation(mutation, current_user: current_user)
+ context 'when user is admin in admin mode', :enable_admin_mode do
+ let(:current_user) { admin }
+
+ it_behaves_like 'when :create_runner_workflow_for_namespace feature flag is disabled'
+ it_behaves_like 'when runner is created successfully'
+ it_behaves_like 'when model is invalid returns error'
+ end
+ end
+ end
+
+ context 'when runnerType is PROJECT_TYPE' do
+ let_it_be(:project) { create(:project, namespace: group) }
+
+ let(:mutation_scope_params) do
+ {
+ runner_type: 'PROJECT_TYPE',
+ project_id: project.to_global_id
+ }
+ end
+
+ it_behaves_like 'when user does not have permissions'
+
+ context 'when user has permissions' do
+ context 'when user is group owner' do
+ let(:current_user) { group_owner }
+
+ it_behaves_like 'when :create_runner_workflow_for_namespace feature flag is disabled'
+ it_behaves_like 'when runner is created successfully'
+ it_behaves_like 'when model is invalid returns error'
+
+ context 'when project_id is missing' do
+ let(:mutation_scope_params) do
+ { runner_type: 'PROJECT_TYPE' }
+ end
+
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include('`project_id` is missing')
+ end
+ end
+
+ context 'when project_id is malformed' do
+ let(:mutation_scope_params) do
+ {
+ runner_type: 'PROJECT_TYPE',
+ project_id: ''
+ }
+ end
+
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(
+ "RunnerCreateInput! was provided invalid value for projectId"
+ )
+ end
+ end
+
+ context 'when project_id does not exist' do
+ let(:mutation_scope_params) do
+ {
+ runner_type: 'PROJECT_TYPE',
+ project_id: "gid://gitlab/Project/#{non_existing_record_id}"
+ }
+ end
+
+ it 'returns an error' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect_graphql_errors_to_include(
+ 'The resource that you are attempting to access does not exist ' \
+ "or you don't have permission to perform this action"
+ )
+ end
+ end
+ end
- expect(response).to have_gitlab_http_status(:success)
+ context 'when user is admin in admin mode', :enable_admin_mode do
+ let(:current_user) { admin }
- expect(mutation_response['errors']).to contain_exactly(
- "Tags list can not be empty when runner is not allowed to pick untagged jobs",
- "Maximum timeout needs to be at least 10 minutes"
- )
+ it_behaves_like 'when :create_runner_workflow_for_namespace feature flag is disabled'
+ it_behaves_like 'when runner is created successfully'
+ it_behaves_like 'when model is invalid returns error'
end
end
end
diff --git a/spec/services/ci/runners/create_runner_service_spec.rb b/spec/services/ci/runners/create_runner_service_spec.rb
index 52acfcbb7af..886411ec5fb 100644
--- a/spec/services/ci/runners/create_runner_service_spec.rb
+++ b/spec/services/ci/runners/create_runner_service_spec.rb
@@ -3,24 +3,20 @@
require 'spec_helper'
RSpec.describe ::Ci::Runners::CreateRunnerService, "#execute", feature_category: :runner_fleet do
- subject(:execute) { described_class.new(user: current_user, type: type, params: params).execute }
+ subject(:execute) { described_class.new(user: current_user, params: params).execute }
let(:runner) { execute.payload[:runner] }
let_it_be(:admin) { create(:admin) }
let_it_be(:non_admin_user) { create(:user) }
let_it_be(:anonymous) { nil }
+ let_it_be(:group_owner) { create(:user) }
- shared_context 'when admin user' do
- let(:current_user) { admin }
-
- before do
- allow(current_user).to receive(:can?).with(:create_instance_runners).and_return true
- end
- end
+ let_it_be(:group) { create(:group) }
shared_examples 'it can create a runner' do
- it 'creates a runner of the specified type' do
+ it 'creates a runner of the specified type', :aggregate_failures do
+ is_expected.to be_success
expect(runner.runner_type).to eq expected_type
end
@@ -42,7 +38,7 @@ RSpec.describe ::Ci::Runners::CreateRunnerService, "#execute", feature_category:
expect(runner.active).to be true
expect(runner.creator).to be current_user
expect(runner.authenticated_user_registration_type?).to be_truthy
- expect(runner.runner_type).to eq 'instance_type'
+ expect(runner.runner_type).to eq expected_type
end
end
@@ -81,7 +77,7 @@ RSpec.describe ::Ci::Runners::CreateRunnerService, "#execute", feature_category:
expect(runner.maximum_timeout).to eq args[:maximum_timeout]
expect(runner.authenticated_user_registration_type?).to be_truthy
- expect(runner.runner_type).to eq 'instance_type'
+ expect(runner.runner_type).to eq expected_type
end
context 'with a nil paused value' do
@@ -138,7 +134,6 @@ RSpec.describe ::Ci::Runners::CreateRunnerService, "#execute", feature_category:
end
shared_examples 'it can return an error' do
- let(:group) { create(:group) }
let(:runner_double) { Ci::Runner.new }
context 'when the runner fails to save' do
@@ -154,25 +149,137 @@ RSpec.describe ::Ci::Runners::CreateRunnerService, "#execute", feature_category:
end
end
- context 'with type param set to nil' do
+ context 'with :runner_type param set to instance_type' do
let(:expected_type) { 'instance_type' }
- let(:type) { nil }
- let(:params) { {} }
+ let(:params) { { runner_type: 'instance_type' } }
+
+ context 'when anonymous user' do
+ let(:current_user) { anonymous }
+
+ it_behaves_like 'it cannot create a runner'
+ end
+
+ context 'when non-admin user' do
+ let(:current_user) { non_admin_user }
+
+ it_behaves_like 'it cannot create a runner'
+ end
+
+ context 'when admin user' do
+ let(:current_user) { admin }
+
+ it_behaves_like 'it cannot create a runner'
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it_behaves_like 'it can create a runner'
+ it_behaves_like 'it can return an error'
- it_behaves_like 'it cannot create a runner' do
+ context 'with unexpected scope param specified' do
+ let(:params) { { runner_type: 'instance_type', scope: group } }
+
+ it_behaves_like 'it cannot create a runner'
+ end
+ end
+ end
+ end
+
+ context 'with :runner_type param set to group_type' do
+ let(:expected_type) { 'group_type' }
+ let(:params) { { runner_type: 'group_type', scope: group } }
+
+ before do
+ group.add_developer(non_admin_user)
+ group.add_owner(group_owner)
+ end
+
+ context 'when anonymous user' do
let(:current_user) { anonymous }
+
+ it_behaves_like 'it cannot create a runner'
end
- it_behaves_like 'it cannot create a runner' do
+ context 'when non-admin user' do
let(:current_user) { non_admin_user }
+
+ it_behaves_like 'it cannot create a runner'
+ end
+
+ context 'when group owner' do
+ let(:current_user) { group_owner }
+
+ it_behaves_like 'it can create a runner'
+
+ context 'with missing scope param' do
+ let(:params) { { runner_type: 'group_type' } }
+
+ it_behaves_like 'it cannot create a runner'
+ end
+ end
+
+ context 'when admin user' do
+ let(:current_user) { admin }
+
+ it_behaves_like 'it cannot create a runner'
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it_behaves_like 'it can create a runner'
+ it_behaves_like 'it can return an error'
+ end
+ end
+ end
+
+ context 'with :runner_type param set to project_type' do
+ let_it_be(:project) { create(:project, namespace: group) }
+
+ let(:expected_type) { 'project_type' }
+ let(:params) { { runner_type: 'project_type', scope: project } }
+
+ before do
+ group.add_developer(non_admin_user)
+ group.add_owner(group_owner)
+ end
+
+ context 'when anonymous user' do
+ let(:current_user) { anonymous }
+
+ it_behaves_like 'it cannot create a runner'
end
- it_behaves_like 'it can create a runner' do
- include_context 'when admin user'
+ context 'when group owner' do
+ let(:current_user) { group_owner }
+
+ it_behaves_like 'it can create a runner'
+
+ context 'with missing scope param' do
+ let(:params) { { runner_type: 'project_type' } }
+
+ it_behaves_like 'it cannot create a runner'
+ end
+ end
+
+ context 'when non-admin user' do
+ let(:current_user) { non_admin_user }
+
+ it_behaves_like 'it cannot create a runner'
+
+ context 'with project permissions to create runner' do
+ before do
+ project.add_maintainer(current_user)
+ end
+
+ it_behaves_like 'it can create a runner'
+ end
end
- it_behaves_like 'it can return an error' do
- include_context 'when admin user'
+ context 'when admin user' do
+ let(:current_user) { admin }
+
+ it_behaves_like 'it cannot create a runner'
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it_behaves_like 'it can create a runner'
+ it_behaves_like 'it can return an error'
+ end
end
end
end
diff --git a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
index 4dc2ce61c4d..b346f35bdc9 100644
--- a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
@@ -65,7 +65,7 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
deprecable = subject(deprecated: { milestone: '1.10', reason: :alpha })
expect(deprecable.deprecation_reason).to eq(
- 'This feature is in Alpha. It can be changed or removed at any time. Introduced in 1.10.'
+ 'This feature is an Experiment. It can be changed or removed at any time. Introduced in 1.10.'
)
end
@@ -73,7 +73,7 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
deprecable = subject(alpha: { milestone: '1.10' })
expect(deprecable.deprecation_reason).to eq(
- 'This feature is in Alpha. It can be changed or removed at any time. Introduced in 1.10.'
+ 'This feature is an Experiment. It can be changed or removed at any time. Introduced in 1.10.'
)
end
@@ -82,7 +82,7 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
subject(alpha: { milestone: '1.10' }, deprecated: { milestone: '1.10', reason: 'my reason' } )
end.to raise_error(
ArgumentError,
- eq("`alpha` and `deprecated` arguments cannot be passed at the same time")
+ eq("`experiment` and `deprecated` arguments cannot be passed at the same time")
)
end
diff --git a/spec/tooling/graphql/docs/renderer_spec.rb b/spec/tooling/graphql/docs/renderer_spec.rb
index bf2383507aa..911dab09701 100644
--- a/spec/tooling/graphql/docs/renderer_spec.rb
+++ b/spec/tooling/graphql/docs/renderer_spec.rb
@@ -377,7 +377,7 @@ RSpec.describe Tooling::Graphql::Docs::Renderer do
| Name | Type | Description |
| ---- | ---- | ----------- |
- | <a id="alphatestfoofooarg"></a>`fooArg` **{warning-solid}** | [`String`](#string) | **Introduced** in 101.2. This feature is in Alpha. It can be changed or removed at any time. Argument description. |
+ | <a id="alphatestfoofooarg"></a>`fooArg` **{warning-solid}** | [`String`](#string) | **Introduced** in 101.2. This feature is an Experiment. It can be changed or removed at any time. Argument description. |
DOC
end
@@ -415,7 +415,7 @@ RSpec.describe Tooling::Graphql::Docs::Renderer do
| Name | Type | Description |
| ---- | ---- | ----------- |
- | <a id="alphatestfoo"></a>`foo` **{warning-solid}** | [`String!`](#string) | **Introduced** in 1.10. This feature is in Alpha. It can be changed or removed at any time. A description. |
+ | <a id="alphatestfoo"></a>`foo` **{warning-solid}** | [`String!`](#string) | **Introduced** in 1.10. This feature is an Experiment. It can be changed or removed at any time. A description. |
#### Fields with arguments
@@ -425,7 +425,7 @@ RSpec.describe Tooling::Graphql::Docs::Renderer do
WARNING:
**Introduced** in 1.10.
- This feature is in Alpha. It can be changed or removed at any time.
+ This feature is an Experiment. It can be changed or removed at any time.
Returns [`String!`](#string).
@@ -460,7 +460,7 @@ RSpec.describe Tooling::Graphql::Docs::Renderer do
WARNING:
**Introduced** in 10.11.
- This feature is in Alpha. It can be changed or removed at any time.
+ This feature is an Experiment. It can be changed or removed at any time.
Returns [`Int`](#int).
DOC