Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-07-08 18:09:32 +00:00
parent 66a3180a3b
commit 7e17b031fa
94 changed files with 406 additions and 217 deletions

View File

@ -2459,12 +2459,6 @@ Style/RegexpLiteralMixedPreserve:
- 'ee/app/presenters/vulnerability_presenter.rb'
- 'ee/lib/api/geo_nodes.rb'
- 'ee/lib/gitlab/vulnerabilities/standard_vulnerability.rb'
- 'ee/spec/controllers/concerns/ee/routable_actions/sso_enforcement_redirect_spec.rb'
- 'ee/spec/controllers/concerns/routable_actions_spec.rb'
- 'ee/spec/controllers/groups/groups_controller_spec.rb'
- 'ee/spec/features/groups/saml_enforcement_spec.rb'
- 'ee/spec/features/markdown/metrics_spec.rb'
- 'ee/spec/services/jira/requests/issues/list_service_spec.rb'
- 'lib/api/invitations.rb'
- 'lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb'
- 'lib/gitlab/metrics/requests_rack_middleware.rb'
@ -2472,24 +2466,3 @@ Style/RegexpLiteralMixedPreserve:
- 'lib/gitlab/regex.rb'
- 'lib/gitlab/utils.rb'
- 'lib/product_analytics/tracker.rb'
- 'qa/qa/page/project/settings/advanced.rb'
- 'qa/spec/service/docker_run/gitlab_runner_spec.rb'
- 'rubocop/cop/gitlab/duplicate_spec_location.rb'
- 'spec/features/clusters/cluster_health_dashboard_spec.rb'
- 'spec/features/markdown/metrics_spec.rb'
- 'spec/features/search/user_searches_for_code_spec.rb'
- 'spec/features/snippets/embedded_snippet_spec.rb'
- 'spec/helpers/diff_helper_spec.rb'
- 'spec/helpers/releases_helper_spec.rb'
- 'spec/lib/gitlab/ci/reports/test_case_spec.rb'
- 'spec/lib/gitlab/consul/internal_spec.rb'
- 'spec/lib/gitlab/import_export/shared_spec.rb'
- 'spec/lib/gitlab/utils/usage_data_spec.rb'
- 'spec/presenters/ci/build_runner_presenter_spec.rb'
- 'spec/requests/api/projects_spec.rb'
- 'spec/services/jira/requests/projects/list_service_spec.rb'
- 'spec/support/capybara.rb'
- 'spec/support/helpers/grafana_api_helpers.rb'
- 'spec/support/helpers/query_recorder.rb'
- 'spec/support/helpers/require_migration.rb'
- 'spec/views/layouts/_head.html.haml_spec.rb'

View File

@ -286,7 +286,7 @@ gem 'gitlab_chronic_duration', '~> 0.10.6.2'
gem 'rack-proxy', '~> 0.6.0'
gem 'sassc-rails', '~> 2.1.0'
gem 'autoprefixer-rails', '10.2.0.0'
gem 'autoprefixer-rails', '10.2.5.1'
gem 'terser', '1.0.2'
gem 'addressable', '~> 2.7'

View File

@ -105,8 +105,8 @@ GEM
attr_encrypted (3.1.0)
encryptor (~> 3.0.0)
attr_required (1.0.1)
autoprefixer-rails (10.2.0.0)
execjs
autoprefixer-rails (10.2.5.1)
execjs (> 0)
awesome_print (1.9.2)
awrence (1.1.1)
aws-eventstream (1.1.0)
@ -343,7 +343,7 @@ GEM
tzinfo
eventmachine (1.2.7)
excon (0.71.1)
execjs (2.7.0)
execjs (2.8.1)
expression_parser (0.9.0)
extended-markdown-filter (0.6.0)
html-pipeline (~> 2.0)
@ -1413,7 +1413,7 @@ DEPENDENCIES
asciidoctor-plantuml (~> 0.0.12)
atlassian-jwt (~> 0.2.0)
attr_encrypted (~> 3.1.0)
autoprefixer-rails (= 10.2.0.0)
autoprefixer-rails (= 10.2.5.1)
awesome_print
aws-sdk-cloudformation (~> 1)
aws-sdk-core (~> 3)

View File

@ -87,7 +87,7 @@ export default {
class="boards-sidebar gl-absolute"
@close="handleClose"
>
<template #header>
<template #title>
<h2 class="gl-my-0 gl-font-size-h2 gl-line-height-24">{{ __('Issue details') }}</h2>
</template>
<template #default>

View File

@ -95,7 +95,7 @@ export default {
:open="isSidebarOpen"
@close="unsetActiveId"
>
<template #header>{{ $options.listSettingsText }}</template>
<template #title>{{ $options.listSettingsText }}</template>
<template v-if="isSidebarOpen">
<div v-if="boardListType === ListType.label">
<label class="js-list-label gl-display-block">{{ listTypeTitle }}</label>

View File

@ -50,9 +50,6 @@ export default function initDiffsApp(store) {
click: this.openFile,
},
class: ['diff-file-finder'],
style: {
display: this.fileFinderVisible ? '' : 'none',
},
});
},
});

View File

