Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-06-27 18:09:04 +00:00
parent 0847321aee
commit 7424d727b8
91 changed files with 593 additions and 801 deletions

View File

@ -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"

View File

@ -40,6 +40,7 @@ AllCops:
TargetRubyVersion: <%= RUBY_VERSION[/^\d+\.\d+/, 0] %>
TargetRailsVersion: 6.0
Exclude:
- 'gems/**/*'
- 'vendor/**/*'
- 'node_modules/**/*'
- 'db/fixtures/**/*'

View File

@ -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>

View File

@ -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),
};

View File

@ -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>

View File

@ -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,
},
];
},

View File

@ -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,
},
];

View File

@ -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 }}

View File

@ -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>

View File

@ -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;
}

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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)

View File

@ -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 %>

View File

@ -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')

View File

@ -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 } }

View File

@ -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" }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
7060d1ed7be6fce2e398d9ac042d6e67826742e639df8eee43245d66b8b87ea3

View File

@ -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));

View File

@ -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` |

View File

@ -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 |

View File

@ -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"

View File

@ -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.|

View File

@ -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.

View File

@ -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">

View File

@ -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

View File

@ -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` |

View File

@ -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

View File

@ -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`).

View File

@ -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.

View File

@ -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'

View File

@ -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'
},
{

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ""

View File

@ -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

View File

@ -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
{

View File

@ -6,4 +6,8 @@ FactoryBot.define do
project
access_level { Gitlab::Access::REPORTER }
end
trait :owner do
access_level { Gitlab::Access::OWNER }
end
end

View File

@ -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

View File

@ -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
}

View File

@ -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({

View File

@ -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

View File

@ -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);
});
});

View File

@ -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",
},
]
`;

View File

@ -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'}

View File

@ -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({

View File

@ -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', () => {

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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') }

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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) }

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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) }

View File

@ -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

View File

@ -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

View File

@ -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