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-09-15 12:12:37 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-15 12:12:37 +0300
commit340f85512a4b4fa1ffd558ecaf64fef2eec8cc87 (patch)
tree17ac8e368361cf8a0173ba979b61194169335364
parent843571b0eca882af2326d3829440e754a2838ec8 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue26
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js8
-rw-r--r--app/assets/javascripts/ci/job_details/components/sidebar/stages_dropdown.vue2
-rw-r--r--app/controllers/profiles/preferences_controller.rb1
-rw-r--r--app/helpers/ci/status_helper.rb44
-rw-r--r--app/models/user.rb1
-rw-r--r--app/models/user_preference.rb1
-rw-r--r--app/views/profiles/preferences/show.html.haml7
-rw-r--r--app/views/projects/commit/_commit_box.html.haml3
-rw-r--r--config/locales/doorkeeper.en.yml3
-rw-r--r--db/migrate/20230914185814_add_keyboard_shortcuts_toggle_to_user_preferences.rb9
-rw-r--r--db/post_migrate/20230913175529_add_index_on_merge_requests_target_project_id_and_merged_commit_sha.rb16
-rw-r--r--db/schema_migrations/202309131755291
-rw-r--r--db/schema_migrations/202309141858141
-rw-r--r--db/structure.sql3
-rw-r--r--doc/api/graphql/reference/index.md22
-rw-r--r--doc/ci/yaml/index.md3
-rw-r--r--doc/tutorials/automate_runner_creation/index.md220
-rw-r--r--doc/user/compliance/compliance_center/index.md26
-rw-r--r--doc/user/group/settings/group_access_tokens.md1
-rw-r--r--doc/user/profile/personal_access_tokens.md1
-rw-r--r--doc/user/project/settings/project_access_tokens.md1
-rw-r--r--doc/user/shortcuts.md17
-rw-r--r--lib/api/metadata.rb2
-rw-r--r--lib/gitlab/auth.rb6
-rw-r--r--lib/gitlab/ci/config/entry/default.rb7
-rw-r--r--lib/gitlab/ci/config/entry/job.rb2
-rw-r--r--lib/gitlab/gon_helper.rb1
-rw-r--r--locale/gitlab.pot12
-rw-r--r--spec/controllers/profiles/preferences_controller_spec.rb1
-rw-r--r--spec/features/projects/user_uses_shortcuts_spec.rb52
-rw-r--r--spec/lib/gitlab/auth_spec.rb22
-rw-r--r--spec/lib/gitlab/ci/config/entry/bridge_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/default_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb46
-rw-r--r--spec/models/user_preference_spec.rb14
-rw-r--r--spec/models/user_spec.rb3
-rw-r--r--spec/requests/api/metadata_spec.rb18
-rw-r--r--spec/requests/openid_connect_spec.rb2
39 files changed, 498 insertions, 111 deletions
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue b/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue
index cb7c6f9f6bc..e81ceae57c0 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_help.vue
@@ -1,15 +1,16 @@
<script>
-import { GlModal, GlSearchBoxByType } from '@gitlab/ui';
+import { GlModal, GlSearchBoxByType, GlLink, GlSprintf } from '@gitlab/ui';
import { s__, __ } from '~/locale';
+import { joinPaths } from '../../lib/utils/url_utility';
import { keybindingGroups } from './keybindings';
import Shortcut from './shortcut.vue';
-import ShortcutsToggle from './shortcuts_toggle.vue';
export default {
components: {
GlModal,
GlSearchBoxByType,
- ShortcutsToggle,
+ GlLink,
+ GlSprintf,
Shortcut,
},
data() {
@@ -39,6 +40,9 @@ export default {
return mapped.filter((group) => group.keybindings.length);
},
+ absoluteUserPreferencesPath() {
+ return joinPaths(gon.relative_url_root || '/', '/-/profile/preferences');
+ },
},
i18n: {
title: __(`Keyboard shortcuts`),
@@ -66,7 +70,21 @@ export default {
:aria-label="$options.i18n.search"
class="gl-w-half gl-mr-3"
/>
- <shortcuts-toggle class="gl-w-half gl-ml-3" />
+ <span>
+ <gl-sprintf
+ :message="
+ __(
+ 'Enable or disable keyboard shortcuts in your %{linkStart}user preferences%{linkEnd}.',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="absoluteUserPreferencesPath">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
</div>
<div v-if="filteredKeybindings.length === 0" class="gl-px-5">
{{ $options.i18n.noMatch }}
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js
index 3f3e0c51de5..22f2478c530 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js
@@ -3,13 +3,7 @@ import 'mousetrap/plugins/pause/mousetrap-pause';
const shorcutsDisabledKey = 'shortcutsDisabled';
-export const shouldDisableShortcuts = () => {
- try {
- return localStorage.getItem(shorcutsDisabledKey) === 'true';
- } catch (e) {
- return false;
- }
-};
+export const shouldDisableShortcuts = () => !window.gon.keyboard_shortcuts_enabled;
export function enableShortcuts() {
localStorage.setItem(shorcutsDisabledKey, false);
diff --git a/app/assets/javascripts/ci/job_details/components/sidebar/stages_dropdown.vue b/app/assets/javascripts/ci/job_details/components/sidebar/stages_dropdown.vue
index 4ccd949e754..6c87bff6c5f 100644
--- a/app/assets/javascripts/ci/job_details/components/sidebar/stages_dropdown.vue
+++ b/app/assets/javascripts/ci/job_details/components/sidebar/stages_dropdown.vue
@@ -117,7 +117,7 @@ export default {
<template #mrId>
<gl-link
:href="pipeline.merge_request.path"
- class="link-commit ref-name gl-text-blue-500!"
+ class="link-commit gl-text-blue-500!"
data-testid="mr-link"
>!{{ pipeline.merge_request.iid }}</gl-link
>
diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb
index 3e8555a4ed1..931070ecdd4 100644
--- a/app/controllers/profiles/preferences_controller.rb
+++ b/app/controllers/profiles/preferences_controller.rb
@@ -55,6 +55,7 @@ class Profiles::PreferencesController < Profiles::ApplicationController
:gitpod_enabled,
:render_whitespace_in_code,
:project_shortcut_buttons,
+ :keyboard_shortcuts_enabled,
:markdown_surround_selection,
:markdown_automatic_lists,
:use_new_navigation,
diff --git a/app/helpers/ci/status_helper.rb b/app/helpers/ci/status_helper.rb
index 73aec454f1d..5d526a6abb6 100644
--- a/app/helpers/ci/status_helper.rb
+++ b/app/helpers/ci/status_helper.rb
@@ -9,27 +9,6 @@
#
module Ci
module StatusHelper
- def ci_label_for_status(status)
- if detailed_status?(status)
- return status.label
- end
-
- label = case status
- when 'success'
- 'passed'
- when 'success-with-warnings'
- 'passed with warnings'
- when 'manual'
- 'waiting for manual action'
- when 'scheduled'
- 'waiting for delayed job'
- else
- status
- end
- translation = "CiStatusLabel|#{label}"
- s_(translation)
- end
-
def ci_status_for_statuseable(subject)
status = subject.try(:status) || 'not found'
status.humanize
@@ -110,11 +89,34 @@ module Ci
end
end
+ private
+
def detailed_status?(status)
status.respond_to?(:text) &&
status.respond_to?(:group) &&
status.respond_to?(:label) &&
status.respond_to?(:icon)
end
+
+ def ci_label_for_status(status)
+ if detailed_status?(status)
+ return status.label
+ end
+
+ label = case status
+ when 'success'
+ 'passed'
+ when 'success-with-warnings'
+ 'passed with warnings'
+ when 'manual'
+ 'waiting for manual action'
+ when 'scheduled'
+ 'waiting for delayed job'
+ else
+ status
+ end
+ translation = "CiStatusLabel|#{label}"
+ s_(translation)
+ end
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 5fb40a1bc6c..c4e867ab571 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -396,6 +396,7 @@ class User < MainClusterwide::ApplicationRecord
:gitpod_enabled, :gitpod_enabled=,
:setup_for_company, :setup_for_company=,
:project_shortcut_buttons, :project_shortcut_buttons=,
+ :keyboard_shortcuts_enabled, :keyboard_shortcuts_enabled=,
:render_whitespace_in_code, :render_whitespace_in_code=,
:markdown_surround_selection, :markdown_surround_selection=,
:markdown_automatic_lists, :markdown_automatic_lists=,
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index eac66905d0c..8fc9f4617d0 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -35,6 +35,7 @@ class UserPreference < MainClusterwide::ApplicationRecord
attribute :time_display_relative, default: true
attribute :render_whitespace_in_code, default: false
attribute :project_shortcut_buttons, default: true
+ attribute :keyboard_shortcuts_enabled, default: true
enum visibility_pipeline_id_type: { id: 0, iid: 1 }
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 51010ec326e..a6534a16e86 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -67,6 +67,13 @@
= link_to _('Learn more'), help_page_path('user/profile/preferences', anchor: 'behavior'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= f.label :layout, class: 'label-bold' do
+ = s_('Preferences|Keyboard shortcuts')
+ - shortcuts_help_link = link_to('', help_page_path('user/shortcuts'), target: '_blank', rel: 'noopener noreferrer')
+ = f.gitlab_ui_checkbox_component :keyboard_shortcuts_enabled,
+ s_('Preferences|Enable keyboard shortcuts'),
+ help_text: safe_format(s_('Preferences|%{link_start}List of keyboard shortcuts%{link_end}'), tag_pair(shortcuts_help_link, :link_start, :link_end))
+ .form-group
+ = f.label :layout, class: 'label-bold' do
= s_('Preferences|Layout width')
= f.gitlab_ui_radio_component :layout, layout_choices[0][1], layout_choices[0][0], help_text: fixed_help_text
= f.gitlab_ui_radio_component :layout, layout_choices[1][1], layout_choices[1][0], help_text: fluid_help_text
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 24d063d3b4d..e79a91eddaf 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -45,11 +45,12 @@
= gl_loading_icon(inline: true, css_class: 'gl-vertical-align-middle')
- if can?(current_user, :read_pipeline, @last_pipeline)
+ - status = @last_pipeline.detailed_status(current_user)
.well-segment.pipeline-info
.js-commit-pipeline-status{ data: { full_path: @project.full_path, iid: @last_pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@last_pipeline) } }
#{ _('Pipeline') }
= link_to "##{@last_pipeline.id}", project_pipeline_path(@project, @last_pipeline.id)
- = ci_label_for_status(@last_pipeline.status)
+ = status&.label
- if @last_pipeline.stages_count.nonzero?
#{ n_(s_('Pipeline|with stage'), s_('Pipeline|with stages'), @last_pipeline.stages_count) }
.js-commit-pipeline-mini-graph{ data: { stages: @last_pipeline_stages.to_json.html_safe, full_path: @project.full_path, iid: @last_pipeline.iid, graphql_resource_etag: graphql_etag_pipeline_path(@last_pipeline) } }
diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml
index d2a93a7cf9d..9568195bb6e 100644
--- a/config/locales/doorkeeper.en.yml
+++ b/config/locales/doorkeeper.en.yml
@@ -78,6 +78,7 @@ en:
admin_mode: Admin Mode is a functionality designed to limit the access level of administrator's personal access tokens.
create_runner: Grants create access to the runners
k8s_proxy: Grants permission to perform Kubernetes API calls using the agent for Kubernetes.
+ ai_features: Access to API endpoints needed for GitLab Duo features
scope_desc:
api:
Grants complete read/write access to the API, including all groups and projects, the container registry, and the package registry.
@@ -97,6 +98,8 @@ en:
Grants read-only access to GitLab Observability.
write_observability:
Grants write access to GitLab Observability.
+ ai_features:
+ Grants access to GitLab Duo related API endpoints.
openid:
Grants permission to authenticate with GitLab using OpenID Connect. Also gives read-only access to the user's profile and group memberships.
sudo:
diff --git a/db/migrate/20230914185814_add_keyboard_shortcuts_toggle_to_user_preferences.rb b/db/migrate/20230914185814_add_keyboard_shortcuts_toggle_to_user_preferences.rb
new file mode 100644
index 00000000000..b7de3f95c7f
--- /dev/null
+++ b/db/migrate/20230914185814_add_keyboard_shortcuts_toggle_to_user_preferences.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddKeyboardShortcutsToggleToUserPreferences < Gitlab::Database::Migration[2.1]
+ enable_lock_retries!
+
+ def change
+ add_column :user_preferences, :keyboard_shortcuts_enabled, :boolean, default: true, null: false
+ end
+end
diff --git a/db/post_migrate/20230913175529_add_index_on_merge_requests_target_project_id_and_merged_commit_sha.rb b/db/post_migrate/20230913175529_add_index_on_merge_requests_target_project_id_and_merged_commit_sha.rb
new file mode 100644
index 00000000000..33fe6538f9b
--- /dev/null
+++ b/db/post_migrate/20230913175529_add_index_on_merge_requests_target_project_id_and_merged_commit_sha.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddIndexOnMergeRequestsTargetProjectIdAndMergedCommitSha < Gitlab::Database::Migration[2.1]
+ INDEX_NAME = 'index_merge_requests_on_target_project_id_and_merged_commit_sha'
+ INDEX_COLUMNS = %i[target_project_id merged_commit_sha]
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :merge_requests, INDEX_COLUMNS, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :merge_requests, name: INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20230913175529 b/db/schema_migrations/20230913175529
new file mode 100644
index 00000000000..f68678def20
--- /dev/null
+++ b/db/schema_migrations/20230913175529
@@ -0,0 +1 @@
+af8c6b5578c04d184f7f3768c5b06b3a252c10d8f158667ceab57eca74fb4341 \ No newline at end of file
diff --git a/db/schema_migrations/20230914185814 b/db/schema_migrations/20230914185814
new file mode 100644
index 00000000000..4a2f98bdd89
--- /dev/null
+++ b/db/schema_migrations/20230914185814
@@ -0,0 +1 @@
+11eea8818e233b09048e89bb4b56beceab4f8f9c5702bb4c167a5d7ac8d99ccc \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 913cee9a3d3..b66130e90c2 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -24330,6 +24330,7 @@ CREATE TABLE user_preferences (
visibility_pipeline_id_type smallint DEFAULT 0 NOT NULL,
project_shortcut_buttons boolean DEFAULT true NOT NULL,
enabled_zoekt boolean DEFAULT true NOT NULL,
+ keyboard_shortcuts_enabled boolean DEFAULT true NOT NULL,
CONSTRAINT check_89bf269f41 CHECK ((char_length(diffs_deletion_color) <= 7)),
CONSTRAINT check_d07ccd35f7 CHECK ((char_length(diffs_addition_color) <= 7))
);
@@ -32659,6 +32660,8 @@ CREATE UNIQUE INDEX index_merge_requests_on_target_project_id_and_iid ON merge_r
CREATE INDEX index_merge_requests_on_target_project_id_and_iid_and_state_id ON merge_requests USING btree (target_project_id, iid, state_id);
+CREATE INDEX index_merge_requests_on_target_project_id_and_merged_commit_sha ON merge_requests USING btree (target_project_id, merged_commit_sha);
+
CREATE INDEX index_merge_requests_on_target_project_id_and_source_branch ON merge_requests USING btree (target_project_id, source_branch);
CREATE INDEX index_merge_requests_on_target_project_id_and_squash_commit_sha ON merge_requests USING btree (target_project_id, squash_commit_sha);
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index d54afe84c25..78f2f584a8a 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -5616,6 +5616,28 @@ Input type: `ProjectSetComplianceFrameworkInput`
| <a id="mutationprojectsetcomplianceframeworkerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationprojectsetcomplianceframeworkproject"></a>`project` | [`Project`](#project) | Project after mutation. |
+### `Mutation.projectSetContinuousVulnerabilityScanning`
+
+Enable/disable Continuous Vulnerability Scanning for the given project.
+
+Input type: `ProjectSetContinuousVulnerabilityScanningInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationprojectsetcontinuousvulnerabilityscanningclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationprojectsetcontinuousvulnerabilityscanningenable"></a>`enable` | [`Boolean!`](#boolean) | Desired status for Continuous Vulnerability Scanning feature. |
+| <a id="mutationprojectsetcontinuousvulnerabilityscanningprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationprojectsetcontinuousvulnerabilityscanningclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationprojectsetcontinuousvulnerabilityscanningcontinuousvulnerabilityscanningenabled"></a>`continuousVulnerabilityScanningEnabled` | [`Boolean!`](#boolean) | Whether feature is enabled. |
+| <a id="mutationprojectsetcontinuousvulnerabilityscanningerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+
### `Mutation.projectSetLocked`
Input type: `ProjectSetLockedInput`
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 83e0894f254..64eefcbdc9d 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -77,6 +77,8 @@ or import additional pipeline configuration.
### `default`
+> Support for `id_tokens` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/419750) in GitLab 16.4.
+
You can set global defaults for some keywords. Jobs that do not define one or more
of the listed keywords use the value defined in the `default` section.
@@ -89,6 +91,7 @@ of the listed keywords use the value defined in the `default` section.
- [`before_script`](#before_script)
- [`cache`](#cache)
- [`hooks`](#hooks)
+- [`id_tokens`](#id_tokens)
- [`image`](#image)
- [`interruptible`](#interruptible)
- [`retry`](#retry)
diff --git a/doc/tutorials/automate_runner_creation/index.md b/doc/tutorials/automate_runner_creation/index.md
new file mode 100644
index 00000000000..fa1373f1e3a
--- /dev/null
+++ b/doc/tutorials/automate_runner_creation/index.md
@@ -0,0 +1,220 @@
+---
+stage: none
+group: Tutorials
+info: For assistance with this tutorial, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-other-projects-and-subjects.
+---
+
+# Tutorial: Automate runner creation and registration **(FREE ALL)**
+
+This tutorial describes how to automate runner creation and registration.
+
+To automate runner creation and registration:
+
+1. [Create a personal access token](#create-a-personal-access-token).
+1. [Create a runner configuration](#create-a-runner-configuration).
+1. [Automate GitLab Runner installation and registration](#automate-runner-installation-and-registration).
+1. [View runners with the same configuration](#view-runners-with-the-same-configuration).
+
+NOTE:
+The instructions in this tutorial describe runner creation and registration
+with runner authentication tokens, which have replaced the deprecated registration
+method that uses registration tokens. For more information, see
+[The new runner registration workflow](../../ci/runners/new_creation_workflow.md#the-new-runner-registration-workflow).
+
+## Prerequisites
+
+- GitLab Runner must be installed on your GitLab instance.
+- To create shared runners, you must be an administrator.
+- To create group runners, you must be an administrator or have the Owner role for the group.
+- To create project runners, you must be an administrator or have the Maintainer role for the project.
+
+## Create an access token
+
+Create an access token so that you can use the REST API to create runners.
+
+You can create:
+
+- A personal access token to use with shared, group, and project runners.
+- A group or project access token to use with group and project runners.
+
+The access token is only visible once in the GitLab UI. After you leave the page,
+you no longer have access to the token. You should use a secrets management solution
+to store the token, like HashiCorp Vault or the Keeper Secrets Manager Terraform plugin.
+
+### Create a personal access token
+
+1. On the left sidebar, select your avatar.
+1. Select **Edit profile**.
+1. On the left sidebar, select **Access Tokens**.
+1. Select **Add new token**.
+1. Enter a name and expiry date for the token.
+ - The token expires on that date at midnight UTC.
+ - If you do not enter an expiry date, the expiry date is automatically set to 365 days later than the current date.
+ - By default, this date can be a maximum of 365 days later than the current date.
+1. In the **Select scopes** section, select the **create_runner** checkbox.
+1. Select **Create personal access token**.
+
+### Create a project or group access token
+
+WARNING:
+Project access tokens are treated as [internal users](../../development/internal_users.md).
+If an internal user creates a project access token, that token is able to access
+all projects that have visibility level set to [Internal](../../user/public_access.md).
+
+To create a project access token:
+
+1. On the left sidebar, select **Search or go to** and find your project or group.
+1. Select **Settings > Access Tokens**.
+1. Select **Add new token**
+1. Enter a name. The token name is visible to any user with permissions to view
+ the group or project.
+1. Enter an expiry date for the token.
+ - The token expires on that date at midnight UTC.
+ - If you do not enter an expiry date, the expiry date is automatically set
+ to 365 days later than the current date.
+ - By default, this date can be a maximum of 365 days later than the current date.
+ - An instance-wide [maximum lifetime](../../administration/settings/account_and_limit_settings.md#limit-the-lifetime-of-access-tokens)
+ setting can limit the maximum allowable lifetime on self-managed instances.
+1. From the **Select a role** dropdown list:
+ - For the project access token, select **Maintainer**.
+ - For the group access token, select **Owner**.
+1. In the **Select scopes** section, select the **create_runner** checkbox.
+1. Select **Create project access token**.
+
+## Create a runner configuration
+
+A runner configuration is where you configure runners to your requirements.
+
+After you create a runner configuration, you receive a runner authentication
+to register the runner. One or many runners can be linked to the
+same configuration when these runners are registered with the same runner authentication
+token. The runner configuration is stored in the `config.toml` file.
+
+To create a runner configuration, you can use:
+
+- The GitLab REST API.
+- The `gitlab_user_runner` Terraform resource.
+
+### With the GitLab REST API
+
+Prerequisites:
+
+- The URL for your GitLab instance. For example, if your project is hosted on
+ `gitlab.example.com/yourname/yourproject`, your GitLab instance URL is
+ `https://gitlab.example.com`.
+- For group or project runners, the ID number of the group or project. The ID number
+ is displayed in the project or group overview page, under the project or group
+ name.
+
+Use the access token in the [`POST /user/runners`](../../api/users.md#create-a-runner)
+REST endpoint to create a runner:
+
+1. Use `curl` to invoke the endpoint to create a runner:
+
+ ::Tabs
+
+ :::TabTitle Project
+
+ ```shell
+ curl --silent --request POST --url "https://gitlab.example.com/api/v4/user/runners"
+ --data "runner_type=project_type"
+ --data "project_id=<project_id>"
+ --data "description=<your_runner_description>"
+ --data "tag_list=<your_comma_separated_job_tags>"
+ --header "PRIVATE-TOKEN: <project_access_token>"
+ ```
+
+ :::TabTitle Group
+
+ ```shell
+ curl --silent --request POST --url "https://gitlab.example.com/api/v4/user/runners"
+ --data "runner_type=group_type"
+ --data "group_id=<group_id>"
+ --data "description=<your_runner_description>"
+ --data "tag_list=<your_comma_separated_job_tags>"
+ --header "PRIVATE-TOKEN: <group_access_token>"
+ ```
+
+ :::TabTitle Shared
+
+ ```shell
+ curl --silent --request POST --url "https://gitlab.example.com/api/v4/user/runners"
+ --data "runner_type=instance_type"
+ --data "description=<your_runner_description>"
+ --data "tag_list=<your_comma_separated_job_tags>"
+ --header "PRIVATE-TOKEN: <personal_access_token>"
+ ```
+
+ ::EndTabs
+
+1. Save the returned `token` value in a secure location or your secrets management
+ solution. The `token` value is returned only once in the API response.
+
+## With the `gitlab_user_runner` Terraform resource
+
+To create the runner configuration with Terraform, use the
+[`gitlab_user_runner` Terraform resource](https://gitlab.com/gitlab-org/terraform-provider-gitlab/-/blob/main/docs/resources/user_runner.md?ref_type=heads)
+from the [GitLab Terraform provider](https://gitlab.com/gitlab-org/terraform-provider-gitlab).
+
+Here's an example configuration block:
+
+```terraform
+resource "gitlab_user_runner" "example_runner" {
+ runner_type = "instance_type"
+ description = "my-runner"
+ tag_list = ["shell", "docker"]
+}
+```
+
+## Automate runner installation and registration
+
+If you host the runner on a virtual machine instance in a public cloud, you can automate
+runner installation and registration.
+
+After you create a runner and its configuration, you can use the same runner
+authentication token to register multiple runners with the same configuration.
+For example, you can deploy multiple shared runners with the same executor type
+and job tags to the target compute host. Each runner registered with the same runner
+authentication token has a unique `system_id`, which GitLab Runner
+generates randomly and stores in your local file system.
+
+Here's an example of an automation workflow you can use to register and deploy your
+runners to Google Compute Engine:
+
+1. Use [Terraform infrastructure as code](../../user/infrastructure/iac/index.md)
+ to install the runner application to a virtual machine hosted on Google Cloud
+ Platform (GCP).
+1. In the [GCP Terraform provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance),
+ use the `metadata` key to add the runner authentication token to the runner
+ configuration file on the GCP virtual machine.
+1. To register the runner with the target GitLab instance, use a `cloud-init` script
+ populated from the GCP Terraform provider. Here's an example:
+
+ ```shell
+ #!/bin/bash
+ apt update
+ curl --location "https://packages.gitlab.com/install/repositories/runner/
+ gitlab-runner/script.deb.sh" | bash
+ GL_NAME=$(curl 169.254.169.254/computeMetadata/v1/instance/name
+ --header "Metadata-Flavor:Google")
+ GL_EXECUTOR=$(curl 169.254.169.254/computeMetadata/v1/instance/attributes/
+ gl_executor --header "Metadata-Flavor:Google")
+ apt update
+ apt install -y gitlab-runner
+ gitlab-runner register --non-interactive --name="$GL_NAME" --url="https://gitlab.com"
+ --token="$RUNNER_TOKEN" --request-concurrency="12" --executor="$GL_EXECUTOR"
+ --docker-image="alpine:latest"
+ systemctl restart gitlab-runner
+ ```
+
+## View runners with the same configuration
+
+Now that you've automated your runner creation and automation, you can view
+the runners that use the same configuration in the GitLab UI.
+
+1. On the left sidebar, select **Search or go to**.
+1. Select **Admin Area**.
+1. On the left sidebar, select **CI/CD > Runners**.
+1. In the search box, enter the runner description or search the list of runners.
+1. To view the runners that use the same configuration, in the **Details** tab,
+ next to **Runners**, select **Show details**.
diff --git a/doc/user/compliance/compliance_center/index.md b/doc/user/compliance/compliance_center/index.md
index 3a2d8d6163d..b0ff8a41d3d 100644
--- a/doc/user/compliance/compliance_center/index.md
+++ b/doc/user/compliance/compliance_center/index.md
@@ -314,6 +314,32 @@ To remove a compliance framework from multiple projects in a group:
1. From the **Choose one bulk action** dropdown list, select **Remove framework from selected projects**.
1. Select **Remove**.
+### Export a report of merge request compliance violations on projects in a group
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356791) in GitLab 16.4 [with a flag](../../../administration/feature_flags.md) named `compliance_violation_csv_export`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named
+`compliance_violation_csv_export`. On GitLab.com, this feature is not available. The feature is not ready for production use.
+
+Export a report of merge request compliance violations on merge requests belonging to projects in a group. Reports:
+
+- Do not use filters on the violations report.
+- Are truncated at 15 MB so the email attachment is not too large.
+
+Prerequisites:
+
+- You must be an administrator or have the Owner role for the group.
+
+To export a report of merge request compliance violations for projects in a group:
+
+1. On the left sidebar, select **Search or go to** and find your group.
+1. On the left sidebar, select **Secure > Compliance center**.
+1. On the page, select the **Violations** tab.
+1. On the Violations tab, select the **Export full report as CSV** action in the top right corner
+
+A report is compiled and delivered to your email inbox as an attachment.
+
### Export a report of compliance frameworks on projects in a group
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/387912) in GitLab 16.0.
diff --git a/doc/user/group/settings/group_access_tokens.md b/doc/user/group/settings/group_access_tokens.md
index 2bd6215263e..220bb6f545e 100644
--- a/doc/user/group/settings/group_access_tokens.md
+++ b/doc/user/group/settings/group_access_tokens.md
@@ -149,6 +149,7 @@ The scope determines the actions you can perform when you authenticate with a gr
| `read_repository` | Grants read access (pull) to all repositories within a group. |
| `write_repository` | Grants read and write access (pull and push) to all repositories within a group. |
| `create_runner` | Grants permission to create runners in a group. |
+| `ai_features` | Grants permission to perform API actions for GitLab Duo. |
## Enable or disable group access token creation
diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md
index 7fd94c2045a..31e92a01606 100644
--- a/doc/user/profile/personal_access_tokens.md
+++ b/doc/user/profile/personal_access_tokens.md
@@ -120,6 +120,7 @@ A personal access token can perform actions based on the assigned scopes.
| `sudo` | Grants permission to perform API actions as any user in the system, when authenticated as an administrator. |
| `admin_mode` | Grants permission to perform API actions as an administrator, when Admin Mode is enabled. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107875) in GitLab 15.8.) |
| `create_runner` | Grants permission to create runners. |
+| `ai_features` | Grants permission to perform API actions for GitLab Duo. |
WARNING:
If you enabled [external authorization](../admin_area/settings/external_authorization.md), personal access tokens cannot access container or package registries. If you use personal access tokens to access these registries, this measure breaks this use of these tokens. Disable external authorization to use personal access tokens with container or package registries.
diff --git a/doc/user/project/settings/project_access_tokens.md b/doc/user/project/settings/project_access_tokens.md
index 8dd29306efa..c47dd86b39c 100644
--- a/doc/user/project/settings/project_access_tokens.md
+++ b/doc/user/project/settings/project_access_tokens.md
@@ -93,6 +93,7 @@ See the warning in [create a project access token](#create-a-project-access-toke
| `read_repository` | Grants read access (pull) to the repository. |
| `write_repository` | Grants read and write access (pull and push) to the repository. |
| `create_runner` | Grants permission to create runners in the project. |
+| `ai_features` | Grants permission to perform API actions for GitLab Duo. |
## Enable or disable project access token creation
diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md
index b6df460e87d..b0ef1fcc99a 100644
--- a/doc/user/shortcuts.md
+++ b/doc/user/shortcuts.md
@@ -325,20 +325,25 @@ These shortcuts are available when viewing [epics](group/epics/index.md):
## Disable keyboard shortcuts
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22113) in GitLab 12.8.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/202494) from the shortcuts page to user preferences in GitLab 16.4.
To disable keyboard shortcuts:
-1. While viewing a page that supports keyboard shortcuts, and outside a text box,
-press <kbd>?</kbd> to display the list of shortcuts.
-1. Select **Toggle shortcuts**.
+1. On the left sidebar, select your avatar.
+1. Select **Preferences**.
+1. In the **Behavior** section, clear the **Enable keyboard shortcuts** checkbox.
+1. Select **Save changes**.
## Enable keyboard shortcuts
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/202494) from the shortcuts page to user preferences in GitLab 16.4.
+
To enable keyboard shortcuts:
-1. On the left sidebar, at the bottom, select **Help** (**{question}**), then **Keyboard shortcuts**.
-1. Select **Toggle shortcuts**.
+1. On the left sidebar, select your avatar.
+1. Select **Preferences**.
+1. In the **Behavior** section, select the **Enable keyboard shortcuts** checkbox.
+1. Select **Save changes**.
## Troubleshooting
diff --git a/lib/api/metadata.rb b/lib/api/metadata.rb
index 788d9843c63..e35d22f656a 100644
--- a/lib/api/metadata.rb
+++ b/lib/api/metadata.rb
@@ -5,7 +5,7 @@ module API
helpers ::API::Helpers::GraphqlHelpers
include APIGuard
- allow_access_with_scope :read_user, if: -> (request) { request.get? || request.head? }
+ allow_access_with_scope [:read_user, :ai_features], if: -> (request) { request.get? || request.head? }
before { authenticate! }
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 2335c8b7979..9ddfc995535 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -15,6 +15,10 @@ module Gitlab
CREATE_RUNNER_SCOPE = :create_runner
API_SCOPES = [API_SCOPE, READ_API_SCOPE, READ_USER_SCOPE, CREATE_RUNNER_SCOPE, K8S_PROXY_SCOPE].freeze
+ # Scopes for Duo
+ AI_FEATURES = :ai_features
+ AI_FEATURES_SCOPES = [AI_FEATURES].freeze
+
PROFILE_SCOPE = :profile
EMAIL_SCOPE = :email
OPENID_SCOPE = :openid
@@ -432,7 +436,7 @@ module Gitlab
end
def non_admin_available_scopes
- API_SCOPES + REPOSITORY_SCOPES + registry_scopes + OBSERVABILITY_SCOPES
+ API_SCOPES + REPOSITORY_SCOPES + registry_scopes + OBSERVABILITY_SCOPES + AI_FEATURES_SCOPES
end
def find_build_by_token(token)
diff --git a/lib/gitlab/ci/config/entry/default.rb b/lib/gitlab/ci/config/entry/default.rb
index e996b6b1312..476b928e471 100644
--- a/lib/gitlab/ci/config/entry/default.rb
+++ b/lib/gitlab/ci/config/entry/default.rb
@@ -14,7 +14,7 @@ module Gitlab
include ::Gitlab::Config::Entry::Inheritable
ALLOWED_KEYS = %i[before_script after_script hooks cache image services
- interruptible timeout retry tags artifacts].freeze
+ interruptible timeout retry tags artifacts id_tokens].freeze
validations do
validates :config, allowed_keys: ALLOWED_KEYS
@@ -65,6 +65,11 @@ module Gitlab
description: 'Default artifacts.',
inherit: false
+ entry :id_tokens, ::Gitlab::Config::Entry::ComposableHash,
+ description: 'Configured JWTs for this job',
+ inherit: false,
+ metadata: { composable_class: ::Gitlab::Ci::Config::Entry::IdToken }
+
private
def overwrite_entry(deps, key, current_entry)
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index bf38e2aedaf..044d920f557 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -120,7 +120,7 @@ module Gitlab
entry :id_tokens, ::Gitlab::Config::Entry::ComposableHash,
description: 'Configured JWTs for this job',
- inherit: false,
+ inherit: true,
metadata: { composable_class: ::Gitlab::Ci::Config::Entry::IdToken }
entry :publish, Entry::Publish,
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index 77a50f9c8bc..f1434158a85 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -55,6 +55,7 @@ module Gitlab
gon.uf_error_prefix = ::Gitlab::Utils::ErrorMessage::UF_ERROR_PREFIX
gon.pat_prefix = Gitlab::CurrentSettings.current_application_settings.personal_access_token_prefix
gon.use_new_navigation = NavHelper.show_super_sidebar?(current_user)
+ gon.keyboard_shortcuts_enabled = current_user ? current_user.keyboard_shortcuts_enabled : true
gon.diagramsnet_url = Gitlab::CurrentSettings.diagramsnet_url if Gitlab::CurrentSettings.diagramsnet_enabled
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 4e853e53ca9..5136b675680 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -17989,6 +17989,9 @@ msgstr ""
msgid "Enable only for confidential applications exclusively used by a trusted backend server that can securely store the client secret. Do not enable for native-mobile, single-page, or other JavaScript applications because they cannot keep the client secret confidential."
msgstr ""
+msgid "Enable or disable keyboard shortcuts in your %{linkStart}user preferences%{linkEnd}."
+msgstr ""
+
msgid "Enable or disable version check and Service Ping."
msgstr ""
@@ -35315,6 +35318,9 @@ msgstr ""
msgid "Preferences saved."
msgstr ""
+msgid "Preferences|%{link_start}List of keyboard shortcuts%{link_end}"
+msgstr ""
+
msgid "Preferences|Automatically add new list items"
msgstr ""
@@ -35384,6 +35390,9 @@ msgstr ""
msgid "Preferences|Enable integrated code intelligence on code views"
msgstr ""
+msgid "Preferences|Enable keyboard shortcuts"
+msgstr ""
+
msgid "Preferences|Failed to save preferences."
msgstr ""
@@ -35402,6 +35411,9 @@ msgstr ""
msgid "Preferences|Integrations"
msgstr ""
+msgid "Preferences|Keyboard shortcuts"
+msgstr ""
+
msgid "Preferences|Layout width"
msgstr ""
diff --git a/spec/controllers/profiles/preferences_controller_spec.rb b/spec/controllers/profiles/preferences_controller_spec.rb
index b4ffe0bc844..aaf169cd42b 100644
--- a/spec/controllers/profiles/preferences_controller_spec.rb
+++ b/spec/controllers/profiles/preferences_controller_spec.rb
@@ -54,6 +54,7 @@ RSpec.describe Profiles::PreferencesController do
preferred_language: 'jp',
tab_width: '5',
project_shortcut_buttons: 'true',
+ keyboard_shortcuts_enabled: 'true',
render_whitespace_in_code: 'true'
}.with_indifferent_access
diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb
index 7b0ae6d8c32..b7b2093d78a 100644
--- a/spec/features/projects/user_uses_shortcuts_spec.rb
+++ b/spec/features/projects/user_uses_shortcuts_spec.rb
@@ -14,58 +14,6 @@ RSpec.describe 'User uses shortcuts', :js, feature_category: :groups_and_project
wait_for_requests
end
- context 'disabling shortcuts' do
- before do
- page.evaluate_script("localStorage.removeItem('shortcutsDisabled')")
- end
-
- it 'can disable shortcuts from help menu' do
- open_modal_shortcut_keys
- click_toggle_button
- close_modal
-
- open_modal_shortcut_keys
-
- expect(page).not_to have_selector('[data-testid="modal-shortcuts"]')
-
- page.refresh
- open_modal_shortcut_keys
-
- # after reload, shortcuts modal doesn't exist at all until we add it
- expect(page).not_to have_selector('[data-testid="modal-shortcuts"]')
- end
-
- it 're-enables shortcuts' do
- open_modal_shortcut_keys
- click_toggle_button
- close_modal
-
- open_modal_from_help_menu
- click_toggle_button
- close_modal
-
- open_modal_shortcut_keys
- expect(find('[data-testid="modal-shortcuts"]')).to be_visible
- end
-
- def open_modal_shortcut_keys
- find('body').native.send_key('?')
- end
-
- def open_modal_from_help_menu
- find('.header-help-dropdown-toggle').click
- find('button', text: 'Keyboard shortcuts').click
- end
-
- def click_toggle_button
- find('.js-toggle-shortcuts .gl-toggle').click
- end
-
- def close_modal
- find('.modal button[aria-label="Close"]').click
- end
- end
-
context 'when navigating to the Project pages' do
it 'redirects to the project overview page' do
visit project_issues_path(project)
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index 2b3a2e573e0..8da617175ca 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -40,29 +40,29 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching, feature_cate
end
it 'contains all non-default scopes' do
- expect(subject.all_available_scopes).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode read_observability write_observability create_runner k8s_proxy]
+ expect(subject.all_available_scopes).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode read_observability write_observability create_runner k8s_proxy ai_features]
end
it 'contains for non-admin user all non-default scopes without ADMIN access and without observability scopes' do
user = build_stubbed(:user, admin: false)
- expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy]
+ expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
end
it 'contains for admin user all non-default scopes with ADMIN access and without observability scopes' do
user = build_stubbed(:user, admin: true)
- expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode create_runner k8s_proxy]
+ expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode create_runner k8s_proxy ai_features]
end
it 'contains for project all resource bot scopes without observability scopes' do
- expect(subject.available_scopes_for(project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy]
+ expect(subject.available_scopes_for(project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
end
it 'contains for group all resource bot scopes' do
group = build_stubbed(:group)
- expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy]
+ expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy ai_features]
end
it 'contains for unsupported type no scopes' do
@@ -70,7 +70,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching, feature_cate
end
it 'optional_scopes contains all non-default scopes' do
- expect(subject.optional_scopes).to match_array %i[read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode openid profile email read_observability write_observability create_runner k8s_proxy]
+ expect(subject.optional_scopes).to match_array %i[read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode openid profile email read_observability write_observability create_runner k8s_proxy ai_features]
end
context 'with observability_group_tab feature flag' do
@@ -82,7 +82,7 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching, feature_cate
it 'contains for group all resource bot scopes without observability scopes' do
group = build_stubbed(:group)
- expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy]
+ expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
end
end
@@ -94,23 +94,23 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching, feature_cate
end
it 'contains for other group all resource bot scopes including observability scopes' do
- expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy]
+ expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy ai_features]
end
it 'contains for admin user all non-default scopes with ADMIN access and without observability scopes' do
user = build_stubbed(:user, admin: true)
- expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode create_runner k8s_proxy]
+ expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry sudo admin_mode create_runner k8s_proxy ai_features]
end
it 'contains for project all resource bot scopes without observability scopes' do
- expect(subject.available_scopes_for(project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy]
+ expect(subject.available_scopes_for(project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
end
it 'contains for other group all resource bot scopes without observability scopes' do
other_group = build_stubbed(:group)
- expect(subject.available_scopes_for(other_group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy]
+ expect(subject.available_scopes_for(other_group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/bridge_spec.rb b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
index 736c184a289..567ffa68836 100644
--- a/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do
# as they do not have sense in context of Bridge
let(:ignored_inheritable_columns) do
%i[before_script after_script hooks image services cache interruptible timeout
- retry tags artifacts]
+ retry tags artifacts id_tokens]
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/default_spec.rb b/spec/lib/gitlab/ci/config/entry/default_spec.rb
index 46e96843ee3..17e716629cd 100644
--- a/spec/lib/gitlab/ci/config/entry/default_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/default_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Default do
it 'contains the expected node names' do
expect(described_class.nodes.keys)
.to match_array(%i[before_script after_script hooks cache image services
- interruptible timeout retry tags artifacts])
+ interruptible timeout retry tags artifacts id_tokens])
end
end
end
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 48c82343087..c09c0b31e97 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -2042,6 +2042,52 @@ module Gitlab
end
end
+ describe 'id_tokens' do
+ subject(:execute) { described_class.new(config).execute }
+
+ let(:build) { execute.builds.first }
+ let(:id_tokens_vars) { { ID_TOKEN_1: { aud: 'http://gcp.com' } } }
+ let(:job_id_tokens_vars) { { ID_TOKEN_2: { aud: 'http://job.com' } } }
+
+ context 'when defined on job level' do
+ let(:config) do
+ YAML.dump({
+ rspec: { script: 'rspec', id_tokens: id_tokens_vars }
+ })
+ end
+
+ it 'returns defined id_tokens' do
+ expect(build[:id_tokens]).to eq(id_tokens_vars)
+ end
+ end
+
+ context 'when defined as default' do
+ let(:config) do
+ YAML.dump({
+ default: { id_tokens: id_tokens_vars },
+ rspec: { script: 'rspec' }
+ })
+ end
+
+ it 'returns inherited by default id_tokens' do
+ expect(build[:id_tokens]).to eq(id_tokens_vars)
+ end
+ end
+
+ context 'when defined as default and on job level' do
+ let(:config) do
+ YAML.dump({
+ default: { id_tokens: id_tokens_vars },
+ rspec: { script: 'rspec', id_tokens: job_id_tokens_vars }
+ })
+ end
+
+ it 'overrides default and returns defined on job level' do
+ expect(build[:id_tokens]).to eq(job_id_tokens_vars)
+ end
+ end
+ end
+
describe "Artifacts" do
it "returns artifacts when defined" do
config = YAML.dump(
diff --git a/spec/models/user_preference_spec.rb b/spec/models/user_preference_spec.rb
index 729635b5a27..401a85e2f82 100644
--- a/spec/models/user_preference_spec.rb
+++ b/spec/models/user_preference_spec.rb
@@ -238,6 +238,20 @@ RSpec.describe UserPreference, feature_category: :user_profile do
end
end
+ describe '#keyboard_shortcuts_enabled' do
+ it 'is set to true by default' do
+ pref = described_class.new
+
+ expect(pref.keyboard_shortcuts_enabled).to eq(true)
+ end
+
+ it 'returns assigned value' do
+ pref = described_class.new(keyboard_shortcuts_enabled: false)
+
+ expect(pref.keyboard_shortcuts_enabled).to eq(false)
+ end
+ end
+
describe '#render_whitespace_in_code' do
it 'is set to false by default' do
pref = described_class.new
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index f286d678360..37263144261 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -65,6 +65,9 @@ RSpec.describe User, feature_category: :user_profile do
it { is_expected.to delegate_method(:project_shortcut_buttons).to(:user_preference) }
it { is_expected.to delegate_method(:project_shortcut_buttons=).to(:user_preference).with_arguments(:args) }
+ it { is_expected.to delegate_method(:keyboard_shortcuts_enabled).to(:user_preference) }
+ it { is_expected.to delegate_method(:keyboard_shortcuts_enabled=).to(:user_preference).with_arguments(:args) }
+
it { is_expected.to delegate_method(:render_whitespace_in_code).to(:user_preference) }
it { is_expected.to delegate_method(:render_whitespace_in_code=).to(:user_preference).with_arguments(:args) }
diff --git a/spec/requests/api/metadata_spec.rb b/spec/requests/api/metadata_spec.rb
index e15186c48a5..b81fe3f51b5 100644
--- a/spec/requests/api/metadata_spec.rb
+++ b/spec/requests/api/metadata_spec.rb
@@ -41,6 +41,22 @@ RSpec.describe API::Metadata, feature_category: :shared do
end
end
+ context 'with ai_features scope' do
+ let(:scopes) { %i(ai_features) }
+
+ it 'returns the metadata information' do
+ get api(endpoint, personal_access_token: personal_access_token)
+
+ expect_metadata
+ end
+
+ it 'returns "200" response on head requests' do
+ head api(endpoint, personal_access_token: personal_access_token)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
context 'with read_user scope' do
let(:scopes) { %i(read_user) }
@@ -57,7 +73,7 @@ RSpec.describe API::Metadata, feature_category: :shared do
end
end
- context 'with neither api nor read_user scope' do
+ context 'with neither api, ai_features nor read_user scope' do
let(:scopes) { %i(read_repository) }
it 'returns authorization error' do
diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb
index 389ae93c986..6573fe570db 100644
--- a/spec/requests/openid_connect_spec.rb
+++ b/spec/requests/openid_connect_spec.rb
@@ -273,7 +273,7 @@ RSpec.describe 'OpenID Connect requests', feature_category: :system_access do
let(:expected_scopes) do
%w[
admin_mode api read_user read_api read_repository write_repository sudo openid profile email
- read_observability write_observability create_runner k8s_proxy
+ read_observability write_observability create_runner k8s_proxy ai_features
]
end