@ -130,7 +130,6 @@ export default {
<div class="ide-view flex-grow d-flex">
<template v-if="loadDeferred">
<find-file
v-show="fileFindVisible"
:files="allBlobs"
:visible="fileFindVisible"
:loading="loading"

View File

@ -8,6 +8,7 @@ import {
REPORT_TYPE_DAST_PROFILES,
REPORT_TYPE_DEPENDENCY_SCANNING,
REPORT_TYPE_CONTAINER_SCANNING,
REPORT_TYPE_CLUSTER_IMAGE_SCANNING,
REPORT_TYPE_COVERAGE_FUZZING,
REPORT_TYPE_API_FUZZING,
REPORT_TYPE_LICENSE_COMPLIANCE,
@ -46,6 +47,7 @@ export default {
[REPORT_TYPE_DAST_PROFILES]: Upgrade,
[REPORT_TYPE_DEPENDENCY_SCANNING]: Upgrade,
[REPORT_TYPE_CONTAINER_SCANNING]: Upgrade,
[REPORT_TYPE_CLUSTER_IMAGE_SCANNING]: Upgrade,
[REPORT_TYPE_COVERAGE_FUZZING]: Upgrade,
[REPORT_TYPE_API_FUZZING]: Upgrade,
[REPORT_TYPE_LICENSE_COMPLIANCE]: Upgrade,

View File

@ -9,6 +9,7 @@ import {
REPORT_TYPE_SECRET_DETECTION,
REPORT_TYPE_DEPENDENCY_SCANNING,
REPORT_TYPE_CONTAINER_SCANNING,
REPORT_TYPE_CLUSTER_IMAGE_SCANNING,
REPORT_TYPE_COVERAGE_FUZZING,
REPORT_TYPE_API_FUZZING,
REPORT_TYPE_LICENSE_COMPLIANCE,
@ -76,6 +77,18 @@ export const CONTAINER_SCANNING_CONFIG_HELP_PATH = helpPagePath(
{ anchor: 'configuration' },
);
export const CLUSTER_IMAGE_SCANNING_NAME = __('ciReport|Cluster Image Scanning');
export const CLUSTER_IMAGE_SCANNING_DESCRIPTION = __(
'Check your Kubernetes cluster images for known vulnerabilities.',
);
export const CLUSTER_IMAGE_SCANNING_HELP_PATH = helpPagePath(
'user/application_security/cluster_image_scanning/index',
);
export const CLUSTER_IMAGE_SCANNING_CONFIG_HELP_PATH = helpPagePath(
'user/application_security/cluster_image_scanning/index',
{ anchor: 'configuration' },
);
export const COVERAGE_FUZZING_NAME = __('Coverage Fuzzing');
export const COVERAGE_FUZZING_DESCRIPTION = __(
'Find bugs in your code with coverage-guided fuzzing.',
@ -131,6 +144,12 @@ export const scanners = [
helpPath: CONTAINER_SCANNING_HELP_PATH,
type: REPORT_TYPE_CONTAINER_SCANNING,
},
{
name: CLUSTER_IMAGE_SCANNING_NAME,
description: CLUSTER_IMAGE_SCANNING_DESCRIPTION,
helpPath: CLUSTER_IMAGE_SCANNING_HELP_PATH,
type: REPORT_TYPE_CLUSTER_IMAGE_SCANNING,
},
{
name: SECRET_DETECTION_NAME,
description: SECRET_DETECTION_DESCRIPTION,
@ -203,6 +222,13 @@ export const securityFeatures = [
configurationHelpPath: CONTAINER_SCANNING_CONFIG_HELP_PATH,
type: REPORT_TYPE_CONTAINER_SCANNING,
},
{
name: CLUSTER_IMAGE_SCANNING_NAME,
description: CLUSTER_IMAGE_SCANNING_DESCRIPTION,
helpPath: CLUSTER_IMAGE_SCANNING_HELP_PATH,
configurationHelpPath: CLUSTER_IMAGE_SCANNING_CONFIG_HELP_PATH,
type: REPORT_TYPE_CLUSTER_IMAGE_SCANNING,
},
{
name: SECRET_DETECTION_NAME,
description: SECRET_DETECTION_DESCRIPTION,

View File

@ -60,7 +60,7 @@ export default {
class="gl-dropdown-text-py-0 gl-dropdown-text-block"
data-testid="input"
>
<gl-form-input-group :value="value" readonly select-on-click :aria-label="name">
<gl-form-input-group :value="value" readonly select-on-click :label="name">
<template #append>
<gl-button
v-gl-tooltip.hover

View File

@ -21,7 +21,7 @@ export default {
</script>
<template>
<gl-drawer class="gl-pt-8" :open="isOpen" @close="$emit('close')">
<template #header>{{ __('Page settings') }}</template>
<template #title>{{ __('Page settings') }}</template>
<front-matter-controls :settings="settings" @updateSettings="$emit('updateSettings', $event)" />
</gl-drawer>
</template>

View File

@ -14,27 +14,25 @@ export default {
};
</script>
<template>
<table class="table m-0">
<thead class="thead-white text-nowrap">
<tr class="d-none d-sm-table-row">
<th class="w-0"></th>
<th>{{ __('Artifact') }}</th>
<th class="w-50"></th>
<th>{{ __('Job') }}</th>
</tr>
</thead>
<div class="gl-pl-7">
<table class="table m-0">
<thead class="thead-white text-nowrap">
<tr class="d-none d-sm-table-row">
<th>{{ __('Artifact') }}</th>
<th>{{ __('Job') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in artifacts" :key="item.text">
<td class="w-0"></td>
<td>
<gl-link :href="item.url" target="_blank">{{ item.text }}</gl-link>
</td>
<td class="w-0"></td>
<td>
<gl-link :href="item.job_path">{{ item.job_name }}</gl-link>
</td>
</tr>
</tbody>
</table>
<tbody>
<tr v-for="item in artifacts" :key="item.text">
<td>
<gl-link :href="item.url" target="_blank">{{ item.text }}</gl-link>
</td>
<td>
<gl-link :href="item.job_path">{{ item.job_name }}</gl-link>
</td>
</tr>
</tbody>
</table>
</div>
</template>

View File

@ -58,7 +58,7 @@ export default {
<template v-else>
<button
class="btn-blank btn s32 square gl-mr-3"
class="btn-blank btn s32 square"
type="button"
:aria-label="ariaLabel"
:disabled="isLoading"

View File

@ -171,7 +171,7 @@ export default {
<template v-else-if="!hasPipeline">
<gl-loading-icon size="md" />
<p
class="gl-flex-grow-1 gl-display-flex gl-ml-5 gl-mb-0"
class="gl-flex-grow-1 gl-display-flex gl-ml-3 gl-mb-0"
data-testid="monitoring-pipeline-message"
>
{{ $options.monitoringPipelineText }}
@ -190,7 +190,7 @@ export default {
</p>
</template>
<template v-else-if="hasPipeline">
<a :href="status.details_path" class="align-self-start gl-mr-3">
<a :href="status.details_path" class="gl-align-self-center gl-mr-3">
<ci-icon :status="status" :size="24" />
</a>
<div class="ci-widget-container d-flex">

View File

@ -103,6 +103,9 @@ export default {
focusedIndex() {
if (!this.mouseOver) {
this.$nextTick(() => {
if (!this.$refs.virtualScrollList?.$el) {
return;
}
const el = this.$refs.virtualScrollList.$el;
const scrollTop = this.focusedIndex * FILE_FINDER_ROW_HEIGHT;
const bottom = this.listShowCount * FILE_FINDER_ROW_HEIGHT;
@ -218,7 +221,7 @@ export default {
</script>
<template>
<div class="file-finder-overlay" @mousedown.self="toggle(false)">
<div v-if="visible" class="file-finder-overlay" @mousedown.self="toggle(false)">
<div class="dropdown-menu diff-file-changes file-finder show">
<div :class="{ 'has-value': showClearInputButton }" class="dropdown-input">
<input

View File

@ -22,6 +22,7 @@ export const REPORT_TYPE_DAST_PROFILES = 'dast_profiles';
export const REPORT_TYPE_SECRET_DETECTION = 'secret_detection';
export const REPORT_TYPE_DEPENDENCY_SCANNING = 'dependency_scanning';
export const REPORT_TYPE_CONTAINER_SCANNING = 'container_scanning';
export const REPORT_TYPE_CLUSTER_IMAGE_SCANNING = 'cluster_image_scanning';
export const REPORT_TYPE_COVERAGE_FUZZING = 'coverage_fuzzing';
export const REPORT_TYPE_LICENSE_COMPLIANCE = 'license_scanning';
export const REPORT_TYPE_API_FUZZING = 'api_fuzzing';

View File

@ -68,7 +68,7 @@ export default {
:open="open"
@close="closeDrawer"
>
<template #header>
<template #title>
<h4 class="page-title gl-my-2">{{ __("What's new") }}</h4>
</template>
<template v-if="features.length">

View File

@ -46,7 +46,7 @@ class Projects::ServicesController < Projects::ApplicationController
end
def test
if integration.can_test?
if integration.testable?
render json: service_test_response, status: :ok
else
render json: {}, status: :not_found

View File

@ -84,7 +84,7 @@ module IntegrationsHelper
integration_level: integration_level(integration),
editable: integration.editable?.to_s,
cancel_path: scoped_integrations_path,
can_test: integration.can_test?.to_s,
can_test: integration.testable?.to_s,
test_path: scoped_test_integration_path(integration),
reset_path: scoped_reset_integration_path(integration, group: group)
}

View File

@ -447,7 +447,7 @@ class Integration < ApplicationRecord
# Disable test for instance-level and group-level integrations.
# https://gitlab.com/gitlab-org/gitlab/-/issues/213138
def can_test?
def testable?
project_level?
end

View File

@ -20,7 +20,7 @@ module Integrations
%w()
end
def can_test?
def testable?
false
end

View File

@ -58,7 +58,7 @@ module Integrations
]
end
def can_test?
def testable?
false
end

View File

@ -27,7 +27,7 @@ module Integrations
'ewm'
end
def can_test?
def testable?
false
end

View File

@ -537,7 +537,7 @@ module Integrations
def update_deployment_type?
(api_url_changed? || url_changed? || username_changed? || password_changed?) &&
can_test?
testable?
end
def update_deployment_type

View File

@ -6,7 +6,7 @@ module Integrations
prop_accessor :token
def can_test?
def testable?
false
end

View File

@ -83,7 +83,7 @@ module Integrations
end
end
def can_test?
def testable?
false
end
end

View File

@ -18,7 +18,7 @@ module Integrations
Gitlab::Json.parse(File.read(Rails.root + 'spec/fixtures/metrics.json'))
end
def can_test?
def testable?
false
end
end

View File

@ -57,7 +57,7 @@ module Integrations
PipelineNotificationWorker.new.perform(pipeline_id, recipients: all_recipients)
end
def can_test?
def testable?
project&.ci_pipelines&.any?
end

View File

@ -50,7 +50,7 @@ module Gitlab
def get_commit_data(commit)
CommitData.new.tap do |data|
data.author_avatar = author_avatar(commit, size: 36, has_tooltip: false)
data.author_avatar = author_avatar(commit, size: 36, has_tooltip: false, lazy: true)
data.age_map_class = age_map_class(commit.committed_date, project_duration)
data.commit_link = link_to commit.title, project_commit_path(project, commit.id), class: "cdark", title: commit.title
data.commit_author_link = commit_author_link(commit, avatar: false)

View File

@ -0,0 +1,57 @@
# frozen_string_literal: true
class AddIndexTypeToPostgresIndexesView < ActiveRecord::Migration[6.1]
def up
execute(<<~SQL)
DROP VIEW IF EXISTS postgres_indexes;
CREATE VIEW postgres_indexes AS
SELECT (pg_namespace.nspname::text || '.'::text) || i.relname::text AS identifier,
pg_index.indexrelid,
pg_namespace.nspname AS schema,
i.relname AS name,
pg_indexes.tablename,
a.amname AS type,
pg_index.indisunique AS "unique",
pg_index.indisvalid AS valid_index,
i.relispartition AS partitioned,
pg_index.indisexclusion AS exclusion,
pg_index.indexprs IS NOT NULL AS expression,
pg_index.indpred IS NOT NULL AS partial,
pg_indexes.indexdef AS definition,
pg_relation_size(i.oid::regclass) AS ondisk_size_bytes
FROM pg_index
JOIN pg_class i ON i.oid = pg_index.indexrelid
JOIN pg_namespace ON i.relnamespace = pg_namespace.oid
JOIN pg_indexes ON i.relname = pg_indexes.indexname
JOIN pg_am a ON i.relam = a.oid
WHERE pg_namespace.nspname <> 'pg_catalog'::name AND (pg_namespace.nspname = ANY (ARRAY["current_schema"(), 'gitlab_partitions_dynamic'::name, 'gitlab_partitions_static'::name]));
SQL
end
def down
execute(<<~SQL)
DROP VIEW IF EXISTS postgres_indexes;
CREATE VIEW postgres_indexes AS
SELECT (((pg_namespace.nspname)::text || '.'::text) || (pg_class.relname)::text) AS identifier,
pg_index.indexrelid,
pg_namespace.nspname AS schema,
pg_class.relname AS name,
pg_indexes.tablename,
pg_index.indisunique AS "unique",
pg_index.indisvalid AS valid_index,
pg_class.relispartition AS partitioned,
pg_index.indisexclusion AS exclusion,
(pg_index.indexprs IS NOT NULL) AS expression,
(pg_index.indpred IS NOT NULL) AS partial,
pg_indexes.indexdef AS definition,
pg_relation_size((pg_class.oid)::regclass) AS ondisk_size_bytes
FROM (((pg_index
JOIN pg_class ON ((pg_class.oid = pg_index.indexrelid)))
JOIN pg_namespace ON ((pg_class.relnamespace = pg_namespace.oid)))
JOIN pg_indexes ON ((pg_class.relname = pg_indexes.indexname)))
WHERE ((pg_namespace.nspname <> 'pg_catalog'::name) AND (pg_namespace.nspname = ANY (ARRAY["current_schema"(), 'gitlab_partitions_dynamic'::name, 'gitlab_partitions_static'::name])));
SQL
end
end

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
class CreateVulnerabilityFindingEvidenceSupportingMessages < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
create_table_with_constraints :vulnerability_finding_evidence_supporting_messages do |t|
t.timestamps_with_timezone null: false
t.references :vulnerability_finding_evidence, index: { name: 'finding_evidence_supporting_messages_on_finding_evidence_id' }, null: false, foreign_key: { on_delete: :cascade }
t.text :name
t.text_limit :name, 2048
end
end
def down
with_lock_retries do
drop_table :vulnerability_finding_evidence_supporting_messages
end
end
end

View File

@ -0,0 +1 @@
45ec2dd6113d112050a1ac062064950fa18b3b5903a9fd60234e9e9fa48c7070

View File

@ -0,0 +1 @@
0c25d19d03bce4f145eca271c852aad6a8327821a8f5ff0aa2f0286f4a65b328

View File

@ -16583,23 +16583,25 @@ END AS attrelname
ORDER BY relation_stats.nspname, relation_stats.tblname, relation_stats.idxname;
CREATE VIEW postgres_indexes AS
SELECT (((pg_namespace.nspname)::text || '.'::text) || (pg_class.relname)::text) AS identifier,
SELECT (((pg_namespace.nspname)::text || '.'::text) || (i.relname)::text) AS identifier,
pg_index.indexrelid,
pg_namespace.nspname AS schema,
pg_class.relname AS name,
i.relname AS name,
pg_indexes.tablename,
a.amname AS type,
pg_index.indisunique AS "unique",
pg_index.indisvalid AS valid_index,
pg_class.relispartition AS partitioned,
i.relispartition AS partitioned,
pg_index.indisexclusion AS exclusion,
(pg_index.indexprs IS NOT NULL) AS expression,
(pg_index.indpred IS NOT NULL) AS partial,
pg_indexes.indexdef AS definition,
pg_relation_size((pg_class.oid)::regclass) AS ondisk_size_bytes
FROM (((pg_index
JOIN pg_class ON ((pg_class.oid = pg_index.indexrelid)))
JOIN pg_namespace ON ((pg_class.relnamespace = pg_namespace.oid)))
JOIN pg_indexes ON ((pg_class.relname = pg_indexes.indexname)))
pg_relation_size((i.oid)::regclass) AS ondisk_size_bytes
FROM ((((pg_index
JOIN pg_class i ON ((i.oid = pg_index.indexrelid)))
JOIN pg_namespace ON ((i.relnamespace = pg_namespace.oid)))
JOIN pg_indexes ON ((i.relname = pg_indexes.indexname)))
JOIN pg_am a ON ((i.relam = a.oid)))
WHERE ((pg_namespace.nspname <> 'pg_catalog'::name) AND (pg_namespace.nspname = ANY (ARRAY["current_schema"(), 'gitlab_partitions_dynamic'::name, 'gitlab_partitions_static'::name])));
CREATE VIEW postgres_partitioned_tables AS
@ -19187,6 +19189,24 @@ CREATE SEQUENCE vulnerability_finding_evidence_responses_id_seq
ALTER SEQUENCE vulnerability_finding_evidence_responses_id_seq OWNED BY vulnerability_finding_evidence_responses.id;
CREATE TABLE vulnerability_finding_evidence_supporting_messages (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
vulnerability_finding_evidence_id bigint NOT NULL,
name text,
CONSTRAINT check_fa33b9ae85 CHECK ((char_length(name) <= 2048))
);
CREATE SEQUENCE vulnerability_finding_evidence_supporting_messages_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE vulnerability_finding_evidence_supporting_messages_id_seq OWNED BY vulnerability_finding_evidence_supporting_messages.id;
CREATE TABLE vulnerability_finding_evidences (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@ -20527,6 +20547,8 @@ ALTER TABLE ONLY vulnerability_finding_evidence_requests ALTER COLUMN id SET DEF
ALTER TABLE ONLY vulnerability_finding_evidence_responses ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_responses_id_seq'::regclass);
ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidence_supporting_messages_id_seq'::regclass);
ALTER TABLE ONLY vulnerability_finding_evidences ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_evidences_id_seq'::regclass);
ALTER TABLE ONLY vulnerability_finding_links ALTER COLUMN id SET DEFAULT nextval('vulnerability_finding_links_id_seq'::regclass);
@ -22244,6 +22266,9 @@ ALTER TABLE ONLY vulnerability_finding_evidence_requests
ALTER TABLE ONLY vulnerability_finding_evidence_responses
ADD CONSTRAINT vulnerability_finding_evidence_responses_pkey PRIMARY KEY (id);
ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages
ADD CONSTRAINT vulnerability_finding_evidence_supporting_messages_pkey PRIMARY KEY (id);
ALTER TABLE ONLY vulnerability_finding_evidences
ADD CONSTRAINT vulnerability_finding_evidences_pkey PRIMARY KEY (id);
@ -22489,6 +22514,8 @@ CREATE INDEX finding_evidence_requests_on_finding_evidence_id ON vulnerability_f
CREATE INDEX finding_evidence_responses_on_finding_evidences_id ON vulnerability_finding_evidence_responses USING btree (vulnerability_finding_evidence_id);
CREATE INDEX finding_evidence_supporting_messages_on_finding_evidence_id ON vulnerability_finding_evidence_supporting_messages USING btree (vulnerability_finding_evidence_id);
CREATE INDEX finding_evidences_on_vulnerability_occurrence_id ON vulnerability_finding_evidences USING btree (vulnerability_occurrence_id);
CREATE INDEX finding_links_on_vulnerability_occurrence_id ON vulnerability_finding_links USING btree (vulnerability_occurrence_id);
@ -27208,6 +27235,9 @@ ALTER TABLE ONLY terraform_states
ALTER TABLE ONLY analytics_cycle_analytics_project_stages
ADD CONSTRAINT fk_rails_796a7dbc9c FOREIGN KEY (project_value_stream_id) REFERENCES analytics_cycle_analytics_project_value_streams(id) ON DELETE CASCADE;
ALTER TABLE ONLY vulnerability_finding_evidence_supporting_messages
ADD CONSTRAINT fk_rails_79e77f6c5c FOREIGN KEY (vulnerability_finding_evidence_id) REFERENCES vulnerability_finding_evidences(id) ON DELETE CASCADE;
ALTER TABLE ONLY software_license_policies
ADD CONSTRAINT fk_rails_7a7a2a92de FOREIGN KEY (software_license_id) REFERENCES software_licenses(id) ON DELETE CASCADE;

View File

@ -28,6 +28,3 @@ swap:
administrator access: the Administrator role
administrator permission: the Administrator role
administrator permissions: the Administrator role
developer access: the Developer role
developer permission: the Developer role
developer permissions: the Developer role

View File

@ -38,3 +38,6 @@ swap:
can sign-in: can sign in
x509: X.509
yaml: YAML
developer access: the Developer role
developer permission: the Developer role
developer permissions: the Developer role

View File

@ -111,7 +111,7 @@ PUT /projects/:id/access_requests/:user_id/approve
| -------------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `user_id` | integer | yes | The user ID of the access requester |
| `access_level` | integer | no | A valid access level (defaults: `30`, developer access level) |
| `access_level` | integer | no | A valid access level (defaults: `30`, the Developer role) |
Example request:

View File

@ -114,7 +114,7 @@ Parameters:
## Delete group milestone
Only for users with Developer access to the group.
Only for users with the Developer role in the group.
```plaintext
DELETE /groups/:id/milestones/:milestone_id

View File

@ -123,7 +123,7 @@ PUT /projects/:id/invitations/:email
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project or group](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `email` | string | yes | The email address to which the invitation was previously sent. |
| `access_level` | integer | no | A valid access level (defaults: `30`, developer access level). |
| `access_level` | integer | no | A valid access level (defaults: `30`, the Developer role). |
| `expires_at` | string | no | A date string in ISO 8601 format (`YYYY-MM-DDTHH:MM:SSZ`). |
```shell

View File

@ -107,7 +107,7 @@ Parameters:
## Delete project milestone
Only for users with Developer access to the project.
Only for users with the Developer role in the project.
```plaintext
DELETE /projects/:id/milestones/:milestone_id
@ -148,7 +148,7 @@ Parameters:
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53861) in GitLab 11.9
Only for users with Developer access to the group.
Only for users with the Developer role in the group.
```plaintext
POST /projects/:id/milestones/:milestone_id/promote

View File

@ -40,8 +40,8 @@ job completes:
- If the job completes in *more than 30 minutes*, the job must use the
[Slack API](https://api.slack.com/) to send data to the channel.
To use the `run` command, you must have
[Developer access or above](../../user/permissions.md#project-members-permissions).
To use the `run` command, you must have the
[Developer role or higher](../../user/permissions.md#project-members-permissions).
If a job shouldn't be able to be triggered from chat, you can set the job to `except: [chat]`.
## Best practices for ChatOps CI jobs
@ -53,7 +53,7 @@ functions available. Consider these best practices when creating ChatOps jobs:
of the standard CI pipeline.
- If the job is set to `when: manual`, ChatOps creates the pipeline, but the job waits to be started.
- ChatOps provides limited support for access control. If the user triggering the
slash command has [Developer access or above](../../user/permissions.md#project-members-permissions)
slash command has the [Developer role or higher](../../user/permissions.md#project-members-permissions)
in the project, the job runs. The job itself can use existing
[CI/CD variables](../variables/index.md#predefined-cicd-variables) like
`GITLAB_USER_ID` to perform additional rights validation, but

View File

@ -25,7 +25,8 @@ If you are using a continuous deployment workflow and want to ensure that concur
## Restrict write access to a critical environment
By default, environments can be modified by any team member that has [Developer permission or higher](../../user/permissions.md#project-members-permissions).
By default, environments can be modified by any team member that has the
[Developer role or higher](../../user/permissions.md#project-members-permissions).
If you want to restrict write access to a critical environment (for example a `production` environment),
you can set up [protected environments](protected_environments.md).

View File

@ -39,7 +39,7 @@ To protect an environment:
- **Maintainers**: Allows access to all maintainers in the project.
- **Developers**: Allows access to all maintainers and all developers in the project.
- You can only select groups that are already associated with the project.
- Only users that have at least the Developer permission level appear in
- Only users that have at least the Developer role appear in
the **Allowed to Deploy** dropdown menu.
1. Click the **Protect** button.
@ -112,7 +112,7 @@ protected environments with this method.
## Deployment branch access
Users with [Developer permissions](../../user/permissions.md) can be granted
Users with the [Developer role](../../user/permissions.md) can be granted
access to a protected environment through any of these methods:
- As an individual contributor, through a role.

View File

@ -222,7 +222,7 @@ to an updated status.
This functionality is only available:
- For users with at least Developer access.
- For users with at least the Developer role.
- If the stage contains [manual actions](#add-manual-interaction-to-your-pipeline).
### Delete a pipeline

View File

@ -224,7 +224,7 @@ To see Visual reviews in action, see the [Visual Reviews Walk through](https://y
### Configure Review Apps for Visual Reviews
The feedback form is served through a script you add to pages in your Review App.
If you have [Developer permissions](../../user/permissions.md) to the project,
If you have the [Developer role](../../user/permissions.md) in the project,
you can access it by clicking the **Review** button in the **Pipeline** section
of the merge request. The form modal also shows a dropdown for changed pages
if [route maps](#route-maps) are configured in the project.

View File

@ -36,7 +36,7 @@ the affected files to find someone.
We also use [GitLab Triage](https://gitlab.com/gitlab-org/gitlab-triage) to automate
some triaging policies. This is currently set up as a scheduled pipeline
(`https://gitlab.com/gitlab-org/quality/triage-ops/pipeline_schedules/10512/editpipeline_schedules/10512/edit`,
must have at least Developer access to the project) running on [quality/triage-ops](https://gitlab.com/gitlab-org/quality/triage-ops)
must have at least the Developer role in the project) running on [quality/triage-ops](https://gitlab.com/gitlab-org/quality/triage-ops)
project.
## Labels

View File

@ -207,6 +207,15 @@ Do not use. Use **use** instead. It's more succinct and easier for non-native En
Do not use Latin abbreviations. Use **with**, **through**, or **by using** instead. ([Vale](../testing.md#vale) rule: [`LatinTerms.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/LatinTerms.yml))
## we
Try to avoid "we" and focus instead on how the user can accomplish something in GitLab.
Instead of: We created a feature for you to add widgets.
Use: Use widgets when you have work you want to organize.
One exception: You can use "we recommend" instead of "it is recommended" or "GitLab recommends."
## whitelist
Do not use. Another option is **allowlist**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))

View File

@ -63,7 +63,7 @@ To update GitLab documentation:
1. Follow the [Merge Request Guidelines](../contributing/merge_request_workflow.md#merge-request-guidelines).
NOTE:
Work in a fork if you do not have Developer access to the GitLab project.
Work in a fork if you do not have the Developer role in the GitLab project.
### Ask for help

View File

@ -21,7 +21,7 @@ message. This avoids an excessive number of pipelines from running.
Before merging translations, make sure to trigger a pipeline to validate
translations. Static analysis validates things CrowdIn doesn't do. Create
a new pipeline at [`https://gitlab.com/gitlab-org/gitlab/pipelines/new`](https://gitlab.com/gitlab-org/gitlab/pipelines/new)
(need developer permissions) for the `master-i18n` branch.
(requires the Developer role) for the `master-i18n` branch.
If there are validation errors, the easiest solution is to disapprove
the offending string in CrowdIn, leaving a comment with what is

View File

@ -23,13 +23,13 @@ a black-box testing framework for the API and the UI.
We run scheduled pipelines each night to test nightly builds created by Omnibus.
You can find these pipelines at <https://gitlab.com/gitlab-org/quality/nightly/pipelines>
(need Developer access permissions). Results are reported in the `#qa-nightly` Slack channel.
(requires the Developer role). Results are reported in the `#qa-nightly` Slack channel.
### Testing staging
We run scheduled pipelines each night to test staging.
You can find these pipelines at <https://gitlab.com/gitlab-org/quality/staging/pipelines>
(need Developer access permissions). Results are reported in the `#qa-staging` Slack channel.
(requires the Developer role). Results are reported in the `#qa-staging` Slack channel.
### Testing code in merge requests

View File

@ -65,7 +65,7 @@ Grant a GitLab user access to the select GitLab projects.
1. Grant the user permission to the GitLab projects.
If you're integrating Jenkins with many GitLab projects, consider granting the user global
Administrator permission. Otherwise, add the user to each project, and grant Developer permission.
Administrator permission. Otherwise, add the user to each project, and grant the Developer role.
## Configure GitLab API access

View File

@ -56,7 +56,7 @@ With Maintainer or higher [permissions](../../user/permissions.md), you can enab
1. To customize the incident, select an
[issue template](../../user/project/description_templates.md#create-an-issue-template).
1. To send [an email notification](paging.md#email-notifications) to users
with [Developer permissions](../../user/permissions.md), select
with the [Developer role](../../user/permissions.md), select
**Send a separate email notification to Developers**. Email notifications are
also sent to users with **Maintainer** and **Owner** permissions.
1. Click **Save changes**.

View File

@ -242,7 +242,7 @@ An example setup is shown below:
Outputs from the data source can now be referenced in your Terraform resources
using `data.terraform_remote_state.example.outputs.<OUTPUT-NAME>`.
You need at least [developer access](../permissions.md) to the target project
You need at least the [Developer role](../permissions.md) in the target project
to read the Terraform state.
## Migrating to GitLab Managed Terraform state

View File

@ -34,7 +34,7 @@ GitLab supports two different modes of file locking:
## Permissions
Locks can be created by any person who has at least
[Developer permissions](../permissions.md) to the repository.
[Developer role](../permissions.md) in the repository.
Only the user who locked the file or directory can edit locked files. Other
users are prevented from modifying locked files by pushing, merging,

View File

@ -333,7 +333,7 @@ of your installation.
## Change the issue type
Users with [developer permission](../../permissions.md)
Users with the [Developer role](../../permissions.md)
can change an issue's type. To do this, edit the issue and select an issue type from the
**Issue type** selector menu:

View File

@ -17,7 +17,7 @@ There are two main ways to have a merge request flow with GitLab:
With the protected branch flow everybody works within the same GitLab project.
The project maintainers get the [Maintainer role](../../permissions.md) and the regular developers
get Developer access.
get the Developer role.
Maintainers mark the authoritative branches as 'Protected'.

View File

@ -21,7 +21,7 @@ request is updated to show the impending merge. If you can't wait
for the pipeline to succeed, you can choose **Merge immediately**
in the dropdown menu on the right of the main button.
The author of the merge request and project members with developer permissions can
The author of the merge request and project members with the Developer role can
cancel the automatic merge at any time before the pipeline finishes.
![Status](img/merge_when_pipeline_succeeds_status.png)

View File

@ -42,7 +42,7 @@ which generates a commit in the merge request authored by the user that suggeste
After the author applies a suggestion, it's marked with the **Applied** label,
the thread is automatically resolved, and GitLab creates a new commit
and pushes the suggested change directly into the codebase in the merge request's
branch. [Developer permission](../../../permissions.md) is required to do so.
branch. The [Developer role](../../../permissions.md) is required to do so.
## Multi-line suggestions

View File

@ -62,7 +62,7 @@ You can create a release in the user interface, or by using the
We recommend using the API to create releases as one of the last steps in your
CI/CD pipeline.
Only users with Developer permissions or higher can create releases.
Only users with the Developer role or higher can create releases.
Read more about [Release permissions](#release-permissions).
To create a new release through the GitLab UI:
@ -102,7 +102,7 @@ release tag. When the `released_at` date and time has passed, the badge is autom
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26016) in GitLab 12.6. Asset link editing was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9427) in GitLab 12.10.
Only users with Developer permissions or higher can edit releases.
Only users with the Developer role or higher can edit releases.
Read more about [Release permissions](#release-permissions).
To edit the details of a release:

View File

@ -44,7 +44,7 @@ users see when viewing the wiki:
## Create a new wiki page
Users with Developer [permissions](../../permissions.md) can create new wiki pages:
Users with the [Developer role](../../permissions.md) can create new wiki pages:
1. Go to your project or group and select **Wiki**.
1. Select **New page** on this page, or any other wiki page.
@ -108,7 +108,7 @@ may not be able to check out the wiki locally afterward.
## Edit a wiki page
You need Developer [permissions](../../permissions.md) or higher to edit a wiki page:
You need the [Developer role](../../permissions.md) or higher to edit a wiki page:
1. Go to your project or group and select **Wiki**.
1. Go to the page you want to edit.
@ -133,7 +133,7 @@ You need the [Maintainer role](../../permissions.md) or higher to delete a wiki
## Move a wiki page
You need Developer [permissions](../../permissions.md) or higher to move a wiki page:
You need the [Developer role](../../permissions.md) or higher to move a wiki page:
1. Go to your project or group and select **Wiki**.
1. Go to the page you want to move.
@ -234,7 +234,7 @@ wikis, with a few limitations:
For updates, follow [the epic that tracks feature parity with project wikis](https://gitlab.com/groups/gitlab-org/-/epics/2782).
Group wikis can be edited by members with [Developer permissions](../../permissions.md#group-members-permissions)
Group wikis can be edited by members with the [Developer role](../../permissions.md#group-members-permissions)
and above. Group wiki repositories can be moved using the
[Group repository storage moves API](../../../api/group_repository_storage_moves.md).

View File

@ -7,6 +7,7 @@ module Gitlab
self.table_name = 'postgres_indexes'
self.primary_key = 'identifier'
self.inheritance_column = :_type_disabled
has_one :bloat_estimate, class_name: 'Gitlab::Database::PostgresIndexBloatEstimate', foreign_key: :identifier
has_many :reindexing_actions, class_name: 'Gitlab::Database::Reindexing::ReindexAction', foreign_key: :index_identifier
@ -22,10 +23,10 @@ module Gitlab
# is defined on a table that is not partitioned.
#
# Deprecated: Switch to scope .reindexing_support
scope :regular, -> { where(unique: false, partitioned: false, exclusion: false, expression: false)}
scope :regular, -> { where(unique: false, partitioned: false, exclusion: false, expression: false, type: Gitlab::Database::Reindexing::SUPPORTED_TYPES)}
# Indexes for reindexing with PG12
scope :reindexing_support, -> { where(partitioned: false, exclusion: false, expression: false) }
scope :reindexing_support, -> { where(partitioned: false, exclusion: false, expression: false, type: Gitlab::Database::Reindexing::SUPPORTED_TYPES) }
scope :not_match, ->(regex) { where("name !~ ?", regex)}
@ -43,6 +44,10 @@ module Gitlab
strong_memoize(:bloat_size) { bloat_estimate&.bloat_size || 0 }
end
def relative_bloat_level
bloat_size / ondisk_size_bytes.to_f
end
def to_s
name
end

View File

@ -6,6 +6,8 @@ module Gitlab
# Number of indexes to reindex per invocation
DEFAULT_INDEXES_PER_INVOCATION = 2
SUPPORTED_TYPES = %w(btree gist).freeze
# candidate_indexes: Array of Gitlab::Database::PostgresIndex
def self.perform(candidate_indexes, how_many: DEFAULT_INDEXES_PER_INVOCATION)
IndexSelection.new(candidate_indexes).take(how_many).each do |index|

View File

@ -6,6 +6,12 @@ module Gitlab
class IndexSelection
include Enumerable
# Only reindex indexes with a relative bloat level (bloat estimate / size) higher than this
MINIMUM_RELATIVE_BLOAT = 0.2
# Only consider indexes with a total ondisk size in this range (before reindexing)
INDEX_SIZE_RANGE = (1.gigabyte..100.gigabyte).freeze
delegate :each, to: :indexes
def initialize(candidates)
@ -24,11 +30,12 @@ module Gitlab
# we force a N+1 pattern here and estimate bloat on a per-index
# basis.
@indexes ||= filter_candidates.sort_by(&:bloat_size).reverse
end
def filter_candidates
candidates.not_recently_reindexed
@indexes ||= candidates
.not_recently_reindexed
.where(ondisk_size_bytes: INDEX_SIZE_RANGE)
.sort_by(&:relative_bloat_level) # forced N+1
.reverse
.select { |candidate| candidate.relative_bloat_level >= MINIMUM_RELATIVE_BLOAT }
end
end
end

View File

@ -10,7 +10,7 @@ module Gitlab
enum state: { started: 0, finished: 1, failed: 2 }
# Amount of time to consider a previous reindexing *recent*
RECENT_THRESHOLD = 7.days
RECENT_THRESHOLD = 10.days
scope :recent, -> { where(state: :finished).where('action_end > ?', Time.zone.now - RECENT_THRESHOLD) }

View File

@ -61,7 +61,8 @@ module Gitlab
index: index.identifier,
table: index.tablename,
estimated_bloat_bytes: bloat_size,
index_size_before_bytes: ondisk_size_before
index_size_before_bytes: ondisk_size_before,
relative_bloat_level: index.relative_bloat_level
)
duration = Benchmark.realtime do
@ -77,6 +78,7 @@ module Gitlab
estimated_bloat_bytes: bloat_size,
index_size_before_bytes: ondisk_size_before,
index_size_after_bytes: index.ondisk_size_bytes,
relative_bloat_level: index.relative_bloat_level,
duration_s: duration.round(2)
)
end

View File

@ -6330,6 +6330,9 @@ msgstr ""
msgid "Check your Docker images for known vulnerabilities."
msgstr ""
msgid "Check your Kubernetes cluster images for known vulnerabilities."
msgstr ""
msgid "Check your source instance permissions."
msgstr ""
@ -12987,6 +12990,9 @@ msgstr ""
msgid "Escalation policies"
msgstr ""
msgid "Escalation policies may not have more than %{rule_count} rules"
msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
@ -38305,6 +38311,9 @@ msgstr ""
msgid "ciReport|Checks"
msgstr ""
msgid "ciReport|Cluster Image Scanning"
msgstr ""
msgid "ciReport|Code quality"
msgstr ""

View File

@ -59,7 +59,7 @@
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "1.202.0",
"@gitlab/tributejs": "1.0.0",
"@gitlab/ui": "30.2.1",
"@gitlab/ui": "31.0.1",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.3-2",
"@rails/ujs": "6.1.3-2",

View File

@ -51,7 +51,7 @@ module QA
# Workaround for a failure to search when there are no spaces around the /
# https://gitlab.com/gitlab-org/gitlab/-/issues/218965
search_and_select(namespace.gsub(/([^\s])\/([^\s])/, '\1 / \2'))
search_and_select(namespace.gsub(%r{([^\s])/([^\s])}, '\1 / \2'))
click_element(:transfer_button)
fill_confirmation_text(project_name)

View File

@ -130,7 +130,7 @@ module QA
end
it 'mounts the docker socket to the host runner' do
expect(subject).to have_received(:shell).with(/-v \/var\/run\/docker.sock:\/var\/run\/docker.sock /)
expect(subject).to have_received(:shell).with(%r{-v /var/run/docker.sock:/var/run/docker.sock })
end
it 'runs in privileged mode' do

View File

@ -25,7 +25,7 @@ module RuboCop
MSG = 'Duplicate spec location in `%<path>s`.'
def on_top_level_describe(node, _args)
path = file_path_for_node(node).sub(/\A#{rails_root}\//, '')
path = file_path_for_node(node).sub(%r{\A#{rails_root}/}, '')
duplicate_path = find_duplicate_path(path)
if duplicate_path && File.exist?(File.join(rails_root, duplicate_path))

View File

@ -6,9 +6,10 @@ RSpec.describe Projects::ServicesController do
include JiraServiceHelper
include AfterNextHelpers
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { create(:jira_integration, project: project) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let_it_be(:service) { create(:jira_integration, project: project) }
let(:service_params) { { username: 'username', password: 'password', url: 'http://example.com' } }
before do
@ -17,9 +18,9 @@ RSpec.describe Projects::ServicesController do
end
describe '#test' do
context 'when can_test? returns false' do
context 'when the integration is not testable' do
it 'renders 404' do
allow_any_instance_of(Integration).to receive(:can_test?).and_return(false)
allow_any_instance_of(Integration).to receive(:testable?).and_return(false)
put :test, params: project_params
@ -41,10 +42,10 @@ RSpec.describe Projects::ServicesController do
context 'success' do
context 'with empty project' do
let(:project) { create(:project) }
let_it_be(:project) { create(:project) }
context 'with chat notification service' do
let(:service) { project.create_microsoft_teams_integration(webhook: 'http://webhook.com') }
let_it_be(:service) { project.create_microsoft_teams_integration(webhook: 'http://webhook.com') }
it 'returns success' do
allow_next(::MicrosoftTeams::Notifier).to receive(:ping).and_return(true)
@ -131,8 +132,7 @@ RSpec.describe Projects::ServicesController do
context 'with the Slack integration' do
let_it_be(:integration) { build(:integrations_slack) }
let(:service) { integration } # TODO: remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 is complete
let_it_be(:service) { integration } # TODO: remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 is complete
it 'returns an error response when the URL is blocked' do
put :test, params: project_params(service: { webhook: 'http://127.0.0.1' })
@ -259,7 +259,8 @@ RSpec.describe Projects::ServicesController do
end
context 'Prometheus integration' do
let!(:service) { create(:prometheus_integration, project: project) }
let_it_be(:service) { create(:prometheus_integration, project: project) }
let(:service_params) { { manual_configuration: '1', api_url: 'http://example.com' } }
context 'feature flag :settings_operations_prometheus_service is enabled' do

View File

@ -176,7 +176,7 @@ RSpec.describe 'Metrics rendering', :js, :kubeclient, :use_clean_rails_memory_st
create(:clusters_integrations_prometheus, cluster: cluster)
stub_kubeclient_discover(cluster.platform.api_url)
stub_prometheus_request(/prometheus-prometheus-server/, body: prometheus_values_body)
stub_prometheus_request(/prometheus\/api\/v1/, body: prometheus_values_body)
stub_prometheus_request(%r{prometheus/api/v1}, body: prometheus_values_body)
end
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, :project, projects: [project], user: user) }

View File

@ -21,7 +21,7 @@ RSpec.describe 'User searches for code' do
expect(page).to have_selector('.results', text: 'application.js')
expect(page).to have_selector('.file-content .code')
expect(page).to have_selector("span.line[lang='javascript']")
expect(page).to have_link('application.js', href: /master\/files\/js\/application.js/)
expect(page).to have_link('application.js', href: %r{master/files/js/application.js})
end
context 'when on a project page', :js do
@ -45,7 +45,7 @@ RSpec.describe 'User searches for code' do
expect(page).to have_selector('.results', text: 'Update capybara, rspec-rails, poltergeist to recent versions')
find("#L3").click
expect(current_url).to match(/master\/.gitignore#L3/)
expect(current_url).to match(%r{master/.gitignore#L3})
end
it 'search mutiple words with refs switching' do
@ -63,7 +63,7 @@ RSpec.describe 'User searches for code' do
expect(page).to have_selector('.results', text: expected_result)
expect(find_field('dashboard_search').value).to eq(search)
expect(find("#L1502")[:href]).to match(/v1.0.0\/files\/markdown\/ruby-style-guide.md#L1502/)
expect(find("#L1502")[:href]).to match(%r{v1.0.0/files/markdown/ruby-style-guide.md#L1502})
end
end

View File

@ -28,8 +28,8 @@ RSpec.describe 'Embedded Snippets' do
blobs.each do |blob|
expect(page).to have_content(blob.path)
expect(page.find(".snippet-file-content .blob-content[data-blob-id='#{blob.id}'] code")).to have_content(blob.data.squish)
expect(page).to have_link('Open raw', href: /-\/snippets\/#{snippet.id}\/raw\/master\/#{blob.path}/)
expect(page).to have_link('Download', href: /-\/snippets\/#{snippet.id}\/raw\/master\/#{blob.path}\?inline=false/)
expect(page).to have_link('Open raw', href: %r{-/snippets/#{snippet.id}/raw/master/#{blob.path}})
expect(page).to have_link('Download', href: %r{-/snippets/#{snippet.id}/raw/master/#{blob.path}\?inline=false})
end
end
end

View File

@ -154,6 +154,16 @@ describe('File finder item spec', () => {
});
});
describe('DOM Performance', () => {
it('renders less DOM nodes if not visible by utilizing v-if', async () => {
vm.visible = false;
await waitForPromises();
expect(vm.$el).toBeInstanceOf(Comment);
});
});
describe('watches', () => {
describe('searchText', () => {
it('resets focusedIndex when updated', (done) => {
@ -169,7 +179,7 @@ describe('File finder item spec', () => {
});
describe('visible', () => {
it('returns searchText when false', (done) => {
it('resets searchText when changed to false', (done) => {
vm.searchText = 'test';
vm.visible = true;

View File

@ -404,7 +404,7 @@ RSpec.describe DiffHelper do
it "returns a valid URL" do
allow(helper).to receive(:safe_params).and_return(params)
expect(subject).to match(/foo\/bar\/-\/commit\/#{commit.sha}\/diff_for_path/)
expect(subject).to match(%r{foo/bar/-/commit/#{commit.sha}/diff_for_path})
end
end

View File

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ReleasesHelper do
describe '#illustration' do
it 'returns the correct image path' do
expect(helper.illustration).to match(/illustrations\/releases-(\w+)\.svg/)
expect(helper.illustration).to match(%r{illustrations/releases-(\w+)\.svg})
end
end

View File

@ -66,7 +66,7 @@ RSpec.describe Gitlab::Ci::Reports::TestCase, :aggregate_failures do
end
it '#attachment_url' do
expect(attachment_test_case.attachment_url).to match(/file\/some\/path.png/)
expect(attachment_test_case.attachment_url).to match(%r{file/some/path.png})
end
end

View File

@ -134,6 +134,6 @@ RSpec.describe Gitlab::Consul::Internal do
end
def stub_consul_discover_prometheus
stub_request(:get, /v1\/catalog\/service\/prometheus/)
stub_request(:get, %r{v1/catalog/service/prometheus})
end
end

View File

@ -38,6 +38,12 @@ RSpec.describe Gitlab::Database::PostgresIndex do
it 'only non-expression indexes' do
expect(described_class.regular).to all(have_attributes(expression: false))
end
it 'only btree and gist indexes' do
types = described_class.regular.map(&:type).uniq
expect(types & %w(btree gist)).to eq(types)
end
end
describe '.reindexing_support' do
@ -52,6 +58,12 @@ RSpec.describe Gitlab::Database::PostgresIndex do
it 'only non-expression indexes' do
expect(described_class.reindexing_support).to all(have_attributes(expression: false))
end
it 'only btree and gist indexes' do
types = described_class.reindexing_support.map(&:type).uniq
expect(types & %w(btree gist)).to eq(types)
end
end
describe '.not_match' do
@ -85,6 +97,16 @@ RSpec.describe Gitlab::Database::PostgresIndex do
end
end
describe '#relative_bloat_level' do
subject { build(:postgres_index, bloat_estimate: bloat_estimate, ondisk_size_bytes: 1024) }
let(:bloat_estimate) { build(:postgres_index_bloat_estimate, bloat_size: 256) }
it 'calculates the relative bloat level' do
expect(subject.relative_bloat_level).to eq(0.25)
end
end
describe '#unique?' do
it 'returns true for a unique index' do
expect(find('public.bar_key')).to be_unique

View File

@ -10,20 +10,50 @@ RSpec.describe Gitlab::Database::Reindexing::IndexSelection do
before do
swapout_view_for_table(:postgres_index_bloat_estimates)
swapout_view_for_table(:postgres_indexes)
create_list(:postgres_index, 10, ondisk_size_bytes: 10.gigabytes).each_with_index do |index, i|
create(:postgres_index_bloat_estimate, index: index, bloat_size_bytes: 2.gigabyte * (i + 1))
end
end
def execute(sql)
ActiveRecord::Base.connection.execute(sql)
end
it 'orders by highest bloat first' do
create_list(:postgres_index, 10).each_with_index do |index, i|
create(:postgres_index_bloat_estimate, index: index, bloat_size_bytes: 1.megabyte * i)
end
it 'orders by highest relative bloat first' do
expected = Gitlab::Database::PostgresIndex.all.sort_by(&:relative_bloat_level).reverse.map(&:name)
expected = Gitlab::Database::PostgresIndexBloatEstimate.order(bloat_size_bytes: :desc).map(&:index)
expect(subject.map(&:name)).to eq(expected)
end
expect(subject).to eq(expected)
it 'excludes indexes with a relative bloat level below 20%' do
excluded = create(
:postgres_index_bloat_estimate,
index: create(:postgres_index, ondisk_size_bytes: 10.gigabytes),
bloat_size_bytes: 1.9.gigabyte # 19% relative index bloat
)
expect(subject).not_to include(excluded.index)
end
it 'excludes indexes smaller than 1 GB ondisk size' do
excluded = create(
:postgres_index_bloat_estimate,
index: create(:postgres_index, ondisk_size_bytes: 0.99.gigabytes),
bloat_size_bytes: 0.8.gigabyte
)
expect(subject).not_to include(excluded.index)
end
it 'excludes indexes larger than 100 GB ondisk size' do
excluded = create(
:postgres_index_bloat_estimate,
index: create(:postgres_index, ondisk_size_bytes: 101.gigabytes),
bloat_size_bytes: 25.gigabyte
)
expect(subject).not_to include(excluded.index)
end
context 'with time frozen' do
@ -31,20 +61,17 @@ RSpec.describe Gitlab::Database::Reindexing::IndexSelection do
freeze_time { example.run }
end
it 'does not return indexes with reindex action in the last 7 days' do
not_recently_reindexed = create_list(:postgres_index, 2).each_with_index do |index, i|
create(:postgres_index_bloat_estimate, index: index, bloat_size_bytes: 1.megabyte * i)
create(:reindex_action, index: index, action_end: Time.zone.now - 7.days - 1.minute)
it 'does not return indexes with reindex action in the last 10 days' do
not_recently_reindexed = Gitlab::Database::PostgresIndex.all.each do |index|
create(:reindex_action, index: index, action_end: Time.zone.now - 10.days - 1.minute)
end
create_list(:postgres_index, 2).each_with_index do |index, i|
create(:postgres_index_bloat_estimate, index: index, bloat_size_bytes: 1.megabyte * i)
create_list(:postgres_index, 10, ondisk_size_bytes: 10.gigabytes).each_with_index do |index, i|
create(:postgres_index_bloat_estimate, index: index, bloat_size_bytes: 2.gigabyte * (i + 1))
create(:reindex_action, index: index, action_end: Time.zone.now)
end
expected = Gitlab::Database::PostgresIndexBloatEstimate.where(identifier: not_recently_reindexed.map(&:identifier)).map(&:index).map(&:identifier).sort
expect(subject.map(&:identifier).sort).to eq(expected)
expect(subject.map(&:name).sort).to eq(not_recently_reindexed.map(&:name).sort)
end
end
end

View File

@ -26,7 +26,7 @@ RSpec.describe Gitlab::ImportExport::Shared do
describe '#export_path' do
it 'uses a random hash relative to project path' do
expect(subject.export_path).to match(/#{base_path}\h{32}\/\h{32}/)
expect(subject.export_path).to match(%r{#{base_path}\h{32}/\h{32}})
end
it 'memoizes the path' do
@ -44,7 +44,7 @@ RSpec.describe Gitlab::ImportExport::Shared do
subject = described_class.new(group)
base_path = %(/tmp/gitlab_exports/@groups/)
expect(subject.base_path).to match(/#{base_path}\h{2}\/\h{2}\/\h{64}/)
expect(subject.base_path).to match(%r{#{base_path}\h{2}/\h{2}/\h{64}})
end
end
end

View File

@ -377,7 +377,7 @@ RSpec.describe Gitlab::Utils::UsageData do
shared_examples 'try to query Prometheus with given address' do
context 'Prometheus is ready' do
before do
stub_request(:get, /\/-\/ready/)
stub_request(:get, %r{/-/ready})
.to_return(status: 200, body: 'Prometheus is Ready.\n')
end
@ -387,7 +387,7 @@ RSpec.describe Gitlab::Utils::UsageData do
context 'Prometheus is not reachable through HTTPS' do
before do
stub_request(:get, /https:\/\/.*/).to_raise(Errno::ECONNREFUSED)
stub_request(:get, %r{https://.*}).to_raise(Errno::ECONNREFUSED)
end
context 'Prometheus is reachable through HTTP' do
@ -396,7 +396,7 @@ RSpec.describe Gitlab::Utils::UsageData do
context 'Prometheus is not reachable through HTTP' do
before do
stub_request(:get, /http:\/\/.*/).to_raise(Errno::ECONNREFUSED)
stub_request(:get, %r{http://.*}).to_raise(Errno::ECONNREFUSED)
end
it_behaves_like 'does not query data from Prometheus'
@ -406,7 +406,7 @@ RSpec.describe Gitlab::Utils::UsageData do
context 'Prometheus is not ready' do
before do
stub_request(:get, /\/-\/ready/)
stub_request(:get, %r{/-/ready})
.to_return(status: 503, body: 'Service Unavailable')
end

View File

@ -139,19 +139,17 @@ RSpec.describe Integration do
end
end
describe '#can_test?' do
subject { integration.can_test? }
describe '#testable?' do
context 'when integration is project-level' do
let(:integration) { build(:service, project: project) }
subject { build(:service, project: project) }
it { is_expected.to be true }
it { is_expected.to be_testable }
end
context 'when integration is not project-level' do
let(:integration) { build(:service, project: nil) }
subject { build(:service, project: nil) }
it { is_expected.to be false }
it { is_expected.not_to be_testable }
end
end

View File

@ -15,24 +15,6 @@ RSpec.describe Integrations::BaseChatNotification do
it { is_expected.to validate_inclusion_of(:labels_to_be_notified_behavior).in_array(%w[match_any match_all]).allow_blank }
end
describe '#can_test?' do
context 'with empty repository' do
it 'returns true' do
subject.project = create(:project, :empty_repo)
expect(subject.can_test?).to be true
end
end
context 'with repository' do
it 'returns true' do
subject.project = create(:project, :repository)
expect(subject.can_test?).to be true
end
end
end
describe '#execute' do
subject(:chat_integration) { described_class.new }

View File

@ -341,7 +341,7 @@ RSpec.describe Integrations::Jira do
context 'when not allowed to test an instance or group' do
it 'does not update deployment type' do
allow(integration).to receive(:can_test?).and_return(false)
allow(integration).to receive(:testable?).and_return(false)
integration.update!(url: 'http://first.url')

View File

@ -177,7 +177,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
end
it 'uses a SHA in the persistent refspec' do
expect(subject[0]).to match(/^\+[0-9a-f]{40}:refs\/pipelines\/[0-9]+$/)
expect(subject[0]).to match(%r{^\+[0-9a-f]{40}:refs/pipelines/[0-9]+$})
end
context 'when ref is tag' do

View File

@ -877,7 +877,7 @@ RSpec.describe API::Projects do
get api(url, current_user), params: params
link = response.header['Link']
url = link&.match(/<[^>]+(\/projects\?[^>]+)>; rel="next"/) do |match|
url = link&.match(%r{<[^>]+(/projects\?[^>]+)>; rel="next"}) do |match|
match[1]
end

View File

@ -37,7 +37,7 @@ RSpec.describe Jira::Requests::Projects::ListService do
context 'when validations and params are ok' do
let(:response_headers) { { 'content-type' => 'application/json' } }
let(:response_body) { [].to_json }
let(:expected_url_pattern) { /.*jira.example.com\/rest\/api\/2\/project/ }
let(:expected_url_pattern) { %r{.*jira.example.com/rest/api/2/project} }
before do
stub_request(:get, expected_url_pattern).to_return(status: 200, body: response_body, headers: response_headers)
@ -60,7 +60,7 @@ RSpec.describe Jira::Requests::Projects::ListService do
context 'when jira runs on a subpath' do
let(:jira_integration) { create(:jira_integration, url: 'http://jira.example.com/jira') }
let(:expected_url_pattern) { /.*jira.example.com\/jira\/rest\/api\/2\/project/ }
let(:expected_url_pattern) { %r{.*jira.example.com/jira/rest/api/2/project} }
it 'takes the subpath into account' do
expect(subject.success?).to be_truthy

View File

@ -197,7 +197,7 @@ RSpec.configure do |config|
raise JSConsoleError, message
end
rescue Selenium::WebDriver::Error::WebDriverError => error
if error.message =~ /unknown command: session\/[0-9a-zA-Z]+(?:\/se)?\/log/
if error.message =~ %r{unknown command: session/[0-9a-zA-Z]+(?:/se)?/log}
message = "Unable to access Chrome javascript console logs. You may be using an outdated version of ChromeDriver."
raise JSConsoleError, message
else

View File

@ -31,7 +31,7 @@ module GrafanaApiHelpers
end
def stub_all_grafana_proxy_requests(base_url)
stub_request(:any, /#{base_url}\/api\/datasources\/proxy/)
stub_request(:any, %r{#{base_url}/api/datasources/proxy})
.to_return(
status: 200,
body: fixture_file('grafana/proxy_response.json'),

View File

@ -15,7 +15,7 @@ class RequireMigration
end
MIGRATION_FOLDERS = %w[db/migrate db/post_migrate].freeze
SPEC_FILE_PATTERN = /.+\/(?<file_name>.+)_spec\.rb/.freeze
SPEC_FILE_PATTERN = %r{.+/(?<file_name>.+)_spec\.rb}.freeze
class << self
def require_migration!(file_name)

View File

@ -100,7 +100,7 @@ RSpec.describe 'layouts/_head' do
it 'add a Matomo Javascript' do
render
expect(rendered).to match(/<script.*>.*var u="\/\/#{matomo_host}\/".*<\/script>/m)
expect(rendered).to match(%r{<script.*>.*var u="//#{matomo_host}/".*</script>}m)
expect(rendered).to match(%r(<noscript>.*<img src="//#{matomo_host}/matomo.php.*</noscript>))
expect(rendered).not_to include('_paq.push(["disableCookies"])')
end

View File

@ -908,15 +908,15 @@
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
"@gitlab/ui@30.2.1":
version "30.2.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-30.2.1.tgz#be582413712cd2372ff01279e47579f5785591d4"
integrity sha512-Pv2w5ZSR7+G5zcaRjvf8KPs7wQRBqAXXNvKOw2pg/aZsRoK+JfN1neNmfeaqO6K/k1TJyiP6inDXAvhU8SqmOg==
"@gitlab/ui@31.0.1":
version "31.0.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-31.0.1.tgz#55c481f2e2fa777ff34237a8229f39553428d107"
integrity sha512-Sw7Hm9VZ4ZE6knZNkd9L7vs1DGmeTFC1d0xzDytOKBw+1kK1+CpCLae2ehT+Kkkwho9GLwUFtHDdATEDLbFaBg==
dependencies:
"@babel/standalone" "^7.0.0"
bootstrap-vue "2.18.1"
copy-to-clipboard "^3.0.8"
dompurify "^2.2.9"
dompurify "^2.3.0"
echarts "^4.9.0"
highlight.js "^10.6.0"
js-beautify "^1.8.8"
@ -4524,7 +4524,7 @@ domhandler@^4.0.0, domhandler@^4.2.0:
dependencies:
domelementtype "^2.2.0"
dompurify@^2.2.9, dompurify@^2.3.0:
dompurify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.0.tgz#07bb39515e491588e5756b1d3e8375b5964814e2"
integrity sha512-VV5C6Kr53YVHGOBKO/F86OYX6/iLTw2yVSI721gKetxpHCK/V5TaLEf9ODjRgl1KLSWRMY6cUhAbv/c+IUnwQw==