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>2022-01-11 06:16:07 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-01-11 06:16:07 +0300
commitf60515eae2fc00c56742462826ae00826eb8826e (patch)
treed8d3cc877f7f9d9c20d27dd95eb145918d2d77bb
parentd9c0b200e192c340f50fa165a66e4b6ff805f9fc (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/diffs/components/image_diff_overlay.vue16
-rw-r--r--app/controllers/groups/application_controller.rb12
-rw-r--r--app/controllers/groups/runners_controller.rb7
-rw-r--r--app/finders/ci/runners_finder.rb2
-rw-r--r--app/graphql/types/deprecated_mutations.rb3
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/policies/group_policy.rb9
-rw-r--r--app/views/projects/runners/_group_runners.html.haml4
-rw-r--r--doc/api/graphql/reference/index.md31
-rw-r--r--doc/ci/caching/index.md33
-rw-r--r--doc/user/permissions.md325
-rw-r--r--lib/sidebars/groups/menus/ci_cd_menu.rb4
-rw-r--r--locale/gitlab.pot11
-rw-r--r--spec/features/runners_spec.rb25
-rw-r--r--spec/frontend/diffs/components/image_diff_overlay_spec.js19
-rw-r--r--spec/graphql/types/mutation_type_spec.rb8
-rw-r--r--spec/policies/group_policy_spec.rb6
-rw-r--r--spec/support/shared_contexts/policies/group_policy_shared_context.rb26
18 files changed, 324 insertions, 218 deletions
diff --git a/app/assets/javascripts/diffs/components/image_diff_overlay.vue b/app/assets/javascripts/diffs/components/image_diff_overlay.vue
index 5572338908f..eede8e52292 100644
--- a/app/assets/javascripts/diffs/components/image_diff_overlay.vue
+++ b/app/assets/javascripts/diffs/components/image_diff_overlay.vue
@@ -4,8 +4,8 @@ import { isArray } from 'lodash';
import { mapActions, mapGetters } from 'vuex';
import imageDiffMixin from 'ee_else_ce/diffs/mixins/image_diff';
-function calcPercent(pos, size, renderedSize) {
- return (((pos / size) * 100) / ((renderedSize / size) * 100)) * 100;
+function calcPercent(pos, renderedSize) {
+ return (100 * pos) / renderedSize;
}
export default {
@@ -65,8 +65,8 @@ export default {
...mapActions('diffs', ['openDiffFileCommentForm']),
getImageDimensions() {
return {
- width: this.$parent.width,
- height: this.$parent.height,
+ width: Math.round(this.$parent.width),
+ height: Math.round(this.$parent.height),
};
},
getPositionForObject(meta) {
@@ -87,15 +87,15 @@ export default {
},
clickedImage(x, y) {
const { width, height } = this.getImageDimensions();
- const xPercent = calcPercent(x, width, this.renderedWidth);
- const yPercent = calcPercent(y, height, this.renderedHeight);
+ const xPercent = calcPercent(x, this.renderedWidth);
+ const yPercent = calcPercent(y, this.renderedHeight);
this.openDiffFileCommentForm({
fileHash: this.fileHash,
width,
height,
- x: width * (xPercent / 100),
- y: height * (yPercent / 100),
+ x: Math.round(width * (xPercent / 100)),
+ y: Math.round(height * (yPercent / 100)),
xPercent,
yPercent,
});
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index ab67a007bd9..f9c875b80b2 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -37,6 +37,18 @@ class Groups::ApplicationController < ApplicationController
end
end
+ def authorize_admin_group_runners!
+ unless can?(current_user, :admin_group_runners, group)
+ render_404
+ end
+ end
+
+ def authorize_read_group_runners!
+ unless can?(current_user, :read_group_runners, group)
+ render_404
+ end
+ end
+
def authorize_create_deploy_token!
unless can?(current_user, :create_deploy_token, group)
render_404
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index 5c21c7b023c..f602d02a165 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -1,9 +1,8 @@
# frozen_string_literal: true
class Groups::RunnersController < Groups::ApplicationController
- # TODO Proper policies, such as `read_group_runners, should be implemented per
- # https://gitlab.com/gitlab-org/gitlab/-/issues/334802
- before_action :authorize_admin_group!
+ before_action :authorize_read_group_runners!, only: [:index, :show]
+ before_action :authorize_admin_group_runners!, only: [:edit, :update, :destroy, :pause, :resume]
before_action :runner_list_group_view_vue_ui_enabled, only: [:index]
before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
@@ -17,7 +16,7 @@ class Groups::RunnersController < Groups::ApplicationController
end
def runner_list_group_view_vue_ui_enabled
- return render_404 unless Feature.enabled?(:runner_list_group_view_vue_ui, group, default_enabled: :yaml)
+ render_404 unless Feature.enabled?(:runner_list_group_view_vue_ui, group, default_enabled: :yaml)
end
def show
diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb
index a514d2e8d03..3ebf6bd1562 100644
--- a/app/finders/ci/runners_finder.rb
+++ b/app/finders/ci/runners_finder.rb
@@ -47,7 +47,7 @@ module Ci
end
def group_runners
- raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :admin_group, @group)
+ raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :read_group_runners, @group)
@runners = case @params[:membership]
when :direct
diff --git a/app/graphql/types/deprecated_mutations.rb b/app/graphql/types/deprecated_mutations.rb
index 49bad56b6f9..70d5fc31cd1 100644
--- a/app/graphql/types/deprecated_mutations.rb
+++ b/app/graphql/types/deprecated_mutations.rb
@@ -5,7 +5,8 @@ module Types
extend ActiveSupport::Concern
prepended do
- # placeholder for any FOSS mutations to be deprecated
+ mount_mutation Mutations::Clusters::AgentTokens::Delete,
+ deprecated: { reason: 'Tokens must be revoked with ClusterAgentTokenRevoke', milestone: '14.7' }
end
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index c9f083efd27..e01bb0b4e70 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -35,7 +35,6 @@ module Types
mount_mutation Mutations::Clusters::Agents::Create
mount_mutation Mutations::Clusters::Agents::Delete
mount_mutation Mutations::Clusters::AgentTokens::Create
- mount_mutation Mutations::Clusters::AgentTokens::Delete
mount_mutation Mutations::Clusters::AgentTokens::Revoke
mount_mutation Mutations::Commits::Create, calls_gitaly: true
mount_mutation Mutations::CustomEmoji::Create, feature_flag: :custom_emoji
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 71133008565..05adcd51082 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -165,7 +165,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :destroy_package
enable :create_projects
enable :admin_pipeline
- enable :admin_group_runners
enable :admin_build
enable :read_cluster
enable :add_cluster
@@ -183,6 +182,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :admin_group_member
enable :change_visibility_level
+ enable :read_group_runners
+ enable :admin_group_runners
+ enable :register_group_runners
+
enable :set_note_created_at
enable :set_emails_disabled
enable :change_prevent_sharing_groups_outside_hierarchy
@@ -208,10 +211,6 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_nested_project_resources
end
- rule { can?(:admin_group_runners) }.policy do
- enable :register_group_runners
- end
-
rule { owner }.enable :create_subgroup
rule { maintainer & maintainer_can_create_group }.enable :create_subgroup
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index 183e747afdd..c25fd7a7587 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -29,9 +29,9 @@
- if can?(current_user, :admin_group_runners, @project.group)
- group_link = link_to _("group's CI/CD settings."), group_settings_ci_cd_path(@project.group)
- = _('Group maintainers can register group runners in the %{link}').html_safe % { link: group_link }
+ = _('Group owners can register group runners in the %{link}').html_safe % { link: group_link }
- else
- = _('Ask your group maintainer to set up a group runner.')
+ = _('Ask your group owner to set up a group runner.')
- else
%h4.underlined-title
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index e5cd42dc4da..465c3027838 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -954,6 +954,10 @@ Input type: `ClusterAgentTokenCreateInput`
### `Mutation.clusterAgentTokenDelete`
+WARNING:
+**Deprecated** in 14.7.
+Tokens must be revoked with ClusterAgentTokenRevoke.
+
Input type: `ClusterAgentTokenDeleteInput`
#### Arguments
@@ -4931,6 +4935,27 @@ Input type: `VulnerabilityExternalIssueLinkDestroyInput`
| <a id="mutationvulnerabilityexternalissuelinkdestroyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationvulnerabilityexternalissuelinkdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+### `Mutation.vulnerabilityFindingDismiss`
+
+Input type: `VulnerabilityFindingDismissInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilityfindingdismissclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilityfindingdismisscomment"></a>`comment` | [`String`](#string) | Comment why finding should be dismissed. |
+| <a id="mutationvulnerabilityfindingdismissdismissalreason"></a>`dismissalReason` | [`VulnerabilityDismissalReason`](#vulnerabilitydismissalreason) | Reason why finding should be dismissed. |
+| <a id="mutationvulnerabilityfindingdismissid"></a>`id` | [`VulnerabilitiesFindingID!`](#vulnerabilitiesfindingid) | ID of the finding to be dismissed. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilityfindingdismissclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilityfindingdismisserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationvulnerabilityfindingdismissfinding"></a>`finding` | [`PipelineSecurityReportFinding`](#pipelinesecurityreportfinding) | Finding after dismissal. |
+
### `Mutation.vulnerabilityResolve`
Input type: `VulnerabilityResolveInput`
@@ -18182,6 +18207,12 @@ A `VulnerabilitiesExternalIssueLinkID` is a global ID. It is encoded as a string
An example `VulnerabilitiesExternalIssueLinkID` is: `"gid://gitlab/Vulnerabilities::ExternalIssueLink/1"`.
+### `VulnerabilitiesFindingID`
+
+A `VulnerabilitiesFindingID` is a global ID. It is encoded as a string.
+
+An example `VulnerabilitiesFindingID` is: `"gid://gitlab/Vulnerabilities::Finding/1"`.
+
### `VulnerabilitiesScannerID`
A `VulnerabilitiesScannerID` is a global ID. It is encoded as a string.
diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md
index 491454aed28..c634491662d 100644
--- a/doc/ci/caching/index.md
+++ b/doc/ci/caching/index.md
@@ -235,6 +235,39 @@ test_async:
- node ./specs/start.js ./specs/async.spec.js
```
+#### Compute the cache key from the lock file
+
+You can use [`cache:key:files`](../yaml/index.md#cachekeyfiles) to compute the cache
+key from a lock file like `package-lock.json` or `yarn.lock`, and reuse it in many jobs.
+
+```yaml
+# Cache modules using lock file
+cache:
+ key:
+ files:
+ - package-lock.json
+ paths:
+ - .npm/
+```
+
+If you're using [Yarn](https://yarnpkg.com/), you can use [`yarn-offline-mirror`](https://classic.yarnpkg.com/blog/2016/11/24/offline-mirror/)
+to cache the zipped `node_modules` tarballs. The cache generates more quickly, because
+fewer files have to be compressed:
+
+```yaml
+job:
+ script:
+ - echo 'yarn-offline-mirror ".yarn-cache/"' >> .yarnrc
+ - echo 'yarn-offline-mirror-pruning true' >> .yarnrc
+ - yarn install --frozen-lockfile --no-progress
+ cache:
+ key:
+ files:
+ - yarn.lock
+ paths:
+ - .yarn-cache/
+```
+
### Cache PHP dependencies
If your project uses [Composer](https://getcomposer.org/) to install
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 3cb07ecfe99..36c49e39151 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -46,168 +46,169 @@ The following table lists project permissions available for each role:
<!-- Keep this table sorted: By topic first, then by minimum role, then alphabetically. -->
-| Action | Guest | Reporter | Developer | Maintainer | Owner |
-|-------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|-------|
-| [Analytics](analytics/index.md):<br>View issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>View licenses in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Manage [security policy](application_security/policies/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>View [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ |
-| [CI/CD](../ci/index.md):<br>Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View [environments](../ci/environments/index.md) | | ✓ | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Cancel and retry jobs | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Create new [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Stop [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Manage CI/CD variables | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Manage job triggers | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Manage runners | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | ✓ | ✓ |
-| [CI/CD](../ci/index.md):<br>Delete pipelines | | | | | ✓ |
-| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
-| [Clusters](infrastructure/clusters/index.md):<br>Manage clusters | | | | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Remove a container registry image | | | ✓ | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Update container registry | | | ✓ | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Manage | | | | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Remove GitLab Pages | | | | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [alerts](../operations/incident_management/alerts.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Assign an alert | ✓| ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [incident](../operations/incident_management/incidents.md) | ✓| ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Create [incident](../operations/incident_management/incidents.md) | (*17*) | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [on-call schedules](../operations/incident_management/oncall_schedules.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Participate in on-call rotation | ✓| ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [escalation policies](../operations/incident_management/escalation_policies.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Manage [on-call schedules](../operations/incident_management/oncall_schedules.md) | | | | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Manage [escalation policies](../operations/incident_management/escalation_policies.md)| | | | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Add Labels | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Create | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Close / reopen | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Lock threads | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Manage related issues | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Manage tracker | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Move issues (*15*) | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Set issue [time tracking](project/time_tracking.md) estimate and time spent | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Delete | | | | | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Assign reviewer | | ✓ | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>See list | | ✓ | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Apply code change suggestions | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Approve (*9*) | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Assign | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Create (*18*) | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Add labels | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Lock threads | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Manage or accept | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Manage merge approval rules (project settings) | | | | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Delete | | | | | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Publish package | | | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Delete package | | | | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ |
-| [Projects](project/index.md):<br>View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [project traffic statistics](../api/project_statistics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) |
-| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Enable Review Apps | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ |
-| [Projects](project/index.md):<br>Add deploy keys | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Add new team members | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (14) | ✓ |
-| [Projects](project/index.md):<br>Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit comments (posted by any user) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit project settings | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Export project | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage [project access tokens](project/settings/project_access_tokens.md) **(FREE SELF)** **(PREMIUM SAAS)** (*12*) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*) |
-| [Projects](project/index.md):<br>View 2FA status of members | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Administer project compliance frameworks | | | | | ✓ |
-| [Projects](project/index.md):<br>Archive project | | | | | ✓ |
-| [Projects](project/index.md):<br>Change project visibility level | | | | | ✓ |
-| [Projects](project/index.md):<br>Delete project | | | | | ✓ |
-| [Projects](project/index.md):<br>Disable notification emails | | | | | ✓ |
-| [Projects](project/index.md):<br>Rename project | | | | | ✓ |
-| [Projects](project/index.md):<br>Transfer project to another namespace | | | | | ✓ |
-| [Repository](project/repository/index.md):<br>Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>View a commit status | | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Add tags | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Create new branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Create or update commit status | | | ✓ (*5*) | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Force push to non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Push to non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Remove non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Rewrite or remove Git tags | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Enable or disable branch protection | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Enable or disable tag protection | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Push to protected branches (*5*) | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Turn on or off protected branch push for developers | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Remove fork relationship | | | | | ✓ |
-| [Repository](project/repository/index.md):<br>Force push to protected branches (*4*) | | | | | |
-| [Repository](project/repository/index.md):<br>Remove protected branches (*4*) | | | | | |
-| [Requirements Management](project/requirements/index.md):<br>Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Requirements Management](project/requirements/index.md):<br>Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Requirements Management](project/requirements/index.md):<br>Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Resolve vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Revert vulnerability to detected state **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability findings in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Terraform](infrastructure/index.md):<br>Read Terraform state | | | ✓ | ✓ | ✓ |
-| [Terraform](infrastructure/index.md):<br>Manage Terraform state | | | | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Archive | | ✓ | ✓ | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Create | | ✓ | ✓ | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Move | | ✓ | ✓ | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Reopen | | ✓ | ✓ | ✓ | ✓ |
+| Action | Guest | Reporter | Developer | Maintainer | Owner |
+|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|-------|
+| [Analytics](analytics/index.md):<br>View issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>View licenses in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Manage [security policy](application_security/policies/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>View [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ |
+| [CI/CD](../ci/index.md):<br>Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View [environments](../ci/environments/index.md) | | ✓ | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Cancel and retry jobs | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Create new [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Stop [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage CI/CD variables | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage job triggers | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage group runners | | | | | ✓ |
+| [CI/CD](../ci/index.md):<br>Manage project runners | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | ✓ | ✓ |
+| [CI/CD](../ci/index.md):<br>Delete pipelines | | | | | ✓ |
+| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
+| [Clusters](infrastructure/clusters/index.md):<br>Manage clusters | | | | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Remove a container registry image | | | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Update container registry | | | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Remove GitLab Pages | | | | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [alerts](../operations/incident_management/alerts.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Assign an alert | ✓| ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [incident](../operations/incident_management/incidents.md) | ✓| ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Create [incident](../operations/incident_management/incidents.md) | (*17*) | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [on-call schedules](../operations/incident_management/oncall_schedules.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Participate in on-call rotation | ✓| ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [escalation policies](../operations/incident_management/escalation_policies.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Manage [on-call schedules](../operations/incident_management/oncall_schedules.md) | | | | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Manage [escalation policies](../operations/incident_management/escalation_policies.md) | | | | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Add Labels | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Create | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Close / reopen | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Lock threads | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Manage related issues | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Manage tracker | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Move issues (*15*) | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Set issue [time tracking](project/time_tracking.md) estimate and time spent | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Delete | | | | | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Assign reviewer | | ✓ | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>See list | | ✓ | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Apply code change suggestions | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Approve (*9*) | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Assign | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Create (*18*) | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Add labels | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Lock threads | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Manage or accept | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Manage merge approval rules (project settings) | | | | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Delete | | | | | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Publish package | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Delete package | | | | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ |
+| [Projects](project/index.md):<br>View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [project traffic statistics](../api/project_statistics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) |
+| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Enable Review Apps | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ |
+| [Projects](project/index.md):<br>Add deploy keys | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Add new team members | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (14) | ✓ |
+| [Projects](project/index.md):<br>Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit comments (posted by any user) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit project settings | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Export project | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage [project access tokens](project/settings/project_access_tokens.md) **(FREE SELF)** **(PREMIUM SAAS)** (*12*) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*) |
+| [Projects](project/index.md):<br>View 2FA status of members | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Administer project compliance frameworks | | | | | ✓ |
+| [Projects](project/index.md):<br>Archive project | | | | | ✓ |
+| [Projects](project/index.md):<br>Change project visibility level | | | | | ✓ |
+| [Projects](project/index.md):<br>Delete project | | | | | ✓ |
+| [Projects](project/index.md):<br>Disable notification emails | | | | | ✓ |
+| [Projects](project/index.md):<br>Rename project | | | | | ✓ |
+| [Projects](project/index.md):<br>Transfer project to another namespace | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View a commit status | | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Add tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create new branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create or update commit status | | | ✓ (*5*) | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Rewrite or remove Git tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable branch protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable tag protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to protected branches (*5*) | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Turn on or off protected branch push for developers | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove fork relationship | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to protected branches (*4*) | | | | | |
+| [Repository](project/repository/index.md):<br>Remove protected branches (*4*) | | | | | |
+| [Requirements Management](project/requirements/index.md):<br>Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Resolve vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Revert vulnerability to detected state **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability findings in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| [Terraform](infrastructure/index.md):<br>Read Terraform state | | | ✓ | ✓ | ✓ |
+| [Terraform](infrastructure/index.md):<br>Manage Terraform state | | | | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Archive | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Create | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Move | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Reopen | | ✓ | ✓ | ✓ | ✓ |
1. On self-managed GitLab instances, guest users are able to perform this action only on
public and internal projects (not on private projects). [External users](#external-users)
diff --git a/lib/sidebars/groups/menus/ci_cd_menu.rb b/lib/sidebars/groups/menus/ci_cd_menu.rb
index f5bce57f496..a1f98b918e6 100644
--- a/lib/sidebars/groups/menus/ci_cd_menu.rb
+++ b/lib/sidebars/groups/menus/ci_cd_menu.rb
@@ -34,10 +34,8 @@ module Sidebars
)
end
- # TODO Proper policies, such as `read_group_runners`, should be implemented per
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/334802
def show_runners?
- can?(context.current_user, :admin_group, context.group) &&
+ can?(context.current_user, :read_group_runners, context.group) &&
Feature.enabled?(:runner_list_group_view_vue_ui, context.group, default_enabled: :yaml)
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 1840f630ada..98356de7376 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4793,7 +4793,7 @@ msgstr ""
msgid "Ask someone with write access to resolve it."
msgstr ""
-msgid "Ask your group maintainer to set up a group runner."
+msgid "Ask your group owner to set up a group runner."
msgstr ""
msgid "Assertion consumer service URL"
@@ -16754,9 +16754,6 @@ msgstr ""
msgid "Group jobs by"
msgstr ""
-msgid "Group maintainers can register group runners in the %{link}"
-msgstr ""
-
msgid "Group members"
msgstr ""
@@ -16781,6 +16778,9 @@ msgstr ""
msgid "Group overview content"
msgstr ""
+msgid "Group owners can register group runners in the %{link}"
+msgstr ""
+
msgid "Group path is already taken. We've suggested one that is available."
msgstr ""
@@ -42052,6 +42052,9 @@ msgstr ""
msgid "failed to dismiss associated finding(id=%{finding_id}): %{message}"
msgstr ""
+msgid "failed to dismiss finding: %{message}"
+msgstr ""
+
msgid "failed to revert associated finding(id=%{finding_id}) to detected"
msgstr ""
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 22de77f7cd0..49c468976b9 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -268,10 +268,27 @@ RSpec.describe 'Runners' do
it 'group runners are not available' do
visit project_runners_path(project)
+ expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).to have_content 'Ask your group owner to set up a group runner'
+ end
+ end
+ end
+
+ context 'as project maintainer and group owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ context 'project with a group but no group runner' do
+ let(:project) { create :project, group: group }
+
+ it 'group runners are available' do
+ visit project_runners_path(project)
+
expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.'
- expect(page).not_to have_content 'Ask your group maintainer to set up a group runner'
+ expect(page).to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).not_to have_content 'Ask your group owner to set up a group runner'
end
end
end
@@ -296,8 +313,8 @@ RSpec.describe 'Runners' do
expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).not_to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.'
- expect(page).to have_content 'Ask your group maintainer to set up a group runner.'
+ expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).to have_content 'Ask your group owner to set up a group runner.'
end
end
diff --git a/spec/frontend/diffs/components/image_diff_overlay_spec.js b/spec/frontend/diffs/components/image_diff_overlay_spec.js
index 47b144b2387..8c1a8041f6c 100644
--- a/spec/frontend/diffs/components/image_diff_overlay_spec.js
+++ b/spec/frontend/diffs/components/image_diff_overlay_spec.js
@@ -6,8 +6,8 @@ import { imageDiffDiscussions } from '../mock_data/diff_discussions';
describe('Diffs image diff overlay component', () => {
const dimensions = {
- width: 100,
- height: 200,
+ width: 99.9,
+ height: 199.5,
};
let wrapper;
let dispatch;
@@ -38,7 +38,6 @@ describe('Diffs image diff overlay component', () => {
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
it('renders comment badges', () => {
@@ -81,17 +80,21 @@ describe('Diffs image diff overlay component', () => {
it('dispatches openDiffFileCommentForm when clicking overlay', () => {
createComponent({ canComment: true });
- wrapper.find('.js-add-image-diff-note-button').trigger('click', { offsetX: 0, offsetY: 0 });
+ wrapper.find('.js-add-image-diff-note-button').trigger('click', { offsetX: 1.2, offsetY: 3.8 });
expect(dispatch).toHaveBeenCalledWith('diffs/openDiffFileCommentForm', {
fileHash: 'ABC',
- x: 0,
- y: 0,
+ x: 1,
+ y: 4,
width: 100,
height: 200,
- xPercent: 0,
- yPercent: 0,
+ xPercent: expect.any(Number),
+ yPercent: expect.any(Number),
});
+
+ const { xPercent, yPercent } = dispatch.mock.calls[0][1];
+ expect(xPercent).toBeCloseTo(0.6);
+ expect(yPercent).toBeCloseTo(1.9);
});
describe('toggle discussion', () => {
diff --git a/spec/graphql/types/mutation_type_spec.rb b/spec/graphql/types/mutation_type_spec.rb
index 95d835c88cf..1fc46f2d511 100644
--- a/spec/graphql/types/mutation_type_spec.rb
+++ b/spec/graphql/types/mutation_type_spec.rb
@@ -7,6 +7,14 @@ RSpec.describe Types::MutationType do
expect(described_class).to have_graphql_mutation(Mutations::MergeRequests::SetDraft)
end
+ describe 'deprecated mutations' do
+ describe 'clusterAgentTokenDelete' do
+ let(:field) { get_field('clusterAgentTokenDelete') }
+
+ it { expect(field.deprecation_reason).to eq('Tokens must be revoked with ClusterAgentTokenRevoke. Deprecated in 14.7.') }
+ end
+ end
+
def get_field(name)
described_class.fields[GraphqlHelpers.fieldnamerize(name)]
end
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 08fc8d2e77c..d2dee3b781c 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -36,6 +36,7 @@ RSpec.describe GroupPolicy do
it { expect_disallowed(:read_crm_organization) }
it { expect_disallowed(:read_crm_contact) }
it { expect_disallowed(:read_counts) }
+ it { expect_disallowed(:read_group_runners) }
it { expect_disallowed(*read_group_permissions) }
end
@@ -51,6 +52,7 @@ RSpec.describe GroupPolicy do
it { expect_disallowed(:read_crm_organization) }
it { expect_disallowed(:read_crm_contact) }
it { expect_disallowed(:read_counts) }
+ it { expect_disallowed(:read_group_runners) }
it { expect_disallowed(*read_group_permissions) }
end
@@ -1126,9 +1128,7 @@ RSpec.describe GroupPolicy do
context 'with maintainer' do
let(:current_user) { maintainer }
- it { is_expected.to be_allowed(:register_group_runners) }
-
- it_behaves_like 'expected outcome based on runner registration control'
+ it { is_expected.to be_disallowed(:register_group_runners) }
end
context 'with reporter' do
diff --git a/spec/support/shared_contexts/policies/group_policy_shared_context.rb b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
index 88b0d997a80..db778086692 100644
--- a/spec/support/shared_contexts/policies/group_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/group_policy_shared_context.rb
@@ -48,22 +48,24 @@ RSpec.shared_context 'GroupPolicy context' do
destroy_package
create_projects
read_cluster create_cluster update_cluster admin_cluster add_cluster
- admin_group_runners
]
end
let(:owner_permissions) do
- [
- :owner_access,
- :admin_group,
- :admin_namespace,
- :admin_group_member,
- :change_visibility_level,
- :set_note_created_at,
- :create_subgroup,
- :read_statistics,
- :update_default_branch_protection
- ].compact
+ %i[
+ owner_access
+ admin_group
+ admin_namespace
+ admin_group_member
+ change_visibility_level
+ set_note_created_at
+ create_subgroup
+ read_statistics
+ update_default_branch_protection
+ read_group_runners
+ admin_group_runners
+ register_group_runners
+ ]
end
let(:admin_permissions) { %i[read_confidential_issues] }