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:
-rw-r--r--.gitlab-ci.yml3
-rw-r--r--.rubocop.yml1
-rw-r--r--app/assets/javascripts/admin/users/components/actions/ban.vue2
-rw-r--r--app/assets/javascripts/analytics/shared/constants.js4
-rw-r--r--app/assets/javascripts/content_editor/components/suggestions_dropdown.vue149
-rw-r--r--app/assets/javascripts/pages/groups/new/components/app.vue8
-rw-r--r--app/assets/javascripts/projects/new/components/app.vue16
-rw-r--r--app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue11
-rw-r--r--app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue8
-rw-r--r--app/assets/stylesheets/components/content_editor.scss11
-rw-r--r--app/controllers/profiles/notifications_controller.rb2
-rw-r--r--app/finders/projects_finder.rb10
-rw-r--r--app/helpers/environment_helper.rb7
-rw-r--r--app/helpers/environments_helper.rb18
-rw-r--r--app/helpers/projects_helper.rb12
-rw-r--r--app/helpers/web_ide_button_helper.rb4
-rw-r--r--app/models/project.rb14
-rw-r--r--app/policies/project_policy.rb8
-rw-r--r--app/presenters/alert_management/alert_presenter.rb12
-rw-r--r--app/serializers/environment_entity.rb8
-rw-r--r--app/serializers/environment_status_entity.rb4
-rw-r--r--app/views/admin/hooks/_form.html.haml2
-rw-r--r--app/views/admin/hooks/index.html.haml7
-rw-r--r--app/views/notify/prometheus_alert_fired_email.html.haml4
-rw-r--r--app/views/notify/prometheus_alert_fired_email.text.erb4
-rw-r--r--app/views/projects/_export.html.haml14
-rw-r--r--app/views/projects/branches/index.html.haml8
-rw-r--r--app/views/projects/hooks/index.html.haml7
-rw-r--r--app/views/projects/tags/_edit_release_button.html.haml3
-rw-r--r--app/views/registrations/welcome/show.html.haml1
-rw-r--r--app/views/shared/file_hooks/_index.html.haml16
-rw-r--r--app/views/shared/web_hooks/_form.html.haml2
-rw-r--r--app/views/shared/web_hooks/_title_and_docs.html.haml6
-rw-r--r--app/views/users/_overview.html.haml6
-rw-r--r--config/application.rb3
-rw-r--r--config/feature_flags/development/hide_projects_of_banned_users.yml (renamed from config/feature_flags/development/ai_chat_history_context.yml)10
-rw-r--r--config/routes.rb1
-rw-r--r--config/routes/project.rb8
-rw-r--r--data/deprecations/15-9-accessibility-testing-deprecation.yml26
-rw-r--r--data/deprecations/15-9-browser-performance-testing-deprecation.yml26
-rw-r--r--data/deprecations/15-9-load-performance-testing-deprecation.yml26
-rw-r--r--db/post_migrate/20230626101519_create_index_for_vulnerability_reads_on_common_project_filters.rb18
-rw-r--r--db/schema_migrations/202306261015191
-rw-r--r--db/structure.sql2
-rw-r--r--doc/api/groups.md1
-rw-r--r--doc/api/users.md2
-rw-r--r--doc/architecture/blueprints/gitlab_ci_events/index.md1
-rw-r--r--doc/development/value_stream_analytics.md4
-rw-r--r--doc/tutorials/left_sidebar/index.md5
-rw-r--r--doc/update/deprecations.md42
-rw-r--r--doc/user/admin_area/moderate_users.md3
-rw-r--r--doc/user/analytics/value_streams_dashboard.md6
-rw-r--r--doc/user/group/saml_sso/index.md7
-rw-r--r--doc/user/group/value_stream_analytics/index.md18
-rw-r--r--doc/user/project/pages/introduction.md7
-rw-r--r--lib/api/helpers/custom_attributes.rb2
-rw-r--r--lib/api/helpers/integrations_helpers.rb58
-rw-r--r--lib/gitlab/alert_management/payload/prometheus.rb12
-rw-r--r--lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb45
-rw-r--r--lib/gitlab/metrics/dashboard/url.rb25
-rw-r--r--lib/gitlab/uuid.rb9
-rw-r--r--locale/gitlab.pot46
-rw-r--r--rubocop/formatter/todo_formatter.rb4
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb12
-rw-r--r--spec/factories/project_authorizations.rb4
-rw-r--r--spec/finders/projects_finder_spec.rb30
-rw-r--r--spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json60
-rw-r--r--spec/frontend/content_editor/components/suggestions_dropdown_spec.js9
-rw-r--r--spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap2
-rw-r--r--spec/frontend/pages/groups/new/components/app_spec.js5
-rw-r--r--spec/frontend/projects/new/components/__snapshots__/app_spec.js.snap30
-rw-r--r--spec/frontend/projects/new/components/app_spec.js6
-rw-r--r--spec/frontend/vue_shared/new_namespace/components/welcome_spec.js12
-rw-r--r--spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js9
-rw-r--r--spec/graphql/resolvers/users/participants_resolver_spec.rb3
-rw-r--r--spec/helpers/environment_helper_spec.rb12
-rw-r--r--spec/helpers/environments_helper_spec.rb26
-rw-r--r--spec/helpers/projects_helper_spec.rb101
-rw-r--r--spec/lib/gitlab/alert_management/payload/prometheus_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/dashboard/url_spec.rb80
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb2
-rw-r--r--spec/mailers/emails/projects_spec.rb3
-rw-r--r--spec/models/project_spec.rb61
-rw-r--r--spec/policies/project_policy_spec.rb26
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb6
-rw-r--r--spec/rubocop/formatter/todo_formatter_spec.rb4
-rw-r--r--spec/serializers/environment_entity_spec.rb26
-rw-r--r--spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb2
-rw-r--r--spec/support/shared_contexts/prometheus/alert_shared_context.rb11
-rw-r--r--spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb30
-rw-r--r--spec/support/shared_examples/features/content_editor_shared_examples.rb10
91 files changed, 593 insertions, 801 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6f60343a96f..a5f07b312fb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -119,6 +119,9 @@ workflow:
variables:
<<: *default-ruby-variables
PIPELINE_NAME: 'Ruby $RUBY_VERSION $CI_COMMIT_BRANCH branch pipeline'
+ - if: '$CI_PROJECT_PATH == "gitlab/gitaly" && $CI_PIPELINE_SOURCE == "parent_pipeline" && $GITALY_TEST'
+ variables:
+ PIPELINE_NAME: 'Gitaly Rails Test Pipeline'
variables:
PG_VERSION: "14"
diff --git a/.rubocop.yml b/.rubocop.yml
index 8edba38cc65..dcd66eeea92 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -40,6 +40,7 @@ AllCops:
TargetRubyVersion: <%= RUBY_VERSION[/^\d+\.\d+/, 0] %>
TargetRailsVersion: 6.0
Exclude:
+ - 'gems/**/*'
- 'vendor/**/*'
- 'node_modules/**/*'
- 'db/fixtures/**/*'
diff --git a/app/assets/javascripts/admin/users/components/actions/ban.vue b/app/assets/javascripts/admin/users/components/actions/ban.vue
index d7bdceb4798..36dcde619cf 100644
--- a/app/assets/javascripts/admin/users/components/actions/ban.vue
+++ b/app/assets/javascripts/admin/users/components/actions/ban.vue
@@ -12,7 +12,7 @@ const messageHtml = `
<li>${s__("AdminUsers|The user can't log in.")}</li>
<li>${s__("AdminUsers|The user can't access git repositories.")}</li>
<li>${s__(
- 'AdminUsers|Issues and merge requests authored by this user are hidden from other users.',
+ 'AdminUsers|Projects, issues, merge requests, and comments of this user are hidden from other users.',
)}</li>
</ul>
<p>${s__('AdminUsers|You can unban their account in the future. Their data remains intact.')}</p>
diff --git a/app/assets/javascripts/analytics/shared/constants.js b/app/assets/javascripts/analytics/shared/constants.js
index 25699c17b10..7ec7eac24ec 100644
--- a/app/assets/javascripts/analytics/shared/constants.js
+++ b/app/assets/javascripts/analytics/shared/constants.js
@@ -39,8 +39,8 @@ export const DORA_METRICS = {
};
const VSA_FLOW_METRICS_GROUP = {
- key: 'key_metrics',
- title: s__('ValueStreamAnalytics|Key metrics'),
+ key: 'lifecycle_metrics',
+ title: s__('ValueStreamAnalytics|Lifecycle metrics'),
keys: Object.values(FLOW_METRICS),
};
diff --git a/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue b/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue
index 4074e50a706..947a952de3c 100644
--- a/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue
+++ b/app/assets/javascripts/content_editor/components/suggestions_dropdown.vue
@@ -1,9 +1,8 @@
<script>
-import { GlDropdownItem, GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui';
+import { GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui';
export default {
components: {
- GlDropdownItem,
GlAvatarLabeled,
GlLoadingIcon,
},
@@ -43,7 +42,7 @@ export default {
data() {
return {
- selectedIndex: 0,
+ selectedIndex: -1,
};
},
@@ -95,7 +94,7 @@ export default {
watch: {
items() {
- this.selectedIndex = 0;
+ this.selectedIndex = -1;
},
selectedIndex() {
this.scrollIntoView();
@@ -193,7 +192,7 @@ export default {
},
scrollIntoView() {
- this.$refs.dropdownItems[this.selectedIndex].$el.scrollIntoView({ block: 'nearest' });
+ this.$refs.dropdownItems[this.selectedIndex]?.scrollIntoView({ block: 'nearest' });
},
selectItem(index) {
@@ -215,73 +214,85 @@ export default {
</script>
<template>
- <div>
- <ul
- v-if="!loading"
- :class="{ show: items.length > 0 }"
- class="gl-dropdown dropdown-menu gl-relative gl-m-0!"
- data-testid="content-editor-suggestions-dropdown"
- >
- <div class="gl-dropdown-inner gl-overflow-y-auto">
- <gl-dropdown-item
- v-for="(item, index) in items"
- ref="dropdownItems"
- :key="index"
- :class="{ 'gl-bg-gray-50': index === selectedIndex }"
- @click="selectItem(index)"
+ <div class="gl-new-dropdown content-editor-suggestions-dropdown">
+ <div class="gl-new-dropdown-panel gl-display-block! gl-absolute">
+ <div class="gl-new-dropdown-inner">
+ <ul
+ v-if="!loading && items.length > 0"
+ class="gl-new-dropdown-contents"
+ data-testid="content-editor-suggestions-dropdown"
>
- <gl-avatar-labeled
- v-if="isUser"
- :label="item.username"
- :sub-label="avatarSubLabel(item)"
- :src="item.avatar_url"
- :entity-name="item.username"
- :shape="item.type === 'Group' ? 'rect' : 'circle'"
- :size="32"
- />
- <span v-if="isIssue || isMergeRequest">
- <small>{{ item.iid }}</small>
- {{ item.title }}
- </span>
- <span v-if="isVulnerability || isSnippet">
- <small>{{ item.id }}</small>
- {{ item.title }}
- </span>
- <span v-if="isEpic">
- <small>{{ item.reference }}</small>
- {{ item.title }}
- </span>
- <span v-if="isMilestone">
- {{ item.title }}
- </span>
- <span v-if="isLabel" class="gl-display-flex gl-align-items-center">
- <span
- data-testid="label-color-box"
- class="gl-rounded-base gl-display-block gl-w-5 gl-h-5 gl-mr-3"
- :style="{ backgroundColor: item.color }"
- ></span>
- {{ item.title }}
- </span>
- <span v-if="isCommand">
- /{{ item.name }} <small> {{ item.params[0] }} </small><br />
- <em>
- <small> {{ item.description }} </small>
- </em>
- </span>
- <div v-if="isEmoji" class="gl-display-flex gl-align-items-center">
- <div class="gl-pr-4 gl-font-lg">{{ item.e }}</div>
- <div class="gl-flex-grow-1">
- {{ item.name }}<br />
- <small>{{ item.d }}</small>
+ <li
+ v-for="(item, index) in items"
+ :key="index"
+ role="presentation"
+ class="gl-new-dropdown-item"
+ :class="{ focused: index === selectedIndex }"
+ >
+ <div
+ ref="dropdownItems"
+ type="button"
+ role="menuitem"
+ class="gl-new-dropdown-item-content"
+ @click="selectItem(index)"
+ >
+ <div class="gl-new-dropdown-item-text-wrapper">
+ <gl-avatar-labeled
+ v-if="isUser"
+ :label="item.username"
+ :sub-label="avatarSubLabel(item)"
+ :src="item.avatar_url"
+ :entity-name="item.username"
+ :shape="item.type === 'Group' ? 'rect' : 'circle'"
+ :size="32"
+ />
+ <span v-if="isIssue || isMergeRequest">
+ <small>{{ item.iid }}</small>
+ {{ item.title }}
+ </span>
+ <span v-if="isVulnerability || isSnippet">
+ <small>{{ item.id }}</small>
+ {{ item.title }}
+ </span>
+ <span v-if="isEpic">
+ <small>{{ item.reference }}</small>
+ {{ item.title }}
+ </span>
+ <span v-if="isMilestone">
+ {{ item.title }}
+ </span>
+ <span v-if="isLabel" class="gl-display-flex">
+ <span
+ data-testid="label-color-box"
+ class="dropdown-label-box gl-flex-shrink-0 gl-top-0 gl-mr-3"
+ :style="{ backgroundColor: item.color }"
+ ></span>
+ {{ item.title }}
+ </span>
+ <div v-if="isCommand">
+ <div class="gl-mb-1">
+ <span class="gl-font-weight-bold">/{{ item.name }}</span>
+ <em class="gl-text-gray-500 gl-font-sm">{{ item.params[0] }}</em>
+ </div>
+ <small class="gl-text-gray-500"> {{ item.description }} </small>
+ </div>
+ <div v-if="isEmoji" class="gl-display-flex gl-align-items-center">
+ <div class="gl-pr-4 gl-font-lg">{{ item.e }}</div>
+ <div class="gl-flex-grow-1">
+ {{ item.name }}<br />
+ <small>{{ item.d }}</small>
+ </div>
+ </div>
+ </div>
+ </div>
+ </li>
+ </ul>
+ <div v-if="loading" class="gl-new-dropdown show dropdown-menu gl-relative gl-m-0!">
+ <div class="gl-new-dropdown-inner gl-overflow-y-auto">
+ <div class="gl-px-5">
+ <gl-loading-icon size="sm" class="gl-display-inline-block" /> {{ __('Loading...') }}
</div>
</div>
- </gl-dropdown-item>
- </div>
- </ul>
- <div v-if="loading" class="gl-dropdown show dropdown-menu gl-relative gl-m-0!">
- <div class="gl-dropdown-inner gl-overflow-y-auto">
- <div class="gl-px-5">
- <gl-loading-icon size="sm" class="gl-display-inline-block" /> {{ __('Loading...') }}
</div>
</div>
</div>
diff --git a/app/assets/javascripts/pages/groups/new/components/app.vue b/app/assets/javascripts/pages/groups/new/components/app.vue
index 3ee15077d00..876e85e4a47 100644
--- a/app/assets/javascripts/pages/groups/new/components/app.vue
+++ b/app/assets/javascripts/pages/groups/new/components/app.vue
@@ -1,6 +1,6 @@
<script>
-import importGroupIllustration from '@gitlab/svgs/dist/illustrations/group-import.svg?raw';
-import newGroupIllustration from '@gitlab/svgs/dist/illustrations/group-new.svg?raw';
+import GROUP_IMPORT_SVG_URL from '@gitlab/svgs/dist/illustrations/group-import.svg?url';
+import GROUP_NEW_SVG_URL from '@gitlab/svgs/dist/illustrations/group-new.svg?url';
import { s__ } from '~/locale';
import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue';
@@ -69,12 +69,12 @@ export default {
description: s__(
'GroupsNew|Assemble related projects together and grant members access to several projects at once.',
),
- illustration: newGroupIllustration,
details: createGroupDescriptionDetails,
detailProps: {
parentGroupName: this.parentGroupName,
importExistingGroupPath: this.importExistingGroupPath,
},
+ imageSrc: GROUP_NEW_SVG_URL,
},
{
name: 'import-group-pane',
@@ -83,8 +83,8 @@ export default {
description: s__(
'GroupsNew|Import a group and related data from another GitLab instance.',
),
- illustration: importGroupIllustration,
details: 'Migrate your existing groups from another instance of GitLab.',
+ imageSrc: GROUP_IMPORT_SVG_URL,
},
];
},
diff --git a/app/assets/javascripts/projects/new/components/app.vue b/app/assets/javascripts/projects/new/components/app.vue
index 6ca83b0b500..a841766a93c 100644
--- a/app/assets/javascripts/projects/new/components/app.vue
+++ b/app/assets/javascripts/projects/new/components/app.vue
@@ -1,8 +1,8 @@
<script>
-import createFromTemplateIllustration from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg?raw';
-import blankProjectIllustration from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg?raw';
-import importProjectIllustration from '@gitlab/svgs/dist/illustrations/project-import-sm.svg?raw';
-import ciCdProjectIllustration from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg?raw';
+import PROJECT_CREATE_FROM_TEMPLATE_SVG_URL from '@gitlab/svgs/dist/illustrations/project-create-from-template-sm.svg?url';
+import PROJECT_CREATE_NEW_SVG_URL from '@gitlab/svgs/dist/illustrations/project-create-new-sm.svg?url';
+import PROJECT_IMPORT_SVG_URL from '@gitlab/svgs/dist/illustrations/project-import-sm.svg?url';
+import PROJECT_RUN_CICD_PIPELINES_SVG_URL from '@gitlab/svgs/dist/illustrations/project-run-CICD-pipelines-sm.svg?url';
import SafeHtml from '~/vue_shared/directives/safe_html';
import { s__ } from '~/locale';
import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue';
@@ -19,7 +19,7 @@ const PANELS = [
description: s__(
'ProjectsNew|Create a blank project to store your files, plan your work, and collaborate on code, among other things.',
),
- illustration: blankProjectIllustration,
+ imageSrc: PROJECT_CREATE_NEW_SVG_URL,
},
{
key: 'template',
@@ -29,7 +29,7 @@ const PANELS = [
description: s__(
'ProjectsNew|Create a project pre-populated with the necessary files to get you started quickly.',
),
- illustration: createFromTemplateIllustration,
+ imageSrc: PROJECT_CREATE_FROM_TEMPLATE_SVG_URL,
},
{
key: 'import',
@@ -39,7 +39,7 @@ const PANELS = [
description: s__(
'ProjectsNew|Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab.',
),
- illustration: importProjectIllustration,
+ imageSrc: PROJECT_IMPORT_SVG_URL,
},
{
key: 'ci',
@@ -47,7 +47,7 @@ const PANELS = [
selector: '#ci-cd-project-pane',
title: s__('ProjectsNew|Run CI/CD for external repository'),
description: s__('ProjectsNew|Connect your external repository to GitLab CI/CD.'),
- illustration: ciCdProjectIllustration,
+ imageSrc: PROJECT_RUN_CICD_PIPELINES_SVG_URL,
},
];
diff --git a/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue b/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue
index caa85d3eaaf..1b4da047057 100644
--- a/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue
+++ b/app/assets/javascripts/vue_shared/new_namespace/components/welcome.vue
@@ -1,11 +1,7 @@
<script>
-import SafeHtml from '~/vue_shared/directives/safe_html';
import Tracking from '~/tracking';
export default {
- directives: {
- SafeHtml,
- },
mixins: [Tracking.mixin()],
props: {
title: {
@@ -38,9 +34,10 @@ export default {
@click="track('click_tab', { label: panel.name })"
>
<div
- v-safe-html="panel.illustration"
- class="new-namespace-panel-illustration gl-text-white gl-display-flex gl-flex-shrink-0 gl-justify-content-center"
- ></div>
+ class="new-namespace-panel-illustration gl-display-flex gl-flex-shrink-0 gl-justify-content-center"
+ >
+ <img aria-hidden :src="panel.imageSrc" />
+ </div>
<div class="gl-pl-4">
<h3 class="gl-font-size-h2 gl-reset-color">
{{ panel.title }}
diff --git a/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
index 5ab2e346a7a..4503ba6e561 100644
--- a/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
+++ b/app/assets/javascripts/vue_shared/new_namespace/new_namespace_page.vue
@@ -1,6 +1,5 @@
<script>
import { GlBreadcrumb, GlIcon } from '@gitlab/ui';
-import SafeHtml from '~/vue_shared/directives/safe_html';
import NewTopLevelGroupAlert from '~/groups/components/new_top_level_group_alert.vue';
import SuperSidebarToggle from '~/super_sidebar/components/super_sidebar_toggle.vue';
@@ -18,9 +17,6 @@ export default {
LegacyContainer,
SuperSidebarToggle,
},
- directives: {
- SafeHtml,
- },
props: {
title: {
type: String,
@@ -137,7 +133,9 @@ export default {
<template v-if="activePanel">
<div class="gl-display-flex gl-align-items-center gl-py-5">
- <div v-safe-html="activePanel.illustration" class="gl-text-white col-auto"></div>
+ <div class="col-auto">
+ <img aria-hidden :src="activePanel.imageSrc" />
+ </div>
<div class="col">
<h4>{{ activePanel.title }}</h4>
diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss
index 2ed955a56b6..4be39d3fe70 100644
--- a/app/assets/stylesheets/components/content_editor.scss
+++ b/app/assets/stylesheets/components/content_editor.scss
@@ -179,6 +179,17 @@
min-width: auto;
}
+.content-editor-suggestions-dropdown {
+ .gl-new-dropdown-panel {
+ width: max-content;
+ }
+
+ li.focused div.gl-new-dropdown-item-content {
+ @include gl-focus($inset: true);
+ @include gl-bg-gray-50;
+ }
+}
+
.bubble-menu-form {
min-width: 320px;
}
diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb
index b663a75f04a..1477f8e0aac 100644
--- a/app/controllers/profiles/notifications_controller.rb
+++ b/app/controllers/profiles/notifications_controller.rb
@@ -45,7 +45,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController
projects = project_notifications.map(&:source)
ActiveRecord::Associations::Preloader.new(
records: projects,
- associations: { namespace: [:route, :owner], group: [] }
+ associations: { namespace: [:route, :owner], group: [], creator: [] }
).call
Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, current_user).execute
diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb
index 57a9538db15..e6ee4355fd4 100644
--- a/app/finders/projects_finder.rb
+++ b/app/finders/projects_finder.rb
@@ -53,6 +53,10 @@ class ProjectsFinder < UnionFinder
init_collection
end
+ if Feature.enabled?(:hide_projects_of_banned_users)
+ collection = without_created_and_owned_by_banned_user(collection)
+ end
+
use_cte = params.delete(:use_cte)
collection = Project.wrap_with_cte(collection) if use_cte
collection = filter_projects(collection)
@@ -282,6 +286,12 @@ class ProjectsFinder < UnionFinder
{ min_access_level: params[:min_access_level] }
end
+
+ def without_created_and_owned_by_banned_user(projects)
+ return projects if current_user&.can?(:admin_all_resources)
+
+ projects.without_created_and_owned_by_banned_user
+ end
end
ProjectsFinder.prepend_mod_with('ProjectsFinder')
diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb
index 00109212934..8140ee97291 100644
--- a/app/helpers/environment_helper.rb
+++ b/app/helpers/environment_helper.rb
@@ -79,7 +79,6 @@ module EnvironmentHelper
can_destroy_environment: can_destroy_environment?(environment),
can_stop_environment: can?(current_user, :stop_environment, environment),
can_admin_environment: can?(current_user, :admin_environment, project),
- **environment_metrics_path(project, environment),
environments_fetch_path: project_environments_path(project, format: :json),
environment_edit_path: edit_project_environment_path(project, environment),
environment_stop_path: stop_project_environment_path(project, environment),
@@ -96,10 +95,4 @@ module EnvironmentHelper
def environments_detail_data_json(user, project, environment)
environments_detail_data(user, project, environment).to_json
end
-
- def environment_metrics_path(project, environment)
- return {} if Feature.enabled?(:remove_monitor_metrics)
-
- { environment_metrics_path: project_metrics_dashboard_path(project, environment: environment) }
- end
end
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb
index 9ae5170d9c8..3360a5256af 100644
--- a/app/helpers/environments_helper.rb
+++ b/app/helpers/environments_helper.rb
@@ -26,7 +26,7 @@ module EnvironmentsHelper
metrics_data = {}
metrics_data.merge!(project_metrics_data(project)) if project
- metrics_data.merge!(environment_metrics_data(environment, project)) if environment
+ metrics_data.merge!(environment_metrics_data(environment)) if environment
metrics_data.merge!(project_and_environment_metrics_data(project, environment)) if project && environment
metrics_data.merge!(static_metrics_data)
@@ -66,34 +66,20 @@ module EnvironmentsHelper
}
end
- def environment_metrics_data(environment, project = nil)
+ def environment_metrics_data(environment)
return {} unless environment
{
- 'metrics_dashboard_base_path' => metrics_dashboard_base_path(environment, project),
'current_environment_name' => environment.name,
'has_metrics' => environment.has_metrics?.to_s,
'environment_state' => environment.state.to_s
}
end
- def metrics_dashboard_base_path(environment, project)
- # This is needed to support our transition from environment scoped metric paths to project scoped.
- if project
- path = project_metrics_dashboard_path(project)
-
- return path if request.path.include?(path)
- end
-
- project_metrics_dashboard_path(project, environment: environment)
- end
-
def project_and_environment_metrics_data(project, environment)
return {} unless project && environment
{
- 'metrics_endpoint' => additional_metrics_project_environment_path(project, environment, format: :json),
- 'dashboard_endpoint' => metrics_dashboard_project_environment_path(project, environment, format: :json),
'deployments_endpoint' => project_environment_deployments_path(project, environment, format: :json),
'operations_settings_path' => project_settings_operations_path(project),
'can_access_operations_settings' => can?(current_user, :admin_operations, project).to_s,
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 9415e7d4dc3..f27f1a17d79 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -547,6 +547,14 @@ module ProjectsHelper
project.ssh_url_to_repo
end
+ def can_view_branch_rules?
+ can?(current_user, :maintainer_access, @project)
+ end
+
+ def can_push_code?
+ current_user&.can?(:push_code, @project)
+ end
+
private
def create_merge_request_path(project, source_project, ref, merge_request)
@@ -892,10 +900,6 @@ def can_admin_group_clusters?(project)
project.group && project.group.clusters.any? && can?(current_user, :admin_cluster, project.group)
end
-def can_view_branch_rules?
- can?(current_user, :maintainer_access, @project)
-end
-
def branch_rules_path
project_settings_repository_path(@project, anchor: 'js-branch-rules')
end
diff --git a/app/helpers/web_ide_button_helper.rb b/app/helpers/web_ide_button_helper.rb
index 9ec22a659d3..185e1b8e0a8 100644
--- a/app/helpers/web_ide_button_helper.rb
+++ b/app/helpers/web_ide_button_helper.rb
@@ -33,10 +33,6 @@ module WebIdeButtonHelper
can_view_pipeline_editor?(project) && path == project.ci_config_path_or_default
end
- def can_push_code?
- current_user&.can?(:push_code, @project)
- end
-
def fork?
!project_fork.nil? && !can_push_code?
end
diff --git a/app/models/project.rb b/app/models/project.rb
index e4d8830ec48..a45b07d94ce 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -904,6 +904,16 @@ class Project < ApplicationRecord
scope :for_group_and_its_ancestor_groups, ->(group) { where(namespace_id: group.self_and_ancestors.select(:id)) }
scope :is_importing, -> { with_import_state.where(import_state: { status: %w[started scheduled] }) }
+ scope :without_created_and_owned_by_banned_user, -> do
+ where_not_exists(
+ Users::BannedUser.joins(
+ 'INNER JOIN project_authorizations ON project_authorizations.user_id = banned_users.user_id'
+ ).where('projects.creator_id = banned_users.user_id')
+ .where('project_authorizations.project_id = projects.id')
+ .where(project_authorizations: { access_level: Gitlab::Access::OWNER })
+ )
+ end
+
class << self
# Searches for a list of projects based on the query given in `query`.
#
@@ -3169,6 +3179,10 @@ class Project < ApplicationRecord
pending_delete? || hidden?
end
+ def created_and_owned_by_banned_user?
+ creator.banned? && team.max_member_access(creator.id) == Gitlab::Access::OWNER
+ end
+
def content_editor_on_issues_feature_flag_enabled?
group&.content_editor_on_issues_feature_flag_enabled? || Feature.enabled?(:content_editor_on_issues, self)
end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 98acf69a5dc..0891c66853e 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -255,6 +255,10 @@ class ProjectPolicy < BasePolicy
condition(:namespace_catalog_available) { namespace_catalog_available? }
+ condition(:created_and_owned_by_banned_user, scope: :subject) do
+ Feature.enabled?(:hide_projects_of_banned_users) && @subject.created_and_owned_by_banned_user?
+ end
+
# `:read_project` may be prevented in EE, but `:read_project_for_iids` should
# not.
rule { guest | admin }.enable :read_project_for_iids
@@ -901,6 +905,10 @@ class ProjectPolicy < BasePolicy
enable :read_model_experiments
end
+ rule { ~admin & created_and_owned_by_banned_user }.policy do
+ prevent :read_project
+ end
+
private
def user_is_user?
diff --git a/app/presenters/alert_management/alert_presenter.rb b/app/presenters/alert_management/alert_presenter.rb
index 659e991e9d8..41831d50692 100644
--- a/app/presenters/alert_management/alert_presenter.rb
+++ b/app/presenters/alert_management/alert_presenter.rb
@@ -44,22 +44,10 @@ module AlertManagement
project.incident_management_setting&.create_issue?
end
- def show_performance_dashboard_link?
- prometheus_alert.present?
- end
-
def incident_issues_link
project_incidents_url(project)
end
- def performance_dashboard_link
- if environment
- metrics_project_environment_url(project, environment)
- else
- metrics_project_environments_url(project)
- end
- end
-
def email_title
[environment&.name, query_title].compact.join(': ')
end
diff --git a/app/serializers/environment_entity.rb b/app/serializers/environment_entity.rb
index 6457127d831..0a3bf4c2a7b 100644
--- a/app/serializers/environment_entity.rb
+++ b/app/serializers/environment_entity.rb
@@ -27,10 +27,6 @@ class EnvironmentEntity < Grape::Entity
ops.merge(except: UNNECESSARY_ENTRIES_FOR_UPCOMING_DEPLOYMENT))
end
- expose :metrics_path, if: -> (*) { expose_metrics_path? } do |environment|
- metrics_project_environment_path(environment.project, environment)
- end
-
expose :environment_path do |environment|
project_environment_path(environment.project, environment)
end
@@ -101,10 +97,6 @@ class EnvironmentEntity < Grape::Entity
def cluster
deployment_platform.cluster
end
-
- def expose_metrics_path?
- !Feature.enabled?(:remove_monitor_metrics) && environment.has_metrics?
- end
end
EnvironmentEntity.prepend_mod_with('EnvironmentEntity')
diff --git a/app/serializers/environment_status_entity.rb b/app/serializers/environment_status_entity.rb
index 9318e0c1de8..8865c030d94 100644
--- a/app/serializers/environment_status_entity.rb
+++ b/app/serializers/environment_status_entity.rb
@@ -15,10 +15,6 @@ class EnvironmentStatusEntity < Grape::Entity
metrics_project_environment_deployment_path(es.project, es.environment, es.deployment)
end
- expose :metrics_monitoring_url, if: ->(*) { can_read_environment? } do |es|
- project_metrics_dashboard_path(es.project, environment: es.environment)
- end
-
expose :stop_url, if: ->(*) { can_stop_environment? } do |es|
stop_project_environment_path(es.project, es.environment)
end
diff --git a/app/views/admin/hooks/_form.html.haml b/app/views/admin/hooks/_form.html.haml
index a309e874317..bdcc7dda644 100644
--- a/app/views/admin/hooks/_form.html.haml
+++ b/app/views/admin/hooks/_form.html.haml
@@ -6,7 +6,7 @@
%p.form-text.text-muted= _('URL must be percent-encoded if necessary.')
.form-group
= form.label :token, _('Secret token'), class: 'label-bold'
- = form.text_field :token, class: 'form-control gl-form-input'
+ = form.text_field :token, class: 'form-control gl-form-input gl-max-w-48'
%p.form-text.text-muted= _('Use this token to validate received payloads.')
.form-group
= form.label :url, _('Trigger'), class: 'label-bold'
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index d4aeb8dc7e8..5bac2586fe6 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -1,10 +1,9 @@
- page_title @hook.pluralized_name
-.row.gl-mt-3
- .col-lg-4
- = render 'shared/web_hooks/title_and_docs', hook: @hook
+.gl-mt-5
+ = render 'shared/web_hooks/title_and_docs', hook: @hook
- .col-lg-8.gl-mb-3
+ .gl-mb-3
= gitlab_ui_form_for @hook, as: :hook, url: admin_hooks_path do |f|
= render partial: 'form', locals: { form: f, hook: @hook }
= f.submit _('Add system hook'), pajamas_button: true
diff --git a/app/views/notify/prometheus_alert_fired_email.html.haml b/app/views/notify/prometheus_alert_fired_email.html.haml
index cdc97d583df..25dc8e59073 100644
--- a/app/views/notify/prometheus_alert_fired_email.html.haml
+++ b/app/views/notify/prometheus_alert_fired_email.html.haml
@@ -25,7 +25,3 @@
- if @alert.show_incident_issues_link?
%p
= link_to(_('View incident issues.'), @alert.incident_issues_link)
-
-- if @alert.show_performance_dashboard_link?
- %p
- = link_to(_('View performance dashboard.'), @alert.performance_dashboard_link)
diff --git a/app/views/notify/prometheus_alert_fired_email.text.erb b/app/views/notify/prometheus_alert_fired_email.text.erb
index b23cd8b6ccc..a9c1d98a396 100644
--- a/app/views/notify/prometheus_alert_fired_email.text.erb
+++ b/app/views/notify/prometheus_alert_fired_email.text.erb
@@ -18,7 +18,3 @@
<% if @alert.show_incident_issues_link? %>
<%= _('View incident issues.') %> <%= @alert.incident_issues_link %>
<% end %>
-
-<% if @alert.show_performance_dashboard_link? %>
-<%= _('View the performance dashboard at') %> <%= @alert.performance_dashboard_link %>
-<% end %>
diff --git a/app/views/projects/_export.html.haml b/app/views/projects/_export.html.haml
index 97f5cdb54e5..3ef2c722e98 100644
--- a/app/views/projects/_export.html.haml
+++ b/app/views/projects/_export.html.haml
@@ -20,10 +20,12 @@
%li= _('Webhooks')
%li= _('Any encrypted tokens')
- if project.export_status == :finished
- = link_to _('Download export'), download_export_project_path(project),
- rel: 'nofollow', download: '', method: :get, class: "btn gl-button btn-default", data: { qa_selector: 'download_export_link' }
- = link_to _('Generate new export'), generate_new_export_project_path(project),
- method: :post, class: "btn gl-button btn-default"
+ = render Pajamas::ButtonComponent.new(href: download_export_project_path(project),
+ method: :get,
+ button_options: { ref: 'nofollow', download: '', data: { qa_selector: 'download_export_link' } }) do
+ = _('Download export')
+ = render Pajamas::ButtonComponent.new(href: generate_new_export_project_path(project), method: :post) do
+ = _('Generate new export')
- else
- = link_to _('Export project'), export_project_path(project),
- method: :post, class: "btn gl-button btn-default", data: { qa_selector: 'export_project_link' }
+ = render Pajamas::ButtonComponent.new(href: export_project_path(project), method: :post, button_options: { data: { qa_selector: 'export_project_link' } }) do
+ = _('Export project')
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index ae328cf0d34..3e98383f13e 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -1,8 +1,6 @@
- add_page_specific_style 'page_bundles/branches'
- page_title _('Branches')
- add_to_breadcrumbs(_('Repository'), project_tree_path(@project))
-- can_access_branch_rules = can?(current_user, :maintainer_access, @project)
-- can_push_code = (can? current_user, :push_code, @project)
-# Possible values for variables passed down from the projects/branches_controller.rb
-#
@@ -24,11 +22,11 @@
sorted_by: @sort }
}
- - if can_access_branch_rules
+ - if can_view_branch_rules?
= link_to project_settings_repository_path(@project, anchor: 'js-branch-rules'), class: 'gl-button btn btn-default' do
= s_('Branches|View branch rules')
- - if can_push_code
+ - if can_push_code?
= link_to new_project_branch_path(@project), class: 'gl-button btn btn-confirm' do
= s_('Branches|New branch')
.js-delete-merged-branches.gl-w-7{ data: {
@@ -38,7 +36,7 @@
= render_if_exists 'projects/commits/mirror_status'
-- if can_access_branch_rules
+- if can_view_branch_rules?
= render 'branch_rules_info'
.js-branch-list{ data: { diverging_counts_endpoint: diverging_commit_counts_namespace_project_branches_path(@project.namespace, @project, format: :json), default_branch: @project.default_branch } }
diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml
index 4d71161c96e..6bc44a9171b 100644
--- a/app/views/projects/hooks/index.html.haml
+++ b/app/views/projects/hooks/index.html.haml
@@ -2,11 +2,10 @@
- page_title _('Webhooks')
- @force_desktop_expanded_sidebar = true
-.row.gl-mt-3.js-search-settings-section
- .col-lg-4
- = render 'shared/web_hooks/title_and_docs', hook: @hook
+.gl-mt-3.js-search-settings-section
+ = render 'shared/web_hooks/title_and_docs', hook: @hook
- .col-lg-8.gl-mb-3
+ .gl-mb-3
= gitlab_ui_form_for @hook, as: :hook, url: polymorphic_path([@project, :hooks]), html: { class: 'js-webhook-form' } do |f|
= render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook }
= f.submit _('Add webhook'), pajamas_button: true, data: { qa_selector: "create_webhook_button" }
diff --git a/app/views/projects/tags/_edit_release_button.html.haml b/app/views/projects/tags/_edit_release_button.html.haml
index 9a6c18df2ca..42af8d4f59f 100644
--- a/app/views/projects/tags/_edit_release_button.html.haml
+++ b/app/views/projects/tags/_edit_release_button.html.haml
@@ -1,9 +1,8 @@
- release_btn_text = s_('TagsPage|Create release')
- release_btn_path = new_project_release_path(project, tag_name: tag.name)
- option_css_classes = local_assigns.fetch(:option_css_classes, '')
-- css_classes = "btn gl-button btn-default btn-icon btn-edit has-tooltip #{option_css_classes}"
- if release
- release_btn_text = s_('TagsPage|Edit release')
- release_btn_path = edit_project_release_path(project, release)
-= link_to release_btn_path, class: css_classes do
+= render Pajamas::ButtonComponent.new(href: release_btn_path, button_options: { class: option_css_classes }) do
= release_btn_text
diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml
index 986bc53fd81..caaa209a702 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -8,6 +8,7 @@
= render "layouts/one_trust"
= render "layouts/bizible"
= render "layouts/google_tag_manager_body"
+
.row.gl-flex-grow-1
.d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-px-5.gl-pb-5
.edit-profile.login-page.d-flex.flex-column.gl-align-items-center
diff --git a/app/views/shared/file_hooks/_index.html.haml b/app/views/shared/file_hooks/_index.html.haml
index ba968c6b2d2..03300be9181 100644
--- a/app/views/shared/file_hooks/_index.html.haml
+++ b/app/views/shared/file_hooks/_index.html.haml
@@ -1,15 +1,13 @@
- file_hooks = Gitlab::FileHook.files
-.row.gl-mt-3
- .col-lg-4
- %h4.gl-mt-0
- = _('File Hooks')
- %p
- = _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.')
- = link_to _('For more information, see the File Hooks documentation.'), help_page_path('administration/file_hooks')
+.gl-mt-7
+ %h4.gl-my-0
+ = _('File Hooks')
+ %p.gl-text-secondary
+ = _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.')
+ = link_to _('For more information, see the File Hooks documentation.'), help_page_path('administration/file_hooks')
-
- .col-lg-8.gl-mb-3
+ .gl-mb-3
- if file_hooks.any?
= render Pajamas::CardComponent.new do |c|
- c.with_header do
diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml
index 7eafd6ae092..da6ce1652c4 100644
--- a/app/views/shared/web_hooks/_form.html.haml
+++ b/app/views/shared/web_hooks/_form.html.haml
@@ -3,7 +3,7 @@
.js-vue-webhook-form{ data: webhook_form_data(hook) }
.form-group
= form.label :token, s_('Webhooks|Secret token'), class: 'label-bold'
- = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input'
+ = form.password_field :token, value: hook.masked_token, autocomplete: 'new-password', class: 'form-control gl-form-input gl-max-w-48'
%p.form-text.text-muted
- code_start = '<code>'.html_safe
- code_end = '</code>'.html_safe
diff --git a/app/views/shared/web_hooks/_title_and_docs.html.haml b/app/views/shared/web_hooks/_title_and_docs.html.haml
index c220b46f70f..8a6968ee01e 100644
--- a/app/views/shared/web_hooks/_title_and_docs.html.haml
+++ b/app/views/shared/web_hooks/_title_and_docs.html.haml
@@ -1,10 +1,10 @@
- webhooks_link_start = '<a href="%{url}">'.html_safe % { url: help_page_path(hook.help_path) }
-%h4.gl-mt-0
+%h4.gl-my-0
= page_title
- if @project
- integrations_link_start = '<a href="%{url}">'.html_safe % { url: scoped_integrations_path(project: @project) }
- %p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe }
+ %p.gl-text-secondary= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe }
- else
- %p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, link_end: '</a>'.html_safe }
+ %p.gl-text-secondary= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, link_end: '</a>'.html_safe }
diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml
index ce82a5e1614..0b76ed6c086 100644
--- a/app/views/users/_overview.html.haml
+++ b/app/views/users/_overview.html.haml
@@ -13,12 +13,10 @@
.col-12.col-md-10.col-lg-8.gl-my-6
.gl-display-flex
%ol.breadcrumb.gl-breadcrumb-list.gl-mb-4
- %li.breadcrumb-item.gl-breadcrumb-item
+ %li.gl-breadcrumb-item
= link_to project_path(@user.user_project) do
= @user.username
- %span.gl-breadcrumb-separator
- = sprite_icon("chevron-right", size: 16)
- %li.breadcrumb-item.gl-breadcrumb-item
+ %li.gl-breadcrumb-item
= link_to @user.user_readme.path, @user.user_project.readme_url
- if current_user == @user
.gl-ml-auto
diff --git a/config/application.rb b/config/application.rb
index c8bb56ce956..9c7d8a83560 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -217,6 +217,9 @@ module Gitlab
sharedSecret
)
+ # This config option can be removed after Rails 7.1 by https://gitlab.com/gitlab-org/gitlab/-/issues/416270
+ config.active_support.use_rfc4122_namespaced_uuids = true
+
# Enable escaping HTML in JSON.
config.active_support.escape_html_entities_in_json = true
diff --git a/config/feature_flags/development/ai_chat_history_context.yml b/config/feature_flags/development/hide_projects_of_banned_users.yml
index cc264093cd5..374782c359a 100644
--- a/config/feature_flags/development/ai_chat_history_context.yml
+++ b/config/feature_flags/development/hide_projects_of_banned_users.yml
@@ -1,8 +1,8 @@
---
-name: ai_chat_history_context
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122920
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/414606
-milestone: '16.1'
+name: hide_projects_of_banned_users
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121488
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/412621
+milestone: '16.2'
type: development
-group: group::ai-enablement
+group: group::anti-abuse
default_enabled: false
diff --git a/config/routes.rb b/config/routes.rb
index 3a9b6c1c0bf..740911f2e3f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -246,7 +246,6 @@ InitializerConnections.raise_if_new_database_connection do
end
get :metrics_dashboard
- get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api
get :cluster_status, format: :json
delete :clear_cache
end
diff --git a/config/routes/project.rb b/config/routes/project.rb
index bf73f461629..d0d14bf80ff 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -29,10 +29,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
# Use this scope for all new project routes.
scope '-' do
get 'archive/*id', format: true, constraints: { format: Gitlab::PathRegex.archive_formats_regex, id: /.+?/ }, to: 'repositories#archive', as: 'archive'
- get 'metrics(/:dashboard_path)', constraints: { dashboard_path: /.+\.yml/ },
- to: 'metrics_dashboard#show', as: :metrics_dashboard, format: false
- get 'metrics(/:dashboard_path)/panel/new', constraints: { dashboard_path: /.+\.yml/ },
- to: 'metrics_dashboard#show', as: :new_metrics_dashboard, format: false
namespace :metrics, module: :metrics do
namespace :dashboards do
@@ -330,9 +326,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
post :stop
post :cancel_auto_stop
get :terminal
- get :metrics
- get :additional_metrics
- get :metrics_dashboard
# This route is also defined in gitlab-workhorse. Make sure to update accordingly.
get '/terminal.ws/authorize', to: 'environments#terminal_websocket_authorize', format: false
@@ -343,7 +336,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
collection do
- get :metrics, action: :metrics_redirect
get :folder, path: 'folders/*id', constraints: { format: /(html|json)/ }
get :search
end
diff --git a/data/deprecations/15-9-accessibility-testing-deprecation.yml b/data/deprecations/15-9-accessibility-testing-deprecation.yml
deleted file mode 100644
index 74fb61ed2fc..00000000000
--- a/data/deprecations/15-9-accessibility-testing-deprecation.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# REQUIRED FIELDS
-#
-- title: "Accessibility Testing is deprecated" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters."
- announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated.
- removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed
- breaking_change: true # (required) Change to false if this is not a breaking change.
- reporter: jocelynjane # (required) GitLab username of the person reporting the change
- stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/390424 # (required) Link to the deprecation issue in GitLab
- body: | # (required) Do not modify this line, instead modify the lines below.
- Due to low customer usage, Accessibility Testing is deprecated and will be removed. There is no planned replacement and users should stop using Accessibility Testing before GitLab 17.0.
-#
-# OPTIONAL END OF SUPPORT FIELDS
-#
-# If an End of Support period applies, the announcement should be shared with GitLab Support
-# in the `#spt_managers` channel in Slack, and mention `@gitlab-com/support` in this MR.
-#
- end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end.
- #
- # OTHER OPTIONAL FIELDS
- #
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- documentation_url: https://docs.gitlab.com/ee/ci/testing/accessibility_testing.html # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/15-9-browser-performance-testing-deprecation.yml b/data/deprecations/15-9-browser-performance-testing-deprecation.yml
deleted file mode 100644
index a5d7429b56b..00000000000
--- a/data/deprecations/15-9-browser-performance-testing-deprecation.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# REQUIRED FIELDS
-#
-- title: "Browser Performance Testing is deprecated" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters."
- announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated.
- removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed
- breaking_change: true # (required) Change to false if this is not a breaking change.
- reporter: jocelynjane # (required) GitLab username of the person reporting the change
- stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/388719 # (required) Link to the deprecation issue in GitLab
- body: | # (required) Do not modify this line, instead modify the lines below.
- Due to limited customer usage, Browser Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Browser Performance Testing before GitLab 17.0.
-#
-# OPTIONAL END OF SUPPORT FIELDS
-#
-# If an End of Support period applies, the announcement should be shared with GitLab Support
-# in the `#spt_managers` channel in Slack, and mention `@gitlab-com/support` in this MR.
-#
- end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end.
- #
- # OTHER OPTIONAL FIELDS
- #
- tiers: Premium # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- documentation_url: https://docs.gitlab.com/ee/ci/testing/browser_performance_testing.html # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/15-9-load-performance-testing-deprecation.yml b/data/deprecations/15-9-load-performance-testing-deprecation.yml
deleted file mode 100644
index 77b56c69f92..00000000000
--- a/data/deprecations/15-9-load-performance-testing-deprecation.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# REQUIRED FIELDS
-#
-- title: "Load Performance Testing is deprecated" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters."
- announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated.
- removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed
- breaking_change: true # (required) Change to false if this is not a breaking change.
- reporter: jocelynjane # (required) GitLab username of the person reporting the change
- stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/388723 # (required) Link to the deprecation issue in GitLab
- body: | # (required) Do not modify this line, instead modify the lines below.
- Due to low customer usage, Load Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Load Performance Testing before GitLab 17.0.
-#
-# OPTIONAL END OF SUPPORT FIELDS
-#
-# If an End of Support period applies, the announcement should be shared with GitLab Support
-# in the `#spt_managers` channel in Slack, and mention `@gitlab-com/support` in this MR.
-#
- end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end.
- #
- # OTHER OPTIONAL FIELDS
- #
- tiers: Premium # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- documentation_url: https://docs.gitlab.com/ee/ci/testing/load_performance_testing.html # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/db/post_migrate/20230626101519_create_index_for_vulnerability_reads_on_common_project_filters.rb b/db/post_migrate/20230626101519_create_index_for_vulnerability_reads_on_common_project_filters.rb
new file mode 100644
index 00000000000..209a2295f22
--- /dev/null
+++ b/db/post_migrate/20230626101519_create_index_for_vulnerability_reads_on_common_project_filters.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateIndexForVulnerabilityReadsOnCommonProjectFilters < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_project_vulnerability_reads_common_finder_query_desc'
+
+ def up
+ add_concurrent_index :vulnerability_reads,
+ [:project_id, :state, :report_type, :severity, :vulnerability_id],
+ order: { severity: :desc, vulnerability_id: :desc },
+ name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :vulnerability_reads, INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20230626101519 b/db/schema_migrations/20230626101519
new file mode 100644
index 00000000000..874d3eec0ee
--- /dev/null
+++ b/db/schema_migrations/20230626101519
@@ -0,0 +1 @@
+7060d1ed7be6fce2e398d9ac042d6e67826742e639df8eee43245d66b8b87ea3 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 7368b3a76de..09709075788 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -32410,6 +32410,8 @@ CREATE INDEX index_project_topics_on_topic_id ON project_topics USING btree (top
CREATE UNIQUE INDEX index_project_user_callouts_feature ON user_project_callouts USING btree (user_id, feature_name, project_id);
+CREATE INDEX index_project_vulnerability_reads_common_finder_query_desc ON vulnerability_reads USING btree (project_id, state, report_type, severity DESC, vulnerability_id DESC);
+
CREATE UNIQUE INDEX index_project_wiki_repositories_on_project_id ON project_wiki_repositories USING btree (project_id);
CREATE INDEX index_projects_aimed_for_deletion ON projects USING btree (marked_for_deletion_at) WHERE ((marked_for_deletion_at IS NOT NULL) AND (pending_delete = false));
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 7b73fe9066e..fb645036dc0 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -303,6 +303,7 @@ Parameters:
| `simple` | boolean | no | Return only limited fields for each project. This is a no-op without authentication where only simple fields are returned. |
| `owned` | boolean | no | Limit by projects owned by the current user |
| `starred` | boolean | no | Limit by projects starred by the current user |
+| `topic` | string | no | Return projects matching the topic |
| `with_issues_enabled` | boolean | no | Limit by projects with issues feature enabled. Default is `false` |
| `with_merge_requests_enabled` | boolean | no | Limit by projects with merge requests feature enabled. Default is `false` |
| `with_shared` | boolean | no | Include projects shared to this group. Default is `true` |
diff --git a/doc/api/users.md b/doc/api/users.md
index ed788600e62..d96dd99c18e 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -510,7 +510,7 @@ Parameters:
| `auditor` **(PREMIUM)** | No | User is an auditor. Valid values are `true` or `false`. Defaults to false. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366404) in GitLab 15.3. |
| `avatar` | No | Image file for user's avatar |
| `bio` | No | User's biography |
-| `can_create_group` | No | User can create groups - true or false |
+| `can_create_group` | No | User can create top-level groups - true or false |
| `color_scheme_id` | No | User's color scheme for the file viewer (for more information, see the [user preference documentation](../user/profile/preferences.md#syntax-highlighting-theme)) |
| `email` | Yes | Email |
| `extern_uid` | No | External UID |
diff --git a/doc/architecture/blueprints/gitlab_ci_events/index.md b/doc/architecture/blueprints/gitlab_ci_events/index.md
index 7ce8fea9410..aab3a54cbd2 100644
--- a/doc/architecture/blueprints/gitlab_ci_events/index.md
+++ b/doc/architecture/blueprints/gitlab_ci_events/index.md
@@ -2,6 +2,7 @@
status: proposed
creation-date: "2023-03-15"
authors: [ "@furkanayhan" ]
+owners: [ "@furkanayhan" ]
coach: "@grzesiek"
approvers: [ "@jreporter", "@cheryl.li" ]
owning-stage: "~devops::verify"
diff --git a/doc/development/value_stream_analytics.md b/doc/development/value_stream_analytics.md
index e056ce9b064..30244407e38 100644
--- a/doc/development/value_stream_analytics.md
+++ b/doc/development/value_stream_analytics.md
@@ -41,8 +41,8 @@ feature-full.
|Total time chart|Yes|No|No|
|Task by type chart|Yes|No|No|
|DORA Metrics|Yes|Yes|No|
-|Cycle time and lead time summary (Key metrics)|Yes|Yes|No|
-|New issues, commits and deploys (Key metrics)|Yes, excluding commits|Yes|Yes|
+|Cycle time and lead time summary (Lifecycle metrics)|Yes|Yes|No|
+|New issues, commits and deploys (Lifecycle metrics)|Yes, excluding commits|Yes|Yes|
|Uses aggregated backend|Yes|No|No|
|Date filter behavior|Filters items [finished within the date range](https://gitlab.com/groups/gitlab-org/-/epics/6046)|Filters items by creation date.|Filters items by creation date.|
|Authorization|At least reporter|At least reporter|Can be public.|
diff --git a/doc/tutorials/left_sidebar/index.md b/doc/tutorials/left_sidebar/index.md
index f26849eac45..80fbbf2032e 100644
--- a/doc/tutorials/left_sidebar/index.md
+++ b/doc/tutorials/left_sidebar/index.md
@@ -63,7 +63,7 @@ To start, we will find the project we want to work on.
![Project-specific options](img/project_selected_v16_0.png)
-## Customize the sidebar
+## Pin frequently used items
You can pin menu items if you tend to use them frequently.
@@ -76,6 +76,9 @@ The item is displayed in the **Pinned** section:
![pinned item](img/pinned_v16_0.png)
+NOTE:
+The items you pin while you're viewing a project are different than the items you pin while viewing a group.
+
## Use a more focused view
On the left sidebar, you can also choose a more focused view into the areas you have access to.
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 58c610048cd..a468fff5fec 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -50,20 +50,6 @@ For deprecation reviewers (Technical Writers only):
<div class="deprecation breaking-change" data-milestone="17.0">
-### Accessibility Testing is deprecated
-
-<div class="deprecation-notes">
-- Announced in: GitLab <span class="milestone">15.9</span>
-- This is a [breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change).
-- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/390424).
-</div>
-
-Due to low customer usage, Accessibility Testing is deprecated and will be removed. There is no planned replacement and users should stop using Accessibility Testing before GitLab 17.0.
-
-</div>
-
-<div class="deprecation breaking-change" data-milestone="17.0">
-
### Atlassian Crowd OmniAuth provider
<div class="deprecation-notes">
@@ -97,20 +83,6 @@ Because Cloud Native Buildpacks do not support automatic testing, the Auto Test
<div class="deprecation breaking-change" data-milestone="17.0">
-### Browser Performance Testing is deprecated
-
-<div class="deprecation-notes">
-- Announced in: GitLab <span class="milestone">15.9</span>
-- This is a [breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change).
-- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/388719).
-</div>
-
-Due to limited customer usage, Browser Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Browser Performance Testing before GitLab 17.0.
-
-</div>
-
-<div class="deprecation breaking-change" data-milestone="17.0">
-
### CiRunner.projects default sort is changing to `id_desc`
<div class="deprecation-notes">
@@ -333,20 +305,6 @@ In GitLab 17.0, the `DISABLED_WITH_OVERRIDE` value of the `SharedRunnersSetting`
<div class="deprecation breaking-change" data-milestone="17.0">
-### Load Performance Testing is deprecated
-
-<div class="deprecation-notes">
-- Announced in: GitLab <span class="milestone">15.9</span>
-- This is a [breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change).
-- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/388723).
-</div>
-
-Due to low customer usage, Load Performance Testing is deprecated and will be removed. There is no planned replacement and users should stop using Load Performance Testing before GitLab 17.0.
-
-</div>
-
-<div class="deprecation breaking-change" data-milestone="17.0">
-
### Maintainer role providing the ability to change Package settings using GraphQL API
<div class="deprecation-notes">
diff --git a/doc/user/admin_area/moderate_users.md b/doc/user/admin_area/moderate_users.md
index fd08c58cbcd..f98f1a874c4 100644
--- a/doc/user/admin_area/moderate_users.md
+++ b/doc/user/admin_area/moderate_users.md
@@ -256,8 +256,9 @@ Users can also be activated using the [GitLab API](../../api/users.md#activate-u
> - Ban and unban users [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/327353) in GitLab 14.8. Feature flag `ban_user_feature_flag` removed.
> - Hiding merge requests of banned users [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107836) in GitLab 15.8 [with a flag](../../administration/feature_flags.md) named `hide_merge_requests_from_banned_users`. Disabled by default.
> - Hiding comments of banned users [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112973) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `hidden_notes`. Disabled by default.
+> - Hiding projects of banned users [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121488) in GitLab 16.2 [with a flag](../../administration/feature_flags.md) named `hide_projects_of_banned_users`. Disabled by default.
-GitLab administrators can ban and unban users. Banned users are blocked, and their issues, merge requests, and comments are hidden.
+GitLab administrators can ban and unban users. Banned users are blocked, and their projects, issues, merge requests, and comments are hidden.
### Ban a user
diff --git a/doc/user/analytics/value_streams_dashboard.md b/doc/user/analytics/value_streams_dashboard.md
index 9b332d78060..2e40be2a43d 100644
--- a/doc/user/analytics/value_streams_dashboard.md
+++ b/doc/user/analytics/value_streams_dashboard.md
@@ -57,7 +57,7 @@ To view the value streams dashboard:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project or group.
1. Select **Analyze > Value stream analytics**.
-1. Below the **Filter results** text box, in the **Key metrics** row, select **Value Streams Dashboard / DORA**.
+1. Below the **Filter results** text box, in the **Lifecycle metrics** row, select **Value Streams Dashboard / DORA**.
1. Optional. To open the new page, append this path `/analytics/dashboards/value_streams_dashboard` to the group URL
(for example, `https://gitlab.com/groups/gitlab-org/-/analytics/dashboards/value_streams_dashboard`).
@@ -142,8 +142,8 @@ panels:
| Lead time for changes | The time to successfully deliver a commit into production. This metric reflects the efficiency of CI/CD pipelines. | [Lead time tab](https://gitlab.com/groups/gitlab-org/-/analytics/ci_cd?tab=lead-time) | [Lead time for changes](dora_metrics.md#lead-time-for-changes) | `lead_time_for_changes` |
| Time to restore service | The time it takes an organization to recover from a failure in production. | [Time to restore service tab](https://gitlab.com/groups/gitlab-org/-/analytics/ci_cd?tab=time-to-restore-service) | [Time to restore service](dora_metrics.md#time-to-restore-service) | `time_to_restore_service` |
| Change failure rate | Percentage of deployments that cause an incident in production. | [Change failure rate tab](https://gitlab.com/groups/gitlab-org/-/analytics/ci_cd?tab=change-failure-rate) | [Change failure rate](dora_metrics.md#change-failure-rate) | `change_failure_rate` |
-| Lead time | Median time from issue created to issue closed. | [Value Stream Analytics](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#key-metrics) | `lead_time` |
-| Cycle time | Median time from the earliest commit of a linked issue's merge request to when that issue is closed. | [VSA overview](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#key-metrics) | `cycle_time` |
+| Lead time | Median time from issue created to issue closed. | [Value Stream Analytics](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#lifecycle-metrics) | `lead_time` |
+| Cycle time | Median time from the earliest commit of a linked issue's merge request to when that issue is closed. | [VSA overview](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [View the lead time and cycle time for issues](../group/value_stream_analytics/index.md#lifecycle-metrics) | `cycle_time` |
| New issues | Number of new issues created. | [Issue Analytics](https://gitlab.com/groups/gitlab-org/-/issues_analytics) | Issue analytics [for projects](issue_analytics.md) and [for groups](../../user/group/issues_analytics/index.md) | `issues` |
| Closed issues | Number of issues closed by month. | [Value Stream Analytics](https://gitlab.com/groups/gitlab-org/-/analytics/value_stream_analytics) | [Value Stream Analytics](../group/value_stream_analytics/index.md) | `issues_completed` |
| Number of deploys | Total number of deploys to production. | [Merge Request Analytics](https://gitlab.com/gitlab-org/gitlab/-/analytics/merge_request_analytics) | [Merge request analytics](merge_request_analytics.md) | `deploys` |
diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md
index 5838b9821de..8cc261af50d 100644
--- a/doc/user/group/saml_sso/index.md
+++ b/doc/user/group/saml_sso/index.md
@@ -396,11 +396,10 @@ convert the information to XML. An example SAML response is shown here.
By default, users provisioned with SAML or SCIM are sent a verification email to verify their identity. Instead, you can
[configure GitLab with a custom domain](../../enterprise_user/index.md#set-up-a-verified-domain) and GitLab
automatically confirms user accounts. Users still receive an
-[enterprise user](../../enterprise_user/index.md) welcome email. Confirmation is
-bypassed for users:
+[enterprise user](../../enterprise_user/index.md) welcome email. Confirmation is bypassed if both of the following are true:
-- That are provisioned with SAML or SCIM.
-- That have an email address that belongs to the verified domain.
+- The user is provisioned with SAML or SCIM.
+- The user has an email address that belongs to the verified domain.
### Block user access
diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md
index 952552fc648..dba7a507fef 100644
--- a/doc/user/group/value_stream_analytics/index.md
+++ b/doc/user/group/value_stream_analytics/index.md
@@ -45,8 +45,8 @@ Value stream analytics offers different features at the project and group level
|Total time chart|Yes|Yes|No|
|Task by type chart|Yes|No|No|
|DORA Metrics|Yes|Yes|No|
-|Cycle time and lead time summary (Key metrics)|Yes|Yes|No|
-|New issues, commits, and deploys (Key metrics)|Yes, excluding commits|Yes|Yes|
+|Cycle time and lead time summary (Lifecycle metrics)|Yes|Yes|No|
+|New issues, commits, and deploys (Lifecycle metrics)|Yes, excluding commits|Yes|Yes|
|Uses aggregated backend|Yes|Yes|No|
|Date filter behavior|Filters items [finished within the date range](https://gitlab.com/groups/gitlab-org/-/epics/6046)|Filters items by creation date.|Filters items by creation date.|
|Authorization|At least reporter|At least reporter|Can be public|
@@ -253,9 +253,9 @@ For the "Tasks by type" chart, only the Date range and Project selector filters
The **Overview** page in value stream analytics displays key metrics of the DevSecOps lifecycle performance for projects and groups.
-### Key metrics
+### Lifecycle metrics
-Value stream analytics includes the following key metrics:
+Value stream analytics includes the following lifecycle metrics:
- **Lead time**: Median time from when the issue was created to when it was closed.
- **Cycle time**: Median time from first commit to issue closed. GitLab measures cycle time from the earliest commit of a
@@ -290,21 +290,21 @@ NOTE:
In GitLab 13.9 and later, deployment frequency metrics are calculated based on when the deployment was finished.
In GitLab 13.8 and earlier, deployment frequency metrics are calculated based on when the deployment was created.
-## View key and DORA metrics
+## View lifecycle and DORA metrics
Prerequisite:
- To view deployment metrics, you must have a
[production environment configured](#how-value-stream-analytics-identifies-the-production-environment).
-To view key lifecycle metrics:
+To view lifecycle metrics:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project or group.
1. Select **Analyze > Value stream analytics**.
- Key metrics display below the **Filter results** text box.
+ Lifecycle metrics display below the **Filter results** text box.
1. Optional. Filter the results:
1. Select the **Filter results** text box.
- Based on the filter you select, the dashboard automatically aggregates key metrics and displays the status of the value stream.
+ Based on the filter you select, the dashboard automatically aggregates lifecycle metrics and displays the status of the value stream.
1. Select a parameter.
1. Select a value or enter text to refine the results.
1. To adjust the date range:
@@ -315,7 +315,7 @@ To view the [Value Streams Dashboard](../../analytics/value_streams_dashboard.md
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project or group.
1. Select **Analyze > Value stream analytics**.
-1. Below the **Filter results** text box, in the **Key metrics** row, select **Value Streams Dashboard / DORA**.
+1. Below the **Filter results** text box, in the **Lifecycle metrics** row, select **Value Streams Dashboard / DORA**.
1. Optional. To open the new page, append this path `/analytics/dashboards/value_streams_dashboard` to the group URL
(for example, `https://gitlab.com/groups/gitlab-org/-/analytics/dashboards/value_streams_dashboard`).
diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md
index 1aef5bd3040..08613408f7d 100644
--- a/doc/user/project/pages/introduction.md
+++ b/doc/user/project/pages/introduction.md
@@ -95,12 +95,7 @@ you can create your project first and access it under `http(s)://namespace.examp
## Enable unique domains
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/9347) in GitLab 15.9 [with a flag](../../../administration/feature_flags.md) named `pages_unique_domain`. Disabled by default.
-> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/388151) in GitLab 15.11.
-
-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 `pages_unique_domain`.
-On GitLab.com, by default this feature is available.
+> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/388151) in GitLab 15.11.
By default, every project in a group shares the same domain, for example, `group.gitlab.io`. This means that cookies are also shared for all projects in a group.
diff --git a/lib/api/helpers/custom_attributes.rb b/lib/api/helpers/custom_attributes.rb
index 88208226c40..fc3f42f0d58 100644
--- a/lib/api/helpers/custom_attributes.rb
+++ b/lib/api/helpers/custom_attributes.rb
@@ -8,7 +8,7 @@ module API
included do
helpers do
params :with_custom_attributes do
- optional :with_custom_attributes, type: Boolean, default: false, desc: 'Include custom attributes in the response'
+ optional :with_custom_attributes, type: ::Grape::API::Boolean, default: false, desc: 'Include custom attributes in the response'
optional :custom_attributes, type: Hash,
desc: 'Filter with custom attributes'
diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb
index 850cc61af2c..09dd69ef03b 100644
--- a/lib/api/helpers/integrations_helpers.rb
+++ b/lib/api/helpers/integrations_helpers.rb
@@ -41,7 +41,7 @@ module API
{
required: false,
name: :notify_only_broken_pipelines,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Send notifications for broken pipelines'
}
].freeze
@@ -129,85 +129,85 @@ module API
{
required: false,
name: :commit_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for commit_events'
},
{
required: false,
name: :push_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for push_events'
},
{
required: false,
name: :issues_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for issues_events'
},
{
required: false,
name: :incident_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for incident_events'
},
{
required: false,
name: :alert_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for alert_events'
},
{
required: false,
name: :confidential_issues_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for confidential_issues_events'
},
{
required: false,
name: :merge_requests_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for merge_requests_events'
},
{
required: false,
name: :note_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for note_events'
},
{
required: false,
name: :confidential_note_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for confidential_note_events'
},
{
required: false,
name: :tag_push_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for tag_push_events'
},
{
required: false,
name: :deployment_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for deployment_events'
},
{
required: false,
name: :job_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for job_events'
},
{
required: false,
name: :pipeline_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for pipeline_events'
},
{
required: false,
name: :wiki_page_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable notifications for wiki_page_events'
}
].freeze
@@ -243,7 +243,7 @@ module API
{
required: false,
name: :app_store_protected_refs,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Only enable for protected refs'
}
],
@@ -285,7 +285,7 @@ module API
{
required: false,
name: :enable_ssl_verification,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable SSL verification'
},
{
@@ -343,7 +343,7 @@ module API
{
required: false,
name: :enable_ssl_verification,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'DEPRECATED: This parameter has no effect since SSL verification will always be enabled'
}
],
@@ -417,7 +417,7 @@ module API
{
required: false,
name: :archive_trace_events,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'When enabled, job logs will be collected by Datadog and shown along pipeline execution traces'
},
{
@@ -471,7 +471,7 @@ module API
{
required: false,
name: :enable_ssl_verification,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable SSL verification'
}
],
@@ -485,13 +485,13 @@ module API
{
required: false,
name: :disable_diffs,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Disable code diffs'
},
{
required: false,
name: :send_from_committer_email,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Send from committer'
},
{
@@ -598,7 +598,7 @@ module API
{
required: false,
name: :colorize_messages,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Colorize messages'
}
],
@@ -612,7 +612,7 @@ module API
{
required: false,
name: :enable_ssl_verification,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable SSL verification'
},
{
@@ -668,7 +668,7 @@ module API
{
required: false,
name: :jira_issue_transition_automatic,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable automatic issue transitions'
},
{
@@ -692,7 +692,7 @@ module API
{
required: false,
name: :comment_on_event_enabled,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable comments inside Jira issues on each GitLab event (commit / merge request)'
}
],
@@ -750,13 +750,13 @@ module API
{
required: false,
name: :notify_only_broken_pipelines,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Notify only broken pipelines'
},
{
required: false,
name: :notify_only_default_branch,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Send notifications only for the default branch'
},
{
@@ -946,7 +946,7 @@ module API
{
required: false,
name: :enable_ssl_verification,
- type: Boolean,
+ type: ::Grape::API::Boolean,
desc: 'Enable SSL verification'
},
{
diff --git a/lib/gitlab/alert_management/payload/prometheus.rb b/lib/gitlab/alert_management/payload/prometheus.rb
index 76f3da8366b..cf6fe449398 100644
--- a/lib/gitlab/alert_management/payload/prometheus.rb
+++ b/lib/gitlab/alert_management/payload/prometheus.rb
@@ -78,18 +78,6 @@ module Gitlab
rescue URI::InvalidURIError, KeyError
end
- def metrics_dashboard_url
- return unless environment && full_query && title
-
- metrics_dashboard_project_environment_url(
- project,
- environment,
- embed_json: dashboard_json,
- embedded: true,
- **alert_embed_window_params
- )
- end
-
def has_required_attributes?
project && title && starts_at_raw
end
diff --git a/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb
index 31d75225972..56a82d1df46 100644
--- a/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb
+++ b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb
@@ -7,59 +7,14 @@ module Gitlab
class ClusterEndpointInserter < BaseStage
def transform!
verify_params
-
- for_metrics do |metric|
- metric[:prometheus_endpoint_path] = endpoint_for_metric(metric)
- end
end
private
- def admin_url(metric)
- Gitlab::Routing.url_helpers.prometheus_api_admin_cluster_path(
- params[:cluster],
- proxy_path: query_type(metric),
- query: query_for_metric(metric)
- )
- end
-
- def endpoint_for_metric(metric)
- case params[:cluster_type]
- when :admin
- admin_url(metric)
- when :group
- error!(_('Group is required when cluster_type is :group')) unless params[:group]
- group_url(metric)
- when :project
- error!(_('Project is required when cluster_type is :project')) unless project
- project_url(metric)
- else
- error!(_('Unrecognized cluster type'))
- end
- end
-
def error!(message)
raise Errors::DashboardProcessingError, message
end
- def group_url(metric)
- Gitlab::Routing.url_helpers.prometheus_api_group_cluster_path(
- params[:group],
- params[:cluster],
- proxy_path: query_type(metric),
- query: query_for_metric(metric)
- )
- end
-
- def project_url(metric)
- Gitlab::Routing.url_helpers.prometheus_api_project_cluster_path(
- project,
- params[:cluster],
- proxy_path: query_type(metric),
- query: query_for_metric(metric)
- )
- end
-
def query_type(metric)
metric[:query] ? :query : :query_range
end
diff --git a/lib/gitlab/metrics/dashboard/url.rb b/lib/gitlab/metrics/dashboard/url.rb
index bdd28744137..e7b901861ef 100644
--- a/lib/gitlab/metrics/dashboard/url.rb
+++ b/lib/gitlab/metrics/dashboard/url.rb
@@ -12,26 +12,6 @@ module Gitlab
ANCHOR_PATTERN = '(?<anchor>\#[a-z0-9_-]+)?'
DASH_PATTERN = '(?:/-)'
- # Matches urls for a metrics dashboard.
- # This regex needs to match the old metrics URL, the new metrics URL,
- # and the dashboard URL (inline_metrics_redactor_filter.rb
- # uses this regex to match against the dashboard URL.)
- #
- # EX - Old URL: https://<host>/<namespace>/<project>/environments/<env_id>/metrics
- # OR
- # New URL: https://<host>/<namespace>/<project>/-/metrics?environment=<env_id>
- # OR
- # dashboard URL: https://<host>/<namespace>/<project>/environments/<env_id>/metrics_dashboard
- def metrics_regex
- strong_memoize(:metrics_regex) do
- regex_for_project_metrics(
- %r{
- ( #{environment_metrics_regex} ) | ( #{non_environment_metrics_regex} )
- }x
- )
- end
- end
-
# Matches dashboard urls for a Grafana embed.
#
# EX - https://<host>/<namespace>/<project>/grafana/metrics_dashboard
@@ -99,11 +79,6 @@ module Gitlab
.symbolize_keys
end
- # Builds a metrics dashboard url based on the passed in arguments
- def build_dashboard_url(...)
- Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_environment_url(...)
- end
-
private
def environment_metrics_regex
diff --git a/lib/gitlab/uuid.rb b/lib/gitlab/uuid.rb
index 016c25eb94b..a3abe90a412 100644
--- a/lib/gitlab/uuid.rb
+++ b/lib/gitlab/uuid.rb
@@ -10,8 +10,6 @@ module Gitlab
}.freeze
UUID_V5_PATTERN = /\h{8}-\h{4}-5\h{3}-\h{4}-\h{12}/.freeze
- NAMESPACE_REGEX = /(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/.freeze
- PACK_PATTERN = "NnnnnN"
class << self
def v5(name, namespace_id: default_namespace_id)
@@ -25,12 +23,7 @@ module Gitlab
private
def default_namespace_id
- @default_namespace_id ||= begin
- namespace_uuid = NAMESPACE_IDS.fetch(Rails.env.to_sym)
- # Digest::UUID is broken when using a UUID as a namespace_id
- # https://github.com/rails/rails/issues/37681#issue-520718028
- namespace_uuid.scan(NAMESPACE_REGEX).flatten.map { |s| s.to_i(16) }.pack(PACK_PATTERN)
- end
+ NAMESPACE_IDS.fetch(Rails.env.to_sym)
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 1fcf4cc719e..27e654115cb 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -99,6 +99,16 @@ msgid_plural "%d Approvals"
msgstr[0] ""
msgstr[1] ""
+msgid "%d Issue"
+msgid_plural "%d Issues"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d Merge Request"
+msgid_plural "%d Merge Requests"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d Module"
msgid_plural "%d Modules"
msgstr[0] ""
@@ -354,16 +364,6 @@ msgid_plural "%d more comments"
msgstr[0] ""
msgstr[1] ""
-msgid "%d opened Issue"
-msgid_plural "%d opened Issues"
-msgstr[0] ""
-msgstr[1] ""
-
-msgid "%d opened Merge Request"
-msgid_plural "%d opened Merge Requests"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "%d package"
msgid_plural "%d packages"
msgstr[0] ""
@@ -3867,9 +3867,6 @@ msgstr ""
msgid "AdminUsers|Is using seat"
msgstr ""
-msgid "AdminUsers|Issues and merge requests authored by this user are hidden from other users."
-msgstr ""
-
msgid "AdminUsers|It's you!"
msgstr ""
@@ -3915,6 +3912,9 @@ msgstr ""
msgid "AdminUsers|Private profile"
msgstr ""
+msgid "AdminUsers|Projects, issues, merge requests, and comments of this user are hidden from other users."
+msgstr ""
+
msgid "AdminUsers|Reactivating a user will:"
msgstr ""
@@ -21478,9 +21478,6 @@ msgstr ""
msgid "Group information"
msgstr ""
-msgid "Group is required when cluster_type is :group"
-msgstr ""
-
msgid "Group jobs by"
msgstr ""
@@ -35653,9 +35650,6 @@ msgstr ""
msgid "Project information"
msgstr ""
-msgid "Project is required when cluster_type is :project"
-msgstr ""
-
msgid "Project members"
msgstr ""
@@ -42002,6 +41996,9 @@ msgstr ""
msgid "SecurityReports|There was an error adding the comment."
msgstr ""
+msgid "SecurityReports|There was an error creating a Jira issue for the finding. Please try again."
+msgstr ""
+
msgid "SecurityReports|There was an error creating the issue."
msgstr ""
@@ -48937,9 +48934,6 @@ msgstr ""
msgid "Unrecognized approval status."
msgstr ""
-msgid "Unrecognized cluster type"
-msgstr ""
-
msgid "Unresolve"
msgstr ""
@@ -50193,7 +50187,7 @@ msgstr ""
msgid "ValueStreamAnalytics|High vulnerabilities over time."
msgstr ""
-msgid "ValueStreamAnalytics|Key metrics"
+msgid "ValueStreamAnalytics|Lifecycle metrics"
msgstr ""
msgid "ValueStreamAnalytics|Median time an incident was open on a production environment in the given time period."
@@ -50506,9 +50500,6 @@ msgstr ""
msgid "View page @ "
msgstr ""
-msgid "View performance dashboard."
-msgstr ""
-
msgid "View project in admin area"
msgstr ""
@@ -50538,9 +50529,6 @@ msgstr ""
msgid "View the latest successful deployment to this environment"
msgstr ""
-msgid "View the performance dashboard at"
-msgstr ""
-
msgid "View usage details"
msgstr ""
diff --git a/rubocop/formatter/todo_formatter.rb b/rubocop/formatter/todo_formatter.rb
index 912ce0da2cc..9e20a95ba85 100644
--- a/rubocop/formatter/todo_formatter.rb
+++ b/rubocop/formatter/todo_formatter.rb
@@ -23,8 +23,8 @@ module RuboCop
# with offenses.
#
# See https://gitlab.com/gitlab-org/gitlab/-/issues/415330#caveats
- # on why the entry must end with `.html.haml.rb`.
- RETAIN_EXCLUSIONS = %r{\.html\.haml\.rb$}
+ # on why the entry must end with `.haml.rb`.
+ RETAIN_EXCLUSIONS = %r{\.haml\.rb$}
class << self
attr_accessor :base_directory
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index bface886674..15b7ddd85ea 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -113,18 +113,6 @@ RSpec.describe Projects::ClustersController, feature_category: :deployment_manag
end
end
- it_behaves_like 'GET #metrics_dashboard for dashboard', 'Cluster health' do
- let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
-
- let(:metrics_dashboard_req_params) do
- {
- id: cluster.id,
- namespace_id: project.namespace.full_path,
- project_id: project.path
- }
- end
- end
-
describe 'POST create for existing cluster' do
let(:params) do
{
diff --git a/spec/factories/project_authorizations.rb b/spec/factories/project_authorizations.rb
index ffdf5576f84..1726da55c99 100644
--- a/spec/factories/project_authorizations.rb
+++ b/spec/factories/project_authorizations.rb
@@ -6,4 +6,8 @@ FactoryBot.define do
project
access_level { Gitlab::Access::REPORTER }
end
+
+ trait :owner do
+ access_level { Gitlab::Access::OWNER }
+ end
end
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 3d108951c64..a795df4dec6 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe ProjectsFinder do
+RSpec.describe ProjectsFinder, feature_category: :groups_and_projects do
include AdminModeHelper
describe '#execute' do
@@ -25,6 +25,12 @@ RSpec.describe ProjectsFinder do
create(:project, :private, name: 'D', path: 'D')
end
+ let_it_be(:banned_user_project) do
+ create(:project, :public, name: 'Project created by a banned user', creator: create(:user, :banned)).tap do |p|
+ create(:project_authorization, :owner, user: p.creator, project: p)
+ end
+ end
+
let(:params) { {} }
let(:current_user) { user }
let(:project_ids_relation) { nil }
@@ -488,16 +494,32 @@ RSpec.describe ProjectsFinder do
describe 'with admin user' do
let(:user) { create(:admin) }
- context 'admin mode enabled' do
+ context 'with admin mode enabled' do
before do
enable_admin_mode!(current_user)
end
- it { is_expected.to match_array([public_project, internal_project, private_project, shared_project]) }
+ it do
+ is_expected.to match_array([
+ public_project,
+ internal_project,
+ private_project,
+ shared_project,
+ banned_user_project
+ ])
+ end
end
- context 'admin mode disabled' do
+ context 'with admin mode disabled' do
it { is_expected.to match_array([public_project, internal_project]) }
+
+ context 'when hide_projects_of_banned_users FF is disabled' do
+ before do
+ stub_feature_flags(hide_projects_of_banned_users: false)
+ end
+
+ it { is_expected.to match_array([public_project, internal_project, banned_user_project]) }
+ end
end
end
end
diff --git a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json
index 8ee207b7ebf..79132c0d039 100644
--- a/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json
+++ b/spec/fixtures/lib/gitlab/metrics/dashboard/schemas/metrics.json
@@ -2,23 +2,57 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
- "label",
- "prometheus_endpoint_path"
+ "label"
],
"oneOf": [
- { "required": ["query"] },
- { "required": ["query_range"] }
+ {
+ "required": [
+ "query"
+ ]
+ },
+ {
+ "required": [
+ "query_range"
+ ]
+ }
],
"properties": {
- "id": { "type": "string" },
- "query_range": { "type": ["string", "number"] },
- "query": { "type": ["string", "number"] },
- "unit": { "type": "string" },
- "label": { "type": "string" },
- "track": { "type": "string" },
- "prometheus_endpoint_path": { "type": "string" },
- "metric_id": { "type": "number" },
- "edit_path": { "type": ["string", "null"] }
+ "id": {
+ "type": "string"
+ },
+ "query_range": {
+ "type": [
+ "string",
+ "number"
+ ]
+ },
+ "query": {
+ "type": [
+ "string",
+ "number"
+ ]
+ },
+ "unit": {
+ "type": "string"
+ },
+ "label": {
+ "type": "string"
+ },
+ "track": {
+ "type": "string"
+ },
+ "prometheus_endpoint_path": {
+ "type": "string"
+ },
+ "metric_id": {
+ "type": "number"
+ },
+ "edit_path": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
},
"additionalProperties": false
}
diff --git a/spec/frontend/content_editor/components/suggestions_dropdown_spec.js b/spec/frontend/content_editor/components/suggestions_dropdown_spec.js
index 9d34d9d0e9e..ee3ad59bf9a 100644
--- a/spec/frontend/content_editor/components/suggestions_dropdown_spec.js
+++ b/spec/frontend/content_editor/components/suggestions_dropdown_spec.js
@@ -1,4 +1,4 @@
-import { GlDropdownItem, GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui';
+import { GlAvatarLabeled, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import SuggestionsDropdown from '~/content_editor/components/suggestions_dropdown.vue';
@@ -113,7 +113,7 @@ describe('~/content_editor/components/suggestions_dropdown', () => {
${'emoji'} | ${'emoji'} | ${':'} | ${exampleEmoji} | ${`😃`} | ${insertedEmojiProps}
`(
'runs a command to insert the selected $referenceType',
- ({ char, nodeType, referenceType, reference, insertedText, insertedProps }) => {
+ async ({ char, nodeType, referenceType, reference, insertedText, insertedProps }) => {
const commandSpy = jest.fn();
buildWrapper({
@@ -129,7 +129,10 @@ describe('~/content_editor/components/suggestions_dropdown', () => {
},
});
- wrapper.findComponent(GlDropdownItem).vm.$emit('click');
+ await wrapper
+ .findByTestId('content-editor-suggestions-dropdown')
+ .find('li .gl-new-dropdown-item-content')
+ .trigger('click');
expect(commandSpy).toHaveBeenCalledWith(
expect.objectContaining({
diff --git a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
index 3b4554700b4..b1eb666b5fd 100644
--- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
+++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
@@ -5,8 +5,6 @@ exports[`Dashboard template matches the default snapshot 1`] = `
class="prometheus-graphs"
data-testid="prometheus-graphs"
environmentstate="available"
- metricsdashboardbasepath="/monitoring/monitor-project/-/metrics?environment=1"
- metricsendpoint="/monitoring/monitor-project/-/environments/1/additional_metrics.json"
>
<div>
<gl-alert-stub
diff --git a/spec/frontend/pages/groups/new/components/app_spec.js b/spec/frontend/pages/groups/new/components/app_spec.js
index 19240f1a044..baf0ca2beca 100644
--- a/spec/frontend/pages/groups/new/components/app_spec.js
+++ b/spec/frontend/pages/groups/new/components/app_spec.js
@@ -1,4 +1,7 @@
import { shallowMount } from '@vue/test-utils';
+import GROUP_IMPORT_SVG_URL from '@gitlab/svgs/dist/illustrations/group-import.svg?url';
+import GROUP_NEW_SVG_URL from '@gitlab/svgs/dist/illustrations/group-new.svg?url';
+
import App from '~/pages/groups/new/components/app.vue';
import NewNamespacePage from '~/vue_shared/new_namespace/new_namespace_page.vue';
@@ -27,6 +30,7 @@ describe('App component', () => {
{ href: '#', text: 'New group' },
]);
expect(findCreateGroupPanel().title).toBe('Create group');
+ expect(findCreateGroupPanel().imageSrc).toBe(GROUP_NEW_SVG_URL);
});
it('creates correct component for subgroup creation', () => {
@@ -45,5 +49,6 @@ describe('App component', () => {
]);
expect(findCreateGroupPanel().title).toBe('Create subgroup');
expect(findCreateGroupPanel().detailProps).toEqual(detailProps);
+ expect(findCreateGroupPanel().imageSrc).toBe(GROUP_IMPORT_SVG_URL);
});
});
diff --git a/spec/frontend/projects/new/components/__snapshots__/app_spec.js.snap b/spec/frontend/projects/new/components/__snapshots__/app_spec.js.snap
new file mode 100644
index 00000000000..0c4d63c3509
--- /dev/null
+++ b/spec/frontend/projects/new/components/__snapshots__/app_spec.js.snap
@@ -0,0 +1,30 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Experimental new project creation app creates correct panels 1`] = `
+Array [
+ Object {
+ "description": "Create a blank project to store your files, plan your work, and collaborate on code, among other things.",
+ "imageSrc": "file-mock",
+ "key": "blank",
+ "name": "blank_project",
+ "selector": "#blank-project-pane",
+ "title": "Create blank project",
+ },
+ Object {
+ "description": "Create a project pre-populated with the necessary files to get you started quickly.",
+ "imageSrc": "file-mock",
+ "key": "template",
+ "name": "create_from_template",
+ "selector": "#create-from-template-pane",
+ "title": "Create from template",
+ },
+ Object {
+ "description": "Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab.",
+ "imageSrc": "file-mock",
+ "key": "import",
+ "name": "import_project",
+ "selector": "#import-project-pane",
+ "title": "Import project",
+ },
+]
+`;
diff --git a/spec/frontend/projects/new/components/app_spec.js b/spec/frontend/projects/new/components/app_spec.js
index 60d8385eb91..006114e7254 100644
--- a/spec/frontend/projects/new/components/app_spec.js
+++ b/spec/frontend/projects/new/components/app_spec.js
@@ -23,6 +23,12 @@ describe('Experimental new project creation app', () => {
expect(wrapper.find(guidelineSelector).text()).toBe(DEMO_GUIDELINES);
});
+ it('creates correct panels', () => {
+ createComponent();
+
+ expect(findNewNamespacePage().props('panels')).toMatchSnapshot();
+ });
+
it.each`
isCiCdAvailable | outcome
${false} | ${'do not show CI/CD panel'}
diff --git a/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js b/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js
index cc8a8d86d19..3306e316ed0 100644
--- a/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js
+++ b/spec/frontend/vue_shared/new_namespace/components/welcome_spec.js
@@ -39,6 +39,18 @@ describe('Welcome page', () => {
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_tab', { label: 'test' });
});
+ it('renders image', () => {
+ const mockImgSrc = 'image1.svg';
+
+ createComponent({
+ propsData: {
+ panels: [{ name: 'test', href: '#', imageSrc: mockImgSrc }],
+ },
+ });
+
+ expect(wrapper.find('img').attributes('src')).toBe(mockImgSrc);
+ });
+
it('renders footer slot if provided', () => {
const DUMMY = 'Test message';
createComponent({
diff --git a/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js b/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js
index abc69da7a58..a7ddcbdd8bc 100644
--- a/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js
+++ b/spec/frontend/vue_shared/new_namespace/new_namespace_page_spec.js
@@ -15,6 +15,7 @@ describe('Experimental new namespace creation app', () => {
const findWelcomePage = () => wrapper.findComponent(WelcomePage);
const findLegacyContainer = () => wrapper.findComponent(LegacyContainer);
const findBreadcrumb = () => wrapper.findComponent(GlBreadcrumb);
+ const findImage = () => wrapper.find('img');
const findNewTopLevelGroupAlert = () => wrapper.findComponent(NewTopLevelGroupAlert);
const findSuperSidebarToggle = () => wrapper.findComponent(SuperSidebarToggle);
@@ -22,8 +23,8 @@ describe('Experimental new namespace creation app', () => {
title: 'Create something',
initialBreadcrumbs: [{ text: 'Something', href: '#' }],
panels: [
- { name: 'panel1', selector: '#some-selector1' },
- { name: 'panel2', selector: '#some-selector2' },
+ { name: 'panel1', selector: '#some-selector1', imageSrc: 'panel1.svg' },
+ { name: 'panel2', selector: '#some-selector2', imageSrc: 'panel2.svg' },
],
persistenceKey: 'DEMO-PERSISTENCE-KEY',
};
@@ -82,6 +83,10 @@ describe('Experimental new namespace creation app', () => {
expect(breadcrumb.exists()).toBe(true);
expect(breadcrumb.props().items[0].text).toBe(DEFAULT_PROPS.initialBreadcrumbs[0].text);
});
+
+ it('renders images', () => {
+ expect(findImage().attributes('src')).toBe(DEFAULT_PROPS.panels[1].imageSrc);
+ });
});
it('renders extra description if provided', () => {
diff --git a/spec/graphql/resolvers/users/participants_resolver_spec.rb b/spec/graphql/resolvers/users/participants_resolver_spec.rb
index 63a14daabba..22111626c5b 100644
--- a/spec/graphql/resolvers/users/participants_resolver_spec.rb
+++ b/spec/graphql/resolvers/users/participants_resolver_spec.rb
@@ -137,7 +137,8 @@ RSpec.describe Resolvers::Users::ParticipantsResolver do
# 1 extra query per source (3 emojis + 2 notes) to fetch participables collection
# 2 extra queries to load work item widgets collection
- expect { query.call }.not_to exceed_query_limit(control_count).with_threshold(7)
+ # 1 extra query to load the project creator to check if they are banned
+ expect { query.call }.not_to exceed_query_limit(control_count).with_threshold(8)
end
it 'does not execute N+1 for system note metadata relation' do
diff --git a/spec/helpers/environment_helper_spec.rb b/spec/helpers/environment_helper_spec.rb
index 64735f8b23b..b9316e46d9d 100644
--- a/spec/helpers/environment_helper_spec.rb
+++ b/spec/helpers/environment_helper_spec.rb
@@ -68,17 +68,5 @@ RSpec.describe EnvironmentHelper, feature_category: :environment_management do
graphql_etag_key: environment.etag_cache_key
}.to_json)
end
-
- context 'when metrics dashboard feature is available' do
- before do
- stub_feature_flags(remove_monitor_metrics: false)
- end
-
- it 'includes metrics path' do
- expect(Gitlab::Json.parse(subject)).to include(
- 'environment_metrics_path' => project_metrics_dashboard_path(project, environment: environment)
- )
- end
- end
end
end
diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb
index c0816f93a68..b69d6022e70 100644
--- a/spec/helpers/environments_helper_spec.rb
+++ b/spec/helpers/environments_helper_spec.rb
@@ -22,7 +22,6 @@ RSpec.describe EnvironmentsHelper, feature_category: :environment_management do
expect(metrics_data).to include(
'settings_path' => edit_project_settings_integration_path(project, 'prometheus'),
'clusters_path' => project_clusters_path(project),
- 'metrics_dashboard_base_path' => project_metrics_dashboard_path(project, environment: environment),
'current_environment_name' => environment.name,
'documentation_path' => help_page_path('administration/monitoring/prometheus/index.md'),
'add_dashboard_documentation_path' => help_page_path('operations/metrics/dashboards/index.md', anchor: 'add-a-new-dashboard-to-your-project'),
@@ -30,7 +29,6 @@ RSpec.describe EnvironmentsHelper, feature_category: :environment_management do
'empty_loading_svg_path' => match_asset_path('/assets/illustrations/monitoring/loading.svg'),
'empty_no_data_svg_path' => match_asset_path('/assets/illustrations/monitoring/no_data.svg'),
'empty_unable_to_connect_svg_path' => match_asset_path('/assets/illustrations/monitoring/unable_to_connect.svg'),
- 'metrics_endpoint' => additional_metrics_project_environment_path(project, environment, format: :json),
'deployments_endpoint' => project_environment_deployments_path(project, environment, format: :json),
'default_branch' => 'master',
'project_path' => project_path(project),
@@ -82,30 +80,6 @@ RSpec.describe EnvironmentsHelper, feature_category: :environment_management do
it { is_expected.to include('environment_state' => 'stopped') }
end
- context 'when request is from project scoped metrics path' do
- let(:request) { double('request', path: path) }
-
- before do
- allow(helper).to receive(:request).and_return(request)
- end
-
- context '/:namespace/:project/-/metrics' do
- let(:path) { project_metrics_dashboard_path(project) }
-
- it 'uses correct path for metrics_dashboard_base_path' do
- expect(metrics_data['metrics_dashboard_base_path']).to eq(project_metrics_dashboard_path(project))
- end
- end
-
- context '/:namespace/:project/-/metrics/some_custom_dashboard.yml' do
- let(:path) { "#{project_metrics_dashboard_path(project)}/some_custom_dashboard.yml" }
-
- it 'uses correct path for metrics_dashboard_base_path' do
- expect(metrics_data['metrics_dashboard_base_path']).to eq(project_metrics_dashboard_path(project))
- end
- end
- end
-
context 'when metrics dashboard feature is unavailable' do
before do
stub_feature_flags(remove_monitor_metrics: true)
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index cde7fc0e272..07479d4e1e0 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
let_it_be(:user) { create(:user) }
before do
+ allow(helper).to receive(:current_user).and_return(user)
helper.instance_variable_set(:@project, project)
end
@@ -143,7 +144,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
let(:project) { project_with_repo }
before do
- allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:can?).with(user, :read_cross_project) { true }
allow(user).to receive(:max_member_access_for_project).and_return(40)
allow(Gitlab::I18n).to receive(:locale).and_return('es')
@@ -287,10 +287,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
describe '#show_no_ssh_key_message?' do
- before do
- allow(helper).to receive(:current_user).and_return(user)
- end
-
context 'user has no keys' do
it 'returns true' do
expect(helper.show_no_ssh_key_message?).to be_truthy
@@ -307,10 +303,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
describe '#show_no_password_message?' do
- before do
- allow(helper).to receive(:current_user).and_return(user)
- end
-
context 'user has password set' do
it 'returns false' do
expect(helper.show_no_password_message?).to be_falsey
@@ -346,10 +338,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
describe '#no_password_message' do
let(:user) { create(:user, password_automatically_set: true) }
- before do
- allow(helper).to receive(:current_user).and_return(user)
- end
-
context 'password authentication is enabled for Git' do
it 'returns message prompting user to set password or set up a PAT' do
stub_application_setting(password_authentication_enabled_for_git?: true)
@@ -431,10 +419,10 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
describe 'default_clone_protocol' do
+ let(:user) { nil }
+
context 'when user is not logged in and gitlab protocol is HTTP' do
it 'returns HTTP' do
- allow(helper).to receive(:current_user).and_return(nil)
-
expect(helper.send(:default_clone_protocol)).to eq('http')
end
end
@@ -442,7 +430,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
context 'when user is not logged in and gitlab protocol is HTTPS' do
it 'returns HTTPS' do
stub_config_setting(protocol: 'https')
- allow(helper).to receive(:current_user).and_return(nil)
expect(helper.send(:default_clone_protocol)).to eq('https')
end
@@ -453,10 +440,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
let(:user) { double(:user, fork_of: nil) }
let(:project) { double(:project, id: 1) }
- before do
- allow(helper).to receive(:current_user).and_return(user)
- end
-
context 'when there is no current_user' do
let(:user) { nil }
@@ -543,10 +526,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
describe '#git_user_name' do
let(:user) { build_stubbed(:user, name: 'John "A" Doe53') }
- before do
- allow(helper).to receive(:current_user).and_return(user)
- end
-
it 'parses quotes in name' do
expect(helper.send(:git_user_name)).to eq('John \"A\" Doe53')
end
@@ -554,9 +533,7 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
describe '#git_user_email' do
context 'not logged-in' do
- before do
- allow(helper).to receive(:current_user).and_return(nil)
- end
+ let(:user) { nil }
it 'returns your@email.com' do
expect(helper.send(:git_user_email)).to eq('your@email.com')
@@ -564,10 +541,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
context 'user logged in' do
- before do
- allow(helper).to receive(:current_user).and_return(user)
- end
-
context 'user has no configured commit email' do
it 'returns the primary email' do
expect(helper.send(:git_user_email)).to eq(user.email)
@@ -807,9 +780,7 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
describe '#can_admin_project_member?' do
context 'when user is project owner' do
- before do
- allow(helper).to receive(:current_user) { project.owner }
- end
+ let(:user) { project.owner }
it 'returns true for owner of project' do
expect(helper.can_admin_project_member?(project)).to eq true
@@ -829,7 +800,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
with_them do
before do
project.add_role(user, user_project_role)
- allow(helper).to receive(:current_user) { user }
end
it 'resolves if the user can import members' do
@@ -1016,7 +986,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
before do
allow(helper).to receive(:can?) { true }
- allow(helper).to receive(:current_user).and_return(user)
end
it 'includes project_permissions_settings' do
@@ -1188,10 +1157,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
shared_examples 'configure import method modal' do
- before do
- allow(helper).to receive(:current_user).and_return(user)
- end
-
context 'as a user' do
it 'returns a link to contact an administrator' do
allow(user).to receive(:can_admin_all_resources?).and_return(false)
@@ -1290,16 +1255,14 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
describe '#can_admin_associated_clusters?' do
- let_it_be(:current_user) { create(:user) }
let_it_be_with_reload(:project) { create(:project) }
subject { helper.send(:can_admin_associated_clusters?, project) }
before do
- allow(helper).to receive(:current_user).and_return(current_user)
allow(helper)
.to receive(:can?)
- .with(current_user, :admin_cluster, namespace)
+ .with(user, :admin_cluster, namespace)
.and_return(user_can_admin_cluster)
end
@@ -1477,8 +1440,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
it 'returns the data related to fork divergence' do
- allow(helper).to receive(:current_user).and_return(user)
-
ahead_path =
"/#{project.full_path}/-/compare/#{source_project.default_branch}...ref?from_project_id=#{source_project.id}"
behind_path =
@@ -1500,8 +1461,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
end
it 'returns view_mr_path if a merge request for the branch exists' do
- allow(helper).to receive(:current_user).and_return(user)
-
merge_request =
create(:merge_request, source_project: project, target_project: project_with_repo,
source_branch: project.default_branch, target_branch: project_with_repo.default_branch)
@@ -1523,8 +1482,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
with_them do
it 'create_mr_path is nil' do
- allow(helper).to receive(:current_user).and_return(user)
-
project.add_member(user, project_role)
source_project.add_member(user, source_project_role)
@@ -1562,4 +1519,50 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
it { expect(subject).to eq('ssh_url_to_repo') }
end
+
+ describe '#can_view_branch_rules?' do
+ subject { helper.can_view_branch_rules? }
+
+ context 'when user is a maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '#can_push_code?' do
+ subject { helper.can_push_code? }
+
+ context 'when user is nil' do
+ let(:user) { nil }
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when user is a developer on the project' do
+ before do
+ project.add_developer(user)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when user is a reporter on the project' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
end
diff --git a/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb b/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb
index 8ead292c27a..cf525801aa0 100644
--- a/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb
+++ b/spec/lib/gitlab/alert_management/payload/prometheus_spec.rb
@@ -185,8 +185,6 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do
subject { parsed_payload.metrics_dashboard_url }
- it { is_expected.to eq(dashboard_url_for_alert) }
-
context 'without environment' do
let(:raw_payload) { payload.except('labels') }
diff --git a/spec/lib/gitlab/metrics/dashboard/url_spec.rb b/spec/lib/gitlab/metrics/dashboard/url_spec.rb
index d49200f87cc..4045d957b44 100644
--- a/spec/lib/gitlab/metrics/dashboard/url_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/url_spec.rb
@@ -5,78 +5,6 @@ require 'spec_helper'
RSpec.describe Gitlab::Metrics::Dashboard::Url do
include Gitlab::Routing.url_helpers
- describe '#metrics_regex' do
- let(:environment_id) { 1 }
- let(:url_params) do
- [
- 'foo',
- 'bar',
- environment_id,
- {
- start: '2019-08-02T05:43:09.000Z',
- dashboard: 'config/prometheus/common_metrics.yml',
- group: 'awesome group',
- anchor: 'title'
- }
- ]
- end
-
- let(:expected_params) do
- {
- 'url' => url,
- 'namespace' => 'foo',
- 'project' => 'bar',
- 'environment' => '1',
- 'query' => '?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z',
- 'anchor' => '#title'
- }
- end
-
- subject { described_class.metrics_regex }
-
- context 'for /-/environments/:environment_id/metrics route' do
- let(:url) { metrics_namespace_project_environment_url(*url_params) }
-
- it_behaves_like 'regex which matches url when expected'
- end
-
- context 'for /-/metrics?environment=:environment_id route' do
- let(:url) { namespace_project_metrics_dashboard_url(*url_params) }
- let(:url_params) do
- [
- 'namespace1',
- 'project1',
- {
- environment: environment_id,
- start: '2019-08-02T05:43:09.000Z',
- dashboard: 'config/prometheus/common_metrics.yml',
- group: 'awesome group',
- anchor: 'title'
- }
- ]
- end
-
- let(:expected_params) do
- {
- 'url' => url,
- 'namespace' => 'namespace1',
- 'project' => 'project1',
- 'environment' => environment_id.to_s,
- 'query' => "?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&environment=#{environment_id}&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z",
- 'anchor' => '#title'
- }
- end
-
- it_behaves_like 'regex which matches url when expected'
- end
-
- context 'for metrics_dashboard route' do
- let(:url) { metrics_dashboard_namespace_project_environment_url(*url_params) }
-
- it_behaves_like 'regex which matches url when expected'
- end
- end
-
describe '#clusters_regex' do
let(:url) { Gitlab::Routing.url_helpers.namespace_project_cluster_url(*url_params) }
let(:url_params) do
@@ -202,12 +130,4 @@ RSpec.describe Gitlab::Metrics::Dashboard::Url do
end
end
end
-
- describe '#build_dashboard_url' do
- it 'builds the url for the dashboard endpoint' do
- url = described_class.build_dashboard_url('foo', 'bar', 1)
-
- expect(url).to match described_class.metrics_regex
- end
- end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 9df869f8801..f7c81f93260 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -804,7 +804,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic
let(:project) { create(:project) }
let(:description_with_embed) { "Some comment\n\nhttps://grafana.example.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
let(:description_with_unintegrated_embed) { "Some comment\n\nhttps://grafana.exp.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
- let(:description_with_non_grafana_inline_metric) { "Some comment\n\n#{Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(*['foo', 'bar', 12])}" }
shared_examples "zero count" do
it "does not count the issue" do
@@ -824,7 +823,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic
create(:issue, project: project, description: description_with_embed)
# In-Valid
create(:issue, project: project, description: description_with_unintegrated_embed)
- create(:issue, project: project, description: description_with_non_grafana_inline_metric)
create(:issue, project: project, description: nil)
create(:issue, project: project, description: '')
create(:issue, project: project)
diff --git a/spec/mailers/emails/projects_spec.rb b/spec/mailers/emails/projects_spec.rb
index ef3c21b32ce..1f0f09f7ca2 100644
--- a/spec/mailers/emails/projects_spec.rb
+++ b/spec/mailers/emails/projects_spec.rb
@@ -104,7 +104,6 @@ RSpec.describe Emails::Projects do
let_it_be(:environment) { create(:environment, project: project) }
let(:payload) { { 'gitlab_environment_name' => environment.name } }
- let(:metrics_url) { metrics_project_environment_url(project, environment) }
it_behaves_like 'an email sent from GitLab'
it_behaves_like 'it should not have Gmail Actions links'
@@ -131,7 +130,6 @@ RSpec.describe Emails::Projects do
let(:alert) { create(:alert_management_alert, :prometheus, :from_payload, payload: payload, project: project) }
let(:title) { "#{prometheus_alert.title} #{prometheus_alert.computed_operator} #{prometheus_alert.threshold}" }
- let(:metrics_url) { metrics_project_environment_url(project, environment) }
before do
payload['labels'] = {
@@ -157,7 +155,6 @@ RSpec.describe Emails::Projects do
is_expected.to have_body_text(environment.name)
is_expected.to have_body_text('Metric:')
is_expected.to have_body_text(prometheus_alert.full_query)
- is_expected.to have_body_text(metrics_url)
is_expected.not_to have_body_text('Description:')
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 73489e6b35e..bb279132ac6 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -9059,6 +9059,67 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
+ describe '.without_created_and_owned_by_banned_user' do
+ let_it_be(:other_project) { create(:project) }
+
+ subject(:results) { described_class.without_created_and_owned_by_banned_user }
+
+ context 'when project creator is not banned' do
+ let_it_be(:project_of_active_user) { create(:project, creator: create(:user)) }
+
+ it 'includes the project' do
+ expect(results).to match_array([other_project, project_of_active_user])
+ end
+ end
+
+ context 'when project creator is banned' do
+ let_it_be(:banned_user) { create(:user, :banned) }
+ let_it_be(:project_of_banned_user) { create(:project, creator: banned_user) }
+
+ context 'when project creator is also an owner' do
+ let_it_be(:project_auth) do
+ project = project_of_banned_user
+ create(:project_authorization, :owner, user: project.creator, project: project)
+ end
+
+ it 'excludes the project' do
+ expect(results).to match_array([other_project])
+ end
+ end
+
+ context 'when project creator is not an owner' do
+ it 'includes the project' do
+ expect(results).to match_array([other_project, project_of_banned_user])
+ end
+ end
+ end
+ end
+
+ describe '#created_and_owned_by_banned_user?' do
+ subject { project.created_and_owned_by_banned_user? }
+
+ context 'when creator is banned' do
+ let_it_be(:creator) { create(:user, :banned) }
+ let_it_be(:project) { create(:project, creator: creator) }
+
+ it { is_expected.to eq false }
+
+ context 'when creator is an owner' do
+ let_it_be(:project_auth) do
+ create(:project_authorization, :owner, user: project.creator, project: project)
+ end
+
+ it { is_expected.to eq true }
+ end
+ end
+
+ context 'when creator is not banned' do
+ let_it_be(:project) { create(:project) }
+
+ it { is_expected.to eq false }
+ end
+ end
+
it_behaves_like 'something that has web-hooks' do
let_it_be_with_reload(:object) { create(:project) }
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 94330dee912..42fe301ea9e 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -3217,6 +3217,32 @@ RSpec.describe ProjectPolicy, feature_category: :system_access do
end
end
+ describe 'when project is created and owned by a banned user' do
+ let_it_be(:project) { create(:project, :public) }
+
+ let(:current_user) { guest }
+
+ before do
+ allow(project).to receive(:created_and_owned_by_banned_user?).and_return(true)
+ end
+
+ it { expect_disallowed(:read_project) }
+
+ context 'when current user is an admin', :enable_admin_mode do
+ let(:current_user) { admin }
+
+ it { expect_allowed(:read_project) }
+ end
+
+ context 'when hide_projects_of_banned_users FF is disabled' do
+ before do
+ stub_feature_flags(hide_projects_of_banned_users: false)
+ end
+
+ it { expect_allowed(:read_project) }
+ end
+ end
+
private
def project_subject(project_type)
diff --git a/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb
index 3417f9529bd..2c49c9bc47b 100644
--- a/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alert/metrics_dashboard_url_spec.rb
@@ -40,12 +40,6 @@ RSpec.describe 'getting Alert Management Alert Assignees', feature_category: :in
create(:alert_management_alert, :prometheus, project: project, payload: payload)
end
- it 'includes the correct metrics dashboard url' do
- post_graphql(graphql_query, current_user: current_user)
-
- expect(first_alert).to include('metricsDashboardUrl' => dashboard_url_for_alert)
- end
-
context 'when metrics dashboard feature is unavailable' do
before do
stub_feature_flags(remove_monitor_metrics: true)
diff --git a/spec/rubocop/formatter/todo_formatter_spec.rb b/spec/rubocop/formatter/todo_formatter_spec.rb
index fdd6117d0e6..55a64198289 100644
--- a/spec/rubocop/formatter/todo_formatter_spec.rb
+++ b/spec/rubocop/formatter/todo_formatter_spec.rb
@@ -106,6 +106,8 @@ RSpec.describe RuboCop::Formatter::TodoFormatter, feature_category: :tooling do
Exclude:
- 'd.rb'
- 'app/views/project.html.haml.rb'
+ - 'app/views/project.haml.rb'
+ - 'app/views/project.text.haml.rb'
- 'app/views/unrelated.html.haml.rb.ext'
- 'app/views/unrelated.html.haml.ext'
- 'app/views/unrelated.html.haml'
@@ -122,7 +124,9 @@ RSpec.describe RuboCop::Formatter::TodoFormatter, feature_category: :tooling do
B/TooManyOffenses:
Exclude:
- 'a.rb'
+ - 'app/views/project.haml.rb'
- 'app/views/project.html.haml.rb'
+ - 'app/views/project.text.haml.rb'
- 'c.rb'
YAML
end
diff --git a/spec/serializers/environment_entity_spec.rb b/spec/serializers/environment_entity_spec.rb
index c60bead12c2..551acd2860d 100644
--- a/spec/serializers/environment_entity_spec.rb
+++ b/spec/serializers/environment_entity_spec.rb
@@ -83,32 +83,6 @@ RSpec.describe EnvironmentEntity do
end
end
- context 'when metrics dashboard feature is available' do
- before do
- stub_feature_flags(remove_monitor_metrics: false)
- end
-
- context 'metrics disabled' do
- before do
- allow(environment).to receive(:has_metrics?).and_return(false)
- end
-
- it "doesn't expose metrics path" do
- expect(subject).not_to include(:metrics_path)
- end
- end
-
- context 'metrics enabled' do
- before do
- allow(environment).to receive(:has_metrics?).and_return(true)
- end
-
- it 'exposes metrics path' do
- expect(subject).to include(:metrics_path)
- end
- end
- end
-
it "doesn't expose metrics path" do
expect(subject).not_to include(:metrics_path)
end
diff --git a/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb b/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb
index beed23a366f..53def716de3 100644
--- a/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/cluster_dashboard_service_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe Metrics::Dashboard::ClusterDashboardService, :use_clean_rails_mem
end
describe '#get_dashboard' do
- let(:service_params) { [project, user, { cluster: cluster, cluster_type: :project }] }
+ let(:service_params) { [project, user, { cluster: cluster, cluster_type: :admin }] }
let(:service_call) { subject.get_dashboard }
subject { described_class.new(*service_params) }
diff --git a/spec/support/shared_contexts/prometheus/alert_shared_context.rb b/spec/support/shared_contexts/prometheus/alert_shared_context.rb
index 932ab899270..13e739680c8 100644
--- a/spec/support/shared_contexts/prometheus/alert_shared_context.rb
+++ b/spec/support/shared_contexts/prometheus/alert_shared_context.rb
@@ -37,17 +37,6 @@ RSpec.shared_context 'self-managed prometheus alert attributes' do
}
}
end
-
- let(:dashboard_url_for_alert) do
- Gitlab::Routing.url_helpers.metrics_dashboard_project_environment_url(
- project,
- environment,
- embed_json: embed_content,
- embedded: true,
- end: '2018-03-12T09:36:00Z',
- start: '2018-03-12T08:36:00Z'
- )
- end
end
RSpec.shared_context 'gitlab-managed prometheus alert attributes' do
diff --git a/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb b/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb
index 5b63ef10c85..013d722a8c1 100644
--- a/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/metrics_dashboard_shared_examples.rb
@@ -12,33 +12,3 @@ RSpec.shared_examples_for 'GET #metrics_dashboard correctly formatted response'
expect(found_keys).to contain_exactly(*expected_keys)
end
end
-
-RSpec.shared_examples_for 'GET #metrics_dashboard for dashboard' do |dashboard_name|
- let(:expected_keys) { %w(dashboard status metrics_data) }
- let(:status_code) { :ok }
-
- before do
- stub_feature_flags(remove_monitor_metrics: false)
- end
-
- it_behaves_like 'GET #metrics_dashboard correctly formatted response'
-
- it 'returns correct dashboard' do
- get :metrics_dashboard, params: metrics_dashboard_req_params, format: :json
-
- expect(json_response['dashboard']['dashboard']).to eq(dashboard_name)
- end
-
- context 'when metrics dashboard feature is unavailable' do
- before do
- stub_feature_flags(remove_monitor_metrics: true)
- end
-
- it 'returns 404 not found' do
- get :metrics_dashboard, params: metrics_dashboard_req_params, format: :json
-
- expect(response).to have_gitlab_http_status(:not_found)
- expect(response.body).to be_empty
- end
- end
-end
diff --git a/spec/support/shared_examples/features/content_editor_shared_examples.rb b/spec/support/shared_examples/features/content_editor_shared_examples.rb
index 2454bb7afc6..254bc3c83ac 100644
--- a/spec/support/shared_examples/features/content_editor_shared_examples.rb
+++ b/spec/support/shared_examples/features/content_editor_shared_examples.rb
@@ -572,7 +572,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi
expect(find(suggestions_dropdown)).to have_text('My Cool Merge Request')
- send_keys :enter
+ send_keys [:arrow_down, :enter]
expect(page).not_to have_css(suggestions_dropdown)
expect(page).to have_text('!1')
@@ -583,7 +583,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi
expect(find(suggestions_dropdown)).to have_text('My Cool Linked Issue')
- send_keys :enter
+ send_keys [:arrow_down, :enter]
expect(page).not_to have_css(suggestions_dropdown)
expect(page).to have_text('#1')
@@ -594,7 +594,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi
expect(find(suggestions_dropdown)).to have_text('My Cool Milestone')
- send_keys :enter
+ send_keys [:arrow_down, :enter]
expect(page).not_to have_css(suggestions_dropdown)
expect(page).to have_text('%My Cool Milestone')
@@ -606,7 +606,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi
expect(find(suggestions_dropdown)).to have_text('🙂 slight_smile')
expect(find(suggestions_dropdown)).to have_text('😸 smile_cat')
- send_keys :enter
+ send_keys [:arrow_down, :enter]
expect(page).not_to have_css(suggestions_dropdown)
@@ -636,7 +636,7 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi
end
def dropdown_scroll_top
- evaluate_script("document.querySelector('#{suggestions_dropdown} .gl-dropdown-inner').scrollTop")
+ evaluate_script("document.querySelector('#{suggestions_dropdown}').scrollTop")
end
end
end