Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/static-analysis.gitlab-ci.yml2
-rw-r--r--.rubocop_todo/naming/inclusive_language.yml24
-rw-r--r--app/assets/javascripts/content_editor/components/content_editor.vue6
-rw-r--r--app/assets/javascripts/content_editor/components/formatting_toolbar.vue236
-rw-r--r--app/assets/javascripts/content_editor/services/create_content_editor.js5
-rw-r--r--app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue6
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/timeline_events_form.vue2
-rw-r--r--app/assets/javascripts/notes/components/comment_field_layout.vue20
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue2
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_block.vue14
-rw-r--r--app/assets/javascripts/vue_shared/components/entity_select/group_select.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/entity_select/project_select.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar.vue36
-rw-r--r--app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue5
-rw-r--r--app/assets/stylesheets/components/content_editor.scss5
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss3
-rw-r--r--app/assets/stylesheets/framework/new_card.scss6
-rw-r--r--app/assets/stylesheets/pages/note_form.scss49
-rw-r--r--app/controllers/admin/application_settings/appearances_controller.rb2
-rw-r--r--app/controllers/concerns/observability/content_security_policy.rb21
-rw-r--r--app/controllers/concerns/requires_allowlisted_monitoring_client.rb (renamed from app/controllers/concerns/requires_whitelisted_monitoring_client.rb)16
-rw-r--r--app/controllers/health_check_controller.rb2
-rw-r--r--app/controllers/health_controller.rb2
-rw-r--r--app/controllers/metrics_controller.rb2
-rw-r--r--app/controllers/projects/tracing_controller.rb22
-rw-r--r--app/helpers/blob_helper.rb4
-rw-r--r--app/services/projects/download_service.rb4
-rw-r--r--app/validators/cron_validator.rb8
-rw-r--r--app/views/shared/_md_preview.html.haml4
-rw-r--r--app/views/shared/notes/_hints.html.haml6
-rw-r--r--config/feature_flags/development/observability_tracing.yml8
-rw-r--r--config/feature_flags/development/packages_dependency_proxy_maven.yml8
-rw-r--r--config/routes/project.rb2
-rw-r--r--db/docs/dependency_proxy_packages_settings.yml2
-rw-r--r--doc/development/pipelines/internals.md1
-rw-r--r--doc/subscriptions/gitlab_com/index.md5
-rw-r--r--doc/update/index.md2
-rw-r--r--doc/user/admin_area/settings/sign_in_restrictions.md8
-rw-r--r--doc/user/application_security/dependency_scanning/index.md9
-rw-r--r--doc/user/application_security/iac_scanning/index.md11
-rw-r--r--doc/user/application_security/index.md36
-rw-r--r--doc/user/application_security/sast/index.md25
-rw-r--r--doc/user/application_security/secret_detection/index.md21
-rw-r--r--doc/user/search/command_palette.md28
-rw-r--r--lib/api/helpers/packages/maven.rb22
-rw-r--r--lib/api/maven_packages.rb6
-rw-r--r--lib/gitlab/git/hook_env.rb8
-rw-r--r--lib/gitlab/observability.rb13
-rw-r--r--lib/sidebars/projects/menus/monitor_menu.rb15
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb1
-rw-r--r--locale/gitlab.pot3
-rw-r--r--rubocop/cop/avoid_return_from_blocks.rb8
-rw-r--r--rubocop/cop/graphql/id_type.rb4
-rw-r--r--scripts/rspec_helpers.sh2
-rw-r--r--scripts/utils.sh4
-rw-r--r--spec/controllers/concerns/issuable_collections_spec.rb4
-rw-r--r--spec/frontend/content_editor/services/create_content_editor_spec.js8
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_block_spec.js47
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap2
-rw-r--r--spec/frontend/vue_shared/components/entity_select/group_select_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/entity_select/project_select_spec.js12
-rw-r--r--spec/lib/gitlab/observability_spec.rb27
-rw-r--r--spec/lib/sidebars/projects/menus/monitor_menu_spec.rb18
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb1
-rw-r--r--spec/requests/groups/observability_controller_spec.rb4
-rw-r--r--spec/requests/projects/issues_controller_spec.rb7
-rw-r--r--spec/requests/projects/merge_requests/creations_spec.rb20
-rw-r--r--spec/requests/projects/merge_requests_controller_spec.rb1
-rw-r--r--spec/requests/projects/tracing_controller_spec.rb56
-rw-r--r--spec/rubocop/cop/avoid_return_from_blocks_spec.rb10
-rw-r--r--spec/rubocop/cop/graphql/id_type_spec.rb4
-rw-r--r--spec/services/design_management/generate_image_versions_service_spec.rb2
-rw-r--r--spec/services/projects/download_service_spec.rb4
-rw-r--r--spec/support/import_export/export_file_helper.rb2
-rw-r--r--spec/support/shared_contexts/navbar_structure_context.rb1
-rw-r--r--spec/support/shared_examples/lib/banzai/filters/sanitization_filter_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/observability/csp_shared_examples.rb172
-rw-r--r--spec/uploaders/avatar_uploader_spec.rb6
-rw-r--r--spec/uploaders/design_management/design_v432x230_uploader_spec.rb6
-rw-r--r--spec/uploaders/favicon_uploader_spec.rb6
-rw-r--r--spec/validators/cron_validator_spec.rb4
85 files changed, 743 insertions, 476 deletions
diff --git a/.gitlab/ci/static-analysis.gitlab-ci.yml b/.gitlab/ci/static-analysis.gitlab-ci.yml
index b9d73d7770d..29887881da5 100644
--- a/.gitlab/ci/static-analysis.gitlab-ci.yml
+++ b/.gitlab/ci/static-analysis.gitlab-ci.yml
@@ -134,7 +134,7 @@ rubocop:
unset CI_SLACK_WEBHOOK_URL
run_timed_command "fail_on_warnings bundle exec rake rubocop:check:graceful"
else
- cat "${RSPEC_CHANGED_FILES_PATH}" | ruby -e 'print $stdin.read.split(" ").select { |f| File.exist?(f) }.join(" ")' > "$RUBOCOP_TARGET_FILES"
+ select_existing_files < "${RSPEC_CHANGED_FILES_PATH}" > "${RUBOCOP_TARGET_FILES}"
# Skip running RuboCop if there's no target files
if [ -s "${RUBOCOP_TARGET_FILES}" ]; then
run_timed_command "fail_on_warnings bundle exec rubocop --parallel --force-exclusion $(cat ${RUBOCOP_TARGET_FILES})"
diff --git a/.rubocop_todo/naming/inclusive_language.yml b/.rubocop_todo/naming/inclusive_language.yml
index 9d1e98f87d3..271286d4752 100644
--- a/.rubocop_todo/naming/inclusive_language.yml
+++ b/.rubocop_todo/naming/inclusive_language.yml
@@ -1,26 +1,19 @@
---
Naming/InclusiveLanguage:
Exclude:
- - 'app/controllers/admin/application_settings/appearances_controller.rb'
- - 'app/controllers/concerns/requires_whitelisted_monitoring_client.rb'
- - 'app/controllers/health_check_controller.rb'
- - 'app/controllers/health_controller.rb'
- - 'app/controllers/metrics_controller.rb'
+ - 'app/controllers/concerns/requires_allowlisted_monitoring_client.rb'
- 'app/helpers/application_settings_helper.rb'
- - 'app/helpers/blob_helper.rb'
- 'app/helpers/markup_helper.rb'
- 'app/models/application_setting.rb'
- 'app/models/application_setting_implementation.rb'
- 'app/models/concerns/cache_markdown_field.rb'
- 'app/services/application_settings/update_service.rb'
- - 'app/services/projects/download_service.rb'
- 'app/uploaders/avatar_uploader.rb'
- 'app/uploaders/content_type_whitelist.rb'
- 'app/uploaders/design_management/design_v432x230_uploader.rb'
- 'app/uploaders/favicon_uploader.rb'
- 'app/uploaders/gitlab_uploader.rb'
- 'app/uploaders/import_export_uploader.rb'
- - 'app/validators/cron_validator.rb'
- 'app/validators/qualified_domain_array_validator.rb'
- 'config/initializers/1_settings.rb'
- 'config/initializers/doorkeeper.rb'
@@ -28,14 +21,12 @@ Naming/InclusiveLanguage:
- 'ee/app/controllers/projects/push_rules_controller.rb'
- 'ee/lib/arkose/verify_response.rb'
- 'ee/lib/system_check/geo/http_connection_check.rb'
- - 'ee/spec/models/dora/lead_time_for_changes_metric_spec.rb'
- 'lib/api/entities/application_setting.rb'
- 'lib/api/settings.rb'
- 'lib/banzai/filter/asset_proxy_filter.rb'
- 'lib/gitlab/asset_proxy.rb'
- 'lib/gitlab/auth/ip_rate_limiter.rb'
- 'lib/gitlab/ci/config/external/file/base.rb'
- - 'lib/gitlab/git/hook_env.rb'
- 'lib/gitlab/github_import/markdown/attachment.rb'
- 'lib/gitlab/markdown_cache/active_record/extension.rb'
- 'lib/gitlab/markdown_cache/field_data.rb'
@@ -44,9 +35,6 @@ Naming/InclusiveLanguage:
- 'lib/gitlab/sanitizers/svg.rb'
- 'lib/gitlab/sanitizers/svg/whitelist.rb'
- 'lib/system_check/app/git_user_default_ssh_config_check.rb'
- - 'rubocop/cop/avoid_return_from_blocks.rb'
- - 'rubocop/cop/graphql/id_type.rb'
- - 'spec/controllers/concerns/issuable_collections_spec.rb'
- 'spec/controllers/health_check_controller_spec.rb'
- 'spec/controllers/metrics_controller_spec.rb'
- 'spec/helpers/markup_helper_spec.rb'
@@ -61,17 +49,7 @@ Naming/InclusiveLanguage:
- 'spec/models/application_setting_spec.rb'
- 'spec/requests/api/settings_spec.rb'
- 'spec/requests/health_controller_spec.rb'
- - 'spec/rubocop/cop/avoid_return_from_blocks_spec.rb'
- - 'spec/rubocop/cop/graphql/id_type_spec.rb'
- 'spec/services/application_settings/update_service_spec.rb'
- - 'spec/services/design_management/generate_image_versions_service_spec.rb'
- - 'spec/services/projects/download_service_spec.rb'
- - 'spec/support/import_export/export_file_helper.rb'
- 'spec/support/shared_contexts/upload_type_check_shared_context.rb'
- - 'spec/support/shared_examples/lib/banzai/filters/sanitization_filter_shared_examples.rb'
- 'spec/support/shared_examples/models/application_setting_shared_examples.rb'
- - 'spec/uploaders/avatar_uploader_spec.rb'
- 'spec/uploaders/content_type_whitelist_spec.rb'
- - 'spec/uploaders/design_management/design_v432x230_uploader_spec.rb'
- - 'spec/uploaders/favicon_uploader_spec.rb'
- - 'spec/validators/cron_validator_spec.rb'
diff --git a/app/assets/javascripts/content_editor/components/content_editor.vue b/app/assets/javascripts/content_editor/components/content_editor.vue
index 344df7a35c3..c6b605cd92f 100644
--- a/app/assets/javascripts/content_editor/components/content_editor.vue
+++ b/app/assets/javascripts/content_editor/components/content_editor.vue
@@ -227,7 +227,7 @@ export default {
</script>
<template>
<content-editor-provider :content-editor="contentEditor">
- <div>
+ <div class="md-area gl-overflow-hidden">
<editor-state-observer
@docUpdate="notifyChange"
@focus="focus"
@@ -238,7 +238,6 @@ export default {
<div
data-testid="content-editor"
data-qa-selector="content_editor_container"
- class="md-area gl-border-none! gl-shadow-none!"
:class="{ 'is-focused': focused }"
>
<formatting-toolbar
@@ -263,7 +262,7 @@ export default {
<reference-bubble-menu />
</div>
<div
- class="gl-display-flex gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-rounded-bottom-left-base gl-rounded-bottom-right-base gl-px-2 gl-mx-2 gl-mb-2 gl-bg-gray-10 gl-text-secondary"
+ class="gl-display-flex gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-rounded-bottom-left-base gl-rounded-bottom-right-base gl-px-2 gl-border-t gl-border-gray-100 gl-text-secondary"
>
<editor-mode-switcher size="small" value="richText" @input="handleEditorModeChanged" />
<gl-button
@@ -274,6 +273,7 @@ export default {
category="tertiary"
size="small"
title="Markdown is supported"
+ class="gl-px-3!"
/>
</div>
</div>
diff --git a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
index 6877f26b7d2..dc27278d255 100644
--- a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
+++ b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
@@ -72,125 +72,123 @@ export default {
};
</script>
<template>
- <div class="gl-mx-2 gl-mt-2">
- <div
- class="gl-w-full gl-display-flex gl-align-items-center gl-flex-wrap gl-bg-gray-50 gl-px-2 gl-rounded-base gl-justify-content-space-between"
- data-testid="formatting-toolbar"
- >
- <div class="gl-py-2 gl-display-flex gl-flex-wrap">
- <toolbar-text-style-dropdown
- data-testid="text-styles"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- v-if="codeSuggestionsEnabled"
- data-testid="code-suggestion"
- content-type="codeSuggestion"
- icon-name="doc-code"
- editor-command="insertCodeSuggestion"
- :label="__('Insert suggestion')"
- :show-active-state="false"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="bold"
- content-type="bold"
- icon-name="bold"
- editor-command="toggleBold"
- :label="i18n.bold"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="italic"
- content-type="italic"
- icon-name="italic"
- editor-command="toggleItalic"
- :label="i18n.italic"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="strike"
- content-type="strike"
- icon-name="strikethrough"
- editor-command="toggleStrike"
- :label="i18n.strike"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="blockquote"
- content-type="blockquote"
- icon-name="quote"
- editor-command="toggleBlockquote"
- :label="i18n.quote"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="code"
- content-type="code"
- icon-name="code"
- editor-command="toggleCode"
- :label="i18n.code"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="link"
- content-type="link"
- icon-name="link"
- editor-command="editLink"
- :label="i18n.link"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="bullet-list"
- content-type="bulletList"
- icon-name="list-bulleted"
- class="gl-display-none gl-sm-display-inline"
- editor-command="toggleBulletList"
- :label="i18n.bulletList"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="ordered-list"
- content-type="orderedList"
- icon-name="list-numbered"
- class="gl-display-none gl-sm-display-inline"
- editor-command="toggleOrderedList"
- :label="i18n.numberedList"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-button
- data-testid="task-list"
- content-type="taskList"
- icon-name="list-task"
- class="gl-display-none gl-sm-display-inline"
- editor-command="toggleTaskList"
- :label="i18n.taskList"
- @execute="trackToolbarControlExecution"
- />
- <toolbar-table-button data-testid="table" @execute="trackToolbarControlExecution" />
- <toolbar-attachment-button
- v-if="!hideAttachmentButton"
- data-testid="attachment"
- @execute="trackToolbarControlExecution"
- />
- <!-- TODO Add icon and trigger functionality from here -->
- <toolbar-button
- v-if="supportsQuickActions"
- data-testid="quick-actions"
- content-type="quickAction"
- icon-name="quick-actions"
- class="gl-display-none gl-sm-display-inline"
- editor-command="insertQuickAction"
- :label="__('Add a quick action')"
- @execute="trackToolbarControlExecution"
- />
- <comment-templates-dropdown
- v-if="newCommentTemplatePath"
- :new-comment-template-path="newCommentTemplatePath"
- @select="insertSavedReply"
- />
- <toolbar-more-dropdown data-testid="more" @execute="trackToolbarControlExecution" />
- </div>
+ <div
+ class="gl-w-full gl-display-flex gl-align-items-center gl-flex-wrap gl-border-b gl-border-gray-100 gl-px-3 gl-rounded-top-base gl-justify-content-space-between"
+ data-testid="formatting-toolbar"
+ >
+ <div class="gl-py-3 gl-display-flex gl-flex-wrap">
+ <toolbar-text-style-dropdown
+ data-testid="text-styles"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ v-if="codeSuggestionsEnabled"
+ data-testid="code-suggestion"
+ content-type="codeSuggestion"
+ icon-name="doc-code"
+ editor-command="insertCodeSuggestion"
+ :label="__('Insert suggestion')"
+ :show-active-state="false"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="bold"
+ content-type="bold"
+ icon-name="bold"
+ editor-command="toggleBold"
+ :label="i18n.bold"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="italic"
+ content-type="italic"
+ icon-name="italic"
+ editor-command="toggleItalic"
+ :label="i18n.italic"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="strike"
+ content-type="strike"
+ icon-name="strikethrough"
+ editor-command="toggleStrike"
+ :label="i18n.strike"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="blockquote"
+ content-type="blockquote"
+ icon-name="quote"
+ editor-command="toggleBlockquote"
+ :label="i18n.quote"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="code"
+ content-type="code"
+ icon-name="code"
+ editor-command="toggleCode"
+ :label="i18n.code"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="link"
+ content-type="link"
+ icon-name="link"
+ editor-command="editLink"
+ :label="i18n.link"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="bullet-list"
+ content-type="bulletList"
+ icon-name="list-bulleted"
+ class="gl-display-none gl-sm-display-inline"
+ editor-command="toggleBulletList"
+ :label="i18n.bulletList"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="ordered-list"
+ content-type="orderedList"
+ icon-name="list-numbered"
+ class="gl-display-none gl-sm-display-inline"
+ editor-command="toggleOrderedList"
+ :label="i18n.numberedList"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="task-list"
+ content-type="taskList"
+ icon-name="list-task"
+ class="gl-display-none gl-sm-display-inline"
+ editor-command="toggleTaskList"
+ :label="i18n.taskList"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-table-button data-testid="table" @execute="trackToolbarControlExecution" />
+ <toolbar-attachment-button
+ v-if="!hideAttachmentButton"
+ data-testid="attachment"
+ @execute="trackToolbarControlExecution"
+ />
+ <!-- TODO Add icon and trigger functionality from here -->
+ <toolbar-button
+ v-if="supportsQuickActions"
+ data-testid="quick-actions"
+ content-type="quickAction"
+ icon-name="quick-actions"
+ class="gl-display-none gl-sm-display-inline"
+ editor-command="insertQuickAction"
+ :label="__('Add a quick action')"
+ @execute="trackToolbarControlExecution"
+ />
+ <comment-templates-dropdown
+ v-if="newCommentTemplatePath"
+ :new-comment-template-path="newCommentTemplatePath"
+ @select="insertSavedReply"
+ />
+ <toolbar-more-dropdown data-testid="more" @execute="trackToolbarControlExecution" />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/content_editor/services/create_content_editor.js b/app/assets/javascripts/content_editor/services/create_content_editor.js
index f7d189e443f..51e41ceefaf 100644
--- a/app/assets/javascripts/content_editor/services/create_content_editor.js
+++ b/app/assets/javascripts/content_editor/services/create_content_editor.js
@@ -74,11 +74,6 @@ import trackInputRulesAndShortcuts from './track_input_rules_and_shortcuts';
const createTiptapEditor = ({ extensions = [], ...options } = {}) =>
new Editor({
extensions: [...extensions],
- editorProps: {
- attributes: {
- class: 'gl-shadow-none!',
- },
- },
...options,
});
diff --git a/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue b/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue
index cc3e2b145ed..cbec10b4ebe 100644
--- a/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue
+++ b/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue
@@ -76,10 +76,10 @@ export default {
<h3 id="related-merge-requests" class="gl-new-card-title">
{{ __('Related merge requests') }}
</h3>
- <div class="gl-display-inline-flex gl-align-items-center gl-m-0">
+ <div class="gl-new-card-count">
<template v-if="totalCount">
- <gl-icon name="merge-request" class="gl-ml-3 gl-mr-2 gl-text-gray-500" />
- <span data-testid="count" class="gl-text-gray-500">{{ totalCount }}</span>
+ <gl-icon name="merge-request" class="gl-mr-2" />
+ <span data-testid="count">{{ totalCount }}</span>
</template>
</div>
</div>
diff --git a/app/assets/javascripts/issues/show/components/incidents/timeline_events_form.vue b/app/assets/javascripts/issues/show/components/incidents/timeline_events_form.vue
index 8267c0130a3..2a59b7a2042 100644
--- a/app/assets/javascripts/issues/show/components/incidents/timeline_events_form.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/timeline_events_form.vue
@@ -229,7 +229,7 @@ export default {
<template #textarea>
<textarea
v-model="timelineText"
- class="note-textarea js-gfm-input js-autosize markdown-area"
+ class="note-textarea note-textarea-rounded-bottom js-gfm-input js-autosize markdown-area gl-bordered"
data-testid="input-note"
dir="auto"
data-supports-quick-actions="false"
diff --git a/app/assets/javascripts/notes/components/comment_field_layout.vue b/app/assets/javascripts/notes/components/comment_field_layout.vue
index bde7d219e9f..cefcc1b0c98 100644
--- a/app/assets/javascripts/notes/components/comment_field_layout.vue
+++ b/app/assets/javascripts/notes/components/comment_field_layout.vue
@@ -66,9 +66,7 @@ export default {
};
</script>
<template>
- <div
- class="comment-warning-wrapper gl-border-solid gl-border-1 gl-rounded-lg gl-border-gray-100 gl-bg-white gl-overflow-hidden"
- >
+ <div class="comment-warning-wrapper">
<div
v-if="withAlertContainer"
class="error-alert"
@@ -76,7 +74,7 @@ export default {
></div>
<noteable-warning
v-if="hasWarning"
- class="gl-py-4 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100 gl-rounded-base gl-rounded-bottom-left-none gl-rounded-bottom-right-none"
+ class="gl-pt-4 gl-pb-5 gl-mb-n3 gl-rounded-lg gl-rounded-bottom-left-none gl-rounded-bottom-right-none"
:is-locked="isLocked"
:is-confidential="isConfidential"
:noteable-type="noteableType"
@@ -84,10 +82,20 @@ export default {
:confidential-noteable-docs-path="noteableData.confidential_issues_docs_path"
/>
<slot></slot>
- <attachments-warning v-if="showAttachmentWarning" />
+ <attachments-warning
+ v-if="showAttachmentWarning"
+ :class="{
+ 'gl-py-3': !showEmailParticipantsWarning,
+ 'gl-pt-4 gl-pb-3 gl-mt-n3': showEmailParticipantsWarning,
+ }"
+ />
<email-participants-warning
v-if="showEmailParticipantsWarning"
- class="gl-border-t-1 gl-border-t-solid gl-border-t-gray-100 gl-rounded-base gl-rounded-top-left-none! gl-rounded-top-right-none!"
+ class="gl-border-t-1 gl-rounded-lg gl-rounded-top-left-none! gl-rounded-top-right-none!"
+ :class="{
+ 'gl-pt-4 gl-pb-3 gl-mt-n3': !showAttachmentWarning,
+ 'gl-py-3 gl-mt-1': showAttachmentWarning,
+ }"
:emails="emailParticipants"
/>
</div>
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index 0b3ba13847b..1c98904aacc 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -336,7 +336,7 @@ export default {
<li
v-else-if="canShowReplyActions && showReplies"
data-testid="reply-wrapper"
- class="discussion-reply-holder gl-border-t-0! clearfix"
+ class="discussion-reply-holder gl-border-t-0! gl-pb-5! clearfix"
:class="discussionHolderClass"
>
<discussion-actions
diff --git a/app/assets/javascripts/related_issues/components/related_issues_block.vue b/app/assets/javascripts/related_issues/components/related_issues_block.vue
index 6ccf53624cf..1044d25c1a3 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_block.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_block.vue
@@ -200,13 +200,9 @@ export default {
/>
<slot name="header-text">{{ headerText }}</slot>
</h3>
- <div
- class="gl-new-card-count js-related-issues-header-issue-count gl-display-inline-flex gl-mx-3 gl-text-gray-500"
- >
- <span class="gl-display-inline-flex gl-align-items-center">
- <gl-icon :name="issuableTypeIcon" class="gl-mr-2 gl-text-gray-500" />
- {{ badgeLabel }}
- </span>
+ <div class="gl-new-card-count js-related-issues-header-issue-count">
+ <gl-icon :name="issuableTypeIcon" class="gl-mr-2" />
+ {{ badgeLabel }}
</div>
</div>
<slot name="header-actions"></slot>
@@ -220,7 +216,7 @@ export default {
>
<slot name="add-button-text">{{ __('Add') }}</slot>
</gl-button>
- <div class="gl-pl-3 gl-ml-3 gl-border-l-1 gl-border-l-solid gl-border-l-gray-100">
+ <div class="gl-new-card-toggle">
<gl-button
category="tertiary"
size="small"
@@ -282,7 +278,7 @@ export default {
@saveReorder="$emit('saveReorder', $event)"
/>
</template>
- <div v-if="!shouldShowTokenBody && !isFormVisible" data-testid="related-items-empty">
+ <div v-if="!shouldShowTokenBody && !isFormVisible">
<p class="gl-new-card-empty">
{{ emptyStateMessage }}
<gl-link
diff --git a/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue b/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
index ff137d764ee..71e3bf4ff63 100644
--- a/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
+++ b/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
@@ -121,6 +121,7 @@ export default {
:default-toggle-text="$options.i18n.toggleText"
:fetch-items="fetchGroups"
:fetch-initial-selection-text="fetchGroupName"
+ v-on="$listeners"
>
<template #error>
<gl-alert v-if="errorMessage" class="gl-mb-3" variant="danger" @dismiss="dismissError">{{
diff --git a/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue b/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
index 7af3819f2a5..13a825a68f6 100644
--- a/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
+++ b/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
@@ -166,6 +166,7 @@ export default {
:fetch-initial-selection-text="fetchProjectName"
:block="block"
clearable
+ v-on="$listeners"
>
<template v-if="hasHtmlLabel" #label>
<span v-safe-html="label"></span>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue b/app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue
index 5cf5fbd5323..81456aed8d7 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/editor_mode_switcher.vue
@@ -27,7 +27,7 @@ export default {
<template>
<div class="content-editor-switcher gl-display-inline-flex gl-align-items-center">
<gl-button
- class="btn btn-default btn-sm gl-button btn-default-tertiary"
+ class="btn btn-default btn-sm gl-button btn-default-tertiary gl-font-sm! gl-text-secondary! gl-px-4!"
data-qa-selector="editing_mode_switcher"
@click="$emit('input')"
>{{ text }}</gl-button
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index 268352a9c9c..7c569763a75 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -355,10 +355,7 @@ export default {
<template>
<div
ref="gl-form"
- :class="{
- 'gl-border-none! gl-shadow-none!': removeBorder,
- }"
- class="js-vue-markdown-field md-area position-relative gfm-form"
+ class="js-vue-markdown-field md-area position-relative gfm-form gl-overflow-hidden"
:data-uploads-path="uploadsPath"
>
<markdown-header
diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index 0899b752cbc..00390194414 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -257,11 +257,11 @@ export default {
</script>
<template>
- <div class="md-header gl-bg-gray-50 gl-px-2 gl-rounded-base gl-mx-2 gl-mt-2">
+ <div class="md-header gl-border-b gl-border-gray-100 gl-px-3">
<div class="gl-display-flex gl-align-items-center gl-flex-wrap">
<div
data-testid="md-header-toolbar"
- class="md-header-toolbar gl-display-flex gl-py-2 gl-flex-wrap gl-row-gap-3"
+ class="md-header-toolbar gl-display-flex gl-py-3 gl-flex-wrap gl-row-gap-3"
>
<gl-button
v-if="enablePreview"
diff --git a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
index 9638baa1dea..186b70a9ecd 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
@@ -226,7 +226,7 @@ export default {
};
</script>
<template>
- <div class="md-area gl-px-0! gl-overflow-hidden">
+ <div class="gl-px-0!">
<local-storage-sync
:value="editingMode"
as-string
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index 50f63c68690..7cce42629d6 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -50,11 +50,11 @@ export default {
<template>
<div
v-if="showCommentToolBar"
- class="comment-toolbar gl-display-flex gl-flex-direction-row gl-mx-2 gl-mb-2 gl-px-2 gl-rounded-bottom-left-base gl-rounded-bottom-right-base"
+ class="comment-toolbar gl-display-flex gl-flex-direction-row gl-px-2 gl-rounded-bottom-left-base gl-rounded-bottom-right-base"
:class="
showContentEditorSwitcher
- ? 'gl-bg-gray-10 gl-justify-content-space-between'
- : 'gl-justify-content-end'
+ ? 'gl-justify-content-space-between gl-align-items-center gl-border-t gl-border-gray-100'
+ : 'gl-justify-content-end gl-my-2'
"
>
<editor-mode-switcher
@@ -63,21 +63,8 @@ export default {
value="markdown"
@input="handleEditorModeChanged"
/>
- <div>
- <div class="toolbar-text gl-font-sm">
- <template v-if="markdownDocsPath">
- <gl-button
- v-gl-tooltip
- icon="markdown-mark"
- :href="markdownDocsPath"
- target="_blank"
- category="tertiary"
- size="small"
- title="Markdown is supported"
- />
- </template>
- </div>
- <span v-if="canAttachFile" class="uploading-container gl-font-sm gl-line-height-32">
+ <div class="gl-display-flex">
+ <div v-if="canAttachFile" class="uploading-container gl-font-sm gl-line-height-32 gl-mr-3">
<span class="uploading-progress-container hide">
<gl-icon name="paperclip" />
<span class="attaching-file-message"></span>
@@ -125,7 +112,18 @@ export default {
>
{{ __('Cancel') }}
</gl-button>
- </span>
+ </div>
+ <gl-button
+ v-if="markdownDocsPath"
+ v-gl-tooltip
+ icon="markdown-mark"
+ :href="markdownDocsPath"
+ target="_blank"
+ category="tertiary"
+ size="small"
+ title="Markdown is supported"
+ class="gl-px-3!"
+ />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue
index 9b3b4df5db6..bfc6ceefccc 100644
--- a/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue
+++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_links.vue
@@ -205,10 +205,7 @@ export default {
>
<template #header>{{ $options.i18n.title }}</template>
<template #header-suffix>
- <span
- class="gl-display-inline-flex gl-align-items-center gl-line-height-24 gl-ml-3 gl-font-weight-bold gl-text-gray-500"
- data-testid="children-count"
- >
+ <span class="gl-new-card-count" data-testid="children-count">
<gl-icon :name="$options.WIDGET_TYPE_TASK_ICON" class="gl-mr-2" />
{{ childrenCountLabel }}
</span>
diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss
index c2e25e1e696..c1a7c4d4d86 100644
--- a/app/assets/stylesheets/components/content_editor.scss
+++ b/app/assets/stylesheets/components/content_editor.scss
@@ -6,11 +6,16 @@
max-height: 55vh;
position: static;
overflow-y: auto;
+ transition: box-shadow ease-in-out 0.15s;
::selection {
background-color: transparent;
}
+ &:focus {
+ @include gl-focus($inset: true);
+ }
+
&:not(.ProseMirror-hideselection) .content-editor-selection,
a.ProseMirror-selectednode,
span.ProseMirror-selectednode {
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index 5fdab7891ec..f8f54567ef2 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -91,7 +91,7 @@
}
.md-preview-holder {
- min-height: 176px;
+ min-height: 173px;
padding: 10px 0;
overflow-x: auto;
}
@@ -106,6 +106,7 @@
box-shadow: none;
width: 100%;
resize: none !important;
+ transition: box-shadow $gl-transition-duration-medium ease;
}
.md-suggestion-diff {
diff --git a/app/assets/stylesheets/framework/new_card.scss b/app/assets/stylesheets/framework/new_card.scss
index 3981b713564..883690681ce 100644
--- a/app/assets/stylesheets/framework/new_card.scss
+++ b/app/assets/stylesheets/framework/new_card.scss
@@ -7,8 +7,7 @@
@include gl-rounded-base;
&-header {
- @include gl-pl-5;
- @include gl-pr-4;
+ @include gl-px-5;
@include gl-py-4;
@include gl-display-flex;
@include gl-justify-content-space-between;
@@ -42,6 +41,8 @@
@include gl-font-base;
@include gl-font-weight-bold;
@include gl-text-gray-500;
+ @include gl-display-inline-flex;
+ @include gl-align-items-center;
}
&-description {
@@ -53,6 +54,7 @@
&-toggle {
@include gl-pl-3;
@include gl-ml-3;
+ @include gl-mr-n2;
@include gl-border-l-1;
@include gl-border-l-solid;
@include gl-border-l-gray-100;
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index d442958ad61..8fe04ddc352 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -48,7 +48,7 @@
.common-note-form {
.md-area {
- border: 1px solid $border-color;
+ border: 1px solid $gray-400;
border-radius: $border-radius-large;
transition: border-color ease-in-out 0.15s,
box-shadow ease-in-out 0.15s;
@@ -65,19 +65,34 @@
}
}
- // Disable inner focus
+ &:hover,
+ &:focus-within {
+ @include gl-shadow-md;
+ }
+
+ &:hover {
+ border: 1px solid $gray-500;
+ }
+
+ &:focus-within {
+ border: 1px solid $gray-900;
+ }
+
+ // Add focus
textarea:focus {
- @include gl-shadow-none;
+ @include gl-focus($inset: true);
}
- }
- .comment-warning-wrapper:focus-within {
- @include gl-focus;
- }
-}
+ .note-textarea-rounded-bottom {
+ border-bottom-left-radius: calc(#{$border-radius-large} - 1px);
+ border-bottom-right-radius: calc(#{$border-radius-large} - 1px);
+ }
-.md-area:focus-within {
- @include gl-focus;
+ // Disable inner focus on fullscreen
+ .zen-backdrop.fullscreen textarea:focus {
+ box-shadow: none;
+ }
+ }
}
.md-header {
@@ -217,6 +232,7 @@ table {
.md-area {
background-color: $white;
+ @include gl-rounded-base;
}
}
@@ -309,13 +325,19 @@ table {
resize: none;
padding: $gl-padding-8 $gl-padding-12;
line-height: 1;
- border: 1px solid $border-color;
+ border: 1px solid $gray-200;
background-color: $white;
overflow: hidden;
+ transition: border-color ease-in-out 0.15s,
+ box-shadow ease-in-out 0.15s;
@include media-breakpoint-down(xs) {
margin-bottom: $gl-padding-8;
}
+
+ &:hover {
+ border: 1px solid $gray-500;
+ }
}
}
@@ -436,9 +458,4 @@ table {
.comment-warning-wrapper {
transition: border-color ease-in-out 0.15s,
box-shadow ease-in-out 0.15s;
-
- .md-area {
- border: 0;
- box-shadow: none;
- }
}
diff --git a/app/controllers/admin/application_settings/appearances_controller.rb b/app/controllers/admin/application_settings/appearances_controller.rb
index 719e8e4a913..1a1e85d48da 100644
--- a/app/controllers/admin/application_settings/appearances_controller.rb
+++ b/app/controllers/admin/application_settings/appearances_controller.rb
@@ -69,7 +69,7 @@ class Admin::ApplicationSettings::AppearancesController < Admin::ApplicationCont
@appearance = Appearance.current || Appearance.new
end
- # Only allow a trusted parameter "white list" through.
+ # Only allow a trusted parameter "allow list" through.
def appearance_params
params.require(:appearance).permit(allowed_appearance_params)
end
diff --git a/app/controllers/concerns/observability/content_security_policy.rb b/app/controllers/concerns/observability/content_security_policy.rb
index 1e25dc492a0..e51d986d36c 100644
--- a/app/controllers/concerns/observability/content_security_policy.rb
+++ b/app/controllers/concerns/observability/content_security_policy.rb
@@ -5,26 +5,23 @@ module Observability
extend ActiveSupport::Concern
included do
- content_security_policy_with_context do |p|
- current_group = if defined?(group)
- group
- else
- defined?(project) ? project&.group : nil
- end
-
- next if p.directives.blank? || !Feature.enabled?(:observability_group_tab, current_group)
+ content_security_policy do |p|
+ next if p.directives.blank?
default_frame_src = p.directives['frame-src'] || p.directives['default-src']
-
- # When ObservabilityUI is not authenticated, it needs to be able
- # to redirect to the GL sign-in page, hence '/users/sign_in' and '/oauth/authorize'
+ # When Gitlab Observability Backend is not authenticated, it needs to be able
+ # to redirect to the GitLab sign-in page, hence '/users/sign_in' and '/oauth/authorize'
frame_src_values = Array.wrap(default_frame_src) | [
Gitlab::Observability.observability_url,
Gitlab::Utils.append_path(Gitlab.config.gitlab.url, '/users/sign_in'),
Gitlab::Utils.append_path(Gitlab.config.gitlab.url, '/oauth/authorize')
]
-
p.frame_src(*frame_src_values)
+
+ default_connect_src = p.directives['connect-src'] || p.directives['default-src']
+ connect_src_values =
+ Array.wrap(default_connect_src) | [Gitlab::Observability.observability_url]
+ p.connect_src(*connect_src_values)
end
end
end
diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_allowlisted_monitoring_client.rb
index ef3d281589a..ad6d4dc548c 100644
--- a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb
+++ b/app/controllers/concerns/requires_allowlisted_monitoring_client.rb
@@ -1,28 +1,28 @@
# frozen_string_literal: true
-module RequiresWhitelistedMonitoringClient
+module RequiresAllowlistedMonitoringClient
extend ActiveSupport::Concern
included do
- before_action :validate_ip_whitelisted_or_valid_token!
+ before_action :validate_ip_allowlisted_or_valid_token!
end
private
- def validate_ip_whitelisted_or_valid_token!
- render_404 unless client_ip_whitelisted? || valid_token?
+ def validate_ip_allowlisted_or_valid_token!
+ render_404 unless client_ip_allowlisted? || valid_token?
end
- def client_ip_whitelisted?
+ def client_ip_allowlisted?
# Always allow developers to access http://localhost:3000/-/metrics for
# debugging purposes
return true if Rails.env.development? && request.local?
- ip_whitelist.any? { |e| e.include?(Gitlab::RequestContext.instance.client_ip) }
+ ip_allowlist.any? { |e| e.include?(Gitlab::RequestContext.instance.client_ip) }
end
- def ip_whitelist
- @ip_whitelist ||= Settings.monitoring.ip_whitelist.map { |ip| IPAddr.new(ip) }
+ def ip_allowlist
+ @ip_allowlist ||= Settings.monitoring.ip_whitelist.map { |ip| IPAddr.new(ip) }
end
def valid_token?
diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb
index a2abed7ba4e..a85629985ba 100644
--- a/app/controllers/health_check_controller.rb
+++ b/app/controllers/health_check_controller.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
class HealthCheckController < HealthCheck::HealthCheckController
- include RequiresWhitelistedMonitoringClient
+ include RequiresAllowlistedMonitoringClient
end
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
index 5fac7c0d663..1381999ab4c 100644
--- a/app/controllers/health_controller.rb
+++ b/app/controllers/health_controller.rb
@@ -3,7 +3,7 @@
# rubocop:disable Rails/ApplicationController
class HealthController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
- include RequiresWhitelistedMonitoringClient
+ include RequiresAllowlistedMonitoringClient
CHECKS = [
Gitlab::HealthChecks::MasterCheck
diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb
index 3dfa8d7b11e..9f41c092fa0 100644
--- a/app/controllers/metrics_controller.rb
+++ b/app/controllers/metrics_controller.rb
@@ -2,7 +2,7 @@
# rubocop:disable Rails/ApplicationController
class MetricsController < ActionController::Base
- include RequiresWhitelistedMonitoringClient
+ include RequiresAllowlistedMonitoringClient
protect_from_forgery with: :exception, prepend: true
diff --git a/app/controllers/projects/tracing_controller.rb b/app/controllers/projects/tracing_controller.rb
new file mode 100644
index 00000000000..71ca03deb8c
--- /dev/null
+++ b/app/controllers/projects/tracing_controller.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Projects
+ class TracingController < Projects::ApplicationController
+ include ::Observability::ContentSecurityPolicy
+
+ feature_category :tracing
+
+ before_action :check_tracing_enabled
+
+ def index
+ # TODO frontend changes coming separately https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125014
+ render html: helpers.tag.strong('Tracing')
+ end
+
+ private
+
+ def check_tracing_enabled
+ render_404 unless Gitlab::Observability.tracing_enabled?(project)
+ end
+ end
+end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index be9306ce80b..6746e6549ec 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -118,8 +118,8 @@ module BlobHelper
"#{blob_raw_path.rpartition('/').first}/"
end
- # SVGs can contain malicious JavaScript; only include whitelisted
- # elements and attributes. Note that this whitelist is by no means complete
+ # SVGs can contain malicious JavaScript; only include allowlisted
+ # elements and attributes. Note that this allowlist is by no means complete
# and may omit some elements.
def sanitize_svg_data(data)
Gitlab::Sanitizers::SVG.clean(data)
diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb
index 72cb3997045..22104409199 100644
--- a/app/services/projects/download_service.rb
+++ b/app/services/projects/download_service.rb
@@ -2,7 +2,7 @@
module Projects
class DownloadService < BaseService
- WHITELIST = [
+ ALLOWLIST = [
/^[^.]+\.fogbugz.com$/
].freeze
@@ -33,7 +33,7 @@ module Projects
def valid_domain?(url)
host = URI.parse(url).host
- WHITELIST.any? { |entry| entry === host }
+ ALLOWLIST.any? { |entry| entry === host }
end
end
end
diff --git a/app/validators/cron_validator.rb b/app/validators/cron_validator.rb
index 91b9cfcccc4..c12b29410d4 100644
--- a/app/validators/cron_validator.rb
+++ b/app/validators/cron_validator.rb
@@ -1,16 +1,16 @@
# frozen_string_literal: true
class CronValidator < ActiveModel::EachValidator
- ATTRIBUTE_WHITELIST = %i[cron freeze_start freeze_end].freeze
+ ATTRIBUTE_ALLOWLIST = %i[cron freeze_start freeze_end].freeze
- NonWhitelistedAttributeError = Class.new(StandardError)
+ NonAllowlistedAttributeError = Class.new(StandardError)
def validate_each(record, attribute, value)
- if ATTRIBUTE_WHITELIST.include?(attribute)
+ if ATTRIBUTE_ALLOWLIST.include?(attribute)
cron_parser = Gitlab::Ci::CronParser.new(record.public_send(attribute), record.cron_timezone) # rubocop:disable GitlabSecurity/PublicSend
record.errors.add(attribute, " is invalid syntax") unless cron_parser.cron_valid?
else
- raise NonWhitelistedAttributeError, "Non-whitelisted attribute"
+ raise NonAllowlistedAttributeError, "Non-allowlisted attribute"
end
end
end
diff --git a/app/views/shared/_md_preview.html.haml b/app/views/shared/_md_preview.html.haml
index e4fc3ebf23c..1fd430527a1 100644
--- a/app/views/shared/_md_preview.html.haml
+++ b/app/views/shared/_md_preview.html.haml
@@ -9,9 +9,9 @@
= _('Only project members can comment.')
.md-area.position-relative
- .md-header.gl-bg-gray-50.gl-px-2.gl-rounded-base.gl-mx-2.gl-mt-2
+ .md-header.gl-px-3.gl-rounded-top-base.gl-border-b.gl-border-gray-100
.gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-justify-content-space-between
- .md-header-toolbar.gl-display-flex.gl-py-2.gl-flex-wrap.gl-row-gap-3
+ .md-header-toolbar.gl-display-flex.gl-py-3.gl-flex-wrap.gl-row-gap-3
= render Pajamas::ButtonComponent.new(category: :tertiary, size: :small, button_options: { class: 'js-md-preview-button', value: 'preview' }) do
= _('Preview')
= render 'shared/blob/markdown_buttons', supports_quick_actions: supports_quick_actions
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index 9be87b0a095..23ce38d50e0 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -1,7 +1,7 @@
- supports_file_upload = local_assigns.fetch(:supports_file_upload, true)
-.comment-toolbar.gl-mx-2.gl-mb-2.gl-px-2.gl-display-flex.gl-justify-content-end.gl-rounded-bottom-left-base.gl-rounded-bottom-right-base.clearfix
- .toolbar-text
- = render Pajamas::ButtonComponent.new(category: :tertiary, icon: 'markdown-mark', size: :small, href: help_page_path('user/markdown'), target: '_blank')
+.comment-toolbar.gl-px-2.gl-display-flex.gl-justify-content-end.gl-rounded-bottom-left-base.gl-rounded-bottom-right-base.clearfix
+ .content-editor-switcher.gl-display-inline-flex.gl-align-items-center
+ = render Pajamas::ButtonComponent.new(category: :tertiary, icon: 'markdown-mark', size: :small, href: help_page_path('user/markdown'), target: '_blank', button_options: { class: 'gl-px-3!' })
- if supports_file_upload
%span.uploading-container.gl-line-height-32.gl-font-sm
%span.uploading-progress-container.hide
diff --git a/config/feature_flags/development/observability_tracing.yml b/config/feature_flags/development/observability_tracing.yml
new file mode 100644
index 00000000000..a32d8409608
--- /dev/null
+++ b/config/feature_flags/development/observability_tracing.yml
@@ -0,0 +1,8 @@
+---
+name: observability_tracing
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124966
+rollout_issue_url: https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2252
+milestone: '16.2'
+type: development
+group: group::observability
+default_enabled: false
diff --git a/config/feature_flags/development/packages_dependency_proxy_maven.yml b/config/feature_flags/development/packages_dependency_proxy_maven.yml
new file mode 100644
index 00000000000..8cf2f5a2879
--- /dev/null
+++ b/config/feature_flags/development/packages_dependency_proxy_maven.yml
@@ -0,0 +1,8 @@
+---
+name: packages_dependency_proxy_maven
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123491
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415218
+milestone: '16.2'
+type: development
+group: group::package registry
+default_enabled: false
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 533e6c63e24..787d95669d1 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -404,6 +404,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
+ resources :tracing, only: [:index], controller: :tracing
+
namespace :design_management do
namespace :designs, path: 'designs/:design_id(/:sha)', constraints: -> (params) { params[:sha].nil? || Gitlab::Git.commit_id?(params[:sha]) } do
resource :raw_image, only: :show
diff --git a/db/docs/dependency_proxy_packages_settings.yml b/db/docs/dependency_proxy_packages_settings.yml
index dcb43553f81..b506848e899 100644
--- a/db/docs/dependency_proxy_packages_settings.yml
+++ b/db/docs/dependency_proxy_packages_settings.yml
@@ -3,7 +3,7 @@ table_name: dependency_proxy_packages_settings
classes:
- DependencyProxy::Packages::Setting
feature_categories:
-- dependency_proxy
+- package_registry
description: Settings for the dependency proxy for packages.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120894
milestone: '16.1'
diff --git a/doc/development/pipelines/internals.md b/doc/development/pipelines/internals.md
index be72fc50988..c0d7bbd3713 100644
--- a/doc/development/pipelines/internals.md
+++ b/doc/development/pipelines/internals.md
@@ -46,6 +46,7 @@ Here's a list of where we're using this right now, and should try to move away
from using `$FORCE_GITLAB_CI`.
- [JiHu validation pipeline](https://about.gitlab.com/handbook/ceo/chief-of-staff-team/jihu-support/jihu-validation-pipelines.html)
+- [Gitaly downstream GitLab pipeline](https://gitlab.com/gitlab-org/gitaly/-/issues/4615)
## Default image
diff --git a/doc/subscriptions/gitlab_com/index.md b/doc/subscriptions/gitlab_com/index.md
index 73f9f36ecd6..8cd5777e4cb 100644
--- a/doc/subscriptions/gitlab_com/index.md
+++ b/doc/subscriptions/gitlab_com/index.md
@@ -103,6 +103,11 @@ To view a list of seats being used:
1. Select **Settings > Usage Quotas**.
1. On the **Seats** tab, view usage information.
+For each user, a list shows groups and projects where the user is a direct member.
+
+- **Group invite** indicates the user is a member of a [group shared with a group](../../user/group/manage.md#share-a-group-with-another-group).
+- **Project invite** indicates the user is a member of a [group shared with a project](../../user/project/members/share_project_with_groups.md#share-a-project-with-a-group).
+
The data in seat usage listing, **Seats in use**, and **Seats in subscription** are updated live.
The counts for **Max seats used** and **Seats owed** are updated once per day.
diff --git a/doc/update/index.md b/doc/update/index.md
index a07532dda88..5f6a7c052e6 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -312,6 +312,8 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap
- Geo: Some project imports do not initialize wiki repositories on project creation. Since the migration of project wikis to SSF, [missing wiki repositories are being incorrectly flagged as failing verification](https://gitlab.com/gitlab-org/gitlab/-/issues/409704). This is not a result of an actual replication/verification failure but an invalid internal state for these missing repositories inside Geo and results in errors in the logs and the verification progress reporting a failed state for these wiki repositories. If you have not imported projects you are not impacted by this issue.
- Impacted versions: GitLab versions 15.11.x, 16.0.x, and 16.1.0 - 16.1.2.
- Versions containing fix: GitLab 16.1.3 and later.
+- Starting with 16.0, GitLab self-managed installations now have two database connections by default, instead of one. This change doubles the number of PostgreSQL connections. It makes self-managed versions of GitLab behave similarly to GitLab.com, and is a step toward enabling a separate database for CI features for self-managed versions of GitLab. Before upgrading to 16.0, determine if you need to [increase max connections for PostgreSQL](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections).
+ - This change applies to installation methods with Linux packages (Omnibus GitLab), GitLab Helm chart, GitLab Operator, GitLab Docker images, and installation from source.
### 15.11.1
diff --git a/doc/user/admin_area/settings/sign_in_restrictions.md b/doc/user/admin_area/settings/sign_in_restrictions.md
index 3b79e55f998..c84f2a12db9 100644
--- a/doc/user/admin_area/settings/sign_in_restrictions.md
+++ b/doc/user/admin_area/settings/sign_in_restrictions.md
@@ -114,11 +114,13 @@ Admin Mode times out after six hours, and you cannot change this timeout limit.
The following access methods are **not** protected by Admin Mode:
- Git client access (SSH using public keys or HTTPS using Personal Access Tokens).
-- API access using a Personal Access Token.
In other words, administrators who are otherwise limited by Admin Mode can still use
-Git clients, and access RESTful API endpoints as administrators, without additional
-authentication steps.
+Git clients without additional authentication steps.
+
+To use the GitLab REST- or GraphQL API, administrators must [create a personal access token](../../profile/personal_access_tokens.md#create-a-personal-access-token) with the [`admin_mode` scope](../../profile/personal_access_tokens.md#personal-access-token-scopes).
+
+If an administrator with a personal access token with the `admin_mode` scope loses their administrator access, that user cannot access the API as an administrator even though they still have the token with the `admin_mode` scope.
We may address these limitations in the future. For more information see the following epic:
[Admin Mode for GitLab Administrators](https://gitlab.com/groups/gitlab-org/-/epics/2158).
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index f9a6ffa8228..15fed4f2adc 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -635,7 +635,6 @@ The following variables allow configuration of global dependency scanning settin
| `DS_IMAGE_SUFFIX` | Suffix added to the image name. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/354796) in GitLab 14.10.) Automatically set to `"-fips"` when FIPS mode is enabled. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/357922) in GitLab 15.0.) |
| `DS_MAX_DEPTH` | Defines how many directory levels deep that the analyzer should search for supported files to scan. A value of `-1` scans all directories regardless of depth. Default: `2`. |
| `SECURE_ANALYZERS_PREFIX` | Override the name of the Docker registry providing the official default images (proxy). |
-| `SECURE_LOG_LEVEL` | Set the minimum logging level. Messages of this logging level or higher are output. From highest to lowest severity, the logging levels are: `fatal`, `error`, `warn`, `info` (default), `debug`. |
#### Configuring specific analyzers used by dependency scanning
@@ -1136,12 +1135,10 @@ version number).
## Troubleshooting
-### Increase log verbosity
+### Debug-level logging
-When a [job log](../../../ci/jobs/index.md#expand-and-collapse-job-log-sections)
-doesn't contain enough information about a dependency-scanning failure,
-[set `SECURE_LOG_LEVEL` to `debug`](#configuring-dependency-scanning)
-and check the resulting, more verbose log.
+Debug-level logging can help when troubleshooting. For details, see
+[debug-level logging](../index.md#debug-level-logging).
### Working around missing support for certain languages or package managers
diff --git a/doc/user/application_security/iac_scanning/index.md b/doc/user/application_security/iac_scanning/index.md
index 8e2f54fed44..83dcfb61772 100644
--- a/doc/user/application_security/iac_scanning/index.md
+++ b/doc/user/application_security/iac_scanning/index.md
@@ -270,15 +270,10 @@ pipelines tab on merge requests by [setting `artifacts: paths`](../../../ci/yaml
## Troubleshooting
-### IaC debug logging
+### Debug-level logging
-To help troubleshoot IaC jobs, you can increase the [Secure scanner log verbosity](../sast/index.md#logging-level)
-by using a global CI/CD variable set to `debug`:
-
-```yaml
-variables:
- SECURE_LOG_LEVEL: "debug"
-```
+Debug-level logging can help when troubleshooting. For details, see
+[debug-level logging](../index.md#debug-level-logging).
### IaC Scanning findings show as `No longer detected` unexpectedly
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index 61d3b463193..56a79191833 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -536,24 +536,48 @@ Feedback is welcome on our vision for [unifying the user experience for these tw
## Troubleshooting
-<!-- NOTE: The below subsection(`### Secure job failing with exit code 1`) documentation URL is referred in the [/gitlab-org/security-products/analyzers/command](https://gitlab.com/gitlab-org/security-products/analyzers/command/-/blob/main/command.go#L19) repository. If this section/subsection changes, please ensure to update the corresponding URL in the mentioned repository.
--->
+### Logging level
-### Secure job failing with exit code 1
+The verbosity of logs output by GitLab analyzers is determined by the `SECURE_LOG_LEVEL` environment
+variable. Messages of this logging level or higher are output.
+
+From highest to lowest severity, the logging levels are:
+
+- `fatal`
+- `error`
+- `warn`
+- `info` (default)
+- `debug`
+
+#### Debug-level logging
WARNING:
Debug logging can be a serious security risk. The output may contain the content of
environment variables and other secrets available to the job. The output is uploaded
-to the GitLab server and visible in job logs.
+to the GitLab server and is visible in job logs.
-If a Secure job is failing and it's unclear why, add `SECURE_LOG_LEVEL: "debug"` as a global CI/CD variable for
-more verbose output that is helpful for troubleshooting.
+To enable debug-level logging, add the following to your `.gitlab-ci.yml` file:
```yaml
variables:
SECURE_LOG_LEVEL: "debug"
```
+This indicates to all GitLab analyzers that they are to output **all** messages. For more details,
+see [logging level](#logging-level).
+
+<!-- NOTE: The below subsection(`### Secure job failing with exit code 1`) documentation URL is referred in the [/gitlab-org/security-products/analyzers/command](https://gitlab.com/gitlab-org/security-products/analyzers/command/-/blob/main/command.go#L19) repository. If this section/subsection changes, please ensure to update the corresponding URL in the mentioned repository.
+-->
+
+### Secure job failing with exit code 1
+
+If a Secure job is failing and it's unclear why:
+
+1. Enable [debug-level logging](#debug-level-logging).
+1. Run the job.
+1. Examine the job's output.
+1. Set the logging level to `info` (default).
+
### Outdated security reports
When a security report generated for a merge request becomes outdated, the merge request shows a
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index 2008375d2a2..657ad904223 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -519,21 +519,6 @@ variables:
SEARCH_MAX_DEPTH: 10
```
-#### Logging level
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10880) in GitLab 13.1.
-
-To control the verbosity of logs, set the `SECURE_LOG_LEVEL` environment variable. Messages of this
-logging level or higher are output.
-
-From highest to lowest severity, the logging levels are:
-
-- `fatal`
-- `error`
-- `warn`
-- `info` (default)
-- `debug`
-
#### Custom Certificate Authority
To trust a custom Certificate Authority, set the `ADDITIONAL_CA_CERT_BUNDLE` variable to the bundle
@@ -772,14 +757,10 @@ By default SAST analyzers are supported in GitLab instances hosted on SELinux. A
## Troubleshooting
-### SAST debug logging
+### Debug-level logging
-Increase the [Secure scanner log verbosity](#logging-level) to `debug` in a global CI variable to help troubleshoot SAST jobs.
-
-```yaml
-variables:
- SECURE_LOG_LEVEL: "debug"
-```
+Debug-level logging can help when troubleshooting. For details, see
+[debug-level logging](../index.md#debug-level-logging).
### Pipeline errors related to changes in the GitLab-managed CI/CD template
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index c6928d3679b..0a969d51f9e 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -629,21 +629,10 @@ This feature is separate from Secret Detection scanning, which checks your Git r
## Troubleshooting
-### Set the logging level
+### Debug-level logging
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10880) in GitLab 13.1.
-
-Set the logging level to `debug` when you need diagnostic information in a Secret Detection job log.
-
-WARNING:
-Debug logging can be a serious security risk. The output may contain the content of environment
-variables and other secrets available to the job. The output is uploaded to the GitLab server and
-visible in job logs.
-
-1. In the `.gitlab-ci.yml` file, set the `SECURE_LOG_LEVEL` CI/CD variable to `debug`.
-1. Run the Secret Detection job.
-1. Analyze the content of the Secret Detection job.
-1. In the `.gitlab-ci.yml` file, set the `SECURE_LOG_LEVEL` CI/CD variable to `info` (default).
+Debug-level logging can help when troubleshooting. For details, see
+[debug-level logging](../index.md#debug-level-logging).
### Warning: `gl-secret-detection-report.json: no matching files`
@@ -661,8 +650,8 @@ For example, you could have a pipeline triggered from a merge request containing
clone is not deep enough to contain all of the relevant commits. To verify the current value, see
[pipeline configuration](../../../ci/pipelines/settings.md#limit-the-number-of-changes-fetched-during-clone).
-To confirm this as the cause of the error, set the [logging level](#set-the-logging-level) to
-`debug`, then rerun the pipeline. The logs should look similar to the following example. The text
+To confirm this as the cause of the error, enable [debug-level logging](../index.md#debug-level-logging),
+then rerun the pipeline. The logs should look similar to the following example. The text
"object not found" is a symptom of this error.
```plaintext
diff --git a/doc/user/search/command_palette.md b/doc/user/search/command_palette.md
new file mode 100644
index 00000000000..138c19be778
--- /dev/null
+++ b/doc/user/search/command_palette.md
@@ -0,0 +1,28 @@
+---
+stage: Manage
+group: Foundations
+info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments"
+type: reference
+---
+
+# Command palette **(FREE)**
+
+> Introduced in GitLab 16.2 [with a flag](../../administration/feature_flags.md) named `command_palette`. Disabled by default.
+
+You can use command palette to narrow down the scope of your search or to
+find an object more quickly.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to enable the feature flag named `command_palette`. On GitLab.com, this feature is not available.
+
+## Open the command palette
+
+To open the command palette:
+
+1. On the left sidebar, at the top, select **Search GitLab** (**{search}**).
+1. Type one of the special characters:
+
+ - <kbd>></kbd> - Use to create a new object or to find a menu item.
+ - <kbd>@</kbd> - Search for user.
+ - <kbd>:</kbd> - Search for project.
+ - <kbd>/</kbd> - Search for project files in the default repository branch.
diff --git a/lib/api/helpers/packages/maven.rb b/lib/api/helpers/packages/maven.rb
new file mode 100644
index 00000000000..694a1ec6436
--- /dev/null
+++ b/lib/api/helpers/packages/maven.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module API
+ module Helpers
+ module Packages
+ module Maven
+ extend Grape::API::Helpers
+
+ params :path_and_file_name do
+ requires :path,
+ type: String,
+ desc: 'Package path',
+ documentation: { example: 'foo/bar/mypkg/1.0-SNAPSHOT' }
+ requires :file_name,
+ type: String,
+ desc: 'Package file name',
+ documentation: { example: 'mypkg-1.0-SNAPSHOT.jar' }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/api/maven_packages.rb b/lib/api/maven_packages.rb
index 241cd93f380..eccc55ed158 100644
--- a/lib/api/maven_packages.rb
+++ b/lib/api/maven_packages.rb
@@ -23,14 +23,10 @@ module API
helpers ::API::Helpers::PackagesHelpers
helpers ::API::Helpers::Packages::DependencyProxyHelpers
+ helpers ::API::Helpers::Packages::Maven
helpers ::API::Helpers::Packages::Maven::BasicAuthHelpers
helpers do
- params :path_and_file_name do
- requires :path, type: String, desc: 'Package path', documentation: { example: 'foo/bar/mypkg/1.0-SNAPSHOT' }
- requires :file_name, type: String, desc: 'Package file name', documentation: { example: 'mypkg-1.0-SNAPSHOT.jar' }
- end
-
def path_exists?(path)
return false if path.blank?
diff --git a/lib/gitlab/git/hook_env.rb b/lib/gitlab/git/hook_env.rb
index f93ab19fc65..2524d4c4cfb 100644
--- a/lib/gitlab/git/hook_env.rb
+++ b/lib/gitlab/git/hook_env.rb
@@ -14,7 +14,7 @@ module Gitlab
#
# This class is thread-safe via RequestStore.
class HookEnv
- WHITELISTED_VARIABLES = %w[
+ ALLOWLISTED_VARIABLES = %w[
GIT_OBJECT_DIRECTORY_RELATIVE
GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE
].freeze
@@ -25,7 +25,7 @@ module Gitlab
raise "missing gl_repository" if gl_repository.blank?
Gitlab::SafeRequestStore[:gitlab_git_env] ||= {}
- Gitlab::SafeRequestStore[:gitlab_git_env][gl_repository] = whitelist_git_env(env)
+ Gitlab::SafeRequestStore[:gitlab_git_env][gl_repository] = allowlist_git_env(env)
end
def self.all(gl_repository)
@@ -46,8 +46,8 @@ module Gitlab
env
end
- def self.whitelist_git_env(env)
- env.select { |key, _| WHITELISTED_VARIABLES.include?(key.to_s) }.with_indifferent_access
+ def self.allowlist_git_env(env)
+ env.select { |key, _| ALLOWLISTED_VARIABLES.include?(key.to_s) }.with_indifferent_access
end
end
end
diff --git a/lib/gitlab/observability.rb b/lib/gitlab/observability.rb
index f7f65c91339..0e6089e1d21 100644
--- a/lib/gitlab/observability.rb
+++ b/lib/gitlab/observability.rb
@@ -23,7 +23,13 @@ module Gitlab
'https://observe.gitlab.com'
end
- # Returns true if the Observability feature flag is enabled
+ def oauth_url
+ "#{Gitlab::Observability.observability_url}/v1/auth/start"
+ end
+
+ # Returns true if the GitLab Observability UI (GOUI) feature flag is enabled
+ #
+ # @deprecated
#
def enabled?(group = nil)
return Feature.enabled?(:observability_group_tab, group) if group
@@ -31,6 +37,11 @@ module Gitlab
Feature.enabled?(:observability_group_tab)
end
+ # Returns true if Tracing UI is enabled
+ def tracing_enabled?(project)
+ Feature.enabled?(:observability_tracing, project)
+ end
+
# Returns the embeddable Observability URL of a given URL
#
# - Validates the URL
diff --git a/lib/sidebars/projects/menus/monitor_menu.rb b/lib/sidebars/projects/menus/monitor_menu.rb
index a74448d0bdc..87b09e42fe1 100644
--- a/lib/sidebars/projects/menus/monitor_menu.rb
+++ b/lib/sidebars/projects/menus/monitor_menu.rb
@@ -8,6 +8,7 @@ module Sidebars
def configure_menu_items
return false unless feature_enabled?
+ add_item(tracing_menu_item)
add_item(error_tracking_menu_item)
add_item(alert_management_menu_item)
add_item(incidents_menu_item)
@@ -62,6 +63,20 @@ module Sidebars
)
end
+ def tracing_menu_item
+ unless Gitlab::Observability.tracing_enabled?(context.project)
+ return ::Sidebars::NilMenuItem.new(item_id: :tracing)
+ end
+
+ ::Sidebars::MenuItem.new(
+ title: _('Tracing'),
+ link: project_tracing_index_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::MonitorMenu,
+ active_routes: { controller: :tracing },
+ item_id: :tracing
+ )
+ end
+
def alert_management_menu_item
unless can?(context.current_user, :read_alert_management_alert, context.project)
return ::Sidebars::NilMenuItem.new(item_id: :alert_management)
diff --git a/lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb b/lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb
index 6e64ac01ffa..0441d3b4a03 100644
--- a/lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb
+++ b/lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb
@@ -17,6 +17,7 @@ module Sidebars
override :configure_menu_items
def configure_menu_items
[
+ :tracing,
:error_tracking,
:alert_management,
:incidents,
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 92bbc28876c..daa40c5f621 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -48319,6 +48319,9 @@ msgstr ""
msgid "TotalRefCountIndicator|1000+"
msgstr ""
+msgid "Tracing"
+msgstr ""
+
msgid "Track groups of issues that share a theme, across projects and milestones"
msgstr ""
diff --git a/rubocop/cop/avoid_return_from_blocks.rb b/rubocop/cop/avoid_return_from_blocks.rb
index c6a7a87c548..bc10410af1d 100644
--- a/rubocop/cop/avoid_return_from_blocks.rb
+++ b/rubocop/cop/avoid_return_from_blocks.rb
@@ -23,7 +23,7 @@ module RuboCop
class AvoidReturnFromBlocks < RuboCop::Cop::Base
MSG = 'Do not return from a block, use next or break instead.'
DEF_METHODS = %i[define_method lambda].freeze
- WHITELISTED_METHODS = %i[each each_filename times loop].freeze
+ ALLOWLISTED_METHODS = %i[each each_filename times loop].freeze
def on_block(node)
block_body = node.body
@@ -32,7 +32,7 @@ module RuboCop
return unless top_block?(node)
block_body.each_node(:return) do |return_node|
- next if parent_blocks(node, return_node).all? { |block_node| whitelisted?(block_node) }
+ next if parent_blocks(node, return_node).all? { |block_node| allowlisted?(block_node) }
add_offense(return_node)
end
@@ -69,8 +69,8 @@ module RuboCop
(node.type == :block && DEF_METHODS.include?(node.method_name))
end
- def whitelisted?(block_node)
- WHITELISTED_METHODS.include?(block_node.method_name)
+ def allowlisted?(block_node)
+ ALLOWLISTED_METHODS.include?(block_node.method_name)
end
end
end
diff --git a/rubocop/cop/graphql/id_type.rb b/rubocop/cop/graphql/id_type.rb
index c9d9b4ea6eb..53d79751fa8 100644
--- a/rubocop/cop/graphql/id_type.rb
+++ b/rubocop/cop/graphql/id_type.rb
@@ -6,7 +6,7 @@ module RuboCop
class IDType < RuboCop::Cop::Base
MSG = 'Do not use GraphQL::Types::ID, use a specific GlobalIDType instead'
- WHITELISTED_ARGUMENTS = %i[iid full_path project_path group_path target_project_path namespace_path].freeze
+ ALLOWLISTED_ARGUMENTS = %i[iid full_path project_path group_path target_project_path namespace_path].freeze
def_node_search :graphql_id_type?, <<~PATTERN
(send nil? :argument (_ #does_not_match?) (const (const (const nil? :GraphQL) :Types) :ID) ...)
@@ -21,7 +21,7 @@ module RuboCop
private
def does_not_match?(arg)
- !WHITELISTED_ARGUMENTS.include?(arg) # rubocop:disable Rails/NegateInclude
+ !ALLOWLISTED_ARGUMENTS.include?(arg) # rubocop:disable Rails/NegateInclude
end
end
end
diff --git a/scripts/rspec_helpers.sh b/scripts/rspec_helpers.sh
index fc6086c6109..b559a8de52a 100644
--- a/scripts/rspec_helpers.sh
+++ b/scripts/rspec_helpers.sh
@@ -371,7 +371,7 @@ function rspec_rerun_previous_failed_tests() {
local test_file_count_threshold=${RSPEC_PREVIOUS_FAILED_TEST_FILE_COUNT_THRESHOLD:-10}
local matching_tests_file=${1}
local rspec_opts=${2}
- local test_files="$(cat "${matching_tests_file}")"
+ local test_files="$(select_existing_files < "${matching_tests_file}")"
local test_file_count=$(wc -w "${matching_tests_file}" | awk {'print $1'})
if [[ "${test_file_count}" -gt "${test_file_count_threshold}" ]]; then
diff --git a/scripts/utils.sh b/scripts/utils.sh
index 9ff8c156234..1ed83c69b0c 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -201,6 +201,10 @@ function install_junit_merge_gem() {
run_timed_command "gem install junit_merge --no-document --version 0.1.2"
}
+function select_existing_files() {
+ ruby -e 'print $stdin.read.split(" ").select { |f| File.exist?(f) }.join(" ")'
+}
+
function fail_on_warnings() {
local cmd="$*"
local warning_file
diff --git a/spec/controllers/concerns/issuable_collections_spec.rb b/spec/controllers/concerns/issuable_collections_spec.rb
index 6fa273bf3d7..9eb0f36cb37 100644
--- a/spec/controllers/concerns/issuable_collections_spec.rb
+++ b/spec/controllers/concerns/issuable_collections_spec.rb
@@ -92,7 +92,7 @@ RSpec.describe IssuableCollections do
}
end
- it 'only allows whitelisted params' do
+ it 'only allows allowlisted params' do
is_expected.to include({
'assignee_id' => '1',
'assignee_username' => 'user1',
@@ -123,7 +123,7 @@ RSpec.describe IssuableCollections do
}
end
- it 'only allows whitelisted params' do
+ it 'only allows allowlisted params' do
is_expected.to include({
'label_name' => %w[label1 label2],
'assignee_username' => %w[user1 user2]
diff --git a/spec/frontend/content_editor/services/create_content_editor_spec.js b/spec/frontend/content_editor/services/create_content_editor_spec.js
index b9a9c3ccd17..b68d57971b9 100644
--- a/spec/frontend/content_editor/services/create_content_editor_spec.js
+++ b/spec/frontend/content_editor/services/create_content_editor_spec.js
@@ -46,14 +46,6 @@ describe('content_editor/services/create_content_editor', () => {
});
});
- it('sets gl-shadow-none! class selector to the tiptapEditor instance', () => {
- expect(editor.tiptapEditor.options.editorProps).toMatchObject({
- attributes: {
- class: 'gl-shadow-none!',
- },
- });
- });
-
it('allows providing external content editor extensions', () => {
const labelReference = 'this is a ~group::editor';
const { tiptapExtension, serializer } = createTestContentEditorExtension();
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
index fb154e01c7a..a24bffdd363 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
@@ -1,6 +1,6 @@
import { nextTick } from 'vue';
import { GlIcon, GlCard } from '@gitlab/ui';
-import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
issuable1,
issuable2,
@@ -14,6 +14,7 @@ import {
linkedIssueTypesTextMap,
PathIdSeparator,
} from '~/related_issues/constants';
+import RelatedIssuesList from '~/related_issues/components/related_issues_list.vue';
describe('RelatedIssuesBlock', () => {
let wrapper;
@@ -21,9 +22,10 @@ describe('RelatedIssuesBlock', () => {
const findToggleButton = () => wrapper.findByTestId('toggle-links');
const findRelatedIssuesBody = () => wrapper.findByTestId('related-issues-body');
const findIssueCountBadgeAddButton = () => wrapper.findByTestId('related-issues-plus-button');
+ const findAllRelatedIssuesList = () => wrapper.findAllComponents(RelatedIssuesList);
+ const findRelatedIssuesList = (index) => findAllRelatedIssuesList().at(index);
const createComponent = ({
- mountFn = mountExtended,
pathIdSeparator = PathIdSeparator.Issue,
issuableType = TYPE_ISSUE,
canAdmin = false,
@@ -35,7 +37,7 @@ describe('RelatedIssuesBlock', () => {
autoCompleteEpics = true,
slots = '',
} = {}) => {
- wrapper = mountFn(RelatedIssuesBlock, {
+ wrapper = shallowMountExtended(RelatedIssuesBlock, {
propsData: {
pathIdSeparator,
issuableType,
@@ -94,10 +96,7 @@ describe('RelatedIssuesBlock', () => {
it('displays header text slot data', () => {
const headerText = '<div>custom header text</div>';
- createComponent({
- mountFn: shallowMountExtended,
- slots: { 'header-text': headerText },
- });
+ createComponent({ slots: { 'header-text': headerText } });
expect(wrapper.findByTestId('card-title').html()).toContain(headerText);
});
@@ -107,10 +106,7 @@ describe('RelatedIssuesBlock', () => {
it('displays header actions slot data', () => {
const headerActions = '<button data-testid="custom-button">custom button</button>';
- createComponent({
- mountFn: shallowMountExtended,
- slots: { 'header-actions': headerActions },
- });
+ createComponent({ slots: { 'header-actions': headerActions } });
expect(wrapper.findByTestId('custom-button').html()).toBe(headerActions);
});
@@ -153,10 +149,6 @@ describe('RelatedIssuesBlock', () => {
});
describe('showCategorizedIssues prop', () => {
- const issueList = () => wrapper.findAll('.js-related-issues-token-list-item');
- const categorizedHeadings = () => wrapper.findAll('h4');
- const headingTextAt = (index) => categorizedHeadings().at(index).text();
-
describe('when showCategorizedIssues=true', () => {
beforeEach(() =>
createComponent({
@@ -166,25 +158,25 @@ describe('RelatedIssuesBlock', () => {
);
it('should render issue tokens items', () => {
- expect(issueList()).toHaveLength(3);
+ expect(findAllRelatedIssuesList()).toHaveLength(3);
});
it('shows "Blocks" heading', () => {
- const blocks = linkedIssueTypesTextMap[linkedIssueTypesMap.BLOCKS];
-
- expect(headingTextAt(0)).toBe(blocks);
+ expect(findRelatedIssuesList(0).props('heading')).toBe(
+ linkedIssueTypesTextMap[linkedIssueTypesMap.BLOCKS],
+ );
});
it('shows "Is blocked by" heading', () => {
- const isBlockedBy = linkedIssueTypesTextMap[linkedIssueTypesMap.IS_BLOCKED_BY];
-
- expect(headingTextAt(1)).toBe(isBlockedBy);
+ expect(findRelatedIssuesList(1).props('heading')).toBe(
+ linkedIssueTypesTextMap[linkedIssueTypesMap.IS_BLOCKED_BY],
+ );
});
it('shows "Relates to" heading', () => {
- const relatesTo = linkedIssueTypesTextMap[linkedIssueTypesMap.RELATES_TO];
-
- expect(headingTextAt(2)).toBe(relatesTo);
+ expect(findRelatedIssuesList(2).props('heading')).toBe(
+ linkedIssueTypesTextMap[linkedIssueTypesMap.RELATES_TO],
+ );
});
});
@@ -194,8 +186,9 @@ describe('RelatedIssuesBlock', () => {
showCategorizedIssues: false,
relatedIssues: [issuable1, issuable2, issuable3],
});
- expect(issueList()).toHaveLength(3);
- expect(categorizedHeadings()).toHaveLength(0);
+ expect(findAllRelatedIssuesList()).toHaveLength(1);
+ expect(findRelatedIssuesList(0).props('relatedIssues')).toHaveLength(3);
+ expect(findRelatedIssuesList(0).props('heading')).toBe('');
});
});
});
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
index ec3d028db1a..05c1a6dd11d 100644
--- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
+++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
@@ -24,7 +24,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
</div>
<div
- class="js-vue-markdown-field md-area position-relative gfm-form js-expanded"
+ class="js-vue-markdown-field md-area position-relative gfm-form gl-overflow-hidden js-expanded"
data-uploads-path=""
>
<markdown-header-stub
diff --git a/spec/frontend/vue_shared/components/entity_select/group_select_spec.js b/spec/frontend/vue_shared/components/entity_select/group_select_spec.js
index 83560e367ea..ae551116560 100644
--- a/spec/frontend/vue_shared/components/entity_select/group_select_spec.js
+++ b/spec/frontend/vue_shared/components/entity_select/group_select_spec.js
@@ -39,6 +39,8 @@ describe('GroupSelect', () => {
const findEntitySelect = () => wrapper.findComponent(EntitySelect);
const findAlert = () => wrapper.findComponent(GlAlert);
+ const handleInput = jest.fn();
+
// Helpers
const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMountExtended(GroupSelect, {
@@ -52,6 +54,9 @@ describe('GroupSelect', () => {
GlAlert,
EntitySelect,
},
+ listeners: {
+ input: handleInput,
+ },
});
};
const openListbox = () => findListbox().vm.$emit('shown');
@@ -132,4 +137,11 @@ describe('GroupSelect', () => {
expect(findAlert().exists()).toBe(true);
expect(findAlert().text()).toBe(FETCH_GROUPS_ERROR);
});
+
+ it('forwards events to the parent scope via `v-on="$listeners"`', () => {
+ createComponent();
+ findEntitySelect().vm.$emit('input');
+
+ expect(handleInput).toHaveBeenCalledTimes(1);
+ });
});
diff --git a/spec/frontend/vue_shared/components/entity_select/project_select_spec.js b/spec/frontend/vue_shared/components/entity_select/project_select_spec.js
index 0a174c98efb..9113152c975 100644
--- a/spec/frontend/vue_shared/components/entity_select/project_select_spec.js
+++ b/spec/frontend/vue_shared/components/entity_select/project_select_spec.js
@@ -45,6 +45,8 @@ describe('ProjectSelect', () => {
const findEntitySelect = () => wrapper.findComponent(EntitySelect);
const findAlert = () => wrapper.findComponent(GlAlert);
+ const handleInput = jest.fn();
+
// Helpers
const createComponent = ({ props = {} } = {}) => {
wrapper = mountExtended(ProjectSelect, {
@@ -59,6 +61,9 @@ describe('ProjectSelect', () => {
GlAlert,
EntitySelect,
},
+ listeners: {
+ input: handleInput,
+ },
});
};
const openListbox = () => findListbox().vm.$emit('shown');
@@ -255,4 +260,11 @@ describe('ProjectSelect', () => {
expect(findAlert().exists()).toBe(true);
expect(findAlert().text()).toBe(FETCH_PROJECTS_ERROR);
});
+
+ it('forwards events to the parent scope via `v-on="$listeners"`', () => {
+ createComponent();
+ findEntitySelect().vm.$emit('input');
+
+ expect(handleInput).toHaveBeenCalledTimes(1);
+ });
});
diff --git a/spec/lib/gitlab/observability_spec.rb b/spec/lib/gitlab/observability_spec.rb
index 5082d193197..84d591e2520 100644
--- a/spec/lib/gitlab/observability_spec.rb
+++ b/spec/lib/gitlab/observability_spec.rb
@@ -31,6 +31,12 @@ RSpec.describe Gitlab::Observability, feature_category: :error_tracking do
end
end
+ describe '.oauth_url' do
+ subject { described_class.oauth_url }
+
+ it { is_expected.to eq("#{described_class.observability_url}/v1/auth/start") }
+ end
+
describe '.build_full_url' do
let_it_be(:group) { build_stubbed(:group, id: 123) }
let(:observability_url) { described_class.observability_url }
@@ -148,6 +154,27 @@ RSpec.describe Gitlab::Observability, feature_category: :error_tracking do
end
end
+ describe '.tracing_enabled?' do
+ let_it_be(:project) { create(:project, :repository) }
+
+ it 'returns true if feature is enabled globally' do
+ expect(described_class.tracing_enabled?(project)).to eq(true)
+ end
+
+ it 'returns true if feature is enabled for the project' do
+ stub_feature_flags(observability_tracing: false)
+ stub_feature_flags(observability_tracing: project)
+
+ expect(described_class.tracing_enabled?(project)).to eq(true)
+ end
+
+ it 'returns false if feature is disabled globally' do
+ stub_feature_flags(observability_tracing: false)
+
+ expect(described_class.tracing_enabled?(project)).to eq(false)
+ end
+ end
+
describe '.allowed_for_action?' do
let(:group) { build_stubbed(:group) }
let(:user) { build_stubbed(:user) }
diff --git a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
index 363822ee5e4..c0787aa9db5 100644
--- a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
@@ -7,7 +7,9 @@ RSpec.describe Sidebars::Projects::Menus::MonitorMenu, feature_category: :naviga
let(:user) { project.first_owner }
let(:show_cluster_hint) { true }
- let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project, show_cluster_hint: show_cluster_hint) }
+ let(:context) do
+ Sidebars::Projects::Context.new(current_user: user, container: project, show_cluster_hint: show_cluster_hint)
+ end
subject { described_class.new(context) }
@@ -86,5 +88,19 @@ RSpec.describe Sidebars::Projects::Menus::MonitorMenu, feature_category: :naviga
it_behaves_like 'access rights checks'
end
+
+ describe 'Tracing' do
+ let(:item_id) { :tracing }
+
+ specify { is_expected.not_to be_nil }
+
+ describe 'when feature is disabled' do
+ before do
+ stub_feature_flags(observability_tracing: false)
+ end
+
+ specify { is_expected.to be_nil }
+ end
+ end
end
end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb
index e59062c7eaf..e5c5204e0b4 100644
--- a/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb
@@ -15,6 +15,7 @@ RSpec.describe Sidebars::Projects::SuperSidebarMenus::MonitorMenu, feature_categ
it 'defines list of NilMenuItem placeholders' do
expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
expect(items.map(&:item_id)).to eq([
+ :tracing,
:error_tracking,
:alert_management,
:incidents,
diff --git a/spec/requests/groups/observability_controller_spec.rb b/spec/requests/groups/observability_controller_spec.rb
index b82cf2b0bad..247535bc990 100644
--- a/spec/requests/groups/observability_controller_spec.rb
+++ b/spec/requests/groups/observability_controller_spec.rb
@@ -17,6 +17,10 @@ RSpec.describe Groups::ObservabilityController, feature_category: :tracing do
end
it_behaves_like 'observability csp policy' do
+ before_all do
+ group.add_developer(user)
+ end
+
let(:tested_path) { path }
end
diff --git a/spec/requests/projects/issues_controller_spec.rb b/spec/requests/projects/issues_controller_spec.rb
index 583fd5f586e..1ae65939c86 100644
--- a/spec/requests/projects/issues_controller_spec.rb
+++ b/spec/requests/projects/issues_controller_spec.rb
@@ -17,6 +17,11 @@ RSpec.describe Projects::IssuesController, feature_category: :team_planning do
describe 'GET #new' do
include_context 'group project issue'
+ before do
+ group.add_developer(user)
+ login_as(user)
+ end
+
it_behaves_like "observability csp policy", described_class do
let(:tested_path) do
new_project_issue_path(project)
@@ -26,11 +31,13 @@ RSpec.describe Projects::IssuesController, feature_category: :team_planning do
describe 'GET #show' do
before do
+ group.add_developer(user)
login_as(user)
end
it_behaves_like "observability csp policy", described_class do
include_context 'group project issue'
+
let(:tested_path) do
project_issue_path(project, issue)
end
diff --git a/spec/requests/projects/merge_requests/creations_spec.rb b/spec/requests/projects/merge_requests/creations_spec.rb
index ace6ef0f7b8..e8a073fef5f 100644
--- a/spec/requests/projects/merge_requests/creations_spec.rb
+++ b/spec/requests/projects/merge_requests/creations_spec.rb
@@ -6,8 +6,13 @@ RSpec.describe 'merge requests creations', feature_category: :code_review_workfl
describe 'GET /:namespace/:project/merge_requests/new' do
include ProjectForksHelper
- let(:project) { create(:project, :repository) }
- let(:user) { project.first_owner }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository, group: group) }
+ let_it_be(:user) { create(:user) }
+
+ before_all do
+ group.add_developer(user)
+ end
before do
login_as(user)
@@ -26,16 +31,13 @@ RSpec.describe 'merge requests creations', feature_category: :code_review_workfl
end
it_behaves_like "observability csp policy", Projects::MergeRequests::CreationsController do
- let_it_be(:group) { create(:group) }
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, group: group) }
let(:tested_path) do
project_new_merge_request_path(project, merge_request: {
title: 'Some feature',
- source_branch: 'fix',
- target_branch: 'feature',
- target_project: project,
- source_project: project
+ source_branch: 'fix',
+ target_branch: 'feature',
+ target_project: project,
+ source_project: project
})
end
end
diff --git a/spec/requests/projects/merge_requests_controller_spec.rb b/spec/requests/projects/merge_requests_controller_spec.rb
index 955e6822211..955b6e53686 100644
--- a/spec/requests/projects/merge_requests_controller_spec.rb
+++ b/spec/requests/projects/merge_requests_controller_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe Projects::MergeRequestsController, feature_category: :source_code
context 'when logged in' do
before do
+ group.add_developer(user)
login_as(user)
end
diff --git a/spec/requests/projects/tracing_controller_spec.rb b/spec/requests/projects/tracing_controller_spec.rb
new file mode 100644
index 00000000000..520e99b120a
--- /dev/null
+++ b/spec/requests/projects/tracing_controller_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::TracingController, feature_category: :tracing do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+ let(:path) { nil }
+ let(:observability_tracing_ff) { true }
+
+ subject do
+ get path
+ response
+ end
+
+ describe 'GET #index' do
+ before do
+ stub_feature_flags(observability_tracing: observability_tracing_ff)
+ sign_in(user)
+ end
+
+ let(:path) { project_tracing_index_path(project) }
+
+ it_behaves_like 'observability csp policy' do
+ before_all do
+ project.add_developer(user)
+ end
+
+ let(:tested_path) { path }
+ end
+
+ context 'when user does not have permissions' do
+ it 'returns 404' do
+ expect(subject).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when user has permissions' do
+ before_all do
+ project.add_developer(user)
+ end
+
+ it 'returns 200' do
+ expect(subject).to have_gitlab_http_status(:ok)
+ end
+
+ context 'when feature is disabled' do
+ let(:observability_tracing_ff) { false }
+
+ it 'returns 404' do
+ expect(subject).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/rubocop/cop/avoid_return_from_blocks_spec.rb b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
index e35705ae791..1b41e140454 100644
--- a/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
+++ b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
@@ -41,10 +41,10 @@ RSpec.describe RuboCop::Cop::AvoidReturnFromBlocks do
RUBY
end
- shared_examples 'examples with whitelisted method' do |whitelisted_method|
- it "doesn't flag violation for return inside #{whitelisted_method}" do
+ shared_examples 'examples with allowlisted method' do |allowlisted_method|
+ it "doesn't flag violation for return inside #{allowlisted_method}" do
expect_no_offenses(<<~RUBY)
- items.#{whitelisted_method} do |item|
+ items.#{allowlisted_method} do |item|
do_something
return if something_else
end
@@ -52,8 +52,8 @@ RSpec.describe RuboCop::Cop::AvoidReturnFromBlocks do
end
end
- %i[each each_filename times loop].each do |whitelisted_method|
- it_behaves_like 'examples with whitelisted method', whitelisted_method
+ %i[each each_filename times loop].each do |allowlisted_method|
+ it_behaves_like 'examples with allowlisted method', allowlisted_method
end
shared_examples 'examples with def methods' do |def_method|
diff --git a/spec/rubocop/cop/graphql/id_type_spec.rb b/spec/rubocop/cop/graphql/id_type_spec.rb
index 3a56753d39e..6eb4890c064 100644
--- a/spec/rubocop/cop/graphql/id_type_spec.rb
+++ b/spec/rubocop/cop/graphql/id_type_spec.rb
@@ -12,8 +12,8 @@ RSpec.describe RuboCop::Cop::Graphql::IDType do
TYPE
end
- context 'whitelisted arguments' do
- RuboCop::Cop::Graphql::IDType::WHITELISTED_ARGUMENTS.each do |arg|
+ context 'allowlisted arguments' do
+ RuboCop::Cop::Graphql::IDType::ALLOWLISTED_ARGUMENTS.each do |arg|
it "does not add an offense for calls to #argument with #{arg} as argument name" do
expect_no_offenses(<<~TYPE.strip)
argument #{arg}, GraphQL::Types::ID, some: other, params: do_not_matter
diff --git a/spec/services/design_management/generate_image_versions_service_spec.rb b/spec/services/design_management/generate_image_versions_service_spec.rb
index 08442f221fa..d02d472f897 100644
--- a/spec/services/design_management/generate_image_versions_service_spec.rb
+++ b/spec/services/design_management/generate_image_versions_service_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe DesignManagement::GenerateImageVersionsService, feature_category:
.from(nil).to(CarrierWave::SanitizedFile)
end
- it 'skips generating image versions if the mime type is not whitelisted' do
+ it 'skips generating image versions if the mime type is not allowlisted' do
stub_const('DesignManagement::DesignV432x230Uploader::MIME_TYPE_ALLOWLIST', [])
described_class.new(version).execute
diff --git a/spec/services/projects/download_service_spec.rb b/spec/services/projects/download_service_spec.rb
index e062ee04bf4..a0b14a36106 100644
--- a/spec/services/projects/download_service_spec.rb
+++ b/spec/services/projects/download_service_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Projects::DownloadService, feature_category: :groups_and_projects
@project = create(:project, creator_id: @user.id, namespace: @user.namespace)
end
- context 'for a URL that is not on whitelist' do
+ context 'for a URL that is not on allowlist' do
before do
url = 'https://code.jquery.com/jquery-2.1.4.min.js'
@link_to_file = download_file(@project, url)
@@ -18,7 +18,7 @@ RSpec.describe Projects::DownloadService, feature_category: :groups_and_projects
it { expect(@link_to_file).to eq(nil) }
end
- context 'for URLs that are on the whitelist' do
+ context 'for URLs that are on the allowlist' do
before do
# `ssrf_filter` resolves the hostname. See https://github.com/carrierwaveuploader/carrierwave/commit/91714adda998bc9e8decf5b1f5d260d808761304
stub_request(:get, %r{http://[\d.]+/rails_sample.jpg}).to_return(body: File.read(Rails.root + 'spec/fixtures/rails_sample.jpg'))
diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb
index ee1b4a3c33a..3be2d39906d 100644
--- a/spec/support/import_export/export_file_helper.rb
+++ b/spec/support/import_export/export_file_helper.rb
@@ -92,7 +92,7 @@ module ExportFileHelper
end
# Returns the offended ObjectWithParent object if a sensitive word is found inside a hash,
- # excluding the whitelisted safe hashes.
+ # excluding the allowlisted safe hashes.
def find_sensitive_attributes(sensitive_word, project_hash)
loop do
object_with_parent = deep_find_with_parent(sensitive_word, project_hash)
diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb
index efb4d244c10..0abf688566a 100644
--- a/spec/support/shared_contexts/navbar_structure_context.rb
+++ b/spec/support/shared_contexts/navbar_structure_context.rb
@@ -82,6 +82,7 @@ RSpec.shared_context 'project navbar structure' do
{
nav_item: _('Monitor'),
nav_sub_items: [
+ _('Tracing'),
_('Error Tracking'),
_('Alerts'),
_('Incidents')
diff --git a/spec/support/shared_examples/lib/banzai/filters/sanitization_filter_shared_examples.rb b/spec/support/shared_examples/lib/banzai/filters/sanitization_filter_shared_examples.rb
index 99d0bc287a3..e6433f963f4 100644
--- a/spec/support/shared_examples/lib/banzai/filters/sanitization_filter_shared_examples.rb
+++ b/spec/support/shared_examples/lib/banzai/filters/sanitization_filter_shared_examples.rb
@@ -25,7 +25,7 @@ RSpec.shared_examples 'default allowlist' do
expect(filter(act).to_html).to eq exp
end
- it 'allows whitelisted HTML tags from the user' do
+ it 'allows allowlisted HTML tags from the user' do
exp = act = "<dl>\n<dt>Term</dt>\n<dd>Definition</dd>\n</dl>"
expect(filter(act).to_html).to eq exp
end
diff --git a/spec/support/shared_examples/observability/csp_shared_examples.rb b/spec/support/shared_examples/observability/csp_shared_examples.rb
index 9d6e7e75f4d..9002ccd5878 100644
--- a/spec/support/shared_examples/observability/csp_shared_examples.rb
+++ b/spec/support/shared_examples/observability/csp_shared_examples.rb
@@ -5,23 +5,28 @@
# It requires the following variables declared in the context including this example:
#
# - `tested_path`: the path under test
-# - `user`: the test user
-# - `group`: the test group
#
# e.g.
#
# ```
-# let_it_be(:group) { create(:group) }
-# let_it_be(:user) { create(:user) }
# it_behaves_like "observability csp policy" do
# let(:tested_path) { ....the path under test }
# end
# ```
#
+# Note that the context's user is expected to be logged-in and the
+# related resources (group, project, etc) are supposed to be provided with proper
+# permissions already, e.g.
+#
+# before do
+# login_as(user)
+# group.add_developer(user)
+# end
+#
# It optionally supports specifying the controller class handling the tested path as a parameter, e.g.
#
# ```
-# it_behaves_like "observability csp policy", Groups::ObservabilityController
+# it_behaves_like "observability csp policy", Projects::TracingController
# ```
# (If not specified it will default to `described_class`)
#
@@ -41,9 +46,6 @@ RSpec.shared_examples 'observability csp policy' do |controller_class = describe
before do
setup_csp_for_controller(controller_class, csp, any_time: true)
- group.add_developer(user)
- login_as(user)
- stub_feature_flags(observability_group_tab: true)
end
subject do
@@ -59,93 +61,127 @@ RSpec.shared_examples 'observability csp policy' do |controller_class = describe
end
end
- context 'when observability is disabled' do
- let(:csp) do
- ActionDispatch::ContentSecurityPolicy.new do |p|
- p.frame_src 'https://something.test'
+ describe 'frame-src' do
+ context 'when frame-src exists in the CSP config' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.frame_src 'https://something.test'
+ end
end
- end
- before do
- stub_feature_flags(observability_group_tab: false)
+ it 'appends the proper url to frame-src CSP directives' do
+ expect(subject).to include(
+ "frame-src https://something.test #{observability_url} #{signin_url} #{oauth_url}")
+ end
end
- it 'does not add observability urls to the csp header' do
- expect(subject).to include("frame-src https://something.test")
- expect(subject).not_to include("#{observability_url} #{signin_url} #{oauth_url}")
- end
- end
+ context 'when signin url is already present in the policy' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.frame_src signin_url
+ end
+ end
- context 'when frame-src exists in the CSP config' do
- let(:csp) do
- ActionDispatch::ContentSecurityPolicy.new do |p|
- p.frame_src 'https://something.test'
+ it 'does not append signin again' do
+ expect(subject).to include(
+ "frame-src #{signin_url} #{observability_url} #{oauth_url};")
end
end
- it 'appends the proper url to frame-src CSP directives' do
- expect(subject).to include(
- "frame-src https://something.test #{observability_url} #{signin_url} #{oauth_url}")
- end
- end
+ context 'when oauth url is already present in the policy' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.frame_src oauth_url
+ end
+ end
- context 'when signin is already present in the policy' do
- let(:csp) do
- ActionDispatch::ContentSecurityPolicy.new do |p|
- p.frame_src signin_url
+ it 'does not append oauth again' do
+ expect(subject).to include(
+ "frame-src #{oauth_url} #{observability_url} #{signin_url};")
end
end
- it 'does not append signin again' do
- expect(subject).to include(
- "frame-src #{signin_url} #{observability_url} #{oauth_url};")
- end
- end
+ context 'when default-src exists in the CSP config' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.default_src 'https://something.test'
+ end
+ end
+
+ it 'does not change default-src' do
+ expect(subject).to include(
+ "default-src https://something.test;")
+ end
- context 'when oauth is already present in the policy' do
- let(:csp) do
- ActionDispatch::ContentSecurityPolicy.new do |p|
- p.frame_src oauth_url
+ it 'appends the proper url to frame-src CSP directives' do
+ expect(subject).to include(
+ "frame-src https://something.test #{observability_url} #{signin_url} #{oauth_url}")
end
end
- it 'does not append oauth again' do
- expect(subject).to include(
- "frame-src #{oauth_url} #{observability_url} #{signin_url};")
+ context 'when frame-src and default-src exist in the CSP config' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.default_src 'https://something_default.test'
+ p.frame_src 'https://something.test'
+ end
+ end
+
+ it 'appends to frame-src CSP directives' do
+ expect(subject).to include(
+ "frame-src https://something.test #{observability_url} #{signin_url} #{oauth_url}")
+ expect(subject).to include(
+ "default-src https://something_default.test")
+ end
end
end
- context 'when default-src exists in the CSP config' do
- let(:csp) do
- ActionDispatch::ContentSecurityPolicy.new do |p|
- p.default_src 'https://something.test'
+ describe 'connect-src' do
+ context 'when connect-src exists in the CSP config' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.connect_src 'https://something.test'
+ end
end
- end
- it 'does not change default-src' do
- expect(subject).to include(
- "default-src https://something.test;")
+ it 'appends the proper url to connect-src CSP directives' do
+ expect(subject).to include(
+ "connect-src https://something.test localhost #{observability_url}")
+ end
end
- it 'appends the proper url to frame-src CSP directives' do
- expect(subject).to include(
- "frame-src https://something.test #{observability_url} #{signin_url} #{oauth_url}")
- end
- end
+ context 'when default-src exists in the CSP config' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.default_src 'https://something.test'
+ end
+ end
+
+ it 'does not change default-src' do
+ expect(subject).to include(
+ "default-src https://something.test;")
+ end
- context 'when frame-src and default-src exist in the CSP config' do
- let(:csp) do
- ActionDispatch::ContentSecurityPolicy.new do |p|
- p.default_src 'https://something_default.test'
- p.frame_src 'https://something.test'
+ it 'appends the proper url to connect-src CSP directives' do
+ expect(subject).to include(
+ "connect-src https://something.test localhost #{observability_url}")
end
end
- it 'appends to frame-src CSP directives' do
- expect(subject).to include(
- "frame-src https://something.test #{observability_url} #{signin_url} #{oauth_url}")
- expect(subject).to include(
- "default-src https://something_default.test")
+ context 'when connect-src and default-src exist in the CSP config' do
+ let(:csp) do
+ ActionDispatch::ContentSecurityPolicy.new do |p|
+ p.default_src 'https://something_default.test'
+ p.connect_src 'https://something.test'
+ end
+ end
+
+ it 'appends to connect-src CSP directives' do
+ expect(subject).to include(
+ "connect-src https://something.test localhost #{observability_url}")
+ expect(subject).to include(
+ "default-src https://something_default.test")
+ end
end
end
end
diff --git a/spec/uploaders/avatar_uploader_spec.rb b/spec/uploaders/avatar_uploader_spec.rb
index e472ac46e66..bba7eb78f99 100644
--- a/spec/uploaders/avatar_uploader_spec.rb
+++ b/spec/uploaders/avatar_uploader_spec.rb
@@ -47,7 +47,7 @@ RSpec.describe AvatarUploader do
end
end
- context 'accept whitelist file content type' do
+ context 'accept allowlist file content type' do
# We need to feed through a valid path, but we force the parsed mime type
# in a stub below so we can set any path.
let_it_be(:path) { File.join('spec', 'fixtures', 'video_sample.mp4') }
@@ -61,13 +61,13 @@ RSpec.describe AvatarUploader do
end
end
- context 'upload non-whitelisted file content type' do
+ context 'upload denylisted file content type' do
let_it_be(:path) { File.join('spec', 'fixtures', 'sanitized.svg') }
it_behaves_like 'denied carrierwave upload'
end
- context 'upload misnamed non-whitelisted file content type' do
+ context 'upload misnamed denylisted file content type' do
let_it_be(:path) { File.join('spec', 'fixtures', 'not_a_png.png') }
it_behaves_like 'denied carrierwave upload'
diff --git a/spec/uploaders/design_management/design_v432x230_uploader_spec.rb b/spec/uploaders/design_management/design_v432x230_uploader_spec.rb
index f3dd77d67a0..3991058b32d 100644
--- a/spec/uploaders/design_management/design_v432x230_uploader_spec.rb
+++ b/spec/uploaders/design_management/design_v432x230_uploader_spec.rb
@@ -58,7 +58,7 @@ RSpec.describe DesignManagement::DesignV432x230Uploader do
)
end
- context 'accept whitelist file content type' do
+ context 'accept allowlisted file content type' do
# We need to feed through a valid path, but we force the parsed mime type
# in a stub below so we can set any path.
let_it_be(:path) { File.join('spec', 'fixtures', 'dk.png') }
@@ -72,13 +72,13 @@ RSpec.describe DesignManagement::DesignV432x230Uploader do
end
end
- context 'upload non-whitelisted file content type' do
+ context 'upload denylisted file content type' do
let_it_be(:path) { File.join('spec', 'fixtures', 'logo_sample.svg') }
it_behaves_like 'denied carrierwave upload'
end
- context 'upload misnamed non-whitelisted file content type' do
+ context 'upload misnamed denylisted file content type' do
let_it_be(:path) { File.join('spec', 'fixtures', 'not_a_png.png') }
it_behaves_like 'denied carrierwave upload'
diff --git a/spec/uploaders/favicon_uploader_spec.rb b/spec/uploaders/favicon_uploader_spec.rb
index 7f452075293..ab14397c27d 100644
--- a/spec/uploaders/favicon_uploader_spec.rb
+++ b/spec/uploaders/favicon_uploader_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe FaviconUploader do
let_it_be(:model) { build_stubbed(:user) }
let_it_be(:uploader) { described_class.new(model, :favicon) }
- context 'accept whitelist file content type' do
+ context 'accept allowlist file content type' do
include_context 'ignore extension allowlist check'
# We need to feed through a valid path, but we force the parsed mime type
@@ -22,7 +22,7 @@ RSpec.describe FaviconUploader do
end
end
- context 'upload non-whitelisted file content type' do
+ context 'upload denylisted file content type' do
include_context 'ignore extension allowlist check'
let_it_be(:path) { File.join('spec', 'fixtures', 'sanitized.svg') }
@@ -30,7 +30,7 @@ RSpec.describe FaviconUploader do
it_behaves_like 'denied carrierwave upload'
end
- context 'upload misnamed non-whitelisted file content type' do
+ context 'upload misnamed denylisted file content type' do
include_context 'ignore extension allowlist check'
let_it_be(:path) { File.join('spec', 'fixtures', 'not_a_png.png') }
diff --git a/spec/validators/cron_validator_spec.rb b/spec/validators/cron_validator_spec.rb
index bd7fe242957..52a57f6e160 100644
--- a/spec/validators/cron_validator_spec.rb
+++ b/spec/validators/cron_validator_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe CronValidator do
expect(subject.valid?).to be_falsy
end
- context 'cron field is not whitelisted' do
+ context 'cron field is not allowlisted' do
subject do
Class.new do
include ActiveModel::Model
@@ -43,7 +43,7 @@ RSpec.describe CronValidator do
it 'raises an error' do
subject.cron_partytime = '0 23 * * 5'
- expect { subject.valid? }.to raise_error(StandardError, "Non-whitelisted attribute")
+ expect { subject.valid? }.to raise_error(StandardError, "Non-allowlisted attribute")
end
end
end