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>2021-12-13 18:12:59 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-12-13 18:12:59 +0300
commitaacba12c6e9817b552989de77b54e89b7c863b85 (patch)
tree08baff36c06079f8442d7cd8d5add675da90074f
parentb0891151f160d287e48a5317d3152b195ef950ae (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/reports.gitlab-ci.yml2
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/batch_comments/components/draft_note.vue2
-rw-r--r--app/assets/javascripts/behaviors/copy_code.js66
-rw-r--r--app/assets/javascripts/content_editor/extensions/code_block_highlight.js2
-rw-r--r--app/assets/javascripts/content_editor/extensions/division.js14
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_serializer.js11
-rw-r--r--app/assets/javascripts/environments/graphql/typedefs.graphql27
-rw-r--r--app/assets/javascripts/issues/show/components/description.vue2
-rw-r--r--app/assets/javascripts/lib/dompurify.js2
-rw-r--r--app/assets/javascripts/lib/utils/dom_utils.js14
-rw-r--r--app/assets/javascripts/main.js2
-rw-r--r--app/assets/javascripts/notes/components/note_body.vue2
-rw-r--r--app/assets/javascripts/notes/i18n.js4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue80
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js62
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/issues.js18
-rw-r--r--app/assets/javascripts/work_items/graphql/typedefs.graphql4
-rw-r--r--app/assets/stylesheets/framework/buttons.scss13
-rw-r--r--app/assets/stylesheets/framework/typography.scss6
-rw-r--r--app/controllers/projects/runners_controller.rb2
-rw-r--r--app/models/bulk_imports/tracker.rb13
-rw-r--r--app/models/ci/runner.rb34
-rw-r--r--app/services/deployments/older_deployments_drop_service.rb2
-rw-r--r--app/views/layouts/_google_tag_manager_head.html.haml6
-rw-r--r--app/views/projects/protected_tags/shared/_matching_tag.html.haml2
-rw-r--r--app/workers/all_queues.yml2
-rw-r--r--app/workers/bulk_imports/entity_worker.rb5
-rw-r--r--app/workers/bulk_imports/pipeline_worker.rb4
-rw-r--r--config/feature_flags/development/vuln_report_new_project_filter.yml8
-rw-r--r--data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml1
-rw-r--r--data/deprecations/14-0-nfs-fot-git-repository-storage.yml2
-rw-r--r--data/deprecations/14-2-deprecation-task-runner.yml2
-rw-r--r--data/deprecations/14-3-database-deprecate-legacy-database-conf.yml1
-rw-r--r--data/deprecations/14-3-deprecation-release-cli.yml2
-rw-r--r--data/deprecations/14-3-package-container-registry-api-group-update.yml1
-rw-r--r--data/deprecations/14-3-repository-push-audit-events.yml1
-rw-r--r--data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml2
-rw-r--r--data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml1
-rw-r--r--data/deprecations/14-5-deprecate-opensuse-15-2.yml1
-rw-r--r--data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml1
-rw-r--r--data/deprecations/14-5-runner-api-status-does-contain-paused.yml1
-rw-r--r--data/deprecations/14-6-deprecate-types.yml2
-rw-r--r--data/deprecations/14-6-runner-api-status-renames-not_connected.yml1
-rw-r--r--data/deprecations/15-0-deprecate-sles-12sp2.yml1
-rw-r--r--data/deprecations/15-0-deprecation-versions-packagetype.yml1
-rw-r--r--data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml1
-rw-r--r--data/deprecations/15-0-remove-package-pipelines-api.yml1
-rw-r--r--data/deprecations/15-0-remove-pipelines-from-version-field.yml1
-rw-r--r--data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml2
-rw-r--r--data/deprecations/deprecation_omniauth-kerberos_gem.yml1
-rw-r--r--data/deprecations/disable_strict_host_key_checking.yml1
-rw-r--r--data/deprecations/job_char_limit.yml2
-rw-r--r--data/deprecations/runner_api_new_stale_status_breaking_change.yml1
-rw-r--r--data/deprecations/serverless.yml1
-rw-r--r--data/deprecations/templates/_deprecation_template.md.erb1
-rw-r--r--data/deprecations/templates/example.yml2
-rw-r--r--db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb7
-rw-r--r--db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb18
-rw-r--r--db/schema_migrations/202112081114251
-rw-r--r--db/schema_migrations/202112130648211
-rw-r--r--db/structure.sql5
-rw-r--r--doc/update/deprecations.md30
-rw-r--r--doc/user/application_security/dast/index.md5
-rw-r--r--lib/api/ci/helpers/runner.rb2
-rw-r--r--lib/banzai/filter/syntax_highlight_filter.rb4
-rw-r--r--locale/gitlab.pot21
-rw-r--r--qa/Gemfile.lock2
-rw-r--r--qa/qa/specs/features/browser_ui/14_non_devops/performance_bar_spec.rb (renamed from qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb)0
-rw-r--r--qa/qa/specs/features/browser_ui/14_non_devops/service_ping_default_enabled_spec.rb (renamed from qa/qa/specs/features/browser_ui/non_devops/service_ping_default_enabled_spec.rb)0
-rw-r--r--qa/qa/specs/features/browser_ui/14_non_devops/service_ping_disabled_spec.rb (renamed from qa/qa/specs/features/browser_ui/non_devops/service_ping_disabled_spec.rb)0
-rw-r--r--spec/features/issues/csv_spec.rb22
-rw-r--r--spec/fixtures/markdown/markdown_golden_master_examples.yml22
-rw-r--r--spec/frontend/lib/utils/dom_utils_spec.js12
-rw-r--r--spec/frontend/vue_mr_widget/components/extensions/utils_spec.js18
-rw-r--r--spec/helpers/markup_helper_spec.rb4
-rw-r--r--spec/lib/api/ci/helpers/runner_helpers_spec.rb5
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb24
-rw-r--r--spec/lib/gitlab/asciidoc_spec.rb10
-rw-r--r--spec/models/ci/runner_spec.rb24
-rw-r--r--spec/services/deployments/older_deployments_drop_service_spec.rb11
-rw-r--r--spec/workers/bulk_imports/entity_worker_spec.rb170
-rw-r--r--spec/workers/bulk_imports/pipeline_worker_spec.rb43
-rw-r--r--workhorse/internal/upstream/metrics.go14
-rw-r--r--workhorse/internal/upstream/metrics_test.go54
-rw-r--r--workhorse/internal/upstream/routes.go22
-rw-r--r--workhorse/internal/upstream/upstream.go2
87 files changed, 778 insertions, 223 deletions
diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml
index 33efc3c4788..6d58bbf9682 100644
--- a/.gitlab/ci/reports.gitlab-ci.yml
+++ b/.gitlab/ci/reports.gitlab-ci.yml
@@ -98,7 +98,7 @@ gemnasium-python-dependency_scanning:
yarn-audit-dependency_scanning:
extends: .ds-analyzer
- image: "registry.gitlab.com/gitlab-org/security-products/analyzers/npm-audit:1.4.0"
+ image: "registry.gitlab.com/gitlab-org/security-products/analyzers/npm-audit:1.4.1"
variables:
TOOL: yarn
rules: !reference [".reports:rules:yarn-audit-dependency_scanning", rules]
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index ad5290c80a3..f16099effce 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-9aa8e36d420402b19210dcf861f7bf619ff39089
+8ede1944ec9793c06dba5011234af7f5c5ec92b7
diff --git a/app/assets/javascripts/batch_comments/components/draft_note.vue b/app/assets/javascripts/batch_comments/components/draft_note.vue
index 918519f386b..a218624f2d4 100644
--- a/app/assets/javascripts/batch_comments/components/draft_note.vue
+++ b/app/assets/javascripts/batch_comments/components/draft_note.vue
@@ -76,7 +76,7 @@ export default {
},
},
safeHtmlConfig: {
- ADD_TAGS: ['use', 'gl-emoji'],
+ ADD_TAGS: ['use', 'gl-emoji', 'copy-code'],
},
};
</script>
diff --git a/app/assets/javascripts/behaviors/copy_code.js b/app/assets/javascripts/behaviors/copy_code.js
new file mode 100644
index 00000000000..a6e203ea5a2
--- /dev/null
+++ b/app/assets/javascripts/behaviors/copy_code.js
@@ -0,0 +1,66 @@
+import { uniqueId } from 'lodash';
+import { __ } from '~/locale';
+import { spriteIcon } from '~/lib/utils/common_utils';
+import { setAttributes } from '~/lib/utils/dom_utils';
+
+class CopyCodeButton extends HTMLElement {
+ connectedCallback() {
+ this.for = uniqueId('code-');
+
+ this.parentNode.querySelector('pre').setAttribute('id', this.for);
+
+ this.appendChild(this.createButton());
+ }
+
+ createButton() {
+ const button = document.createElement('button');
+
+ setAttributes(button, {
+ type: 'button',
+ class: 'btn btn-default btn-md gl-button btn-icon has-tooltip',
+ 'data-title': __('Copy to clipboard'),
+ 'data-clipboard-target': `pre#${this.for}`,
+ });
+
+ button.innerHTML = spriteIcon('copy-to-clipboard');
+
+ return button;
+ }
+}
+
+function addCodeButton() {
+ [...document.querySelectorAll('pre.code.js-syntax-highlight')]
+ .filter((el) => !el.closest('.js-markdown-code'))
+ .forEach((el) => {
+ const copyCodeEl = document.createElement('copy-code');
+ copyCodeEl.setAttribute('for', uniqueId('code-'));
+
+ const wrapper = document.createElement('div');
+ wrapper.className = 'gl-relative markdown-code-block js-markdown-code';
+ wrapper.appendChild(el.cloneNode(true));
+ wrapper.appendChild(copyCodeEl);
+
+ el.parentNode.insertBefore(wrapper, el);
+
+ el.remove();
+ });
+}
+
+export const initCopyCodeButton = (selector = '#content-body') => {
+ if (!customElements.get('copy-code')) {
+ customElements.define('copy-code', CopyCodeButton);
+ }
+
+ const el = document.querySelector(selector);
+
+ if (!el) return () => {};
+
+ const observer = new MutationObserver(() => addCodeButton());
+
+ observer.observe(document.querySelector(selector), {
+ childList: true,
+ subtree: true,
+ });
+
+ return () => observer.disconnect();
+};
diff --git a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
index 1ed1ab0315f..6154fae21df 100644
--- a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
+++ b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
@@ -17,7 +17,7 @@ export default CodeBlockLowlight.extend({
};
},
renderHTML({ HTMLAttributes }) {
- return ['pre', HTMLAttributes, ['code', {}, 0]];
+ return ['div', ['pre', HTMLAttributes, ['code', {}, 0]]];
},
}).configure({
lowlight,
diff --git a/app/assets/javascripts/content_editor/extensions/division.js b/app/assets/javascripts/content_editor/extensions/division.js
index c70d1700941..566ed85acf3 100644
--- a/app/assets/javascripts/content_editor/extensions/division.js
+++ b/app/assets/javascripts/content_editor/extensions/division.js
@@ -1,12 +1,26 @@
import { Node } from '@tiptap/core';
import { PARSE_HTML_PRIORITY_LOWEST } from '../constants';
+const getDiv = (element) => {
+ if (element.nodeName === 'DIV') return element;
+ return element.querySelector('div');
+};
+
export default Node.create({
name: 'division',
content: 'block*',
group: 'block',
defining: true,
+ addAttributes() {
+ return {
+ className: {
+ default: null,
+ parseHTML: (element) => getDiv(element).className || null,
+ },
+ };
+ },
+
parseHTML() {
return [{ tag: 'div', priority: PARSE_HTML_PRIORITY_LOWEST }];
},
diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js
index 38b0438fa3a..278ef326c7a 100644
--- a/app/assets/javascripts/content_editor/services/markdown_serializer.js
+++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js
@@ -138,7 +138,16 @@ const defaultSerializerConfig = {
state.write('```');
state.closeBlock(node);
},
- [Division.name]: renderHTMLNode('div'),
+ [Division.name]: (state, node) => {
+ if (node.attrs.className?.includes('js-markdown-code')) {
+ state.renderInline(node);
+ } else {
+ const newNode = node;
+ delete newNode.attrs.className;
+
+ renderHTMLNode('div')(state, newNode);
+ }
+ },
[DescriptionList.name]: renderHTMLNode('dl', true),
[DescriptionItem.name]: (state, node, parent, index) => {
if (index === 1) state.ensureNewLine();
diff --git a/app/assets/javascripts/environments/graphql/typedefs.graphql b/app/assets/javascripts/environments/graphql/typedefs.graphql
index f0172765ebe..026f2ca9375 100644
--- a/app/assets/javascripts/environments/graphql/typedefs.graphql
+++ b/app/assets/javascripts/environments/graphql/typedefs.graphql
@@ -9,12 +9,29 @@ type LocalEnvironment {
autoStopPath: String
}
+input LocalEnvironmentInput {
+ id: Int!
+ globalId: ID!
+ name: String!
+ folderPath: String
+ stopPath: String
+ deletePath: String
+ retryUrl: String
+ autoStopPath: String
+}
+
type NestedLocalEnvironment {
name: String!
size: Int!
latest: LocalEnvironment!
}
+input NestedLocalEnvironmentInput {
+ name: String!
+ size: Int!
+ latest: LocalEnvironmentInput!
+}
+
type LocalEnvironmentFolder {
environments: [LocalEnvironment!]!
availableCount: Int!
@@ -40,13 +57,13 @@ type LocalErrors {
extend type Query {
environmentApp: LocalEnvironmentApp
- folder(environment: NestedLocalEnvironment): LocalEnvironmentFolder
+ folder(environment: NestedLocalEnvironmentInput): LocalEnvironmentFolder
isLastDeployment: Boolean
}
extend type Mutation {
- stopEnvironment(environment: LocalEnvironment): LocalErrors
- deleteEnvironment(environment: LocalEnvironment): LocalErrors
- rollbackEnvironment(environment: LocalEnvironment): LocalErrors
- cancelAutoStop(environment: LocalEnvironment): LocalErrors
+ stopEnvironment(environment: LocalEnvironmentInput): LocalErrors
+ deleteEnvironment(environment: LocalEnvironmentInput): LocalErrors
+ rollbackEnvironment(environment: LocalEnvironmentInput): LocalErrors
+ cancelAutoStop(environment: LocalEnvironmentInput): LocalErrors
}
diff --git a/app/assets/javascripts/issues/show/components/description.vue b/app/assets/javascripts/issues/show/components/description.vue
index 03497589dfb..7be4c13f544 100644
--- a/app/assets/javascripts/issues/show/components/description.vue
+++ b/app/assets/javascripts/issues/show/components/description.vue
@@ -133,7 +133,7 @@ export default {
}
},
},
- safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
+ safeHtmlConfig: { ADD_TAGS: ['gl-emoji', 'copy-code'] },
};
</script>
diff --git a/app/assets/javascripts/lib/dompurify.js b/app/assets/javascripts/lib/dompurify.js
index 47ede8cb1bb..47568f0ecff 100644
--- a/app/assets/javascripts/lib/dompurify.js
+++ b/app/assets/javascripts/lib/dompurify.js
@@ -3,7 +3,7 @@ import { getNormalizedURL, getBaseURL, relativePathToAbsolute } from '~/lib/util
const defaultConfig = {
// Safely allow SVG <use> tags
- ADD_TAGS: ['use', 'gl-emoji'],
+ ADD_TAGS: ['use', 'gl-emoji', 'copy-code'],
// Prevent possible XSS attacks with data-* attributes used by @rails/ujs
// See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1421
FORBID_ATTR: ['data-remote', 'data-url', 'data-type', 'data-method'],
diff --git a/app/assets/javascripts/lib/utils/dom_utils.js b/app/assets/javascripts/lib/utils/dom_utils.js
index f7687a929de..b52a736f153 100644
--- a/app/assets/javascripts/lib/utils/dom_utils.js
+++ b/app/assets/javascripts/lib/utils/dom_utils.js
@@ -89,3 +89,17 @@ export const getParents = (element) => {
return parents;
};
+
+/**
+ * This method takes a HTML element and an object of attributes
+ * to save repeated calls to `setAttribute` when multiple
+ * attributes need to be set.
+ *
+ * @param {HTMLElement} el
+ * @param {Object} attributes
+ */
+export const setAttributes = (el, attributes) => {
+ Object.keys(attributes).forEach((key) => {
+ el.setAttribute(key, attributes[key]);
+ });
+};
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 251086363c7..0d307d7744b 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -36,6 +36,7 @@ import GlFieldErrors from './gl_field_errors';
import initUserPopovers from './user_popovers';
import initBroadcastNotifications from './broadcast_notification';
import { initTopNav } from './nav';
+import { initCopyCodeButton } from './behaviors/copy_code';
import 'ee_else_ce/main_ee';
import 'jh_else_ce/main_jh';
@@ -97,6 +98,7 @@ function deferredInitialisation() {
initPersistentUserCallouts();
initDefaultTrackers();
initFeatureHighlight();
+ initCopyCodeButton();
if (gon.features?.newHeaderSearch) {
initHeaderSearchApp();
diff --git a/app/assets/javascripts/notes/components/note_body.vue b/app/assets/javascripts/notes/components/note_body.vue
index c09582d6287..f465ad23a06 100644
--- a/app/assets/javascripts/notes/components/note_body.vue
+++ b/app/assets/javascripts/notes/components/note_body.vue
@@ -149,7 +149,7 @@ export default {
},
},
safeHtmlConfig: {
- ADD_TAGS: ['use', 'gl-emoji'],
+ ADD_TAGS: ['use', 'gl-emoji', 'copy-code'],
},
};
</script>
diff --git a/app/assets/javascripts/notes/i18n.js b/app/assets/javascripts/notes/i18n.js
index cd47985d8d0..951fa9733d4 100644
--- a/app/assets/javascripts/notes/i18n.js
+++ b/app/assets/javascripts/notes/i18n.js
@@ -12,7 +12,9 @@ export const COMMENT_FORM = {
epic: __('epic'),
bodyPlaceholder: __('Write a comment or drag your files here…'),
confidential: s__('Notes|Make this comment confidential'),
- confidentialVisibility: s__('Notes|Confidential comments are only visible to project members'),
+ confidentialVisibility: s__(
+ 'Notes|Confidential comments are only visible to members with the role of Reporter or higher',
+ ),
discussionThatNeedsResolution: __(
'Discuss a specific suggestion or question that needs to be resolved.',
),
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index b103267ed9a..f5159f22973 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -16,6 +16,7 @@ import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue';
import { EXTENSION_ICON_CLASS, EXTENSION_ICONS } from '../../constants';
import StatusIcon from './status_icon.vue';
import Actions from './actions.vue';
+import { generateText } from './utils';
export const LOADING_STATES = {
collapsedLoading: 'collapsedLoading',
@@ -147,6 +148,9 @@ export default {
Sentry.captureException(e);
});
},
+ isArray(arr) {
+ return Array.isArray(arr);
+ },
appear(index) {
if (index === this.fullData.length - 1) {
this.showFade = false;
@@ -157,6 +161,7 @@ export default {
this.showFade = true;
}
},
+ generateText,
},
EXTENSION_ICON_CLASS,
};
@@ -177,7 +182,7 @@ export default {
<div class="gl-flex-grow-1">
<template v-if="isLoadingSummary">{{ widgetLoadingText }}</template>
<template v-else-if="hasFetchError">{{ widgetErrorText }}</template>
- <div v-else v-safe-html="summary(collapsedData)"></div>
+ <div v-else v-safe-html="generateText(summary(collapsedData))"></div>
</div>
<actions
:widget="$options.label || $options.name"
@@ -224,32 +229,59 @@ export default {
:class="{
'gl-border-b-solid gl-border-b-1 gl-border-gray-100': index !== fullData.length - 1,
}"
- class="gl-display-flex gl-align-items-center gl-py-3 gl-pl-7"
+ class="gl-py-3 gl-pl-7"
data-testid="extension-list-item"
>
- <status-icon v-if="data.icon" :icon-name="data.icon.name" :size="12" class="gl-pl-0" />
- <gl-intersection-observer
- :options="{ rootMargin: '100px', thresholds: 0.1 }"
- class="gl-flex-wrap gl-display-flex gl-w-full"
- @appear="appear(index)"
- @disappear="disappear(index)"
- >
- <div
- v-safe-html="data.text"
- class="gl-mr-4 gl-display-flex gl-align-items-center"
- ></div>
- <div v-if="data.link">
- <gl-link :href="data.link.href">{{ data.link.text }}</gl-link>
+ <div class="gl-w-full">
+ <div v-if="data.header" class="gl-mb-2">
+ <template v-if="isArray(data.header)">
+ <component
+ :is="headerI === 0 ? 'strong' : 'span'"
+ v-for="(header, headerI) in data.header"
+ :key="headerI"
+ v-safe-html="generateText(header)"
+ class="gl-display-block"
+ />
+ </template>
+ <strong v-else v-safe-html="generateText(data.header)"></strong>
+ </div>
+ <div class="gl-display-flex">
+ <status-icon
+ v-if="data.icon"
+ :icon-name="data.icon.name"
+ :size="12"
+ class="gl-pl-0"
+ />
+ <gl-intersection-observer
+ :options="{ rootMargin: '100px', thresholds: 0.1 }"
+ class="gl-w-full"
+ @appear="appear(index)"
+ @disappear="disappear(index)"
+ >
+ <div class="gl-flex-wrap gl-display-flex gl-w-full">
+ <div class="gl-mr-4 gl-display-flex gl-align-items-center">
+ <p v-safe-html="generateText(data.text)" class="gl-m-0"></p>
+ </div>
+ <div v-if="data.link">
+ <gl-link :href="data.link.href">{{ data.link.text }}</gl-link>
+ </div>
+ <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
+ {{ data.badge.text }}
+ </gl-badge>
+ <actions
+ :widget="$options.label || $options.name"
+ :tertiary-buttons="data.actions"
+ class="gl-ml-auto"
+ />
+ </div>
+ <p
+ v-if="data.subtext"
+ v-safe-html="generateText(data.subtext)"
+ class="gl-m-0 gl-font-sm"
+ ></p>
+ </gl-intersection-observer>
</div>
- <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
- {{ data.badge.text }}
- </gl-badge>
- <actions
- :widget="$options.label || $options.name"
- :tertiary-buttons="data.actions"
- class="gl-ml-auto"
- />
- </gl-intersection-observer>
+ </div>
</li>
</smart-virtual-list>
<div
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js
new file mode 100644
index 00000000000..8ba13cf8252
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js
@@ -0,0 +1,62 @@
+const TEXT_STYLES = {
+ success: {
+ start: '%{success_start}',
+ end: '%{success_end}',
+ },
+ danger: {
+ start: '%{danger_start}',
+ end: '%{danger_end}',
+ },
+ critical: {
+ start: '%{critical_start}',
+ end: '%{critical_end}',
+ },
+ same: {
+ start: '%{same_start}',
+ end: '%{same_end}',
+ },
+ strong: {
+ start: '%{strong_start}',
+ end: '%{strong_end}',
+ },
+ small: {
+ start: '%{small_start}',
+ end: '%{small_end}',
+ },
+};
+
+const getStartTag = (tag) => TEXT_STYLES[tag].start;
+const textStyleTags = {
+ [getStartTag('success')]: '<span class="gl-font-weight-bold gl-text-green-500">',
+ [getStartTag('danger')]: '<span class="gl-font-weight-bold gl-text-red-500">',
+ [getStartTag('critical')]: '<span class="gl-font-weight-bold gl-text-red-800">',
+ [getStartTag('same')]: '<span class="gl-font-weight-bold gl-text-gray-700">',
+ [getStartTag('strong')]: '<span class="gl-font-weight-bold">',
+ [getStartTag('small')]: '<span class="gl-font-sm">',
+};
+
+export const generateText = (text) => {
+ if (typeof text !== 'string') return null;
+
+ return text
+ .replace(
+ new RegExp(
+ `(${Object.values(TEXT_STYLES)
+ .reduce((acc, i) => [...acc, ...Object.values(i)], [])
+ .join('|')})`,
+ 'gi',
+ ),
+ (replace) => {
+ const replacement = textStyleTags[replace];
+
+ // If the replacement tag ends with a `_end` then we can just return `</span>`
+ // unless we have a replacement, for cases were we want to change the HTML tag
+ if (!replacement && replace.endsWith('_end}')) {
+ return '</span>';
+ }
+
+ return replacement;
+ },
+ )
+ .replace(/%{([a-z]|_)+}/g, ''); // Filter out any tags we don't know about
+};
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
index 9cbc0b0e5d1..ba3336df2eb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
@@ -2,6 +2,7 @@
import { EXTENSION_ICONS } from '../constants';
import issuesCollapsedQuery from './issues_collapsed.query.graphql';
import issuesQuery from './issues.query.graphql';
+import { n__, sprintf } from '~/locale';
export default {
// Give the extension a name
@@ -20,7 +21,14 @@ export default {
// Small summary text to be displayed in the collapsed state
// Receives the collapsed data as an argument
summary(count) {
- return 'Summary text<br/>Second line';
+ return sprintf(
+ n__(
+ 'ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change',
+ 'ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes',
+ changesFound,
+ ),
+ { changesFound },
+ );
},
// Status icon to be used next to the summary text
// Receives the collapsed data as an argument
@@ -57,9 +65,13 @@ export default {
.query({ query: issuesQuery, variables: { projectPath: targetProjectFullPath } })
.then(({ data }) => {
// Return some transformed data to be rendered in the expanded state
- return data.project.issues.nodes.map((issue) => ({
+ return data.project.issues.nodes.map((issue, i) => ({
id: issue.id, // Required: The ID of the object
- text: issue.title, // Required: The text to get used on each row
+ header: ['New', 'This is an %{strong_start}issue%{strong_end} row'],
+ text:
+ '%{critical_start}1 Critical%{critical_end}, %{danger_start}1 High%{danger_end}, and %{strong_start}1 Other%{strong_end}. %{small_start}Some smaller text%{small_end}', // Required: The text to get used on each row
+ subtext:
+ 'Reported resource changes: %{strong_start}2%{strong_end} to add, 0 to change, 0 to delete', // Optional: The sub-text to get displayed below each rows main content
// Icon to get rendered on the side of each row
icon: {
// Required: Name maps to an icon in GitLabs SVG
diff --git a/app/assets/javascripts/work_items/graphql/typedefs.graphql b/app/assets/javascripts/work_items/graphql/typedefs.graphql
index 8247a0795cf..177eea00322 100644
--- a/app/assets/javascripts/work_items/graphql/typedefs.graphql
+++ b/app/assets/javascripts/work_items/graphql/typedefs.graphql
@@ -33,11 +33,11 @@ type LocalWorkItem {
widgets: [LocalWorkItemWidgetConnection]
}
-type LocalCreateWorkItemInput {
+input LocalCreateWorkItemInput {
title: String!
}
-type LocalUpdateWorkItemInput {
+input LocalUpdateWorkItemInput {
id: ID!
title: String
}
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index e458dfd5316..cc8a2092031 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -451,3 +451,16 @@ fieldset[disabled] .btn,
box-shadow: none;
border-width: 1px;
}
+
+copy-code {
+ @include gl-absolute;
+ @include gl-transition-medium;
+ @include gl-opacity-0;
+
+ top: 7px;
+ right: $input-horizontal-padding;
+
+ .markdown-code-block:hover & {
+ @include gl-opacity-10;
+ }
+}
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index cb36c4e5767..16ff4b81f95 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -625,6 +625,7 @@ body {
/** CODE **/
pre {
+ @include gl-relative;
font-family: $monospace-font;
display: block;
padding: $gl-padding-8 $input-horizontal-padding;
@@ -636,6 +637,11 @@ pre {
background-color: $gray-light;
border: 1px solid $gray-100;
border-radius: $border-radius-small;
+
+ // Select only code elements that will have the copy code button
+ .markdown-code-block & {
+ padding: $input-horizontal-padding;
+ }
}
code {
diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb
index e841c3e3d49..62a9f8a4625 100644
--- a/app/controllers/projects/runners_controller.rb
+++ b/app/controllers/projects/runners_controller.rb
@@ -4,8 +4,6 @@ class Projects::RunnersController < Projects::ApplicationController
before_action :authorize_admin_build!
before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
- layout 'project_settings'
-
feature_category :runner
def index
diff --git a/app/models/bulk_imports/tracker.rb b/app/models/bulk_imports/tracker.rb
index 9de3239ee0f..cfe33c013ba 100644
--- a/app/models/bulk_imports/tracker.rb
+++ b/app/models/bulk_imports/tracker.rb
@@ -29,7 +29,7 @@ class BulkImports::Tracker < ApplicationRecord
def self.stage_running?(entity_id, stage)
where(stage: stage, bulk_import_entity_id: entity_id)
- .with_status(:created, :started)
+ .with_status(:created, :enqueued, :started)
.exists?
end
@@ -45,15 +45,24 @@ class BulkImports::Tracker < ApplicationRecord
state :created, value: 0
state :started, value: 1
state :finished, value: 2
+ state :enqueued, value: 3
state :failed, value: -1
state :skipped, value: -2
event :start do
- transition created: :started
+ transition enqueued: :started
# To avoid errors when re-starting a pipeline in case of network errors
transition started: :started
end
+ event :retry do
+ transition started: :enqueued
+ end
+
+ event :enqueue do
+ transition created: :enqueued
+ end
+
event :finish do
transition started: :finished
transition failed: :failed
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index a441d362b74..a80fd02080f 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -26,6 +26,21 @@ module Ci
project_type: 3
}
+ enum executor_type: {
+ unknown: 0,
+ custom: 1,
+ shell: 2,
+ docker: 3,
+ docker_windows: 4,
+ docker_ssh: 5,
+ ssh: 6,
+ parallels: 7,
+ virtualbox: 8,
+ docker_machine: 9,
+ docker_ssh_machine: 10,
+ kubernetes: 11
+ }, _suffix: true
+
# This `ONLINE_CONTACT_TIMEOUT` needs to be larger than
# `RUNNER_QUEUE_EXPIRY_TIME+UPDATE_CONTACT_COLUMN_EVERY`
#
@@ -152,7 +167,7 @@ module Ci
after_destroy :cleanup_runner_queue
- cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at
+ cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at, :executor_type
chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout,
error_message: 'Maximum job timeout has a value which could not be accepted'
@@ -398,8 +413,9 @@ module Ci
# database after heartbeat write happens.
#
::Gitlab::Database::LoadBalancing::Session.without_sticky_writes do
- values = values&.slice(:version, :revision, :platform, :architecture, :ip_address, :config) || {}
+ values = values&.slice(:version, :revision, :platform, :architecture, :ip_address, :config, :executor) || {}
values[:contacted_at] = Time.current
+ values[:executor_type] = EXECUTOR_NAME_TO_TYPES.fetch(values.delete(:executor), :unknown)
cache_attributes(values)
@@ -424,6 +440,20 @@ module Ci
private
+ EXECUTOR_NAME_TO_TYPES = {
+ 'custom' => :custom,
+ 'shell' => :shell,
+ 'docker' => :docker,
+ 'docker-windows' => :docker_windows,
+ 'docker-ssh' => :docker_ssh,
+ 'ssh' => :ssh,
+ 'parallels' => :parallels,
+ 'virtualbox' => :virtualbox,
+ 'docker+machine' => :docker_machine,
+ 'docker-ssh+machine' => :docker_ssh_machine,
+ 'kubernetes' => :kubernetes
+ }.freeze
+
def cleanup_runner_queue
Gitlab::Redis::SharedState.with do |redis|
redis.del(runner_queue_key)
diff --git a/app/services/deployments/older_deployments_drop_service.rb b/app/services/deployments/older_deployments_drop_service.rb
index 504b55b99ac..15384fb0db1 100644
--- a/app/services/deployments/older_deployments_drop_service.rb
+++ b/app/services/deployments/older_deployments_drop_service.rb
@@ -12,6 +12,8 @@ module Deployments
return unless @deployment&.running?
older_deployments_builds.each do |build|
+ next if build.manual?
+
Gitlab::OptimisticLocking.retry_lock(build, name: 'older_deployments_drop') do |build|
build.drop(:forward_deployment_failure)
end
diff --git a/app/views/layouts/_google_tag_manager_head.html.haml b/app/views/layouts/_google_tag_manager_head.html.haml
index d0700f8bc8e..25af51ca9cb 100644
--- a/app/views/layouts/_google_tag_manager_head.html.haml
+++ b/app/views/layouts/_google_tag_manager_head.html.haml
@@ -1,13 +1,13 @@
- return unless google_tag_manager_enabled?
- if Feature.enabled?(:gtm_nonce, type: :ops)
- = javascript_tag do
+ = javascript_tag nonce: content_security_policy_nonce do
:plain
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
- 'https://www.googletagmanager.com/gtm.js?id='+i+dl;var n=d.querySelector('[nonce]');
- n&&j.setAttribute('nonce',n.nonce||n.getAttribute('nonce'));f.parentNode.insertBefore(j,f);
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;j.setAttribute('nonce',
+ '#{content_security_policy_nonce}');f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','#{google_tag_manager_id}');
- else
= javascript_tag do
diff --git a/app/views/projects/protected_tags/shared/_matching_tag.html.haml b/app/views/projects/protected_tags/shared/_matching_tag.html.haml
index bf030d36cd6..3b6a6bd876f 100644
--- a/app/views/projects/protected_tags/shared/_matching_tag.html.haml
+++ b/app/views/projects/protected_tags/shared/_matching_tag.html.haml
@@ -3,7 +3,7 @@
= link_to matching_tag.name, project_ref_path(@project, matching_tag.name), class: 'ref-name'
- if @project.root_ref?(matching_tag.name)
- %span.badge.badge-info.gl-ml-2 default
+ = gl_badge_tag s_('ProtectedTag|default'), { variant: :info }, { class: 'gl-ml-2' }
%td
- commit = @project.commit(matching_tag.name)
= link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha')
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index e84646047e4..8ede2bebeca 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -1931,7 +1931,7 @@
:urgency: :low
:resource_boundary: :unknown
:weight: 1
- :idempotent:
+ :idempotent: true
:tags: []
- :name: bulk_imports_export_request
:worker_name: BulkImports::ExportRequestWorker
diff --git a/app/workers/bulk_imports/entity_worker.rb b/app/workers/bulk_imports/entity_worker.rb
index 5c04cdc96a0..70d6626df91 100644
--- a/app/workers/bulk_imports/entity_worker.rb
+++ b/app/workers/bulk_imports/entity_worker.rb
@@ -12,6 +12,9 @@ module BulkImports
worker_has_external_dependencies!
+ idempotent!
+ deduplicate :until_executed, including_scheduled: true
+
def perform(entity_id, current_stage = nil)
return if stage_running?(entity_id, current_stage)
@@ -48,7 +51,7 @@ module BulkImports
end
def next_pipeline_trackers_for(entity_id)
- BulkImports::Tracker.next_pipeline_trackers_for(entity_id)
+ BulkImports::Tracker.next_pipeline_trackers_for(entity_id).update(status_event: 'enqueue')
end
def logger
diff --git a/app/workers/bulk_imports/pipeline_worker.rb b/app/workers/bulk_imports/pipeline_worker.rb
index 35633b55489..8e5d7013c2c 100644
--- a/app/workers/bulk_imports/pipeline_worker.rb
+++ b/app/workers/bulk_imports/pipeline_worker.rb
@@ -16,7 +16,7 @@ module BulkImports
def perform(pipeline_tracker_id, stage, entity_id)
pipeline_tracker = ::BulkImports::Tracker
- .with_status(:created, :started)
+ .with_status(:enqueued)
.find_by_id(pipeline_tracker_id)
if pipeline_tracker.present?
@@ -68,6 +68,8 @@ module BulkImports
message: "Retrying error: #{e.message}"
)
+ pipeline_tracker.update!(status_event: 'retry', jid: jid)
+
reenqueue(pipeline_tracker, delay: e.retry_delay)
else
fail_tracker(pipeline_tracker, e)
diff --git a/config/feature_flags/development/vuln_report_new_project_filter.yml b/config/feature_flags/development/vuln_report_new_project_filter.yml
deleted file mode 100644
index 3eb02054205..00000000000
--- a/config/feature_flags/development/vuln_report_new_project_filter.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: vuln_report_new_project_filter
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55745
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334380
-milestone: '14.3'
-type: development
-group: group::threat insights
-default_enabled: true
diff --git a/data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml b/data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
index 08cc0d7a603..c4c5f6258b4 100644
--- a/data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
+++ b/data/deprecations/ runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
In GitLab 15.0 and later, to access the AWS S3 cache, you must specify the `AuthenticationType` for [`[runners.cache.s3]`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscaches3-section). The `AuthenticationType` must be `IAM` or `credentials`.
diff --git a/data/deprecations/14-0-nfs-fot-git-repository-storage.yml b/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
index 6884f6e3f69..a1261154e8c 100644
--- a/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
+++ b/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.0" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-06-22" # The date of the milestone release when this feature was first announced as deprecated
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
With the general availability of Gitaly Cluster ([introduced in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/)), we have deprecated development (bugfixes, performance improvements, etc) for NFS for Git repository storage in GitLab 14.0. We will continue to provide technical support for NFS for Git repositories throughout 14.x, but we will remove all support for NFS in GitLab 15.0. Please see our official [Statement of Support](https://about.gitlab.com/support/statement-of-support.html#gitaly-and-nfs) for further information.
@@ -19,4 +20,3 @@
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-2-deprecation-task-runner.yml b/data/deprecations/14-2-deprecation-task-runner.yml
index 52fd1f0f288..9f4d81ddd3a 100644
--- a/data/deprecations/14-2-deprecation-task-runner.yml
+++ b/data/deprecations/14-2-deprecation-task-runner.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-08-22" # The date of the milestone release when this feature was first announced as deprecated
removal_milestone: "14.5" # The milestone when this feature is planned to be removed
+ removal_date: "2021-11-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
@@ -13,4 +14,3 @@
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: "2021-11-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml b/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
index f3f6553729e..e460abcb077 100644
--- a/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
+++ b/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.3"
announcement_date: "2021-09-22"
removal_milestone: "15.0"
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: |
The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
diff --git a/data/deprecations/14-3-deprecation-release-cli.yml b/data/deprecations/14-3-deprecation-release-cli.yml
index 4273d00fc73..d04e97df380 100644
--- a/data/deprecations/14-3-deprecation-release-cli.yml
+++ b/data/deprecations/14-3-deprecation-release-cli.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-08-22" # The date of the milestone release when this feature was first announced as deprecated
removal_milestone: "14.6" # The milestone when this feature is planned to be removed
+ removal_date: "2021-12-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
@@ -10,4 +11,3 @@
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: "2021-12-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-3-package-container-registry-api-group-update.yml b/data/deprecations/14-3-package-container-registry-api-group-update.yml
index 3021e283846..de5d184888a 100644
--- a/data/deprecations/14-3-package-container-registry-api-group-update.yml
+++ b/data/deprecations/14-3-package-container-registry-api-group-update.yml
@@ -1,6 +1,7 @@
- name: "Update to the Container Registry group-level API"
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
In milestone 15.0, support for the `tags` and `tags_count` parameters will be removed from the Container Registry API that [gets registry repositories from a group](../api/container_registry.md#within-a-group).
diff --git a/data/deprecations/14-3-repository-push-audit-events.yml b/data/deprecations/14-3-repository-push-audit-events.yml
index 4bca8751db4..defa4576cde 100644
--- a/data/deprecations/14-3-repository-push-audit-events.yml
+++ b/data/deprecations/14-3-repository-push-audit-events.yml
@@ -1,6 +1,7 @@
- name: "Audit events for repository push events"
announcement_milestone: "14.3" # The milestone when this feature was first announced as deprecated.
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push) are now deprecated and will be removed in GitLab 15.0.
diff --git a/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml b/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
index 86e7718b9e1..e93fa25facb 100644
--- a/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
+++ b/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5"
announcement_date: "2021-11-15"
removal_milestone: "15.0"
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: |
[We are deprecating the certificate-based integration with Kubernetes](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
The timeline of removal of the integration from the product is not yet planned and we will communicate
@@ -16,4 +17,3 @@
tiers: [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: 'https://gitlab.com/groups/gitlab-org/configure/-/epics/8'
documentation_url: 'https://docs.gitlab.com/ee/user/infrastructure/clusters/#certificate-based-kubernetes-integration-deprecated'
- removal_date: # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml b/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml
index c5f9e244af0..29b8fe0e70c 100644
--- a/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml
+++ b/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
In GitLab 15.0, we will remove the feature that enables you to convert an instance (shared) runner to a project (specific) runner. Users who need to add a runner to only a particular project can register a runner to the project directly.
diff --git a/data/deprecations/14-5-deprecate-opensuse-15-2.yml b/data/deprecations/14-5-deprecate-opensuse-15-2.yml
index b887f92e6a3..7b776293dbb 100644
--- a/data/deprecations/14-5-deprecate-opensuse-15-2.yml
+++ b/data/deprecations/14-5-deprecate-opensuse-15-2.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "14.8" # The milestone when this feature is planned to be removed
+ removal_date: "2022-02-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
Distribution support and security updates for openSUSE Leap 15.2 are [ending December 2021](https://en.opensuse.org/Lifetime#openSUSE_Leap).
diff --git a/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml b/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml
index 922c58be67e..5706e826a9d 100644
--- a/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml
+++ b/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
We are changing how the date filter works in Value Stream Analytics. Instead of filtering by the time that the issue or merge request was created, the date filter will filter by the end event time of the given stage. This will result in completely different figures after this change has rolled out.
diff --git a/data/deprecations/14-5-runner-api-status-does-contain-paused.yml b/data/deprecations/14-5-runner-api-status-does-contain-paused.yml
index 846e8824565..5cf7b107354 100644
--- a/data/deprecations/14-5-runner-api-status-does-contain-paused.yml
+++ b/data/deprecations/14-5-runner-api-status-does-contain-paused.yml
@@ -1,6 +1,7 @@
- name: "REST API Runner will not contain `paused`"
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 15.0.
diff --git a/data/deprecations/14-6-deprecate-types.yml b/data/deprecations/14-6-deprecate-types.yml
index ca639df9e29..5cbc07efa89 100644
--- a/data/deprecations/14-6-deprecate-types.yml
+++ b/data/deprecations/14-6-deprecate-types.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
The `type` and `types` CI/CD keywords will be removed in GitLab 15.0. Pipelines that use these keywords will stop working, so you must switch to `stage` and `stages`, which have the same behavior.
# The following items are not published on the docs page, but may be used in the future.
@@ -11,4 +12,3 @@
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-6-runner-api-status-renames-not_connected.yml b/data/deprecations/14-6-runner-api-status-renames-not_connected.yml
index ac79698cd50..5f7db1ac0e5 100644
--- a/data/deprecations/14-6-runner-api-status-renames-not_connected.yml
+++ b/data/deprecations/14-6-runner-api-status-renames-not_connected.yml
@@ -1,6 +1,7 @@
- name: "Deprecation of Runner status `not_connected` API value"
announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22"
body: | # Do not modify this line, instead modify the lines below.
The GitLab Runner REST and GraphQL [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints
will return `never_contacted` instead of `not_connected` as the status values in 15.0.
diff --git a/data/deprecations/15-0-deprecate-sles-12sp2.yml b/data/deprecations/15-0-deprecate-sles-12sp2.yml
index fd5057bb8d3..a466d8b4100 100644
--- a/data/deprecations/15-0-deprecate-sles-12sp2.yml
+++ b/data/deprecations/15-0-deprecate-sles-12sp2.yml
@@ -2,5 +2,6 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
Long term service and support (LTSS) for SUSE Linux Enterprise Server (SLES) 12 SP2 [ended on March 31, 2021](https://www.suse.com/lifecycle/). The CA certificates on SP2 include the expired DST root certificate, and it's not getting new CA certificate package updates. We have implemented some [workarounds](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/merge_requests/191), but we will not be able to continue to keep the build running properly.
diff --git a/data/deprecations/15-0-deprecation-versions-packagetype.yml b/data/deprecations/15-0-deprecation-versions-packagetype.yml
index 4e1501b48ba..e409e9be072 100644
--- a/data/deprecations/15-0-deprecation-versions-packagetype.yml
+++ b/data/deprecations/15-0-deprecation-versions-packagetype.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
As part of the work to create a [Package Registry GraphQL API](https://gitlab.com/groups/gitlab-org/-/epics/6318), the Package group deprecated the `Version` type for the basic `PackageType` type and moved it to [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#packagedetailstype).
diff --git a/data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml b/data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml
index 292dc4a14c0..b7e317d148e 100644
--- a/data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml
+++ b/data/deprecations/15-0-remove-dependency-proxy-permissions-flag.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
We added a feature flag because [GitLab-#11582](https://gitlab.com/gitlab-org/gitlab/-/issues/11582) changed how public groups use the Dependency Proxy. Prior to this change, you could use the Dependency Proxy without authentication. The change requires authentication to use the Dependency Proxy.
diff --git a/data/deprecations/15-0-remove-package-pipelines-api.yml b/data/deprecations/15-0-remove-package-pipelines-api.yml
index ba69ed75e0f..d26e291bb97 100644
--- a/data/deprecations/15-0-remove-package-pipelines-api.yml
+++ b/data/deprecations/15-0-remove-package-pipelines-api.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
A request to the API for `/api/v4/projects/:id/packages` returns a paginated result of packages. Each package lists all of its pipelines in this response. This is a performance concern, as it's possible for a package to have hundreds or thousands of associated pipelines.
diff --git a/data/deprecations/15-0-remove-pipelines-from-version-field.yml b/data/deprecations/15-0-remove-pipelines-from-version-field.yml
index 6f4f8db55cd..88eafedf36b 100644
--- a/data/deprecations/15-0-remove-pipelines-from-version-field.yml
+++ b/data/deprecations/15-0-remove-pipelines-from-version-field.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
In GraphQL, there are two `pipelines` fields that you can use in a [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/#packagedetailstype) to get the pipelines for package versions:
diff --git a/data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml b/data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
index 4021f0af665..5da61172410 100644
--- a/data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
+++ b/data/deprecations/deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
The GraphQL API field `defaultMergeCommitMessageWithDescription` has been deprecated and will be removed in GitLab 15.0. For projects with a commit message template set, it will ignore the template.
# The following items are not published on the docs page, but may be used in the future.
@@ -11,4 +12,3 @@
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/deprecation_omniauth-kerberos_gem.yml b/data/deprecations/deprecation_omniauth-kerberos_gem.yml
index 8adbeb19416..903d64db717 100644
--- a/data/deprecations/deprecation_omniauth-kerberos_gem.yml
+++ b/data/deprecations/deprecation_omniauth-kerberos_gem.yml
@@ -1,6 +1,7 @@
- name: "OmniAuth Kerberos gem"
announcement_milestone: "14.3"
removal_milestone: "15.0"
+ removal_date: "2022-05-22"
body: | # Do not modify this line, instead modify the lines below.
The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
diff --git a/data/deprecations/disable_strict_host_key_checking.yml b/data/deprecations/disable_strict_host_key_checking.yml
index 62011795bb9..e7e5eb1fa9f 100644
--- a/data/deprecations/disable_strict_host_key_checking.yml
+++ b/data/deprecations/disable_strict_host_key_checking.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22"
body: | # Do not modify this line, instead modify the lines below.
In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/3074), we added a configuration setting in the GitLab Runner `config.toml` file. This setting, [`[runners.ssh.disable_strict_host_key_checking]`](https://docs.gitlab.com/runner/executors/ssh.html#security), controls whether or not to use strict host key checking with the SSH executor.
diff --git a/data/deprecations/job_char_limit.yml b/data/deprecations/job_char_limit.yml
index 4df0f21ec04..706e3a078eb 100644
--- a/data/deprecations/job_char_limit.yml
+++ b/data/deprecations/job_char_limit.yml
@@ -23,4 +23,4 @@
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
+ removal_date: "2022-05-22"
diff --git a/data/deprecations/runner_api_new_stale_status_breaking_change.yml b/data/deprecations/runner_api_new_stale_status_breaking_change.yml
index e47634f54fa..bb3098ff517 100644
--- a/data/deprecations/runner_api_new_stale_status_breaking_change.yml
+++ b/data/deprecations/runner_api_new_stale_status_breaking_change.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-12-22"
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22"
body: | # Do not modify this line, instead modify the lines below.
A breaking change will occur for the Runner [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints in 15.0.
diff --git a/data/deprecations/serverless.yml b/data/deprecations/serverless.yml
index 1b99ece154f..3d280ff2f62 100644
--- a/data/deprecations/serverless.yml
+++ b/data/deprecations/serverless.yml
@@ -2,6 +2,7 @@
announcement_milestone: "14.3"
announcement_date: "2021-09-22"
removal_milestone: "15.0"
+ removal_date: "2022-05-22"
body: |
[GitLab Serverless](https://docs.gitlab.com/ee/user/project/clusters/serverless/) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
diff --git a/data/deprecations/templates/_deprecation_template.md.erb b/data/deprecations/templates/_deprecation_template.md.erb
index 80b860b367f..b0068c32ad9 100644
--- a/data/deprecations/templates/_deprecation_template.md.erb
+++ b/data/deprecations/templates/_deprecation_template.md.erb
@@ -44,6 +44,7 @@ For deprecation reviewers (Technical Writers only):
<%= deprecation["body"] -%>
Announced: <%= deprecation["announcement_date"]%>
+Planned removal: <%= deprecation["removal_date"]%>
<%- end -%>
<%- end -%>
<%- else -%>
diff --git a/data/deprecations/templates/example.yml b/data/deprecations/templates/example.yml
index 0aaa68e4bd8..07e65af8277 100644
--- a/data/deprecations/templates/example.yml
+++ b/data/deprecations/templates/example.yml
@@ -14,6 +14,7 @@
announcement_milestone: "XX.YY" # The milestone when this feature was first announced as deprecated.
announcement_date: "YYYY-MM-DD" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "XX.YY" # The milestone when this feature is planned to be removed
+ removal_date: "YYYY-MM-DD" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
body: | # Do not modify this line, instead modify the lines below.
<!-- START OF BODY COMMENT
@@ -29,4 +30,3 @@
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
diff --git a/db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb b/db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb
new file mode 100644
index 00000000000..1e1fdbdb122
--- /dev/null
+++ b/db/migrate/20211208111425_add_executor_type_column_to_ci_runners.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddExecutorTypeColumnToCiRunners < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :ci_runners, :executor_type, :smallint, null: true
+ end
+end
diff --git a/db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb b/db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb
new file mode 100644
index 00000000000..92b5a1b085c
--- /dev/null
+++ b/db/post_migrate/20211213064821_add_agent_id_location_index_to_vulnerability_occurrences.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddAgentIdLocationIndexToVulnerabilityOccurrences < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_vulnerability_occurrences_on_location_agent_id'
+
+ def up
+ add_concurrent_index :vulnerability_occurrences, "(location -> 'agent_id')",
+ using: 'GIN',
+ where: 'report_type = 7',
+ name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :vulnerability_occurrences, INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20211208111425 b/db/schema_migrations/20211208111425
new file mode 100644
index 00000000000..0b1aa9199b6
--- /dev/null
+++ b/db/schema_migrations/20211208111425
@@ -0,0 +1 @@
+1e3f29ed1a820588da9fe135fbdd0feaa960038b99397dbd7921d4804dce1e1f \ No newline at end of file
diff --git a/db/schema_migrations/20211213064821 b/db/schema_migrations/20211213064821
new file mode 100644
index 00000000000..119805a99b7
--- /dev/null
+++ b/db/schema_migrations/20211213064821
@@ -0,0 +1 @@
+9d7e85ac7c9ee2b9505c479b878cb07888cf089c04d34bdeb834fbb0c5111931 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 260c84be257..b25db1fbfbc 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -12175,7 +12175,8 @@ CREATE TABLE ci_runners (
token_encrypted character varying,
public_projects_minutes_cost_factor double precision DEFAULT 0.0 NOT NULL,
private_projects_minutes_cost_factor double precision DEFAULT 1.0 NOT NULL,
- config jsonb DEFAULT '{}'::jsonb NOT NULL
+ config jsonb DEFAULT '{}'::jsonb NOT NULL,
+ executor_type smallint
);
CREATE SEQUENCE ci_runners_id_seq
@@ -27941,6 +27942,8 @@ CREATE INDEX index_vulnerability_occurrences_deduplication ON vulnerability_occu
CREATE INDEX index_vulnerability_occurrences_for_issue_links_migration ON vulnerability_occurrences USING btree (project_id, report_type, encode(project_fingerprint, 'hex'::text));
+CREATE INDEX index_vulnerability_occurrences_on_location_agent_id ON vulnerability_occurrences USING gin (((location -> 'agent_id'::text))) WHERE (report_type = 7);
+
CREATE INDEX index_vulnerability_occurrences_on_location_cluster_id ON vulnerability_occurrences USING gin (((location -> 'cluster_id'::text))) WHERE (report_type = 7);
CREATE INDEX index_vulnerability_occurrences_on_location_image ON vulnerability_occurrences USING gin (((location -> 'image'::text))) WHERE (report_type = ANY (ARRAY[2, 7]));
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index aed1a39a2c2..2f6468ff9e1 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -45,6 +45,7 @@ The Task Runner pod is used to execute periodic housekeeping tasks within the Gi
This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`.
Announced: 2021-08-22
+Planned removal: 2021-11-22
## 14.6
@@ -53,6 +54,7 @@ Announced: 2021-08-22
The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
Announced: 2021-08-22
+Planned removal: 2021-12-22
## 14.8
@@ -63,6 +65,7 @@ Distribution support and security updates for openSUSE Leap 15.2 are [ending Dec
Starting in 14.5 we are providing packages for openSUSE Leap 15.3, and will stop providing packages for openSUSE Leap 15.2 in the 14.8 milestone.
Announced: 2021-11-22
+Planned removal: 2022-02-22
## 15.0
@@ -73,6 +76,7 @@ A breaking change will occur for the Runner [API](https://docs.gitlab.com/ee/api
Instead of the GitLab Runner API endpoints returning `offline` and `not_connected` for runners that have not contacted the GitLab instance in the past three months, the API endpoints will return the `stale` value, which was introduced in 14.6.
Announced: 2021-12-22
+Planned removal: 2022-05-22
### Audit events for repository push events
@@ -83,12 +87,14 @@ feature flag. Enabling them can cause too many events to be generated which can
dramatically slow down GitLab instances. For this reason, they are being removed.
Announced: 2021-09-22
+Planned removal: 2022-05-22
### CI/CD job name length limit
In GitLab 15.0 we are going to limit the number of characters in CI/CD job names to 255. Any pipeline with job names that exceed the 255 character limit will stop working after the 15.0 release.
Announced: 2021-12-22
+Planned removal: 2022-05-22
### Certificate-based integration with Kubernetes
@@ -103,12 +109,14 @@ For a more robust, secure, forthcoming, and reliable integration with Kubernetes
[Kubernetes Agent](https://docs.gitlab.com/ee/user/clusters/agent/) to connect Kubernetes clusters with GitLab.
Announced: 2021-11-15
+Planned removal: 2022-05-22
### Converting an instance (shared) runner to a project (specific) runner is deprecated
In GitLab 15.0, we will remove the feature that enables you to convert an instance (shared) runner to a project (specific) runner. Users who need to add a runner to only a particular project can register a runner to the project directly.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Deprecate `Versions` on base `PackageType`
@@ -117,6 +125,7 @@ As part of the work to create a [Package Registry GraphQL API](https://gitlab.co
In milestone 15.0, we will completely remove `Version` from `PackageType`.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Deprecate legacy approval status names from License Compliance API
@@ -125,12 +134,14 @@ We deprecated legacy names for approval status of license policy (blacklisted, a
If you are using our License Compliance API you should stop using the `approved` and `blacklisted` query parameters, they are now `allowed` and `denied`. In 15.0 the responses will also stop using `approved` and `blacklisted` so you need to adjust any of your custom tools to use the old and new values so they do not break with the 15.0 release.
Announced: 2021-12-22
+Planned removal: 2022-05-22
### Deprecate support for SLES 12 SP2
Long term service and support (LTSS) for SUSE Linux Enterprise Server (SLES) 12 SP2 [ended on March 31, 2021](https://www.suse.com/lifecycle/). The CA certificates on SP2 include the expired DST root certificate, and it's not getting new CA certificate package updates. We have implemented some [workarounds](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/merge_requests/191), but we will not be able to continue to keep the build running properly.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Deprecation of Runner status `not_connected` API value
@@ -140,6 +151,7 @@ will return `never_contacted` instead of `not_connected` as the status values in
Runners that have never contacted the GitLab instance will also return `stale` if created more than 3 months ago.
Announced: 2021-12-22
+Planned removal: 2022-05-22
### Deprecation of bundler-audit Dependency Scanning tool
@@ -148,6 +160,7 @@ As of 14.6 bundler-audit is being deprecated from Dependency Scanning. It will c
If you have explicitly excluded bundler-audit using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration, for example to edit the `bundler-audit-dependency_scanning` job, you will want to switch to gemnasium-dependency_scanning before removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference bundler-audit, or customized your template specifically for bundler-audit, you will not need to take action.
Announced: 2021-12-22
+Planned removal: 2022-05-22
### GitLab Serverless
@@ -156,6 +169,7 @@ Announced: 2021-12-22
We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
Announced: 2021-09-22
+Planned removal: 2022-05-22
### Known host required for GitLab Runner SSH executor
@@ -164,6 +178,7 @@ In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/30
In GitLab 15.0 and later, the default value for this configuration option will change from `true` to `false`. This means that strict host key checking will be enforced when using the GitLab Runner SSH executor.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Legacy database configuration
@@ -174,6 +189,7 @@ supported using a single PostgreSQL adapter, whereas the new format is changing
This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
Announced: 2021-09-22
+Planned removal: 2022-05-22
### Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`
@@ -182,6 +198,7 @@ In GitLab 15.0 and later, to access the AWS S3 cache, you must specify the `Auth
Prior to 14.5, if you did not define the `AuthenticationType`, GitLab Runner chose a type for you.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### NFS for Git repository storage deprecated
@@ -196,6 +213,7 @@ Gitaly Cluster offers tremendous benefits for our customers such as:
We encourage customers currently using NFS for Git repositories to plan their migration by reviewing our documentation on [migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/index.html#migrate-to-gitaly-cluster).
Announced: 2021-06-22
+Planned removal: 2022-05-22
### OmniAuth Kerberos gem
@@ -206,6 +224,7 @@ This gem has not been maintained and has very little usage. We therefore plan to
Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
Announced: 2021-09-22
+Planned removal: 2022-05-22
### Package pipelines in API payload is paginated
@@ -214,6 +233,7 @@ A request to the API for `/api/v4/projects/:id/packages` returns a paginated res
In milestone 15.0, we will remove the `pipelines` attribute from the API response.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### REST API Runner will not contain `paused`
@@ -226,30 +246,35 @@ When checking if a runner is `paused`, API users are advised to check the boolea
`active` to be `false` instead. When checking if a runner is `active`, check if `active` is `true`.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Removal of `defaultMergeCommitMessageWithDescription` GraphQL API field
The GraphQL API field `defaultMergeCommitMessageWithDescription` has been deprecated and will be removed in GitLab 15.0. For projects with a commit message template set, it will ignore the template.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Removal of `promote-db` command from `gitlab-ctl`
In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-db` which is used to promote database nodes in multi-node Geo secondary sites. `gitlab-ctl promote-db` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Removal of `promote-to-primary-node` command from `gitlab-ctl`
In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-to-primary-node` which was only usable for single-node Geo sites. `gitlab-ctl promote-to-primary-node` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Remove `type` and `types` keyword in CI/CD configuration
The `type` and `types` CI/CD keywords will be removed in GitLab 15.0. Pipelines that use these keywords will stop working, so you must switch to `stage` and `stages`, which have the same behavior.
Announced: 2021-12-22
+Planned removal: 2022-05-22
### Remove the `:dependency_proxy_for_private_groups` feature flag
@@ -258,6 +283,7 @@ We added a feature flag because [GitLab-#11582](https://gitlab.com/gitlab-org/gi
In milestone 15.0, we will remove the feature flag entirely. Moving forward, you must authenticate when using the Dependency Proxy.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Remove the `pipelines` field from the `version` field
@@ -269,6 +295,7 @@ In GraphQL, there are two `pipelines` fields that you can use in a [`PackageDeta
To mitigate possible performance problems, we will remove the `versions` field's `pipelines` field in milestone 15.0. Although you will no longer be able to get all pipelines for all versions of a package, you can still get the pipelines of a single version through the remaining `pipelines` field for that version.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Update to the Container Registry group-level API
@@ -277,6 +304,7 @@ In milestone 15.0, support for the `tags` and `tags_count` parameters will be re
The `GET /groups/:id/registry/repositories` endpoint will remain, but won't return any info about tags. To get the info about tags, you can use the existing `GET /registry/repositories/:id` endpoint, which will continue to support the `tags` and `tag_count` options as it does today. The latter must be called once per image repository.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### Value Stream Analytics filtering calculation change
@@ -285,6 +313,7 @@ We are changing how the date filter works in Value Stream Analytics. Instead of
If you monitor Value Stream Analytics metrics and rely on the date filter, to avoid losing data, you must save the data prior to this change.
Announced: 2021-11-22
+Planned removal: 2022-05-22
### apiFuzzingCiConfigurationCreate GraphQL mutation
@@ -293,3 +322,4 @@ API request anymore. We are therefore deprecating the `apiFuzzingCiConfiguration
which isn't being used in GitLab anymore.
Announced: 2021-12-22
+Planned removal: 2022-05-22
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index e4f042e7b0a..23e186e25ec 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -970,6 +970,11 @@ To view running completed and scheduled on-demand DAST scans for a project, go t
- To view scheduled scans, select **Scheduled**. It shows on-demand scans that have a schedule
set up. Those are _not_ included in the **All** tab.
+#### Cancel an on-demand scan
+
+To cancel a pending or running on-demand scan, select **Cancel** (**{cancel}**) in the
+on-demand scans list.
+
### Run an on-demand DAST scan
Prerequisites:
diff --git a/lib/api/ci/helpers/runner.rb b/lib/api/ci/helpers/runner.rb
index 29d02e7d1f1..72c388160b4 100644
--- a/lib/api/ci/helpers/runner.rb
+++ b/lib/api/ci/helpers/runner.rb
@@ -29,7 +29,7 @@ module API
def get_runner_details_from_request
return get_runner_ip unless params['info'].present?
- attributes_for_keys(%w(name version revision platform architecture), params['info'])
+ attributes_for_keys(%w(name version revision platform architecture executor), params['info'])
.merge(get_runner_config_from_request)
.merge(get_runner_ip)
end
diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb
index cd9b5fe13ad..9fcfcf4acc4 100644
--- a/lib/banzai/filter/syntax_highlight_filter.rb
+++ b/lib/banzai/filter/syntax_highlight_filter.rb
@@ -58,10 +58,10 @@ module Banzai
sourcepos_attr = sourcepos ? "data-sourcepos=\"#{sourcepos}\"" : ''
- highlighted = %(<pre #{sourcepos_attr} class="#{css_classes}"
+ highlighted = %(<div class="gl-relative markdown-code-block js-markdown-code"><pre #{sourcepos_attr} class="#{css_classes}"
lang="#{language}"
#{lang_params}
- v-pre="true"><code>#{code}</code></pre>)
+ v-pre="true"><code>#{code}</code></pre><copy-code></copy-code></div>)
# Extracted to a method to measure it
replace_parent_pre_element(node, highlighted)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 26dbf747fc0..17abab94272 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -23978,7 +23978,7 @@ msgstr ""
msgid "Notes|Collapse replies"
msgstr ""
-msgid "Notes|Confidential comments are only visible to project members"
+msgid "Notes|Confidential comments are only visible to members with the role of Reporter or higher"
msgstr ""
msgid "Notes|Make this comment confidential"
@@ -24481,6 +24481,9 @@ msgstr ""
msgid "OnDemandScans|Target"
msgstr ""
+msgid "OnDemandScans|The scan could not be canceled."
+msgstr ""
+
msgid "OnDemandScans|There are no finished scans."
msgstr ""
@@ -28475,6 +28478,9 @@ msgstr ""
msgid "ProtectedTag|What are protected tags?"
msgstr ""
+msgid "ProtectedTag|default"
+msgstr ""
+
msgid "Protip: %{linkStart}Auto DevOps%{linkEnd} uses Kubernetes clusters to deploy your code!"
msgstr ""
@@ -40980,6 +40986,9 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
+msgstr ""
+
msgid "ciReport|%{degradedNum} degraded"
msgstr ""
@@ -41010,7 +41019,7 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
-msgid "ciReport|%{prefix} %{strongStart}%{score}%{strongEnd} %{delta} %{deltaPercent} in %{path}"
+msgid "ciReport|%{prefix} %{strong_start}%{score}%{strong_end} %{delta} %{deltaPercent} in %{path}"
msgstr ""
msgid "ciReport|%{remainingPackagesCount} more"
@@ -41058,8 +41067,8 @@ msgstr ""
msgid "ciReport|Browser performance test metrics: "
msgstr ""
-msgid "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Browser performance test metrics: %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Browser performance test metrics: %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
@@ -41153,8 +41162,8 @@ msgstr ""
msgid "ciReport|Load Performance"
msgstr ""
-msgid "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} change"
-msgid_plural "ciReport|Load performance test metrics detected %{strongStart}%{changesFound}%{strongEnd} changes"
+msgid "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} change"
+msgid_plural "ciReport|Load performance test metrics detected %{strong_start}%{changesFound}%{strong_end} changes"
msgstr[0] ""
msgstr[1] ""
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 793d7606061..14f10d2b047 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -205,7 +205,7 @@ GEM
parallel (1.19.2)
parallel_tests (2.29.0)
parallel
- parser (3.0.2.0)
+ parser (3.0.3.2)
ast (~> 2.4.1)
proc_to_ast (0.1.0)
coderay
diff --git a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb b/qa/qa/specs/features/browser_ui/14_non_devops/performance_bar_spec.rb
index 9d84658da76..9d84658da76 100644
--- a/qa/qa/specs/features/browser_ui/non_devops/performance_bar_spec.rb
+++ b/qa/qa/specs/features/browser_ui/14_non_devops/performance_bar_spec.rb
diff --git a/qa/qa/specs/features/browser_ui/non_devops/service_ping_default_enabled_spec.rb b/qa/qa/specs/features/browser_ui/14_non_devops/service_ping_default_enabled_spec.rb
index ecc59aa7cc8..ecc59aa7cc8 100644
--- a/qa/qa/specs/features/browser_ui/non_devops/service_ping_default_enabled_spec.rb
+++ b/qa/qa/specs/features/browser_ui/14_non_devops/service_ping_default_enabled_spec.rb
diff --git a/qa/qa/specs/features/browser_ui/non_devops/service_ping_disabled_spec.rb b/qa/qa/specs/features/browser_ui/14_non_devops/service_ping_disabled_spec.rb
index 309369265c9..309369265c9 100644
--- a/qa/qa/specs/features/browser_ui/non_devops/service_ping_disabled_spec.rb
+++ b/qa/qa/specs/features/browser_ui/14_non_devops/service_ping_disabled_spec.rb
diff --git a/spec/features/issues/csv_spec.rb b/spec/features/issues/csv_spec.rb
index b4c737495b4..9fd171bf44b 100644
--- a/spec/features/issues/csv_spec.rb
+++ b/spec/features/issues/csv_spec.rb
@@ -47,13 +47,13 @@ RSpec.describe 'Issues csv', :js do
expect(page).to have_content "emailed to #{user.notification_email_or_default}"
end
- it 'includes a csv attachment', :sidekiq_might_not_need_inline do
+ it 'includes a csv attachment', :sidekiq_inline do
request_csv
expect(attachment.content_type).to include('text/csv')
end
- it 'ignores pagination', :sidekiq_might_not_need_inline do
+ it 'ignores pagination', :sidekiq_inline do
create_list(:issue, 30, project: project, author: user)
request_csv
@@ -61,13 +61,13 @@ RSpec.describe 'Issues csv', :js do
expect(csv.count).to eq 31
end
- it 'uses filters from issue index', :sidekiq_might_not_need_inline do
+ it 'uses filters from issue index', :sidekiq_inline do
request_csv(state: :closed)
expect(csv.count).to eq 0
end
- it 'ignores sorting from issue index', :sidekiq_might_not_need_inline do
+ it 'ignores sorting from issue index', :sidekiq_inline do
issue2 = create(:labeled_issue, project: project, author: user, labels: [feature_label])
request_csv(sort: :label_priority)
@@ -76,23 +76,11 @@ RSpec.describe 'Issues csv', :js do
expect(csv.map { |row| row['Issue ID'] }).to eq expected
end
- it 'uses array filters, such as label_name', :sidekiq_might_not_need_inline do
+ it 'uses array filters, such as label_name', :sidekiq_inline do
issue.update!(labels: [idea_label])
request_csv("label_name[]" => 'Bug')
expect(csv.count).to eq 0
end
-
- it 'avoids excessive database calls' do
- control_count = ActiveRecord::QueryRecorder.new { request_csv }.count
- create_list(:labeled_issue,
- 10,
- project: project,
- assignees: [user],
- author: user,
- milestone: milestone,
- labels: [feature_label, idea_label])
- expect { request_csv }.not_to exceed_query_limit(control_count + 5)
- end
end
diff --git a/spec/fixtures/markdown/markdown_golden_master_examples.yml b/spec/fixtures/markdown/markdown_golden_master_examples.yml
index 13af419d309..29d823c46aa 100644
--- a/spec/fixtures/markdown/markdown_golden_master_examples.yml
+++ b/spec/fixtures/markdown/markdown_golden_master_examples.yml
@@ -111,7 +111,6 @@
# `html` value based on the spec failure that is printed out.
---
-
#- name: an_example_of_pending
# pending: 'This is an example of the pending attribute: http://example.com'
# markdown: ;)
@@ -297,7 +296,10 @@
console.log('hello world')
```
html: |-
+ <div class="gl-relative markdown-code-block js-markdown-code">
<pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-javascript" lang="javascript" v-pre="true"><code><span id="LC1" class="line" lang="javascript"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hello world</span><span class="dl">'</span><span class="p">)</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
- name: color_chips
markdown: |-
@@ -469,23 +471,34 @@
}
;;;
html: |-
+ <div class="gl-relative markdown-code-block js-markdown-code">
<pre data-sourcepos="1:1-5:3" class="code highlight js-syntax-highlight language-json" lang="json" data-lang-params="frontmatter" v-pre="true"><code><span id="LC1" class="line" lang="json"><span class="p">{</span></span>
<span id="LC2" class="line" lang="json"><span class="w"> </span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Page title"</span></span>
<span id="LC3" class="line" lang="json"><span class="p">}</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
- name: frontmatter_toml
markdown: |-
+++
title = "Page title"
+++
- html: <pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-toml" lang="toml" data-lang-params="frontmatter" v-pre="true"><code><span id="LC1" class="line" lang="toml"><span class="py">title</span> <span class="p">=</span> <span class="s">"Page title"</span></span></code></pre>
+ html: |-
+ <div class="gl-relative markdown-code-block js-markdown-code">
+ <pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-toml" lang="toml" data-lang-params="frontmatter" v-pre="true"><code><span id="LC1" class="line" lang="toml"><span class="py">title</span> <span class="p">=</span> <span class="s">"Page title"</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
- name: frontmatter_yaml
markdown: |-
---
title: Page title
---
- html: <pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-yaml" lang="yaml" data-lang-params="frontmatter" v-pre="true"><code><span id="LC1" class="line" lang="yaml"><span class="na">title</span><span class="pi">:</span> <span class="s">Page title</span></span></code></pre>
+ html: |-
+ <div class="gl-relative markdown-code-block js-markdown-code">
+ <pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-yaml" lang="yaml" data-lang-params="frontmatter" v-pre="true"><code><span id="LC1" class="line" lang="yaml"><span class="na">title</span><span class="pi">:</span> <span class="s">Page title</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
- name: hard_break
markdown: |-
@@ -617,7 +630,10 @@
html: |-
<p data-sourcepos="1:1-1:36" dir="auto">This math is inline <code class="code math js-render-math" data-math-style="inline">a^2+b^2=c^2</code>.</p>
<p data-sourcepos="3:1-3:27" dir="auto">This is on a separate line:</p>
+ <div class="gl-relative markdown-code-block js-markdown-code">
<pre data-sourcepos="5:1-7:3" class="code highlight js-syntax-highlight language-math js-render-math" lang="math" v-pre="true" data-math-style="display"><code><span id="LC1" class="line" lang="math">a^2+b^2=c^2</span></code></pre>
+ <copy-code></copy-code>
+ </div>
- name: ordered_list
markdown: |-
diff --git a/spec/frontend/lib/utils/dom_utils_spec.js b/spec/frontend/lib/utils/dom_utils_spec.js
index cb8b1c7ca9a..2f240f25d2a 100644
--- a/spec/frontend/lib/utils/dom_utils_spec.js
+++ b/spec/frontend/lib/utils/dom_utils_spec.js
@@ -6,6 +6,7 @@ import {
isElementVisible,
isElementHidden,
getParents,
+ setAttributes,
} from '~/lib/utils/dom_utils';
const TEST_MARGIN = 5;
@@ -208,4 +209,15 @@ describe('DOM Utils', () => {
]);
});
});
+
+ describe('setAttributes', () => {
+ it('sets multiple attribues on element', () => {
+ const div = document.createElement('div');
+
+ setAttributes(div, { class: 'test', title: 'another test' });
+
+ expect(div.getAttribute('class')).toBe('test');
+ expect(div.getAttribute('title')).toBe('another test');
+ });
+ });
});
diff --git a/spec/frontend/vue_mr_widget/components/extensions/utils_spec.js b/spec/frontend/vue_mr_widget/components/extensions/utils_spec.js
new file mode 100644
index 00000000000..64e802c4fa5
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/extensions/utils_spec.js
@@ -0,0 +1,18 @@
+import { generateText } from '~/vue_merge_request_widget/components/extensions/utils';
+
+describe('generateText', () => {
+ it.each`
+ text | expectedText
+ ${'%{strong_start}Hello world%{strong_end}'} | ${'<span class="gl-font-weight-bold">Hello world</span>'}
+ ${'%{success_start}Hello world%{success_end}'} | ${'<span class="gl-font-weight-bold gl-text-green-500">Hello world</span>'}
+ ${'%{danger_start}Hello world%{danger_end}'} | ${'<span class="gl-font-weight-bold gl-text-red-500">Hello world</span>'}
+ ${'%{critical_start}Hello world%{critical_end}'} | ${'<span class="gl-font-weight-bold gl-text-red-800">Hello world</span>'}
+ ${'%{same_start}Hello world%{same_end}'} | ${'<span class="gl-font-weight-bold gl-text-gray-700">Hello world</span>'}
+ ${'%{small_start}Hello world%{small_end}'} | ${'<span class="gl-font-sm">Hello world</span>'}
+ ${'%{strong_start}%{danger_start}Hello world%{danger_end}%{strong_end}'} | ${'<span class="gl-font-weight-bold"><span class="gl-font-weight-bold gl-text-red-500">Hello world</span></span>'}
+ ${'%{no_exist_start}Hello world%{no_exist_end}'} | ${'Hello world'}
+ ${['array']} | ${null}
+ `('generates $expectedText from $text', ({ text, expectedText }) => {
+ expect(generateText(text)).toBe(expectedText);
+ });
+});
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index 5db4ef6ad3a..ab2f6fa5b7e 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -584,9 +584,9 @@ FooBar
it 'preserves code color scheme' do
object = create_object("```ruby\ndef test\n 'hello world'\nend\n```")
- expected = "<pre class=\"code highlight js-syntax-highlight language-ruby\">" \
+ expected = "\n<pre class=\"code highlight js-syntax-highlight language-ruby\">" \
"<code><span class=\"line\"><span class=\"k\">def</span> <span class=\"nf\">test</span>...</span>\n" \
- "</code></pre>"
+ "</code></pre>\n"
expect(first_line_in_markdown(object, attribute, 150, project: project)).to eq(expected)
end
diff --git a/spec/lib/api/ci/helpers/runner_helpers_spec.rb b/spec/lib/api/ci/helpers/runner_helpers_spec.rb
index c6638bea59e..c4d740f0adc 100644
--- a/spec/lib/api/ci/helpers/runner_helpers_spec.rb
+++ b/spec/lib/api/ci/helpers/runner_helpers_spec.rb
@@ -38,6 +38,7 @@ RSpec.describe API::Ci::Helpers::Runner do
let(:revision) { '10.0' }
let(:platform) { 'test' }
let(:architecture) { 'arm' }
+ let(:executor) { 'shell' }
let(:config) { { 'gpus' => 'all' } }
let(:runner_params) do
{
@@ -48,6 +49,7 @@ RSpec.describe API::Ci::Helpers::Runner do
'revision' => revision,
'platform' => platform,
'architecture' => architecture,
+ 'executor' => executor,
'config' => config,
'ignored' => 1
}
@@ -57,12 +59,13 @@ RSpec.describe API::Ci::Helpers::Runner do
subject(:details) { runner_helper.get_runner_details_from_request }
it 'extracts the runner details', :aggregate_failures do
- expect(details.keys).to match_array(%w(name version revision platform architecture config ip_address))
+ expect(details.keys).to match_array(%w(name version revision platform architecture executor config ip_address))
expect(details['name']).to eq(name)
expect(details['version']).to eq(version)
expect(details['revision']).to eq(revision)
expect(details['platform']).to eq(platform)
expect(details['architecture']).to eq(architecture)
+ expect(details['executor']).to eq(executor)
expect(details['config']).to eq(config)
expect(details['ip_address']).to eq(ip_address)
end
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index 62e93cb1653..ef46fd62486 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "highlights as plaintext" do
result = filter('<pre><code>def fun end</code></pre>')
- expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre>')
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">def fun end</span></code></pre><copy-code></copy-code></div>')
end
include_examples "XSS prevention", ""
@@ -46,7 +46,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
filter('<pre><code lang="ruby">def fun end</code></pre>')
end
- expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight language-ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre>')
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-ruby" lang="ruby" v-pre="true"><code><span id="LC1" class="line" lang="ruby"><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></span></code></pre><copy-code></copy-code></div>')
end
include_examples "XSS prevention", "ruby"
@@ -60,7 +60,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
filter('<pre><code lang="gnuplot">This is a test</code></pre>')
end
- expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre>')
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
end
include_examples "XSS prevention", "gnuplot"
@@ -79,7 +79,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
filter(%{<pre><code lang="#{lang}">This is a test</code></pre>})
end
- expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>})
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
end
include_examples "XSS prevention", lang
@@ -103,7 +103,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}">This is a test</code></pre>})
end
- expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>})
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
end
include_examples "XSS prevention", lang
@@ -126,7 +126,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
let(:lang_params) { '-1+10' }
let(:expected_result) do
- %{<pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params} more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>}
+ %{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params} more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>}
end
context 'when delimiter is space' do
@@ -134,11 +134,11 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
result = filter(%{<pre lang="#{lang}" data-meta="#{lang_params} more-things"><code>This is a test</code></pre>})
- expect(result.to_html).to eq(expected_result)
+ expect(result.to_html.delete("\n")).to eq(expected_result)
else
result = filter(%{<pre><code lang="#{lang}#{delimiter}#{lang_params}#{delimiter}more-things">This is a test</code></pre>})
- expect(result.to_html).to eq(%{<pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}#{delimiter}more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre>})
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight language-#{lang}" lang="#{lang}" #{data_attr}="#{lang_params}#{delimiter}more-things" v-pre="true"><code><span id="LC1" class="line" lang="#{lang}">This is a test</span></code></pre><copy-code></copy-code></div>})
end
end
end
@@ -148,9 +148,9 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
result = filter(%{<pre lang="#{lang}#{delimiter}#{lang_params} more-things"><code>This is a test</code></pre>})
if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- expect(result.to_html).to eq(expected_result)
+ expect(result.to_html.delete("\n")).to eq(expected_result)
else
- expect(result.to_html).to eq(%{<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">This is a test</span></code></pre>})
+ expect(result.to_html.delete("\n")).to eq(%{<div class="gl-relative markdown-code-block js-markdown-code"><pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">This is a test</span></code></pre><copy-code></copy-code></div>})
end
end
end
@@ -161,7 +161,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
it "includes it in the highlighted code block" do
result = filter('<pre data-sourcepos="1:1-3:3"><code lang="plaintext">This is a test</code></pre>')
- expect(result.to_html).to eq('<pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre>')
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre data-sourcepos="1:1-3:3" class="code highlight js-syntax-highlight language-plaintext" lang="plaintext" v-pre="true"><code><span id="LC1" class="line" lang="plaintext">This is a test</span></code></pre><copy-code></copy-code></div>')
end
end
@@ -179,7 +179,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
filter('<pre><code lang="ruby">This is a test</code></pre>')
end
- expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code><span id="LC1" class="line" lang="">This is a test</span></code></pre>')
+ expect(result.to_html.delete("\n")).to eq('<div class="gl-relative markdown-code-block js-markdown-code"><pre class="code highlight js-syntax-highlight" lang="" v-pre="true"><code><span id="LC1" class="line" lang="">This is a test</span></code></pre><copy-code></copy-code></div>')
end
include_examples "XSS prevention", "ruby"
diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb
index 87874c73e75..7200ff3c4db 100644
--- a/spec/lib/gitlab/asciidoc_spec.rb
+++ b/spec/lib/gitlab/asciidoc_spec.rb
@@ -97,9 +97,9 @@ module Gitlab
input = '```mypre"><script>alert(3)</script>'
output =
if Feature.enabled?(:use_cmark_renderer, default_enabled: :yaml)
- "<div>\n<div>\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code></code></pre>\n</div>\n</div>"
+ "<div>\n<div>\n<div class=\"gl-relative markdown-code-block js-markdown-code\">\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code></code></pre>\n<copy-code></copy-code>\n</div>\n</div>\n</div>"
else
- "<div>\n<div>\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">\"&gt;</span></code></pre>\n</div>\n</div>"
+ "<div>\n<div>\n<div class=\"gl-relative markdown-code-block js-markdown-code\">\n<pre class=\"code highlight js-syntax-highlight language-plaintext\" lang=\"plaintext\" v-pre=\"true\"><code><span id=\"LC1\" class=\"line\" lang=\"plaintext\">\"&gt;</span></code></pre>\n<copy-code></copy-code>\n</div>\n</div>\n</div>"
end
expect(render(input, context)).to include(output)
@@ -365,7 +365,10 @@ module Gitlab
output = <<~HTML
<div>
<div>
+ <div class="gl-relative markdown-code-block js-markdown-code">
<pre class="code highlight js-syntax-highlight language-javascript" lang="javascript" v-pre="true"><code><span id="LC1" class="line" lang="javascript"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hello world</span><span class="dl">'</span><span class="p">)</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
</div>
</div>
HTML
@@ -392,11 +395,14 @@ module Gitlab
<div>
<div>class.cpp</div>
<div>
+ <div class="gl-relative markdown-code-block js-markdown-code">
<pre class="code highlight js-syntax-highlight language-cpp" lang="cpp" v-pre="true"><code><span id="LC1" class="line" lang="cpp"><span class="cp">#include &lt;stdio.h&gt;</span></span>
<span id="LC2" class="line" lang="cpp"></span>
<span id="LC3" class="line" lang="cpp"><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span></span>
<span id="LC4" class="line" lang="cpp"> <span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"*"</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span></span>
<span id="LC5" class="line" lang="cpp"><span class="p">}</span></span></code></pre>
+ <copy-code></copy-code>
+ </div>
</div>
</div>
HTML
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index af810572106..5142f70fa2c 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -903,8 +903,9 @@ RSpec.describe Ci::Runner do
describe '#heartbeat' do
let(:runner) { create(:ci_runner, :project) }
+ let(:executor) { 'shell' }
- subject { runner.heartbeat(architecture: '18-bit', config: { gpus: "all" }) }
+ subject { runner.heartbeat(architecture: '18-bit', config: { gpus: "all" }, executor: executor) }
context 'when database was updated recently' do
before do
@@ -940,6 +941,26 @@ RSpec.describe Ci::Runner do
expect_redis_update
does_db_update
end
+
+ %w(custom shell docker docker-windows docker-ssh ssh parallels virtualbox docker+machine docker-ssh+machine kubernetes some-unknown-type).each do |executor|
+ context "with #{executor} executor" do
+ let(:executor) { executor }
+
+ it 'updates with expected executor type' do
+ expect_redis_update
+
+ subject
+
+ expect(runner.reload.read_attribute(:executor_type)).to eq(expected_executor_type)
+ end
+
+ def expected_executor_type
+ return 'unknown' if executor == 'some-unknown-type'
+
+ executor.gsub(/[+-]/, '_')
+ end
+ end
+ end
end
def expect_redis_update
@@ -953,6 +974,7 @@ RSpec.describe Ci::Runner do
expect { subject }.to change { runner.reload.read_attribute(:contacted_at) }
.and change { runner.reload.read_attribute(:architecture) }
.and change { runner.reload.read_attribute(:config) }
+ .and change { runner.reload.read_attribute(:executor_type) }
end
end
diff --git a/spec/services/deployments/older_deployments_drop_service_spec.rb b/spec/services/deployments/older_deployments_drop_service_spec.rb
index 15bd894e7bf..d9a512a5dd2 100644
--- a/spec/services/deployments/older_deployments_drop_service_spec.rb
+++ b/spec/services/deployments/older_deployments_drop_service_spec.rb
@@ -70,13 +70,12 @@ RSpec.describe Deployments::OlderDeploymentsDropService do
let(:older_deployment) { create(:deployment, :created, environment: environment, deployable: build) }
let(:build) { create(:ci_build, :manual) }
- it 'drops the older deployment' do
- deployable = older_deployment.deployable
- expect(deployable.failed?).to be_falsey
+ # Manual jobs should not be accounted as outdated deployment jobs.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/255978 for more information.
+ it 'does not drop any builds nor track the exception' do
+ expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
- subject
-
- expect(deployable.reload.failed?).to be_truthy
+ expect { subject }.not_to change { Ci::Build.failed.count }
end
end
diff --git a/spec/workers/bulk_imports/entity_worker_spec.rb b/spec/workers/bulk_imports/entity_worker_spec.rb
index deae15a3ca2..ce45299c7f7 100644
--- a/spec/workers/bulk_imports/entity_worker_spec.rb
+++ b/spec/workers/bulk_imports/entity_worker_spec.rb
@@ -14,96 +14,118 @@ RSpec.describe BulkImports::EntityWorker do
)
end
- it 'enqueues the first stage pipelines work' do
- expect_next_instance_of(Gitlab::Import::Logger) do |logger|
- expect(logger)
- .to receive(:info)
- .with(
- worker: described_class.name,
- entity_id: entity.id,
- current_stage: nil
- )
- end
+ let(:job_args) { entity.id }
- expect(BulkImports::PipelineWorker)
- .to receive(:perform_async)
- .with(
- pipeline_tracker.id,
- pipeline_tracker.stage,
- entity.id
- )
+ it 'updates pipeline trackers to enqueued state when selected' do
+ worker = BulkImports::EntityWorker.new
- subject.perform(entity.id)
- end
+ next_tracker = worker.send(:next_pipeline_trackers_for, entity.id).first
- it 'do not enqueue a new pipeline job if the current stage still running' do
- expect(BulkImports::PipelineWorker)
- .not_to receive(:perform_async)
+ next_tracker.reload
- subject.perform(entity.id, 0)
- end
-
- it 'enqueues the next stage pipelines when the current stage is finished' do
- next_stage_pipeline_tracker = create(
- :bulk_import_tracker,
- entity: entity,
- pipeline_name: 'Stage1::Pipeline',
- stage: 1
- )
+ expect(next_tracker.enqueued?).to be_truthy
- pipeline_tracker.fail_op!
+ expect(worker.send(:next_pipeline_trackers_for, entity.id))
+ .not_to include(next_tracker)
+ end
- expect_next_instance_of(Gitlab::Import::Logger) do |logger|
- expect(logger)
- .to receive(:info)
+ include_examples 'an idempotent worker' do
+ it 'enqueues the first stage pipelines work' do
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ # the worker runs twice but only executes once
+ expect(logger)
+ .to receive(:info).twice
+ .with(
+ worker: described_class.name,
+ entity_id: entity.id,
+ current_stage: nil
+ )
+ end
+
+ expect(BulkImports::PipelineWorker)
+ .to receive(:perform_async)
.with(
- worker: described_class.name,
- entity_id: entity.id,
- current_stage: 0
+ pipeline_tracker.id,
+ pipeline_tracker.stage,
+ entity.id
)
+
+ subject
end
- expect(BulkImports::PipelineWorker)
- .to receive(:perform_async)
- .with(
- next_stage_pipeline_tracker.id,
- next_stage_pipeline_tracker.stage,
- entity.id
- )
+ it 'logs and tracks the raised exceptions' do
+ exception = StandardError.new('Error!')
+
+ expect(BulkImports::PipelineWorker)
+ .to receive(:perform_async)
+ .and_raise(exception)
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:info).twice
+ .with(
+ worker: described_class.name,
+ entity_id: entity.id,
+ current_stage: nil
+ )
+
+ expect(logger)
+ .to receive(:error)
+ .with(
+ worker: described_class.name,
+ entity_id: entity.id,
+ current_stage: nil,
+ error_message: 'Error!'
+ )
+ end
+
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception)
+ .with(exception, entity_id: entity.id)
+
+ subject
+ end
- subject.perform(entity.id, 0)
- end
+ context 'in first stage' do
+ let(:job_args) { [entity.id, 0] }
- it 'logs and tracks the raised exceptions' do
- exception = StandardError.new('Error!')
+ it 'do not enqueue a new pipeline job if the current stage still running' do
+ expect(BulkImports::PipelineWorker)
+ .not_to receive(:perform_async)
- expect(BulkImports::PipelineWorker)
- .to receive(:perform_async)
- .and_raise(exception)
+ subject
+ end
- expect_next_instance_of(Gitlab::Import::Logger) do |logger|
- expect(logger)
- .to receive(:info)
- .with(
- worker: described_class.name,
- entity_id: entity.id,
- current_stage: nil
+ it 'enqueues the next stage pipelines when the current stage is finished' do
+ next_stage_pipeline_tracker = create(
+ :bulk_import_tracker,
+ entity: entity,
+ pipeline_name: 'Stage1::Pipeline',
+ stage: 1
)
- expect(logger)
- .to receive(:error)
- .with(
- worker: described_class.name,
- entity_id: entity.id,
- current_stage: nil,
- error_message: 'Error!'
- )
+ pipeline_tracker.fail_op!
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:info).twice
+ .with(
+ worker: described_class.name,
+ entity_id: entity.id,
+ current_stage: 0
+ )
+ end
+
+ expect(BulkImports::PipelineWorker)
+ .to receive(:perform_async)
+ .with(
+ next_stage_pipeline_tracker.id,
+ next_stage_pipeline_tracker.stage,
+ entity.id
+ )
+
+ subject
+ end
end
-
- expect(Gitlab::ErrorTracking)
- .to receive(:track_exception)
- .with(exception, entity_id: entity.id)
-
- subject.perform(entity.id)
end
end
diff --git a/spec/workers/bulk_imports/pipeline_worker_spec.rb b/spec/workers/bulk_imports/pipeline_worker_spec.rb
index c902d1f2034..2da9195a6ef 100644
--- a/spec/workers/bulk_imports/pipeline_worker_spec.rb
+++ b/spec/workers/bulk_imports/pipeline_worker_spec.rb
@@ -60,18 +60,8 @@ RSpec.describe BulkImports::PipelineWorker do
create(
:bulk_import_tracker,
entity: entity,
- pipeline_name: 'FakePipeline'
- )
- end
- end
-
- it_behaves_like 'successfully runs the pipeline' do
- let(:pipeline_tracker) do
- create(
- :bulk_import_tracker,
- :started,
- entity: entity,
- pipeline_name: 'FakePipeline'
+ pipeline_name: 'FakePipeline',
+ status_event: 'enqueue'
)
end
end
@@ -109,7 +99,8 @@ RSpec.describe BulkImports::PipelineWorker do
pipeline_tracker = create(
:bulk_import_tracker,
entity: entity,
- pipeline_name: 'InexistentPipeline'
+ pipeline_name: 'InexistentPipeline',
+ status_event: 'enqueue'
)
expect_next_instance_of(Gitlab::Import::Logger) do |logger|
@@ -150,7 +141,8 @@ RSpec.describe BulkImports::PipelineWorker do
pipeline_tracker = create(
:bulk_import_tracker,
entity: entity,
- pipeline_name: 'FakePipeline'
+ pipeline_name: 'FakePipeline',
+ status_event: 'enqueue'
)
exception = BulkImports::NetworkError.new(
@@ -163,7 +155,21 @@ RSpec.describe BulkImports::PipelineWorker do
.and_raise(exception)
end
- expect(subject).to receive(:jid).and_return('jid')
+ expect(subject).to receive(:jid).and_return('jid').twice
+
+ expect_any_instance_of(BulkImports::Tracker) do |tracker|
+ expect(tracker).to receive(:retry).and_call_original
+ end
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:info)
+ .with(
+ worker: described_class.name,
+ pipeline_name: 'FakePipeline',
+ entity_id: entity.id
+ )
+ end
expect(described_class)
.to receive(:perform_in)
@@ -175,6 +181,10 @@ RSpec.describe BulkImports::PipelineWorker do
)
subject.perform(pipeline_tracker.id, pipeline_tracker.stage, entity.id)
+
+ pipeline_tracker.reload
+
+ expect(pipeline_tracker.enqueued?).to be_truthy
end
end
end
@@ -200,7 +210,8 @@ RSpec.describe BulkImports::PipelineWorker do
create(
:bulk_import_tracker,
entity: entity,
- pipeline_name: 'NdjsonPipeline'
+ pipeline_name: 'NdjsonPipeline',
+ status_event: 'enqueue'
)
end
diff --git a/workhorse/internal/upstream/metrics.go b/workhorse/internal/upstream/metrics.go
index 38528056d43..1a11bdc8b53 100644
--- a/workhorse/internal/upstream/metrics.go
+++ b/workhorse/internal/upstream/metrics.go
@@ -101,6 +101,16 @@ var (
},
[]string{"code", "method", "route"},
)
+
+ httpGeoProxiedRequestsTotal = promauto.NewCounterVec(
+ prometheus.CounterOpts{
+ Namespace: namespace,
+ Subsystem: httpSubsystem,
+ Name: "geo_proxied_requests_total",
+ Help: "A counter for Geo proxied requests through workhorse.",
+ },
+ []string{"code", "method", "route"},
+ )
)
func instrumentRoute(next http.Handler, method string, regexpStr string) http.Handler {
@@ -115,3 +125,7 @@ func instrumentRoute(next http.Handler, method string, regexpStr string) http.Ha
return handler
}
+
+func instrumentGeoProxyRoute(next http.Handler, method string, regexpStr string) http.Handler {
+ return promhttp.InstrumentHandlerCounter(httpGeoProxiedRequestsTotal.MustCurryWith(map[string]string{"route": regexpStr}), next)
+}
diff --git a/workhorse/internal/upstream/metrics_test.go b/workhorse/internal/upstream/metrics_test.go
new file mode 100644
index 00000000000..29a9e09777c
--- /dev/null
+++ b/workhorse/internal/upstream/metrics_test.go
@@ -0,0 +1,54 @@
+package upstream
+
+import (
+ "io"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/prometheus/client_golang/prometheus/testutil"
+ "github.com/sirupsen/logrus"
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
+)
+
+func TestInstrumentGeoProxyRoute(t *testing.T) {
+ const (
+ remote = `\A/remote\z`
+ local = `\A/local\z`
+ main = ""
+ )
+
+ u := newUpstream(config.Config{}, logrus.StandardLogger(), func(u *upstream) {
+ u.Routes = []routeEntry{
+ handleRouteWithMatchers(u, remote, withGeoProxy()),
+ handleRouteWithMatchers(u, local),
+ handleRouteWithMatchers(u, main),
+ }
+ })
+ ts := httptest.NewServer(u)
+ defer ts.Close()
+
+ testCases := []testCase{
+ {"remote", "/remote", remote},
+ {"local", "/local", local},
+ {"main", "/", main},
+ }
+
+ httpGeoProxiedRequestsTotal.Reset()
+
+ runTestCases(t, ts, testCases)
+
+ require.Equal(t, 1, testutil.CollectAndCount(httpGeoProxiedRequestsTotal))
+ require.InDelta(t, 1, testutil.ToFloat64(httpGeoProxiedRequestsTotal.WithLabelValues("200", "get", remote)), 0.1)
+ require.InDelta(t, 0, testutil.ToFloat64(httpGeoProxiedRequestsTotal.WithLabelValues("200", "get", local)), 0.1)
+ require.InDelta(t, 0, testutil.ToFloat64(httpGeoProxiedRequestsTotal.WithLabelValues("200", "get", main)), 0.1)
+}
+
+func handleRouteWithMatchers(u *upstream, regex string, matchers ...func(*routeOptions)) routeEntry {
+ handler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+ io.WriteString(w, regex)
+ })
+ return u.route("", regex, handler, matchers...)
+}
diff --git a/workhorse/internal/upstream/routes.go b/workhorse/internal/upstream/routes.go
index 22b30fe8a63..06160702f84 100644
--- a/workhorse/internal/upstream/routes.go
+++ b/workhorse/internal/upstream/routes.go
@@ -42,8 +42,9 @@ type routeEntry struct {
}
type routeOptions struct {
- tracing bool
- matchers []matcherFunc
+ tracing bool
+ isGeoProxyRoute bool
+ matchers []matcherFunc
}
type uploadPreparers struct {
@@ -94,7 +95,13 @@ func withoutTracing() func(*routeOptions) {
}
}
-func (u *upstream) observabilityMiddlewares(handler http.Handler, method string, regexpStr string) http.Handler {
+func withGeoProxy() func(*routeOptions) {
+ return func(options *routeOptions) {
+ options.isGeoProxyRoute = true
+ }
+}
+
+func (u *upstream) observabilityMiddlewares(handler http.Handler, method string, regexpStr string, opts *routeOptions) http.Handler {
handler = log.AccessLogger(
handler,
log.WithAccessLogger(u.accessLogger),
@@ -106,6 +113,11 @@ func (u *upstream) observabilityMiddlewares(handler http.Handler, method string,
)
handler = instrumentRoute(handler, method, regexpStr) // Add prometheus metrics
+
+ if opts != nil && opts.isGeoProxyRoute {
+ handler = instrumentGeoProxyRoute(handler, method, regexpStr) // Add Geo prometheus metrics
+ }
+
return handler
}
@@ -119,7 +131,7 @@ func (u *upstream) route(method, regexpStr string, handler http.Handler, opts ..
f(&options)
}
- handler = u.observabilityMiddlewares(handler, method, regexpStr)
+ handler = u.observabilityMiddlewares(handler, method, regexpStr, &options)
handler = denyWebsocket(handler) // Disallow websockets
if options.tracing {
// Add distributed tracing
@@ -136,7 +148,7 @@ func (u *upstream) route(method, regexpStr string, handler http.Handler, opts ..
func (u *upstream) wsRoute(regexpStr string, handler http.Handler, matchers ...matcherFunc) routeEntry {
method := "GET"
- handler = u.observabilityMiddlewares(handler, method, regexpStr)
+ handler = u.observabilityMiddlewares(handler, method, regexpStr, nil)
return routeEntry{
method: method,
diff --git a/workhorse/internal/upstream/upstream.go b/workhorse/internal/upstream/upstream.go
index 99d1245fafc..065cae53e2b 100644
--- a/workhorse/internal/upstream/upstream.go
+++ b/workhorse/internal/upstream/upstream.go
@@ -239,5 +239,5 @@ func (u *upstream) updateGeoProxyFields(geoProxyURL *url.URL) {
geoProxyRoundTripper := roundtripper.NewBackendRoundTripper(u.geoProxyBackend, "", u.ProxyHeadersTimeout, u.DevelopmentMode)
geoProxyUpstream := proxypkg.NewProxy(u.geoProxyBackend, u.Version, geoProxyRoundTripper)
u.geoProxyCableRoute = u.wsRoute(`^/-/cable\z`, geoProxyUpstream)
- u.geoProxyRoute = u.route("", "", geoProxyUpstream)
+ u.geoProxyRoute = u.route("", "", geoProxyUpstream, withGeoProxy())
}