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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-07-04 15:10:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-04 15:10:11 +0300
commitcef4494e260d221524fc4e7e1d06d7554fdc7daa (patch)
tree711ecf05d532c728c8f255fb208c20d68d05113b
parent5f95234f7babb69685710dbfc637f29eeac2a917 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_todo/layout/first_hash_element_indentation.yml1
-rw-r--r--.rubocop_todo/layout/line_length.yml1
-rw-r--r--.rubocop_todo/lint/empty_block.yml1
-rw-r--r--.rubocop_todo/rspec/described_class.yml1
-rw-r--r--.rubocop_todo/rspec/missing_feature_category.yml2
-rw-r--r--.rubocop_todo/rspec/verified_doubles.yml1
-rw-r--r--app/assets/javascripts/content_editor/components/formatting_toolbar.vue41
-rw-r--r--app/assets/javascripts/content_editor/components/toolbar_table_button.vue83
-rw-r--r--app/assets/javascripts/pages/projects/blob/show/index.js2
-rw-r--r--app/assets/javascripts/repository/components/blob_content_viewer.vue26
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/index.js8
-rw-r--r--app/assets/javascripts/repository/index.js8
-rw-r--r--app/assets/javascripts/repository/mixins/highlight_mixin.js5
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue9
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js4
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_lines.js20
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue3
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_utils.js10
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_worker.js (renamed from app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight.js)0
-rw-r--r--app/controllers/projects/blob_controller.rb1
-rw-r--r--app/controllers/projects/tree_controller.rb1
-rw-r--r--app/controllers/projects_controller.rb1
-rw-r--r--app/experiments/concerns/project_commit_count.rb21
-rw-r--r--app/graphql/resolvers/alert_management/http_integrations_resolver.rb2
-rw-r--r--app/graphql/resolvers/alert_management/integrations_resolver.rb2
-rw-r--r--app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb8
-rw-r--r--app/models/issue.rb29
-rw-r--r--config/application.rb29
-rw-r--r--config/feature_flags/development/highlight_js_worker.yml (renamed from config/feature_flags/development/issue_type_uses_work_item_types_table.yml)10
-rw-r--r--config/webpack.config.js28
-rw-r--r--doc/development/integrations/secure.md9
-rw-r--r--doc/user/enterprise_user/index.md2
-rw-r--r--doc/user/search/index.md38
-rw-r--r--lib/gitlab/ci/project_config/bridge.rb5
-rw-r--r--locale/gitlab.pot13
-rw-r--r--spec/experiments/concerns/project_commit_count_spec.rb41
-rw-r--r--spec/frontend/content_editor/components/formatting_toolbar_spec.js25
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js3
-rw-r--r--spec/frontend/repository/mixins/highlight_mixin_spec.js5
-rw-r--r--spec/frontend/search/topbar/components/app_spec.js16
-rw-r--r--spec/frontend/vue_shared/components/markdown/header_spec.js33
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/highlight_util_spec.js11
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/plugins/wrap_lines_spec.js12
-rw-r--r--spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb3
-rw-r--r--spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb3
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb2
-rw-r--r--spec/models/issue_spec.rb60
-rw-r--r--spec/simplecov_env.rb9
-rw-r--r--spec/support/rspec_order_todo.yml2
49 files changed, 370 insertions, 280 deletions
diff --git a/.rubocop_todo/layout/first_hash_element_indentation.yml b/.rubocop_todo/layout/first_hash_element_indentation.yml
index 007616b40b1..5f586cc6206 100644
--- a/.rubocop_todo/layout/first_hash_element_indentation.yml
+++ b/.rubocop_todo/layout/first_hash_element_indentation.yml
@@ -9,7 +9,6 @@ Layout/FirstHashElementIndentation:
- 'app/controllers/projects/badges_controller.rb'
- 'app/controllers/projects/merge_requests_controller.rb'
- 'app/controllers/repositories/lfs_locks_api_controller.rb'
- - 'app/experiments/concerns/project_commit_count.rb'
- 'app/graphql/mutations/notes/create/diff_note.rb'
- 'app/graphql/mutations/notes/create/image_diff_note.rb'
- 'app/graphql/mutations/notes/create/note.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 99d866627d0..ed2245f39e0 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -3210,7 +3210,6 @@ Layout/LineLength:
- 'spec/controllers/uploads_controller_spec.rb'
- 'spec/db/schema_spec.rb'
- 'spec/deprecation_toolkit_env.rb'
- - 'spec/experiments/concerns/project_commit_count_spec.rb'
- 'spec/factories/ci/job_artifacts.rb'
- 'spec/factories/ci/pipelines.rb'
- 'spec/factories/ci/reports/codequality_degradations.rb'
diff --git a/.rubocop_todo/lint/empty_block.yml b/.rubocop_todo/lint/empty_block.yml
index 5751ca7641f..dbcef42eab4 100644
--- a/.rubocop_todo/lint/empty_block.yml
+++ b/.rubocop_todo/lint/empty_block.yml
@@ -4,7 +4,6 @@ Lint/EmptyBlock:
- 'app/controllers/groups/boards_controller.rb'
- 'app/controllers/projects/boards_controller.rb'
- 'app/controllers/projects/pipelines_controller.rb'
- - 'app/experiments/logged_out_marketing_header_experiment.rb'
- 'config/application.rb'
- 'ee/app/controllers/projects/learn_gitlab_controller.rb'
- 'ee/spec/factories/incident_management/escalation_rules.rb'
diff --git a/.rubocop_todo/rspec/described_class.yml b/.rubocop_todo/rspec/described_class.yml
index 94ef19d7cfe..7f0db541ab0 100644
--- a/.rubocop_todo/rspec/described_class.yml
+++ b/.rubocop_todo/rspec/described_class.yml
@@ -46,7 +46,6 @@ RSpec/DescribedClass:
- 'spec/config/settings_spec.rb'
- 'spec/controllers/repositories/git_http_controller_spec.rb'
- 'spec/experiments/application_experiment_spec.rb'
- - 'spec/experiments/concerns/project_commit_count_spec.rb'
- 'spec/frontend/fixtures/timezones.rb'
- 'spec/graphql/gitlab_schema_spec.rb'
- 'spec/graphql/graphql_triggers_spec.rb'
diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml
index b03146e74ae..5dab0b6c5e1 100644
--- a/.rubocop_todo/rspec/missing_feature_category.yml
+++ b/.rubocop_todo/rspec/missing_feature_category.yml
@@ -1801,8 +1801,6 @@ RSpec/MissingFeatureCategory:
- 'spec/dependencies/omniauth_saml_spec.rb'
- 'spec/docs_screenshots/container_registry_docs.rb'
- 'spec/docs_screenshots/wiki_docs.rb'
- - 'spec/experiments/concerns/project_commit_count_spec.rb'
- - 'spec/experiments/force_company_trial_experiment_spec.rb'
- 'spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb'
- 'spec/experiments/ios_specific_templates_experiment_spec.rb'
- 'spec/features/admin/dashboard_spec.rb'
diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml
index d5430dabbf0..3b4d4bc9e94 100644
--- a/.rubocop_todo/rspec/verified_doubles.yml
+++ b/.rubocop_todo/rspec/verified_doubles.yml
@@ -260,7 +260,6 @@ RSpec/VerifiedDoubles:
- 'spec/controllers/projects/snippets_controller_spec.rb'
- 'spec/controllers/sessions_controller_spec.rb'
- 'spec/dependencies/omniauth_saml_spec.rb'
- - 'spec/experiments/concerns/project_commit_count_spec.rb'
- 'spec/factories/ci/job_artifacts.rb'
- 'spec/features/admin/admin_system_info_spec.rb'
- 'spec/features/clusters/create_agent_spec.rb'
diff --git a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
index b6c16e9f306..4f26ed7fac5 100644
--- a/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
+++ b/app/assets/javascripts/content_editor/components/formatting_toolbar.vue
@@ -1,5 +1,7 @@
<script>
import CommentTemplatesDropdown from '~/vue_shared/components/markdown/comment_templates_dropdown.vue';
+import { __, sprintf } from '~/locale';
+import { getModifierKey } from '~/constants';
import trackUIControl from '../services/track_ui_control';
import ToolbarButton from './toolbar_button.vue';
import ToolbarAttachmentButton from './toolbar_attachment_button.vue';
@@ -32,6 +34,27 @@ export default {
required: false,
},
},
+ data() {
+ const modifierKey = getModifierKey();
+ const shiftKey = modifierKey === '⌘' ? '⇧' : 'Shift+';
+
+ return {
+ i18n: {
+ bold: sprintf(__('Bold (%{modifierKey}B)'), { modifierKey }),
+ italic: sprintf(__('Italic (%{modifierKey}I)'), { modifierKey }),
+ strike: sprintf(__('Strikethrough (%{modifierKey}%{shiftKey}X)'), {
+ modifierKey,
+ shiftKey,
+ }),
+ quote: __('Insert a quote'),
+ code: __('Code'),
+ link: sprintf(__('Insert link (%{modifierKey}K)'), { modifierKey }),
+ bulletList: __('Add a bullet list'),
+ numberedList: __('Add a numbered list'),
+ taskList: __('Add a checklist'),
+ },
+ };
+ },
methods: {
trackToolbarControlExecution({ contentType, value }) {
trackUIControl({ property: contentType, value });
@@ -58,7 +81,7 @@ export default {
content-type="bold"
icon-name="bold"
editor-command="toggleBold"
- :label="__('Bold text')"
+ :label="i18n.bold"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -66,7 +89,7 @@ export default {
content-type="italic"
icon-name="italic"
editor-command="toggleItalic"
- :label="__('Italic text')"
+ :label="i18n.italic"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -74,7 +97,7 @@ export default {
content-type="strike"
icon-name="strikethrough"
editor-command="toggleStrike"
- :label="__('Strikethrough')"
+ :label="i18n.strike"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -82,7 +105,7 @@ export default {
content-type="blockquote"
icon-name="quote"
editor-command="toggleBlockquote"
- :label="__('Insert a quote')"
+ :label="i18n.quote"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -90,7 +113,7 @@ export default {
content-type="code"
icon-name="code"
editor-command="toggleCode"
- :label="__('Code')"
+ :label="i18n.code"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -98,7 +121,7 @@ export default {
content-type="link"
icon-name="link"
editor-command="editLink"
- :label="__('Insert link')"
+ :label="i18n.link"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -107,7 +130,7 @@ export default {
icon-name="list-bulleted"
class="gl-display-none gl-sm-display-inline"
editor-command="toggleBulletList"
- :label="__('Add a bullet list')"
+ :label="i18n.bulletList"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -116,7 +139,7 @@ export default {
icon-name="list-numbered"
class="gl-display-none gl-sm-display-inline"
editor-command="toggleOrderedList"
- :label="__('Add a numbered list')"
+ :label="i18n.numberedList"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
@@ -125,7 +148,7 @@ export default {
icon-name="list-task"
class="gl-display-none gl-sm-display-inline"
editor-command="toggleTaskList"
- :label="__('Add a checklist')"
+ :label="i18n.taskList"
@execute="trackToolbarControlExecution"
/>
<toolbar-table-button data-testid="table" @execute="trackToolbarControlExecution" />
diff --git a/app/assets/javascripts/content_editor/components/toolbar_table_button.vue b/app/assets/javascripts/content_editor/components/toolbar_table_button.vue
index 771455dfe66..ab1546b9016 100644
--- a/app/assets/javascripts/content_editor/components/toolbar_table_button.vue
+++ b/app/assets/javascripts/content_editor/components/toolbar_table_button.vue
@@ -1,5 +1,6 @@
<script>
-import { GlDisclosureDropdown, GlButton, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
+import { GlDisclosureDropdown, GlButton, GlTooltip } from '@gitlab/ui';
+import { uniqueId } from 'lodash';
import { __, sprintf } from '~/locale';
import { clamp } from '../services/utils';
@@ -14,13 +15,12 @@ export default {
components: {
GlButton,
GlDisclosureDropdown,
- },
- directives: {
GlTooltip,
},
inject: ['tiptapEditor'],
data() {
return {
+ toggleId: uniqueId('dropdown-toggle-btn-'),
maxRows: MIN_ROWS,
maxCols: MIN_COLS,
rows: 1,
@@ -82,44 +82,47 @@ export default {
};
</script>
<template>
- <gl-disclosure-dropdown
- ref="dropdown"
- v-gl-tooltip
- size="small"
- category="tertiary"
- icon="table"
- no-caret
- :aria-label="__('Insert table')"
- :toggle-text="__('Insert table')"
- positioning-strategy="fixed"
- class="content-editor-table-dropdown gl-mr-3"
- text-sr-only
- :fluid-width="true"
- @shown="setFocus(1, 1)"
- >
- <div
- class="gl-p-3 gl-pt-2"
- role="grid"
- :aria-colcount="$options.MAX_COLS"
- :aria-rowcount="$options.MAX_ROWS"
+ <div class="gl-display-inline-flex gl-vertical-align-middle">
+ <gl-disclosure-dropdown
+ ref="dropdown"
+ :toggle-id="toggleId"
+ size="small"
+ category="tertiary"
+ icon="table"
+ no-caret
+ :aria-label="__('Insert table')"
+ :toggle-text="__('Insert table')"
+ positioning-strategy="fixed"
+ class="content-editor-table-dropdown gl-mr-3"
+ text-sr-only
+ :fluid-width="true"
+ @shown="setFocus(1, 1)"
>
- <div v-for="r of list(maxRows)" :key="r" class="gl-display-flex" role="row">
- <div v-for="c of list(maxCols)" :key="c" role="gridcell">
- <gl-button
- :ref="`table-${r}-${c}`"
- :class="{ 'active gl-bg-blue-50!': r <= rows && c <= cols }"
- :aria-label="getButtonLabel(r, c)"
- class="table-creator-grid-item gl-display-inline gl-rounded-0! gl-w-6! gl-h-6! gl-p-0!"
- @mouseover="setRowsAndCols(r, c)"
- @focus="setRowsAndCols(r, c)"
- @click="insertTable()"
- @keydown="onKeydown($event.key)"
- />
+ <div
+ class="gl-p-3 gl-pt-2"
+ role="grid"
+ :aria-colcount="$options.MAX_COLS"
+ :aria-rowcount="$options.MAX_ROWS"
+ >
+ <div v-for="r of list(maxRows)" :key="r" class="gl-display-flex" role="row">
+ <div v-for="c of list(maxCols)" :key="c" role="gridcell">
+ <gl-button
+ :ref="`table-${r}-${c}`"
+ :class="{ 'active gl-bg-blue-50!': r <= rows && c <= cols }"
+ :aria-label="getButtonLabel(r, c)"
+ class="table-creator-grid-item gl-display-inline gl-rounded-0! gl-w-6! gl-h-6! gl-p-0!"
+ @mouseover="setRowsAndCols(r, c)"
+ @focus="setRowsAndCols(r, c)"
+ @click="insertTable()"
+ @keydown="onKeydown($event.key)"
+ />
+ </div>
</div>
</div>
- </div>
- <div class="gl-border-t gl-px-4 gl-pt-3 gl-pb-2">
- {{ getButtonLabel(rows, cols) }}
- </div>
- </gl-disclosure-dropdown>
+ <div class="gl-border-t gl-px-4 gl-pt-3 gl-pb-2">
+ {{ getButtonLabel(rows, cols) }}
+ </div>
+ </gl-disclosure-dropdown>
+ <gl-tooltip :target="toggleId" placement="top">{{ __('Insert table') }}</gl-tooltip>
+ </div>
</template>
diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js
index f8dcf1a5c9c..0b0399ef271 100644
--- a/app/assets/javascripts/pages/projects/blob/show/index.js
+++ b/app/assets/javascripts/pages/projects/blob/show/index.js
@@ -18,6 +18,7 @@ import { generateRefDestinationPath } from '~/repository/utils/ref_switcher_util
import RefSelector from '~/ref/components/ref_selector.vue';
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
import { parseBoolean } from '~/lib/utils/common_utils';
+import HighlightWorker from '~/vue_shared/components/source_viewer/workers/highlight_worker?worker';
Vue.use(Vuex);
Vue.use(VueApollo);
@@ -78,6 +79,7 @@ if (viewBlobEl) {
router,
apolloProvider,
provide: {
+ highlightWorker: gon.features.highlightJsWorker ? new HighlightWorker() : null,
targetBranch,
originalBranch,
resourceId,
diff --git a/app/assets/javascripts/repository/components/blob_content_viewer.vue b/app/assets/javascripts/repository/components/blob_content_viewer.vue
index e056a822c8b..3d30b42b2aa 100644
--- a/app/assets/javascripts/repository/components/blob_content_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_content_viewer.vue
@@ -15,6 +15,7 @@ import CodeIntelligence from '~/code_navigation/components/app.vue';
import LineHighlighter from '~/blob/line_highlighter';
import blobInfoQuery from 'shared_queries/repository/blob_info.query.graphql';
import { addBlameLink } from '~/blob/blob_blame_link';
+import highlightMixin from '~/repository/mixins/highlight_mixin';
import projectInfoQuery from '../queries/project_info.query.graphql';
import getRefMixin from '../mixins/get_ref';
import userInfoQuery from '../queries/user_info.query.graphql';
@@ -36,7 +37,7 @@ export default {
CodeIntelligence,
AiGenie: () => import('ee_component/ai/components/ai_genie.vue'),
},
- mixins: [getRefMixin, glFeatureFlagMixin()],
+ mixins: [getRefMixin, glFeatureFlagMixin(), highlightMixin],
inject: {
originalBranch: {
default: '',
@@ -81,7 +82,10 @@ export default {
shouldFetchRawText: Boolean(this.glFeatures.highlightJs),
};
},
- result() {
+ result({ data }) {
+ const blob = data.project?.repository?.blobs?.nodes[0] || {};
+ this.initHighlightWorker(blob);
+
const urlHash = getLocationHash();
const plain = this.$route?.query?.plain;
@@ -170,7 +174,14 @@ export default {
},
blobViewer() {
const { fileType } = this.viewer;
- return this.shouldLoadLegacyViewer ? null : loadViewer(fileType, this.isUsingLfs);
+ return this.shouldLoadLegacyViewer
+ ? null
+ : loadViewer(
+ fileType,
+ this.isUsingLfs,
+ this.glFeatures.highlightJsWorker,
+ this.blobInfo.language,
+ );
},
shouldLoadLegacyViewer() {
const isTextFile = this.viewer.fileType === TEXT_FILE_TYPE && !this.glFeatures.highlightJs;
@@ -386,7 +397,14 @@ export default {
:loading="isLoadingLegacyViewer"
:data-loading="isRenderingLegacyTextViewer"
/>
- <component :is="blobViewer" v-else :blob="blobInfo" class="blob-viewer" @error="onError" />
+ <component
+ :is="blobViewer"
+ v-else
+ :blob="blobInfo"
+ :chunks="chunks"
+ class="blob-viewer"
+ @error="onError"
+ />
<code-intelligence
v-if="blobViewer || legacyViewerLoaded"
:code-navigation-path="blobInfo.codeNavigationPath"
diff --git a/app/assets/javascripts/repository/components/blob_viewers/index.js b/app/assets/javascripts/repository/components/blob_viewers/index.js
index b749702972f..368f42e0064 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/index.js
+++ b/app/assets/javascripts/repository/components/blob_viewers/index.js
@@ -15,9 +15,15 @@ const viewers = {
geo_json: () => import('./geo_json/geo_json_viewer.vue'),
};
-export const loadViewer = (type, isUsingLfs) => {
+export const loadViewer = (type, isUsingLfs, hljsWorkerEnabled, language) => {
let viewer = viewers[type];
+ if (hljsWorkerEnabled && language === 'json') {
+ // The New Source Viewer currently only supports JSON files.
+ // More language support will be added in: https://gitlab.com/gitlab-org/gitlab/-/issues/415753
+ viewer = () => import('~/vue_shared/components/source_viewer/source_viewer_new.vue');
+ }
+
if (!viewer && isUsingLfs) {
viewer = viewers.lfs;
}
diff --git a/app/assets/javascripts/repository/index.js b/app/assets/javascripts/repository/index.js
index befd731a61b..c1e0104c6ac 100644
--- a/app/assets/javascripts/repository/index.js
+++ b/app/assets/javascripts/repository/index.js
@@ -8,6 +8,7 @@ import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
import PerformancePlugin from '~/performance/vue_performance_plugin';
import createStore from '~/code_navigation/store';
import RefSelector from '~/ref/components/ref_selector.vue';
+import HighlightWorker from '~/vue_shared/components/source_viewer/workers/highlight_worker?worker';
import App from './components/app.vue';
import Breadcrumbs from './components/breadcrumbs.vue';
import DirectoryDownloadLinks from './components/directory_download_links.vue';
@@ -290,7 +291,12 @@ export default function setupVueRepositoryList() {
store: createStore(),
router,
apolloProvider,
- provide: { resourceId, userId, explainCodeAvailable: parseBoolean(explainCodeAvailable) },
+ provide: {
+ resourceId,
+ userId,
+ explainCodeAvailable: parseBoolean(explainCodeAvailable),
+ highlightWorker: gon.features.highlightJsWorker ? new HighlightWorker() : null,
+ },
render(h) {
return h(App);
},
diff --git a/app/assets/javascripts/repository/mixins/highlight_mixin.js b/app/assets/javascripts/repository/mixins/highlight_mixin.js
index 95d0c55bb04..232cb0dac03 100644
--- a/app/assets/javascripts/repository/mixins/highlight_mixin.js
+++ b/app/assets/javascripts/repository/mixins/highlight_mixin.js
@@ -1,4 +1,3 @@
-import { nextTick } from 'vue';
import {
LEGACY_FALLBACKS,
EVENT_ACTION,
@@ -39,7 +38,7 @@ export default {
this?.onError();
},
initHighlightWorker({ rawTextBlob, language, simpleViewer }) {
- if (simpleViewer?.fileType !== TEXT_FILE_TYPE) return;
+ if (simpleViewer?.fileType !== TEXT_FILE_TYPE || !this.glFeatures.highlightJsWorker) return;
if (this.isUnsupportedLanguage(language)) {
this.handleUnsupportedLanguage(language);
@@ -97,7 +96,7 @@ export default {
}
// Line numbers in the DOM needs to update first based on changes made to `chunks`.
- await nextTick();
+ await this.$nextTick();
const lineHighlighter = new LineHighlighter({ scrollBehavior: 'auto' });
lineHighlighter.highlightHash(hash);
diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index c794ed951ef..0899b752cbc 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -97,10 +97,12 @@ export default {
},
},
data() {
+ const modifierKey = getModifierKey();
return {
tag: '> ',
suggestPopoverVisible: false,
- modifierKey: getModifierKey(),
+ modifierKey,
+ shiftKey: modifierKey === '⌘' ? '⇧' : 'Shift+',
};
},
computed: {
@@ -346,8 +348,9 @@ export default {
tag="~~"
:button-title="
/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
- sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)'), {
- modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
+ sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}%{shiftKey}X)'), {
+ modifierKey,
+ shiftKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */,
})
"
:shortcuts="$options.shortcuts.strikethrough"
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js
index d694adf7147..3f8a9258fc3 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/index.js
@@ -1,6 +1,7 @@
import wrapChildNodes from './wrap_child_nodes';
import linkDependencies from './link_dependencies';
import wrapBidiChars from './wrap_bidi_chars';
+import wrapLines from './wrap_lines';
export const HLJS_ON_AFTER_HIGHLIGHT = 'after:highlight';
@@ -11,10 +12,11 @@ export const HLJS_ON_AFTER_HIGHLIGHT = 'after:highlight';
*
* @param {Object} hljs - the Highlight.js instance.
*/
-export const registerPlugins = (hljs, fileType, rawContent) => {
+export const registerPlugins = (hljs, fileType, rawContent, shouldWrapLines) => {
hljs.addPlugin({ [HLJS_ON_AFTER_HIGHLIGHT]: wrapChildNodes });
hljs.addPlugin({ [HLJS_ON_AFTER_HIGHLIGHT]: wrapBidiChars });
hljs.addPlugin({
[HLJS_ON_AFTER_HIGHLIGHT]: (result) => linkDependencies(result, fileType, rawContent),
});
+ if (shouldWrapLines) hljs.addPlugin({ [HLJS_ON_AFTER_HIGHLIGHT]: wrapLines });
};
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_lines.js b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_lines.js
new file mode 100644
index 00000000000..384ada30001
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/wrap_lines.js
@@ -0,0 +1,20 @@
+/**
+ * Highlight.js plugin for wrapping lines in the correct classes and attributes.
+ * Needed for things like hash highlighting to work.
+ *
+ * Plugin API: https://github.com/highlightjs/highlight.js/blob/main/docs/plugin-api.rst
+ *
+ * @param {Object} Result - an object that represents the highlighted result from Highlight.js
+ */
+
+function wrapLine(content, number, language) {
+ return `<div id="LC${number}" lang="${language}" class="line">${content}</div>`;
+}
+
+export default (result) => {
+ // eslint-disable-next-line no-param-reassign
+ result.value = result.value
+ .split(/\r?\n/)
+ .map((content, index) => wrapLine(content, index + 1, result.language))
+ .join('\n');
+};
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue
index 7e18c8414d5..4d4d15a12b4 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer_new.vue
@@ -19,9 +19,6 @@ export default {
SafeHtml,
},
mixins: [Tracking.mixin()],
- inject: {
- highlightWorker: { default: null },
- },
props: {
blob: {
type: Object,
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_utils.js b/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_utils.js
index 142c135e9c1..8d8e945cd5f 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_utils.js
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_utils.js
@@ -1,9 +1,13 @@
-import hljs from 'highlight.js';
+import hljs from 'highlight.js/lib/core';
+import json from 'highlight.js/lib/languages/json';
import { registerPlugins } from '../plugins/index';
import { LINES_PER_CHUNK, NEWLINE, ROUGE_TO_HLJS_LANGUAGE_MAP } from '../constants';
-const initHighlightJs = (fileType, content) => {
- registerPlugins(hljs, fileType, content);
+const initHighlightJs = (fileType, content, language) => {
+ // The Highlight Worker is currently scoped to JSON files.
+ // See the following issue for more: https://gitlab.com/gitlab-org/gitlab/-/issues/415753
+ hljs.registerLanguage(language, json);
+ registerPlugins(hljs, fileType, content, true);
};
const splitByLineBreaks = (content = '') => content.split(/\r?\n/);
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight.js b/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_worker.js
index 535e857d7a9..535e857d7a9 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight.js
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/workers/highlight_worker.js
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index a60cc5301e2..b41e4d11d24 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -49,6 +49,7 @@ class Projects::BlobController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
+ push_frontend_feature_flag(:highlight_js_worker, @project)
push_frontend_feature_flag(:explain_code_chat, current_user)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index d2a820d93b0..b961339111b 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -19,6 +19,7 @@ class Projects::TreeController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
+ push_frontend_feature_flag(:highlight_js_worker, @project)
push_frontend_feature_flag(:explain_code_chat, current_user)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index bc4831d7772..51f6158d9c0 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -38,6 +38,7 @@ class ProjectsController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:highlight_js, @project)
+ push_frontend_feature_flag(:highlight_js_worker, @project)
push_frontend_feature_flag(:remove_monitor_metrics, @project)
push_frontend_feature_flag(:explain_code_chat, current_user)
push_frontend_feature_flag(:ci_namespace_catalog_experimental, @project)
diff --git a/app/experiments/concerns/project_commit_count.rb b/app/experiments/concerns/project_commit_count.rb
deleted file mode 100644
index 3f08538c21f..00000000000
--- a/app/experiments/concerns/project_commit_count.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-module ProjectCommitCount
- include Gitlab::Git::WrapsGitalyErrors
-
- def commit_count_for(project, default_count: 0, max_count: nil, **exception_details)
- raw_repo = project.repository&.raw_repository
- root_ref = raw_repo&.root_ref
-
- return default_count unless root_ref
-
- Gitlab::GitalyClient::CommitService.new(raw_repo).commit_count(root_ref, {
- all: true, # include all branches
- max_count: max_count # limit as an optimization
- })
- rescue StandardError => e
- Gitlab::ErrorTracking.track_exception(e, exception_details)
-
- default_count
- end
-end
diff --git a/app/graphql/resolvers/alert_management/http_integrations_resolver.rb b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
index 225e20bab83..ac04e0967e6 100644
--- a/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
+++ b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
@@ -35,7 +35,7 @@ module Resolvers
end
def http_integrations
- ::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute
+ ::AlertManagement::HttpIntegrationsFinder.new(project, { type_identifier: :http }).execute
end
end
end
diff --git a/app/graphql/resolvers/alert_management/integrations_resolver.rb b/app/graphql/resolvers/alert_management/integrations_resolver.rb
index a97650e95d9..9b20d3367f1 100644
--- a/app/graphql/resolvers/alert_management/integrations_resolver.rb
+++ b/app/graphql/resolvers/alert_management/integrations_resolver.rb
@@ -40,7 +40,7 @@ module Resolvers
def http_integrations
return [] unless http_integrations_allowed?
- ::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute
+ ::AlertManagement::HttpIntegrationsFinder.new(project, { type_identifier: :http }).execute
end
def prometheus_integrations_allowed?
diff --git a/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb b/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb
index 2ea7a02bf15..d9bcf39b818 100644
--- a/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb
+++ b/app/graphql/resolvers/concerns/issues/look_ahead_preloads.rb
@@ -20,17 +20,15 @@ module Issues
end
def preloads
- preload_hash = {
+ {
alert_management_alert: [:alert_management_alert],
assignees: [:assignees],
participants: Issue.participant_includes,
timelogs: [:timelogs],
customer_relations_contacts: { customer_relations_contacts: [:group] },
- escalation_status: [:incident_management_issuable_escalation_status]
+ escalation_status: [:incident_management_issuable_escalation_status],
+ type: :work_item_type
}
- preload_hash[:type] = :work_item_type if Feature.enabled?(:issue_type_uses_work_item_types_table)
-
- preload_hash
end
end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 0afe8916455..453c451cebf 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -204,24 +204,17 @@ class Issue < ApplicationRecord
scope :with_issue_type, ->(types) {
types = Array(types)
- if Feature.enabled?(:issue_type_uses_work_item_types_table)
- # Using != 1 since we also want the guard clause to handle empty arrays
- return joins(:work_item_type).where(work_item_types: { base_type: types }) if types.size != 1
+ # Using != 1 since we also want the guard clause to handle empty arrays
+ return joins(:work_item_type).where(work_item_types: { base_type: types }) if types.size != 1
- where(
- '"issues"."work_item_type_id" = (?)',
- WorkItems::Type.by_type(types.first).select(:id).limit(1)
- )
- else
- where(issue_type: types)
- end
+ # This optimization helps the planer use the correct indexes when filtering by a single type
+ where(
+ '"issues"."work_item_type_id" = (?)',
+ WorkItems::Type.by_type(types.first).select(:id).limit(1)
+ )
}
scope :without_issue_type, ->(types) {
- if Feature.enabled?(:issue_type_uses_work_item_types_table)
- joins(:work_item_type).where.not(work_item_types: { base_type: types })
- else
- where.not(issue_type: types)
- end
+ joins(:work_item_type).where.not(work_item_types: { base_type: types })
}
scope :public_only, -> { where(confidential: false) }
@@ -756,11 +749,7 @@ class Issue < ApplicationRecord
end
def issue_type
- if ::Feature.enabled?(:issue_type_uses_work_item_types_table)
- work_item_type_with_default.base_type
- else
- super
- end
+ work_item_type_with_default.base_type
end
def unsubscribe_email_participant(email)
diff --git a/config/application.rb b/config/application.rb
index 03c7a1ae24d..d20b60b9217 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -18,10 +18,7 @@ Bundler.require(*Rails.groups)
module Gitlab
class Application < Rails::Application
- config.load_defaults 6.1
-
- config.active_support.hash_digest_class = ::OpenSSL::Digest::SHA256
-
+ config.load_defaults 7.0
# This section contains configuration from Rails upgrades to override the new defaults so that we
# keep existing behavior.
#
@@ -31,6 +28,30 @@ module Gitlab
#
# To switch a setting to the new default value, we just need to delete the specific line here.
+ # Rails 7.0
+ config.action_controller.raise_on_open_redirects = false
+ config.action_controller.wrap_parameters_by_default = false
+ config.action_dispatch.default_headers = { "X-Frame-Options" => "SAMEORIGIN",
+ "X-XSS-Protection" => "1; mode=block",
+ "X-Content-Type-Options" => "nosniff",
+ "X-Download-Options" => "noopen",
+ "X-Permitted-Cross-Domain-Policies" => "none",
+ "Referrer-Policy" => "strict-origin-when-cross-origin" }
+
+ config.action_dispatch.return_only_request_media_type_on_content_type = true
+ config.action_mailer.smtp_timeout = nil # New default is 5
+ config.action_view.button_to_generates_button_tag = nil # New default is true
+ config.active_record.automatic_scope_inversing = nil # New default is true
+ config.active_record.verify_foreign_keys_for_fixtures = nil # New default is true
+ config.active_record.partial_inserts = true # New default is false
+ config.active_support.cache_format_version = nil # New default is 7.0
+ config.active_support.disable_to_s_conversion = false # New default is true
+ config.active_support.executor_around_test_case = nil # New default is true
+ config.active_support.isolation_level = nil # New default is thread
+ config.active_support.key_generator_hash_digest_class = nil # New default is OpenSSL::Digest::SHA256
+ config.active_support.remove_deprecated_time_with_zone_name = nil # New default is true
+ config.active_support.use_rfc4122_namespaced_uuids = nil # New default is true
+
# Rails 6.1
config.action_dispatch.cookies_same_site_protection = nil # New default is :lax
ActiveSupport.utc_to_local_returns_utc_offset_times = false
diff --git a/config/feature_flags/development/issue_type_uses_work_item_types_table.yml b/config/feature_flags/development/highlight_js_worker.yml
index 4ce66b7ab33..ee74cbb7004 100644
--- a/config/feature_flags/development/issue_type_uses_work_item_types_table.yml
+++ b/config/feature_flags/development/highlight_js_worker.yml
@@ -1,8 +1,8 @@
---
-name: issue_type_uses_work_item_types_table
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107690
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/386603
-milestone: '15.8'
+name: highlight_js_worker
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124276
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415755
+milestone: '16.2'
type: development
-group: group::project management
+group: group::source code
default_enabled: false
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 39052d29287..1c6ac0bc843 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -371,6 +371,20 @@ module.exports = {
loader: 'babel-loader',
},
{
+ test: /_worker\.js$/,
+ resourceQuery: /worker/,
+ use: [
+ {
+ loader: 'worker-loader',
+ options: {
+ name: '[name].[contenthash:8].worker.js',
+ inline: IS_DEV_SERVER,
+ },
+ },
+ 'babel-loader',
+ ],
+ },
+ {
test: /mermaid\/.*\.js?$/,
include: /node_modules/,
loader: 'babel-loader',
@@ -439,20 +453,6 @@ module.exports = {
options: { limit: 2048 },
},
{
- test: /_worker\.js$/,
- resourceQuery: /worker/,
- use: [
- {
- loader: 'worker-loader',
- options: {
- name: '[name].[contenthash:8].worker.js',
- inline: IS_DEV_SERVER,
- },
- },
- 'babel-loader',
- ],
- },
- {
test: /\.(worker(\.min)?\.js|pdf)$/,
exclude: /node_modules/,
loader: 'file-loader',
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index ee94e57a247..08316230954 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -626,19 +626,14 @@ This is addressed in [issue #7586](https://gitlab.com/gitlab-org/gitlab/-/issues
See also [deduplication process](../../user/application_security/vulnerability_report/pipeline.md#deduplication-process).
-##### Severity and confidence
+##### Severity
-The `severity` field describes how much the vulnerability impacts the software,
-whereas the `confidence` field describes how reliable the assessment of the vulnerability is.
+The `severity` field describes how badly the vulnerability impacts the software.
The severity is used to sort the vulnerabilities in the security dashboard.
The severity ranges from `Info` to `Critical`, but it can also be `Unknown`.
Valid values are: `Unknown`, `Info`, `Low`, `Medium`, `High`, or `Critical`
-The confidence ranges from `Low` to `Confirmed`, but it can also be `Unknown`,
-`Experimental` or even `Ignore` if the vulnerability is to be ignored.
-Valid values are: `Ignore`, `Unknown`, `Experimental`, `Low`, `Medium`, `High`, or `Confirmed`
-
`Unknown` values means that data is unavailable to determine it's actual value. Therefore, it may be `high`, `medium`, or `low`,
and needs to be investigated. We have [provided a chart](../../user/application_security/sast/analyzers.md#data-provided-by-analyzers)
of the available SAST Analyzers and what data is currently available.
diff --git a/doc/user/enterprise_user/index.md b/doc/user/enterprise_user/index.md
index ea320402dd7..a59a4213f74 100644
--- a/doc/user/enterprise_user/index.md
+++ b/doc/user/enterprise_user/index.md
@@ -10,7 +10,7 @@ type: reference
Enterprise users have user accounts that are administered by an organization that
has purchased a [GitLab subscription](../../subscriptions/index.md).
-Enterprise users are identified by the [**Enterprise** badge](../project/badges.md)
+Enterprise users are identified by the **Enterprise** badge
next to their names on the [Members list](../group/index.md#filter-and-sort-members-in-a-group).
## Provision an enterprise user
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index 0645fd56b73..10f8dd61497 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -99,6 +99,32 @@ To filter code search results by one or more languages:
1. On the code search page, on the left sidebar, select one or more languages.
1. On the left sidebar, select **Apply**.
+## Exclude search results
+
+### From archived projects
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121981) in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `search_projects_hide_archived`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `search_projects_hide_archived`. On GitLab.com, this feature is not available.
+
+Archived projects are included in search results by default. To exclude archived projects, ensure the `search_projects_hide_archived` flag is enabled.
+
+To include archived projects with `search_projects_hide_archived` enabled, you must add the parameter `include_archived=true` to the URL.
+
+### From issues in archived projects
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124846) in GitLab 16.2 [with a flag](../../administration/feature_flags.md) named `search_issues_hide_archived_projects`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `search_issues_hide_archived_projects`. On GitLab.com, this feature is not available.
+
+Issues in archived projects are included in search results by default. To exclude issues in archived projects, ensure the `search_issues_hide_archived_projects` flag is enabled.
+
+To include issues in archived projects with `search_issues_hide_archived_projects` enabled, you must add the parameter `include_archived=true` to the URL.
+
## Search for a project by full path
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/108906) in GitLab 15.9 [with a flag](../../administration/feature_flags.md) named `full_path_project_search`. Disabled by default.
@@ -112,18 +138,6 @@ For example:
- `gitlab-org/gitlab` searches for the `gitlab` project in the `gitlab-org` namespace.
- `gitlab-org/` displays autocomplete suggestions for projects that belong to the `gitlab-org` namespace.
-### Exclude archived projects from project search results
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121981) in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `search_projects_hide_archived`. Disabled by default.
-
-FLAG:
-On self-managed GitLab, by default this feature is not available. To make it available,
-ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `search_projects_hide_archived`. On GitLab.com, this feature is not available.
-
-Archived projects are included in project search results by default. To exclude archived projects, ensure the `search_projects_hide_archived` flag is enabled.
-
-To include archived projects with `search_projects_hide_archived` enabled, you must add the parameter `include_archived=true` to the URL.
-
## Search for a commit SHA
To search for a commit SHA:
diff --git a/lib/gitlab/ci/project_config/bridge.rb b/lib/gitlab/ci/project_config/bridge.rb
index c342ab2c215..45aa330508f 100644
--- a/lib/gitlab/ci/project_config/bridge.rb
+++ b/lib/gitlab/ci/project_config/bridge.rb
@@ -10,6 +10,11 @@ module Gitlab
pipeline_source_bridge.yaml_for_downstream
end
+ # Bridge.yaml_for_downstream injects an `include`
+ def internal_include_prepended?
+ true
+ end
+
def source
:bridge_source
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b7d1c1db37e..1ed0a415ad2 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -7904,6 +7904,9 @@ msgstr ""
msgid "Board|Loading epics"
msgstr ""
+msgid "Bold (%{modifierKey}B)"
+msgstr ""
+
msgid "Bold text"
msgstr ""
@@ -24345,7 +24348,7 @@ msgstr ""
msgid "Insert comment template"
msgstr ""
-msgid "Insert link"
+msgid "Insert link (%{modifierKey}K)"
msgstr ""
msgid "Insert or edit diagram"
@@ -25456,6 +25459,9 @@ msgstr ""
msgid "It's you"
msgstr ""
+msgid "Italic (%{modifierKey}I)"
+msgstr ""
+
msgid "Italic text"
msgstr ""
@@ -27838,6 +27844,9 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}%{shiftKey}X)"
+msgstr ""
+
msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
msgstr ""
@@ -44394,7 +44403,7 @@ msgstr ""
msgid "Store your files, plan your work, collaborate on code, and more."
msgstr ""
-msgid "Strikethrough"
+msgid "Strikethrough (%{modifierKey}%{shiftKey}X)"
msgstr ""
msgid "Strikethrough text"
diff --git a/spec/experiments/concerns/project_commit_count_spec.rb b/spec/experiments/concerns/project_commit_count_spec.rb
deleted file mode 100644
index f5969ad6241..00000000000
--- a/spec/experiments/concerns/project_commit_count_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ProjectCommitCount do
- let(:klass) { Class.include(ProjectCommitCount) }
- let(:instance) { klass.new }
-
- describe '#commit_count_for' do
- subject { instance.commit_count_for(project, default_count: 42, caller_info: :identifiable) }
-
- let(:project) { create(:project, :repository) }
-
- context 'when a root_ref exists' do
- it 'returns commit count from GitlayClient' do
- allow(Gitlab::GitalyClient).to receive(:call).and_call_original
- allow(Gitlab::GitalyClient).to receive(:call).with(anything, :commit_service, :count_commits, anything, anything)
- .and_return(double(count: 4))
-
- expect(subject).to eq(4)
- end
- end
-
- context 'when a root_ref does not exist' do
- let(:project) { create(:project, :empty_repo) }
-
- it 'returns the default_count' do
- expect(subject).to eq(42)
- end
- end
-
- it "handles exceptions by logging them with exception_details and returns the default_count" do
- allow(Gitlab::GitalyClient).to receive(:call).and_call_original
- allow(Gitlab::GitalyClient).to receive(:call).with(anything, :commit_service, :count_commits, anything, anything).and_raise(e = StandardError.new('_message_'))
-
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(e, { caller_info: :identifiable })
-
- expect(subject).to eq(42)
- end
- end
-end
diff --git a/spec/frontend/content_editor/components/formatting_toolbar_spec.js b/spec/frontend/content_editor/components/formatting_toolbar_spec.js
index 0e9dc8d6184..bff53375340 100644
--- a/spec/frontend/content_editor/components/formatting_toolbar_spec.js
+++ b/spec/frontend/content_editor/components/formatting_toolbar_spec.js
@@ -31,11 +31,12 @@ describe('content_editor/components/formatting_toolbar', () => {
describe.each`
testId | controlProps
${'text-styles'} | ${{}}
- ${'bold'} | ${{ contentType: 'bold', iconName: 'bold', label: 'Bold text', editorCommand: 'toggleBold' }}
- ${'italic'} | ${{ contentType: 'italic', iconName: 'italic', label: 'Italic text', editorCommand: 'toggleItalic' }}
- ${'strike'} | ${{ contentType: 'strike', iconName: 'strikethrough', label: 'Strikethrough', editorCommand: 'toggleStrike' }}
+ ${'bold'} | ${{ contentType: 'bold', iconName: 'bold', label: 'Bold (Ctrl+B)', editorCommand: 'toggleBold' }}
+ ${'italic'} | ${{ contentType: 'italic', iconName: 'italic', label: 'Italic (Ctrl+I)', editorCommand: 'toggleItalic' }}
+ ${'strike'} | ${{ contentType: 'strike', iconName: 'strikethrough', label: 'Strikethrough (Ctrl+Shift+X)', editorCommand: 'toggleStrike' }}
${'blockquote'} | ${{ contentType: 'blockquote', iconName: 'quote', label: 'Insert a quote', editorCommand: 'toggleBlockquote' }}
${'code'} | ${{ contentType: 'code', iconName: 'code', label: 'Code', editorCommand: 'toggleCode' }}
+ ${'link'} | ${{ contentType: 'link', iconName: 'link', label: 'Insert link (Ctrl+K)', editorCommand: 'editLink' }}
${'link'} | ${{}}
${'bullet-list'} | ${{ contentType: 'bulletList', iconName: 'list-bulleted', label: 'Add a bullet list', editorCommand: 'toggleBulletList' }}
${'ordered-list'} | ${{ contentType: 'orderedList', iconName: 'list-numbered', label: 'Add a numbered list', editorCommand: 'toggleOrderedList' }}
@@ -70,6 +71,24 @@ describe('content_editor/components/formatting_toolbar', () => {
});
});
+ describe('MacOS shortcuts', () => {
+ beforeEach(() => {
+ window.gl = { client: { isMac: true } };
+
+ buildWrapper();
+ });
+
+ it.each`
+ testId | label
+ ${'bold'} | ${'Bold (⌘B)'}
+ ${'italic'} | ${'Italic (⌘I)'}
+ ${'strike'} | ${'Strikethrough (⌘⇧X)'}
+ ${'link'} | ${'Insert link (⌘K)'}
+ `('shows label $label for $testId', ({ testId, label }) => {
+ expect(wrapper.findByTestId(testId).props('label')).toBe(label);
+ });
+ });
+
describe('when attachment button is hidden', () => {
it('does not show the attachment button', () => {
buildWrapper({ props: { hideAttachmentButton: true } });
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index 6a5ee8ba827..5b9542150f1 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -152,6 +152,7 @@ const createComponent = async (mockData = {}, mountFn = shallowMount, mockRoute
...inject,
glFeatures: {
highlightJs,
+ highlightJsWorker: false,
},
},
}),
@@ -405,7 +406,7 @@ describe('Blob content viewer component', () => {
await waitForPromises();
- expect(loadViewer).toHaveBeenCalledWith(viewer, false);
+ expect(loadViewer).toHaveBeenCalledWith(viewer, false, false, 'javascript');
expect(wrapper.findComponent(loadViewerReturnValue).exists()).toBe(true);
});
});
diff --git a/spec/frontend/repository/mixins/highlight_mixin_spec.js b/spec/frontend/repository/mixins/highlight_mixin_spec.js
index 5f872749581..56df6d99bd3 100644
--- a/spec/frontend/repository/mixins/highlight_mixin_spec.js
+++ b/spec/frontend/repository/mixins/highlight_mixin_spec.js
@@ -31,7 +31,10 @@ describe('HighlightMixin', () => {
const dummyComponent = {
mixins: [highlightMixin],
- inject: { highlightWorker: { default: workerMock } },
+ inject: {
+ highlightWorker: { default: workerMock },
+ glFeatures: { default: { highlightJsWorker: true } },
+ },
template: '<div>{{chunks[0]?.highlightedContent}}</div>',
created() {
this.initHighlightWorker({ rawTextBlob, simpleViewer, language });
diff --git a/spec/frontend/search/topbar/components/app_spec.js b/spec/frontend/search/topbar/components/app_spec.js
index 423ec6ff63b..9dc14b97ce0 100644
--- a/spec/frontend/search/topbar/components/app_spec.js
+++ b/spec/frontend/search/topbar/components/app_spec.js
@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import { MOCK_QUERY } from 'jest/search/mock_data';
+import { stubComponent } from 'helpers/stub_component';
import GlobalSearchTopbar from '~/search/topbar/components/app.vue';
import GroupFilter from '~/search/topbar/components/group_filter.vue';
import ProjectFilter from '~/search/topbar/components/project_filter.vue';
@@ -93,11 +94,20 @@ describe('GlobalSearchTopbar', () => {
});
it('dispatched correct click action', () => {
- const draweToggleSpy = jest.fn();
- wrapper.vm.$refs.markdownDrawer.toggleDrawer = draweToggleSpy;
+ const drawerToggleSpy = jest.fn();
+
+ createComponent(
+ { query: { repository_ref: '' } },
+ { elasticsearchEnabled: true, defaultBranchName: '' },
+ {
+ MarkdownDrawer: stubComponent(MarkdownDrawer, {
+ methods: { toggleDrawer: drawerToggleSpy },
+ }),
+ },
+ );
findSyntaxOptionButton().vm.$emit('click');
- expect(draweToggleSpy).toHaveBeenCalled();
+ expect(drawerToggleSpy).toHaveBeenCalled();
});
});
diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js
index 4738fd44128..eb728879fb7 100644
--- a/spec/frontend/vue_shared/components/markdown/header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/header_spec.js
@@ -72,6 +72,39 @@ describe('Markdown field header component', () => {
});
});
+ it('renders correct title on non MacOS systems', () => {
+ window.gl = {
+ client: {
+ isMac: false,
+ },
+ };
+
+ createWrapper();
+
+ const buttons = [
+ 'Insert suggestion',
+ 'Add bold text (Ctrl+B)',
+ 'Add italic text (Ctrl+I)',
+ 'Add strikethrough text (Ctrl+Shift+X)',
+ 'Insert a quote',
+ 'Insert code',
+ 'Add a link (Ctrl+K)',
+ 'Add a bullet list',
+ 'Add a numbered list',
+ 'Add a checklist',
+ 'Indent line (Ctrl+])',
+ 'Outdent line (Ctrl+[)',
+ 'Add a collapsible section',
+ 'Add a table',
+ 'Go full screen',
+ ];
+ const elements = findToolbarButtons();
+
+ elements.wrappers.forEach((buttonEl, index) => {
+ expect(buttonEl.props('buttonTitle')).toBe(buttons[index]);
+ });
+ });
+
it('renders "Attach a file or image" button using gl-button', () => {
const button = wrapper.findByTestId('button-attach-file');
diff --git a/spec/frontend/vue_shared/components/source_viewer/highlight_util_spec.js b/spec/frontend/vue_shared/components/source_viewer/highlight_util_spec.js
index d2dd4afe09e..49e3083f8ed 100644
--- a/spec/frontend/vue_shared/components/source_viewer/highlight_util_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/highlight_util_spec.js
@@ -1,10 +1,11 @@
-import hljs from 'highlight.js';
+import hljs from 'highlight.js/lib/core';
import { registerPlugins } from '~/vue_shared/components/source_viewer/plugins/index';
import { highlight } from '~/vue_shared/components/source_viewer/workers/highlight_utils';
import { LINES_PER_CHUNK, NEWLINE } from '~/vue_shared/components/source_viewer/constants';
-jest.mock('highlight.js', () => ({
+jest.mock('highlight.js/lib/core', () => ({
highlight: jest.fn().mockReturnValue({ value: 'highlighted content' }),
+ registerLanguage: jest.fn(),
}));
jest.mock('~/vue_shared/components/source_viewer/plugins/index', () => ({
@@ -14,11 +15,15 @@ jest.mock('~/vue_shared/components/source_viewer/plugins/index', () => ({
const fileType = 'text';
const rawContent = 'function test() { return true }; \n // newline';
const highlightedContent = 'highlighted content';
-const language = 'javascript';
+const language = 'json';
describe('Highlight utility', () => {
beforeEach(() => highlight(fileType, rawContent, language));
+ it('registers the language', () => {
+ expect(hljs.registerLanguage).toHaveBeenCalledWith(language, expect.any(Function));
+ });
+
it('registers the plugins', () => {
expect(registerPlugins).toHaveBeenCalled();
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/plugins/wrap_lines_spec.js b/spec/frontend/vue_shared/components/source_viewer/plugins/wrap_lines_spec.js
new file mode 100644
index 00000000000..def76856dba
--- /dev/null
+++ b/spec/frontend/vue_shared/components/source_viewer/plugins/wrap_lines_spec.js
@@ -0,0 +1,12 @@
+import wrapLines from '~/vue_shared/components/source_viewer/plugins/wrap_lines';
+
+describe('Highlight.js plugin for wrapping lines', () => {
+ it('mutates the input value by wrapping each line in a div with the correct attributes', () => {
+ const inputValue = `// some content`;
+ const outputValue = `<div id="LC1" lang="javascript" class="line">${inputValue}</div>`;
+ const hljsResultMock = { value: inputValue, language: 'javascript' };
+
+ wrapLines(hljsResultMock);
+ expect(hljsResultMock.value).toBe(outputValue);
+ });
+});
diff --git a/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb b/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb
index 0f40565c5d3..80234aaaacf 100644
--- a/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb
+++ b/spec/graphql/resolvers/alert_management/http_integrations_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::AlertManagement::HttpIntegrationsResolver do
+RSpec.describe Resolvers::AlertManagement::HttpIntegrationsResolver, feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:guest) { create(:user) }
@@ -13,6 +13,7 @@ RSpec.describe Resolvers::AlertManagement::HttpIntegrationsResolver do
let_it_be(:active_http_integration) { create(:alert_management_http_integration, project: project) }
let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) }
let_it_be(:other_proj_integration) { create(:alert_management_http_integration) }
+ let_it_be(:migrated_integration) { create(:alert_management_prometheus_integration, :legacy, project: project) }
let(:params) { {} }
diff --git a/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb b/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb
index 11114d41522..ed2e7d35ee3 100644
--- a/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb
+++ b/spec/graphql/resolvers/alert_management/integrations_resolver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Resolvers::AlertManagement::IntegrationsResolver do
+RSpec.describe Resolvers::AlertManagement::IntegrationsResolver, feature_category: :incident_management do
include GraphqlHelpers
let_it_be(:current_user) { create(:user) }
@@ -13,6 +13,7 @@ RSpec.describe Resolvers::AlertManagement::IntegrationsResolver do
let_it_be(:inactive_http_integration) { create(:alert_management_http_integration, :inactive, project: project) }
let_it_be(:other_proj_integration) { create(:alert_management_http_integration, project: project2) }
let_it_be(:other_proj_prometheus_integration) { create(:prometheus_integration, project: project2) }
+ let_it_be(:migrated_integration) { create(:alert_management_prometheus_integration, :legacy, project: project) }
let(:params) { {} }
diff --git a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
index a9a52972294..9c268d9039e 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Config::Content, feature_category: :
expect(pipeline.config_source).to eq 'bridge_source'
expect(command.config_content).to eq 'the-yaml'
- expect(command.pipeline_config.internal_include_prepended?).to eq(false)
+ expect(command.pipeline_config.internal_include_prepended?).to eq(true)
end
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 09c135a2e78..ecf9e4480eb 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -467,18 +467,6 @@ RSpec.describe Issue, feature_category: :team_planning do
expect(described_class.with_issue_type([]).to_sql).to include('WHERE 1=0')
end
end
-
- context 'when the issue_type_uses_work_item_types_table feature flag is disabled' do
- before do
- stub_feature_flags(issue_type_uses_work_item_types_table: false)
- end
-
- it 'uses the issue_type column for filtering' do
- expect do
- described_class.with_issue_type(:issue).to_a
- end.to make_queries_matching(/"issues"\."issue_type" = 0/)
- end
- end
end
describe '.without_issue_type' do
@@ -506,18 +494,6 @@ RSpec.describe Issue, feature_category: :team_planning do
}x
)
end
-
- context 'when the issue_type_uses_work_item_types_table feature flag is disabled' do
- before do
- stub_feature_flags(issue_type_uses_work_item_types_table: false)
- end
-
- it 'uses the issue_type column for filtering' do
- expect do
- described_class.without_issue_type(:issue).to_a
- end.to make_queries_matching(/"issues"\."issue_type" != 0/)
- end
- end
end
describe '.order_severity' do
@@ -1879,39 +1855,17 @@ RSpec.describe Issue, feature_category: :team_planning do
describe '#issue_type' do
let_it_be(:issue) { create(:issue) }
- context 'when the issue_type_uses_work_item_types_table feature flag is enabled' do
- it 'gets the type field from the work_item_types table' do
- expect(issue).to receive_message_chain(:work_item_type, :base_type)
-
- issue.issue_type
- end
-
- context 'when the issue is not persisted' do
- it 'uses the default work item type' do
- non_persisted_issue = build(:issue, work_item_type: nil)
+ it 'gets the type field from the work_item_types table' do
+ expect(issue).to receive_message_chain(:work_item_type, :base_type)
- expect(non_persisted_issue.issue_type).to eq(described_class::DEFAULT_ISSUE_TYPE.to_s)
- end
- end
+ issue.issue_type
end
- context 'when the issue_type_uses_work_item_types_table feature flag is disabled' do
- before do
- stub_feature_flags(issue_type_uses_work_item_types_table: false)
- end
-
- it 'does not get the value from the work_item_types table' do
- expect(issue).not_to receive(:work_item_type)
-
- issue.issue_type
- end
-
- context 'when the issue is not persisted' do
- it 'uses the default work item type' do
- non_persisted_issue = build(:issue, work_item_type: nil)
+ context 'when the issue is not persisted' do
+ it 'uses the default work item type' do
+ non_persisted_issue = build(:issue, work_item_type: nil)
- expect(non_persisted_issue.issue_type).to eq(described_class::DEFAULT_ISSUE_TYPE.to_s)
- end
+ expect(non_persisted_issue.issue_type).to eq(described_class::DEFAULT_ISSUE_TYPE.to_s)
end
end
end
diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb
index 3de44482e2e..78a78f5bcbf 100644
--- a/spec/simplecov_env.rb
+++ b/spec/simplecov_env.rb
@@ -62,16 +62,21 @@ module SimpleCovEnv
add_group 'Channels', 'app/channels' # Matches EE files as well
add_group 'Components', 'app/components' # Matches EE files as well
+ add_group 'Config', %w[/config /ee/config]
add_group 'Controllers', 'app/controllers' # Matches EE files as well
+ add_group 'Elastic migrations', 'ee/elastic'
+ add_group 'Enums', 'app/enums' # Matches EE files as well
add_group 'Events', 'app/events' # Matches EE files as well
add_group 'Experiments', 'app/experiments' # Matches EE files as well
add_group 'Finders', 'app/finders' # Matches EE files as well
+ add_group 'Fixtures', 'db/fixtures' # Matches EE files as well
add_group 'GraphQL', 'app/graphql' # Matches EE files as well
add_group 'Helpers', 'app/helpers' # Matches EE files as well
add_group 'Mailers', 'app/mailers' # Matches EE files as well
add_group 'Models', 'app/models' # Matches EE files as well
add_group 'Policies', 'app/policies' # Matches EE files as well
add_group 'Presenters', 'app/presenters' # Matches EE files as well
+ add_group 'Replicators', 'app/replicators' # Matches EE files as well
add_group 'Serializers', 'app/serializers' # Matches EE files as well
add_group 'Services', 'app/services' # Matches EE files as well
add_group 'Uploaders', 'app/uploaders' # Matches EE files as well
@@ -79,9 +84,9 @@ module SimpleCovEnv
add_group 'Views', 'app/views' # Matches EE files as well
add_group 'Workers', 'app/workers' # Matches EE files as well
add_group 'Initializers', %w[config/initializers config/initializers_before_autoloader] # Matches EE files as well
- add_group 'Migrations', %w[db/migrate db/optional_migrations db/post_migrate] # Matches EE files as well
+ add_group 'Migrations', %w[db/migrate db/optional_migrations db/post_migrate db/geo/migrate db/geo/post_migrate] # Matches EE files as well
add_group 'Libraries', %w[/lib /ee/lib]
- add_group 'Tooling', %w[/haml_lint /rubocop /tooling]
+ add_group 'Tooling', %w[/haml_lint /rubocop /scripts /tooling]
merge_timeout 365 * 24 * 3600
end
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index c3e0dc43c9e..9747dbea646 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -3536,8 +3536,6 @@
- './spec/db/schema_spec.rb'
- './spec/dependencies/omniauth_saml_spec.rb'
- './spec/experiments/application_experiment_spec.rb'
-- './spec/experiments/concerns/project_commit_count_spec.rb'
-- './spec/experiments/force_company_trial_experiment_spec.rb'
- './spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb'
- './spec/experiments/ios_specific_templates_experiment_spec.rb'
- './spec/features/abuse_report_spec.rb'