summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-12 12:11:05 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-12 12:11:05 +0000
commit2fe5ea34a5f63661a050404d3b5fbe3056a39765 (patch)
tree630d5b896d2933d38a206abf4e2baf7e1b773027
parentdcb517514405d6f550cc077686889dbb34c37c75 (diff)
downloadgitlab-ce-2fe5ea34a5f63661a050404d3b5fbe3056a39765.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/content_editor/extensions/code_block_highlight.js12
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_serializer.js8
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard_panel.vue13
-rw-r--r--app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue15
-rw-r--r--app/assets/javascripts/sidebar/mount_sidebar.js2
-rw-r--r--app/assets/javascripts/tracking/constants.js6
-rw-r--r--app/assets/javascripts/tracking/tracking.js3
-rw-r--r--app/assets/javascripts/tracking/utils.js10
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue34
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue260
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql12
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue32
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js22
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js8
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js21
-rw-r--r--app/helpers/analytics/navbar_helper.rb28
-rw-r--r--app/models/remote_mirror.rb17
-rw-r--r--app/services/git/branch_hooks_service.rb2
-rw-r--r--app/services/service_ping/service_ping_settings.rb6
-rw-r--r--app/views/layouts/nav/sidebar/_analytics_links.html.haml22
-rw-r--r--app/views/layouts/nav/sidebar/_group_menus.html.haml2
-rw-r--r--config/feature_flags/development/agent_kubeconfig_ci_variable.yml8
-rw-r--r--config/metrics/license/20210201124932_recorded_at.yml1
-rw-r--r--config/metrics/license/20210201124933_uuid.yml1
-rw-r--r--config/metrics/license/20210204124827_hostname.yml1
-rw-r--r--config/metrics/license/20210204124829_active_user_count.yml1
-rw-r--r--config/metrics/license/20210204124928_version.yml1
-rw-r--r--config/metrics/license/20210204124936_pages_version.yml1
-rw-r--r--config/metrics/license/20210204124938_recording_ce_finished_at.yml1
-rw-r--r--config/metrics/license/20210216175601_version.yml1
-rw-r--r--config/metrics/license/20210216175602_installation_type.yml2
-rw-r--r--config/metrics/license/20210216181053_version.yml1
-rw-r--r--config/metrics/license/20210216183237_version.yml1
-rw-r--r--config/metrics/settings/20210201124935_database_adapter.yml1
-rw-r--r--config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124858_container_registry_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124900_dependency_proxy_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124904_gravatar_enabled.yml2
-rw-r--r--config/metrics/settings/20210204124906_ldap_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124908_mattermost_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124910_omniauth_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124912_prometheus_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124916_reply_by_email_enabled.yml11
-rw-r--r--config/metrics/settings/20210204124918_signup_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124922_grafana_link_enabled.yml1
-rw-r--r--config/metrics/settings/20210204124934_pages_enabled.yml1
-rw-r--r--config/metrics/settings/20210216174829_smtp_server.yml1
-rw-r--r--config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml1
-rw-r--r--config/metrics/settings/20210216175604_edition.yml2
-rw-r--r--config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml2
-rw-r--r--config/metrics/settings/20210216175609_version.yml2
-rw-r--r--config/metrics/settings/20210216180314_gitpod_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180836_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180838_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180840_direct_upload.yml1
-rw-r--r--config/metrics/settings/20210216180841_background_upload.yml1
-rw-r--r--config/metrics/settings/20210216180843_provider.yml1
-rw-r--r--config/metrics/settings/20210216180845_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180847_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180849_direct_upload.yml1
-rw-r--r--config/metrics/settings/20210216180851_background_upload.yml1
-rw-r--r--config/metrics/settings/20210216180852_provider.yml1
-rw-r--r--config/metrics/settings/20210216180854_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180856_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180858_direct_upload.yml1
-rw-r--r--config/metrics/settings/20210216180900_background_upload.yml1
-rw-r--r--config/metrics/settings/20210216180902_provider.yml1
-rw-r--r--config/metrics/settings/20210216180903_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180905_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180907_direct_upload.yml1
-rw-r--r--config/metrics/settings/20210216180909_background_upload.yml1
-rw-r--r--config/metrics/settings/20210216180911_provider.yml1
-rw-r--r--config/metrics/settings/20210216180913_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180915_enabled.yml1
-rw-r--r--config/metrics/settings/20210216180916_direct_upload.yml1
-rw-r--r--config/metrics/settings/20210216180918_background_upload.yml1
-rw-r--r--config/metrics/settings/20210216180920_provider.yml1
-rw-r--r--config/metrics/settings/20210216183241_filesystems.yml1
-rw-r--r--config/metrics/settings/20210216183248_pg_system_id.yml3
-rw-r--r--config/metrics/settings/20210225045628_operating_system.yml1
-rw-r--r--config/metrics/settings/20210321224827_gitaly_apdex.yml1
-rw-r--r--config/metrics/settings/20210323120839_topology.yml3
-rw-r--r--config/metrics/settings/20210702140138_collected_data_categories.yml1
-rw-r--r--doc/ci/yaml/index.md2
-rw-r--r--doc/development/code_review.md7
-rw-r--r--doc/development/service_ping/index.md172
-rw-r--r--doc/development/service_ping/metrics_dictionary.md2
-rw-r--r--doc/development/service_ping/metrics_lifecycle.md179
-rw-r--r--doc/user/clusters/agent/ci_cd_tunnel.md42
-rw-r--r--doc/user/project/merge_requests/status_checks.md3
-rw-r--r--doc/user/project/settings/index.md9
-rw-r--r--lib/gitlab/ci/config.rb11
-rw-r--r--lib/gitlab/git/remote_mirror.rb6
-rw-r--r--lib/gitlab/gitaly_client/remote_service.rb9
-rw-r--r--lib/gitlab/usage_data_counters/hll_redis_counter.rb6
-rw-r--r--lib/gitlab/usage_data_counters/redis_counter.rb4
-rw-r--r--qa/qa/page/group/menu.rb13
-rw-r--r--spec/factories/projects.rb1
-rw-r--r--spec/features/clusters/cluster_health_dashboard_spec.rb16
-rw-r--r--spec/frontend/content_editor/extensions/code_block_highlight_spec.js1
-rw-r--r--spec/frontend/tracking_spec.js41
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js434
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js7
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js52
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js25
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js88
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js52
-rw-r--r--spec/javascripts/monitoring/components/dashboard_resize_browser_spec.js95
-rw-r--r--spec/javascripts/monitoring/fixture_data.js1
-rw-r--r--spec/javascripts/monitoring/mock_data.js5
-rw-r--r--spec/javascripts/monitoring/store_utils.js1
-rw-r--r--spec/lib/gitlab/git/remote_mirror_spec.rb25
-rw-r--r--spec/lib/gitlab/gitaly_client/remote_service_spec.rb31
-rw-r--r--spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb2
-rw-r--r--spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb4
-rw-r--r--spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb10
-rw-r--r--spec/models/remote_mirror_spec.rb30
-rw-r--r--spec/services/git/branch_hooks_service_spec.rb2
-rw-r--r--spec/services/projects/update_remote_mirror_service_spec.rb2
-rw-r--r--spec/services/service_ping/service_ping_settings_spec.rb16
124 files changed, 812 insertions, 1224 deletions
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 177ea4c2e7d..c6d32fb8547 100644
--- a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
+++ b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
@@ -14,18 +14,6 @@ export default CodeBlockLowlight.extend({
};
},
},
- /* `params` is the name of the attribute that
- prosemirror-markdown uses to extract the language
- of a codeblock.
- https://github.com/ProseMirror/prosemirror-markdown/blob/master/src/to_markdown.js#L62
- */
- params: {
- parseHTML: (element) => {
- return {
- params: extractLanguage(element),
- };
- },
- },
class: {
default: 'code highlight js-syntax-highlight',
},
diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js
index 702344f5514..5c59fb7710a 100644
--- a/app/assets/javascripts/content_editor/services/markdown_serializer.js
+++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js
@@ -51,7 +51,13 @@ const defaultSerializerConfig = {
nodes: {
[Blockquote.name]: defaultMarkdownSerializer.nodes.blockquote,
[BulletList.name]: defaultMarkdownSerializer.nodes.bullet_list,
- [CodeBlockHighlight.name]: defaultMarkdownSerializer.nodes.code_block,
+ [CodeBlockHighlight.name]: (state, node) => {
+ state.write(`\`\`\`${node.attrs.language || ''}\n`);
+ state.text(node.textContent, false);
+ state.ensureNewLine();
+ state.write('```');
+ state.closeBlock(node);
+ },
[Emoji.name]: (state, node) => {
const { name } = node.attrs;
diff --git a/app/assets/javascripts/monitoring/components/dashboard_panel.vue b/app/assets/javascripts/monitoring/components/dashboard_panel.vue
index b786d015f3b..446c6b52602 100644
--- a/app/assets/javascripts/monitoring/components/dashboard_panel.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard_panel.vue
@@ -404,21 +404,16 @@ export default {
-->
<gl-dropdown
v-gl-tooltip
+ icon="ellipsis_v"
+ :text="__('More actions')"
+ :text-sr-only="true"
toggle-class="gl-px-3!"
no-caret
data-qa-selector="prometheus_widgets_dropdown"
right
:title="__('More actions')"
>
- <template #button-content>
- <gl-icon class="gl-mr-0!" name="ellipsis_v" />
- </template>
- <gl-dropdown-item
- v-if="expandBtnAvailable"
- ref="expandBtn"
- :href="clipboardText"
- @click.prevent="onExpand"
- >
+ <gl-dropdown-item v-if="expandBtnAvailable" ref="expandBtn" @click.prevent="onExpand">
{{ s__('Metrics|Expand panel') }}
</gl-dropdown-item>
<gl-dropdown-item
diff --git a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
index b7832ca679c..55179947756 100644
--- a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
+++ b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
@@ -55,12 +55,13 @@ export default {
},
getUpdateVariables(dropdownLabels) {
const currentLabelIds = this.selectedLabels.map((label) => label.id);
- const userAddedLabelIds = dropdownLabels
- .filter((label) => label.set)
- .map((label) => label.id);
- const userRemovedLabelIds = dropdownLabels
- .filter((label) => !label.set)
- .map((label) => label.id);
+ const dropdownLabelIds = dropdownLabels.map((label) => label.id);
+ const userAddedLabelIds = this.glFeatures.labelsWidget
+ ? difference(dropdownLabelIds, currentLabelIds)
+ : dropdownLabels.filter((label) => label.set).map((label) => label.id);
+ const userRemovedLabelIds = this.glFeatures.labelsWidget
+ ? difference(currentLabelIds, dropdownLabelIds)
+ : dropdownLabels.filter((label) => !label.set).map((label) => label.id);
const labelIds = difference(union(currentLabelIds, userAddedLabelIds), userRemovedLabelIds);
@@ -155,7 +156,7 @@ export default {
:labels-manage-path="labelsManagePath"
:labels-select-in-progress="isLabelsSelectInProgress"
:selected-labels="selectedLabels"
- :variant="$options.sidebar"
+ :variant="$options.variant"
data-qa-selector="labels_block"
@onDropdownClose="handleDropdownClose"
@onLabelRemove="handleLabelRemove"
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index 8837f3601e4..031472a7d20 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -24,6 +24,7 @@ import SidebarDropdownWidget from '~/sidebar/components/sidebar_dropdown_widget.
import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
import { apolloProvider } from '~/sidebar/graphql';
import trackShowInviteMemberLink from '~/sidebar/track_invite_members';
+import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_vue/constants';
import Translate from '../vue_shared/translate';
import SidebarAssignees from './components/assignees/sidebar_assignees.vue';
import CopyEmailToClipboard from './components/copy_email_to_clipboard.vue';
@@ -256,6 +257,7 @@ export function mountSidebarLabels() {
allowLabelEdit: parseBoolean(el.dataset.canEdit),
allowScopedLabels: parseBoolean(el.dataset.allowScopedLabels),
initiallySelectedLabels: JSON.parse(el.dataset.selectedLabels),
+ variant: DropdownVariant.Sidebar,
},
render: (createElement) => createElement(SidebarLabels),
});
diff --git a/app/assets/javascripts/tracking/constants.js b/app/assets/javascripts/tracking/constants.js
index dfca633dc24..598111e4086 100644
--- a/app/assets/javascripts/tracking/constants.js
+++ b/app/assets/javascripts/tracking/constants.js
@@ -18,3 +18,9 @@ export const DEFAULT_SNOWPLOW_OPTIONS = {
fields: { allow: [] },
},
};
+
+export const ACTION_ATTR_SELECTOR = '[data-track-action]';
+export const LOAD_ACTION_ATTR_SELECTOR = '[data-track-action="render"]';
+
+export const DEPRECATED_EVENT_ATTR_SELECTOR = '[data-track-event]';
+export const DEPRECATED_LOAD_EVENT_ATTR_SELECTOR = '[data-track-event="render"]';
diff --git a/app/assets/javascripts/tracking/tracking.js b/app/assets/javascripts/tracking/tracking.js
index 7ae3a8cd834..a1f745bc172 100644
--- a/app/assets/javascripts/tracking/tracking.js
+++ b/app/assets/javascripts/tracking/tracking.js
@@ -1,3 +1,4 @@
+import { LOAD_ACTION_ATTR_SELECTOR, DEPRECATED_LOAD_EVENT_ATTR_SELECTOR } from './constants';
import { dispatchSnowplowEvent } from './dispatch_snowplow_event';
import getStandardContext from './get_standard_context';
import { getEventHandlers, createEventPayload, renameKey, addExperimentContext } from './utils';
@@ -98,7 +99,7 @@ export default class Tracking {
}
const loadEvents = parent.querySelectorAll(
- '[data-track-action="render"], [data-track-event="render"]',
+ `${LOAD_ACTION_ATTR_SELECTOR}, ${DEPRECATED_LOAD_EVENT_ATTR_SELECTOR}`,
);
loadEvents.forEach((element) => {
diff --git a/app/assets/javascripts/tracking/utils.js b/app/assets/javascripts/tracking/utils.js
index 3647280c41a..1189b2168ad 100644
--- a/app/assets/javascripts/tracking/utils.js
+++ b/app/assets/javascripts/tracking/utils.js
@@ -1,6 +1,12 @@
import { omitBy, isUndefined } from 'lodash';
import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
import { getExperimentData } from '~/experimentation/utils';
+import {
+ ACTION_ATTR_SELECTOR,
+ LOAD_ACTION_ATTR_SELECTOR,
+ DEPRECATED_EVENT_ATTR_SELECTOR,
+ DEPRECATED_LOAD_EVENT_ATTR_SELECTOR,
+} from './constants';
export const addExperimentContext = (opts) => {
const { experiment, ...options } = opts;
@@ -65,7 +71,9 @@ export const createEventPayload = (el, { suffix = '' } = {}) => {
};
export const eventHandler = (e, func, opts = {}) => {
- const el = e.target.closest('[data-track-event], [data-track-action]');
+ const actionSelector = `${ACTION_ATTR_SELECTOR}:not(${LOAD_ACTION_ATTR_SELECTOR})`;
+ const deprecatedEventSelector = `${DEPRECATED_EVENT_ATTR_SELECTOR}:not(${DEPRECATED_LOAD_EVENT_ATTR_SELECTOR})`;
+ const el = e.target.closest(`${actionSelector}, ${deprecatedEventSelector}`);
if (!el) {
return;
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
index 1f0704f7308..6694e349b6e 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
@@ -21,9 +21,29 @@ export default {
type: String,
required: true,
},
+ selectedLabels: {
+ type: Array,
+ required: true,
+ },
+ allowMultiselect: {
+ type: Boolean,
+ required: true,
+ },
+ labelsListTitle: {
+ type: String,
+ required: true,
+ },
+ footerCreateLabelTitle: {
+ type: String,
+ required: true,
+ },
+ footerManageLabelTitle: {
+ type: String,
+ required: true,
+ },
},
computed: {
- ...mapState(['showDropdownContentsCreateView', 'labelsListTitle']),
+ ...mapState(['showDropdownContentsCreateView']),
...mapGetters(['isDropdownVariantSidebar', 'isDropdownVariantEmbedded']),
dropdownContentsView() {
if (this.showDropdownContentsCreateView) {
@@ -75,6 +95,16 @@ export default {
@click="toggleDropdownContents"
/>
</div>
- <component :is="dropdownContentsView" @hideCreateView="toggleDropdownContentsCreateView" />
+ <component
+ :is="dropdownContentsView"
+ :selected-labels="selectedLabels"
+ :allow-multiselect="allowMultiselect"
+ :labels-list-title="labelsListTitle"
+ :footer-create-label-title="footerCreateLabelTitle"
+ :footer-manage-label-title="footerManageLabelTitle"
+ @hideCreateView="toggleDropdownContentsCreateView"
+ @closeDropdown="$emit('closeDropdown', $event)"
+ @toggleDropdownContentsCreateView="toggleDropdownContentsCreateView"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
index bff34743344..ffa37424c2c 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
@@ -1,38 +1,91 @@
<script>
-import { GlIntersectionObserver, GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui';
+import { GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
-import { mapState, mapGetters, mapActions } from 'vuex';
-
+import { debounce } from 'lodash';
+import createFlash from '~/flash';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
-
+import { __ } from '~/locale';
+import { DropdownVariant } from './constants';
+import projectLabelsQuery from './graphql/project_labels.query.graphql';
import LabelItem from './label_item.vue';
export default {
components: {
- GlIntersectionObserver,
GlLoadingIcon,
GlSearchBoxByType,
GlLink,
LabelItem,
},
+ inject: ['projectPath', 'allowLabelCreate', 'labelsManagePath', 'variant'],
+ props: {
+ selectedLabels: {
+ type: Array,
+ required: true,
+ },
+ allowMultiselect: {
+ type: Boolean,
+ required: true,
+ },
+ labelsListTitle: {
+ type: String,
+ required: true,
+ },
+ footerCreateLabelTitle: {
+ type: String,
+ required: true,
+ },
+ footerManageLabelTitle: {
+ type: String,
+ required: true,
+ },
+ },
data() {
return {
searchKey: '',
+ labels: [],
currentHighlightItem: -1,
+ localSelectedLabels: [...this.selectedLabels],
};
},
+ apollo: {
+ labels: {
+ query: projectLabelsQuery,
+ variables() {
+ return {
+ fullPath: this.projectPath,
+ searchTerm: this.searchKey,
+ };
+ },
+ skip() {
+ return this.searchKey.length === 1;
+ },
+ update: (data) => data.workspace?.labels?.nodes || [],
+ async result() {
+ if (this.$refs.searchInput) {
+ await this.$nextTick();
+ this.$refs.searchInput.focusInput();
+ }
+ },
+ error() {
+ createFlash({ message: __('Error fetching labels.') });
+ },
+ },
+ },
computed: {
- ...mapState([
- 'allowLabelCreate',
- 'allowMultiselect',
- 'labelsManagePath',
- 'labels',
- 'labelsFetchInProgress',
- 'labelsListTitle',
- 'footerCreateLabelTitle',
- 'footerManageLabelTitle',
- ]),
- ...mapGetters(['selectedLabelsList', 'isDropdownVariantSidebar', 'isDropdownVariantEmbedded']),
+ isDropdownVariantSidebar() {
+ return this.variant === DropdownVariant.Sidebar;
+ },
+ isDropdownVariantEmbedded() {
+ return this.variant === DropdownVariant.Embedded;
+ },
+ labelsFetchInProgress() {
+ return this.$apollo.queries.labels.loading;
+ },
+ localSelectedLabelsIds() {
+ return this.localSelectedLabels.map((label) => label.id);
+ },
visibleLabels() {
if (this.searchKey) {
return fuzzaldrinPlus.filter(this.labels, this.searchKey, {
@@ -55,17 +108,16 @@ export default {
}
},
},
+ created() {
+ this.debouncedSearchKeyUpdate = debounce(this.setSearchKey, DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
+ },
+ beforeDestroy() {
+ this.$emit('closeDropdown', this.localSelectedLabels);
+ this.debouncedSearchKeyUpdate.cancel();
+ },
methods: {
- ...mapActions([
- 'toggleDropdownContents',
- 'toggleDropdownContentsCreateView',
- 'fetchLabels',
- 'receiveLabelsSuccess',
- 'updateSelectedLabels',
- 'toggleDropdownContents',
- ]),
isLabelSelected(label) {
- return this.selectedLabelsList.includes(label.id);
+ return this.localSelectedLabelsIds.includes(getIdFromGraphQLId(label.id));
},
/**
* This method scrolls item from dropdown into
@@ -86,23 +138,17 @@ export default {
}
}
},
- handleComponentAppear() {
- // We can avoid putting `catch` block here
- // as failure is handled within actions.js already.
- return this.fetchLabels().then(() => {
- this.$refs.searchInput.focusInput();
- });
- },
- /**
- * We want to remove loaded labels to ensure component
- * fetches fresh set of labels every time when shown.
- */
- handleComponentDisappear() {
- this.receiveLabelsSuccess([]);
- },
- handleCreateLabelClick() {
- this.receiveLabelsSuccess([]);
- this.toggleDropdownContentsCreateView();
+ updateSelectedLabels(label) {
+ if (this.isLabelSelected(label)) {
+ this.localSelectedLabels = this.localSelectedLabels.filter(
+ ({ id }) => id !== getIdFromGraphQLId(label.id),
+ );
+ } else {
+ this.localSelectedLabels.push({
+ ...label,
+ id: getIdFromGraphQLId(label.id),
+ });
+ }
},
/**
* This method enables keyboard navigation support for
@@ -117,10 +163,10 @@ export default {
) {
this.currentHighlightItem += 1;
} else if (e.keyCode === ENTER_KEY_CODE && this.currentHighlightItem > -1) {
- this.updateSelectedLabels([this.visibleLabels[this.currentHighlightItem]]);
+ this.updateSelectedLabels(this.visibleLabels[this.currentHighlightItem]);
this.searchKey = '';
} else if (e.keyCode === ESC_KEY_CODE) {
- this.toggleDropdownContents();
+ this.$emit('closeDropdown', this.localSelectedLabels);
}
if (e.keyCode !== ESC_KEY_CODE) {
@@ -132,68 +178,82 @@ export default {
}
},
handleLabelClick(label) {
- this.updateSelectedLabels([label]);
- if (!this.allowMultiselect) this.toggleDropdownContents();
+ this.updateSelectedLabels(label);
+ if (!this.allowMultiselect) {
+ this.$emit('closeDropdown', this.localSelectedLabels);
+ }
+ },
+ setSearchKey(value) {
+ this.searchKey = value;
},
},
};
</script>
<template>
- <gl-intersection-observer @appear="handleComponentAppear" @disappear="handleComponentDisappear">
- <div class="labels-select-contents-list js-labels-list" @keydown="handleKeyDown">
- <div class="dropdown-input" @click.stop="() => {}">
- <gl-search-box-by-type
- ref="searchInput"
- v-model="searchKey"
- :disabled="labelsFetchInProgress"
- data-qa-selector="dropdown_input_field"
- />
- </div>
- <div ref="labelsListContainer" class="dropdown-content" data-testid="dropdown-content">
- <gl-loading-icon
- v-if="labelsFetchInProgress"
- class="labels-fetch-loading gl-align-items-center w-100 h-100"
- size="md"
+ <div
+ class="labels-select-contents-list js-labels-list"
+ data-testid="dropdown-wrapper"
+ @keydown="handleKeyDown"
+ >
+ <div class="dropdown-input" @click.stop="() => {}">
+ <gl-search-box-by-type
+ ref="searchInput"
+ :value="searchKey"
+ :disabled="labelsFetchInProgress"
+ data-qa-selector="dropdown_input_field"
+ data-testid="dropdown-input-field"
+ @input="debouncedSearchKeyUpdate"
+ />
+ </div>
+ <div ref="labelsListContainer" class="dropdown-content" data-testid="dropdown-content">
+ <gl-loading-icon
+ v-if="labelsFetchInProgress"
+ class="labels-fetch-loading gl-align-items-center gl-w-full gl-h-full"
+ size="md"
+ />
+ <ul v-else class="list-unstyled gl-mb-0 gl-word-break-word" data-testid="labels-list">
+ <label-item
+ v-for="(label, index) in visibleLabels"
+ :key="label.id"
+ :label="label"
+ :is-label-set="isLabelSelected(label)"
+ :highlight="index === currentHighlightItem"
+ @clickLabel="handleLabelClick(label)"
/>
- <ul v-else class="list-unstyled gl-mb-0 gl-word-break-word">
- <label-item
- v-for="(label, index) in visibleLabels"
- :key="label.id"
- :label="label"
- :is-label-set="label.set"
- :highlight="index === currentHighlightItem"
- @clickLabel="handleLabelClick(label)"
- />
- <li v-show="showNoMatchingResultsMessage" class="gl-p-3 gl-text-center">
- {{ __('No matching results') }}
- </li>
- </ul>
- </div>
- <div
- v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded"
- class="dropdown-footer"
- data-testid="dropdown-footer"
- >
- <ul class="list-unstyled">
- <li v-if="allowLabelCreate">
- <gl-link
- class="gl-display-flex w-100 flex-row text-break-word label-item"
- @click="handleCreateLabelClick"
- >
- {{ footerCreateLabelTitle }}
- </gl-link>
- </li>
- <li>
- <gl-link
- :href="labelsManagePath"
- class="gl-display-flex flex-row text-break-word label-item"
- >
- {{ footerManageLabelTitle }}
- </gl-link>
- </li>
- </ul>
- </div>
+ <li
+ v-show="showNoMatchingResultsMessage"
+ class="gl-p-3 gl-text-center"
+ data-testid="no-results"
+ >
+ {{ __('No matching results') }}
+ </li>
+ </ul>
+ </div>
+ <div
+ v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded"
+ class="dropdown-footer"
+ data-testid="dropdown-footer"
+ >
+ <ul class="list-unstyled">
+ <li v-if="allowLabelCreate">
+ <gl-link
+ class="gl-display-flex gl-flex-direction-row gl-w-full gl-overflow-break-word label-item"
+ data-testid="create-label-button"
+ @click="$emit('toggleDropdownContentsCreateView')"
+ >
+ {{ footerCreateLabelTitle }}
+ </gl-link>
+ </li>
+ <li>
+ <gl-link
+ :href="labelsManagePath"
+ class="gl-display-flex gl-flex-direction-row gl-w-full gl-overflow-break-word label-item"
+ >
+ {{ footerManageLabelTitle }}
+ </gl-link>
+ </li>
+ </ul>
</div>
- </gl-intersection-observer>
+ </div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql
new file mode 100644
index 00000000000..dc39220487d
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql
@@ -0,0 +1,12 @@
+query projectLabels($fullPath: ID!, $searchTerm: String) {
+ workspace: project(fullPath: $fullPath) {
+ labels(searchTerm: $searchTerm, includeAncestorGroups: true) {
+ nodes {
+ id
+ title
+ color
+ description
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
index 6cc14def14b..0499dfe468f 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
@@ -197,23 +197,6 @@ export default {
methods: {
...mapActions(['setInitialState', 'toggleDropdownContents']),
/**
- * This method differentiates between
- * dispatched actions and calls necessary method.
- */
- handleVuexActionDispatch(action, state) {
- if (
- action.type === 'toggleDropdownContents' &&
- !state.showDropdownButton &&
- !state.showDropdownContents
- ) {
- let filterFn = (label) => label.touched;
- if (this.isDropdownVariantEmbedded) {
- filterFn = (label) => label.set;
- }
- this.handleDropdownClose(state.labels.filter(filterFn));
- }
- },
- /**
* This method stores a mousedown event's target.
* Required by the click listener because the click
* event itself has no reference to this element.
@@ -276,6 +259,9 @@ export default {
handleDropdownClose(labels) {
// Only emit label updates if there are any labels to update
// on UI.
+ if (this.showDropdownContents) {
+ this.toggleDropdownContents();
+ }
if (labels.length) this.$emit('updateSelectedLabels', labels);
this.$emit('onDropdownClose');
},
@@ -332,8 +318,14 @@ export default {
<dropdown-contents
v-if="dropdownButtonVisible && showDropdownContents"
ref="dropdownContents"
+ :allow-multiselect="allowMultiselect"
+ :labels-list-title="labelsListTitle"
+ :footer-create-label-title="footerCreateLabelTitle"
+ :footer-manage-label-title="footerManageLabelTitle"
:render-on-top="!contentIsOnViewport"
:labels-create-title="labelsCreateTitle"
+ :selected-labels="selectedLabels"
+ @closeDropdown="handleDropdownClose"
/>
</template>
<template v-if="isDropdownVariantStandalone || isDropdownVariantEmbedded">
@@ -341,7 +333,13 @@ export default {
<dropdown-contents
v-if="dropdownButtonVisible && showDropdownContents"
ref="dropdownContents"
+ :allow-multiselect="allowMultiselect"
+ :labels-list-title="labelsListTitle"
+ :footer-create-label-title="footerCreateLabelTitle"
+ :footer-manage-label-title="footerManageLabelTitle"
:render-on-top="!contentIsOnViewport"
+ :selected-labels="selectedLabels"
+ @closeDropdown="handleDropdownClose"
/>
</template>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js
index 935f020f559..b3d4a204a81 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js
@@ -1,6 +1,3 @@
-import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
import * as types from './mutation_types';
export const setInitialState = ({ commit }, props) => commit(types.SET_INITIAL_STATE, props);
@@ -11,24 +8,5 @@ export const toggleDropdownContents = ({ commit }) => commit(types.TOGGLE_DROPDO
export const toggleDropdownContentsCreateView = ({ commit }) =>
commit(types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW);
-export const requestLabels = ({ commit }) => commit(types.REQUEST_LABELS);
-export const receiveLabelsSuccess = ({ commit }, labels) =>
- commit(types.RECEIVE_SET_LABELS_SUCCESS, labels);
-export const receiveLabelsFailure = ({ commit }) => {
- commit(types.RECEIVE_SET_LABELS_FAILURE);
- createFlash({
- message: __('Error fetching labels.'),
- });
-};
-export const fetchLabels = ({ state, dispatch }) => {
- dispatch('requestLabels');
- return axios
- .get(state.labelsFetchPath)
- .then(({ data }) => {
- dispatch('receiveLabelsSuccess', data);
- })
- .catch(() => dispatch('receiveLabelsFailure'));
-};
-
export const updateSelectedLabels = ({ commit }, labels) =>
commit(types.UPDATE_SELECTED_LABELS, { labels });
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js
index b8da7a90b36..bd71c3b85f1 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js
@@ -1,13 +1,5 @@
export const SET_INITIAL_STATE = 'SET_INITIAL_STATE';
-export const REQUEST_LABELS = 'REQUEST_LABELS';
-export const RECEIVE_LABELS_SUCCESS = 'RECEIVE_LABELS_SUCCESS';
-export const RECEIVE_LABELS_FAILURE = 'RECEIVE_LABELS_FAILURE';
-
-export const REQUEST_SET_LABELS = 'REQUEST_SET_LABELS';
-export const RECEIVE_SET_LABELS_SUCCESS = 'RECEIVE_SET_LABELS_SUCCESS';
-export const RECEIVE_SET_LABELS_FAILURE = 'RECEIVE_SET_LABELS_FAILURE';
-
export const TOGGLE_DROPDOWN_BUTTON = 'TOGGLE_DROPDOWN_VISIBILITY';
export const TOGGLE_DROPDOWN_CONTENTS = 'TOGGLE_DROPDOWN_CONTENTS';
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js
index 1c03d95f37b..45ec4d7ae04 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js
+++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js
@@ -26,27 +26,6 @@ export default {
[types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW](state) {
state.showDropdownContentsCreateView = !state.showDropdownContentsCreateView;
},
-
- [types.REQUEST_LABELS](state) {
- state.labelsFetchInProgress = true;
- },
- [types.RECEIVE_SET_LABELS_SUCCESS](state, labels) {
- // Iterate over every label and add a `set` prop
- // to determine whether it is already a part of
- // selectedLabels array.
- const selectedLabelIds = state.selectedLabels.map((label) => label.id);
- state.labelsFetchInProgress = false;
- state.labels = labels.reduce((allLabels, label) => {
- allLabels.push({
- ...label,
- set: selectedLabelIds.includes(label.id),
- });
- return allLabels;
- }, []);
- },
- [types.RECEIVE_SET_LABELS_FAILURE](state) {
- state.labelsFetchInProgress = false;
- },
[types.UPDATE_SELECTED_LABELS](state, { labels }) {
// Find the label to update from all the labels
// and change `set` prop value to represent their current state.
diff --git a/app/helpers/analytics/navbar_helper.rb b/app/helpers/analytics/navbar_helper.rb
deleted file mode 100644
index 091571ff15a..00000000000
--- a/app/helpers/analytics/navbar_helper.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-# frozen_string_literal: true
-
-module Analytics
- module NavbarHelper
- class NavbarSubItem
- attr_reader :title, :path, :link, :link_to_options
-
- def initialize(title:, path:, link:, link_to_options: {})
- @title = title
- @path = path
- @link = link
- @link_to_options = link_to_options.merge(title: title)
- end
- end
-
- def group_analytics_navbar_links(group, current_user)
- []
- end
-
- private
-
- def navbar_sub_item(args)
- NavbarSubItem.new(**args)
- end
- end
-end
-
-Analytics::NavbarHelper.prepend_mod_with('Analytics::NavbarHelper')
diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb
index 4937f2e862b..7f41f0907d5 100644
--- a/app/models/remote_mirror.rb
+++ b/app/models/remote_mirror.rb
@@ -22,8 +22,6 @@ class RemoteMirror < ApplicationRecord
validates :url, presence: true, public_url: { schemes: %w(ssh git http https), allow_blank: true, enforce_user: true }
- before_save :set_new_remote_name, if: :mirror_url_changed?
-
after_save :set_override_remote_mirror_available, unless: -> { Gitlab::CurrentSettings.current_application_settings.mirror_available }
after_update :reset_fields, if: :saved_change_to_mirror_url?
@@ -85,10 +83,6 @@ class RemoteMirror < ApplicationRecord
end
end
- def remote_name
- super || fallback_remote_name
- end
-
def update_failed?
update_status == 'failed'
end
@@ -100,7 +94,6 @@ class RemoteMirror < ApplicationRecord
def update_repository
Gitlab::Git::RemoteMirror.new(
project.repository.raw,
- remote_name,
remote_url,
**options_for_update
).update
@@ -268,12 +261,6 @@ class RemoteMirror < ApplicationRecord
super
end
- def fallback_remote_name
- return unless id
-
- "remote_mirror_#{id}"
- end
-
def recently_scheduled?
return false unless self.last_update_started_at
@@ -296,10 +283,6 @@ class RemoteMirror < ApplicationRecord
project.update(remote_mirror_available_overridden: enabled)
end
- def set_new_remote_name
- self.remote_name = "remote_mirror_#{SecureRandom.hex}"
- end
-
def mirror_url_changed?
url_changed? || attribute_changed?(:credentials)
end
diff --git a/app/services/git/branch_hooks_service.rb b/app/services/git/branch_hooks_service.rb
index a49b981c680..9738615c804 100644
--- a/app/services/git/branch_hooks_service.rb
+++ b/app/services/git/branch_hooks_service.rb
@@ -95,7 +95,7 @@ module Git
end
def track_ci_config_change_event
- return unless Gitlab::CurrentSettings.usage_ping_enabled?
+ return unless ::ServicePing::ServicePingSettings.enabled?
return unless default_branch?
commits_changing_ci_config.each do |commit|
diff --git a/app/services/service_ping/service_ping_settings.rb b/app/services/service_ping/service_ping_settings.rb
index 2b6535d89d1..6964210b1db 100644
--- a/app/services/service_ping/service_ping_settings.rb
+++ b/app/services/service_ping/service_ping_settings.rb
@@ -5,12 +5,10 @@ module ServicePing
extend self
def product_intelligence_enabled?
- pings_enabled? && !User.single_user&.requires_usage_stats_consent?
+ enabled? && !User.single_user&.requires_usage_stats_consent?
end
- private
-
- def pings_enabled?
+ def enabled?
::Gitlab::CurrentSettings.usage_ping_enabled?
end
end
diff --git a/app/views/layouts/nav/sidebar/_analytics_links.html.haml b/app/views/layouts/nav/sidebar/_analytics_links.html.haml
deleted file mode 100644
index 92a7b97203f..00000000000
--- a/app/views/layouts/nav/sidebar/_analytics_links.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-- navbar_links = links.sort_by(&:title)
-- all_paths = navbar_links.map(&:path)
-- analytics_link = navbar_links.find { |link| link.title == _('Value stream') } || navbar_links.first
-
-- if navbar_links.any?
- = nav_link(path: all_paths) do
- = link_to analytics_link.link, {class: 'shortcuts-analytics has-sub-items', data: { qa_selector: 'analytics_anchor' } } do
- .nav-icon-container
- = sprite_icon('chart')
- %span.nav-item-name{ data: { qa_selector: 'analytics_link' } }
- = _('Analytics')
-
- %ul.sidebar-sub-level-items{ data: { qa_selector: 'analytics_sidebar_submenu' } }
- = nav_link(path: analytics_link.path, html_options: { class: "fly-out-top-item" } ) do
- = link_to analytics_link.link do
- %strong.fly-out-top-item-name
- = _('Analytics')
- %li.divider.fly-out-top-item
- - navbar_links.each do |menu_item|
- = nav_link(path: menu_item.path) do
- = link_to(menu_item.link, menu_item.link_to_options) do
- %span= menu_item.title
diff --git a/app/views/layouts/nav/sidebar/_group_menus.html.haml b/app/views/layouts/nav/sidebar/_group_menus.html.haml
index 2eea076f8db..8a6183f8efe 100644
--- a/app/views/layouts/nav/sidebar/_group_menus.html.haml
+++ b/app/views/layouts/nav/sidebar/_group_menus.html.haml
@@ -1,5 +1,3 @@
-= render 'layouts/nav/sidebar/analytics_links', links: group_analytics_navbar_links(@group, current_user)
-
- if group_sidebar_link?(:wiki)
= render 'layouts/nav/sidebar/wiki_link', wiki_url: @group.wiki.web_url
diff --git a/config/feature_flags/development/agent_kubeconfig_ci_variable.yml b/config/feature_flags/development/agent_kubeconfig_ci_variable.yml
deleted file mode 100644
index 78a10a094c6..00000000000
--- a/config/feature_flags/development/agent_kubeconfig_ci_variable.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: agent_kubeconfig_ci_variable
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67089
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337164
-milestone: '14.2'
-type: development
-group: group::configure
-default_enabled: false
diff --git a/config/metrics/license/20210201124932_recorded_at.yml b/config/metrics/license/20210201124932_recorded_at.yml
index 7a40498abea..d9fabfaad19 100644
--- a/config/metrics/license/20210201124932_recorded_at.yml
+++ b/config/metrics/license/20210201124932_recorded_at.yml
@@ -19,3 +19,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/license/20210201124933_uuid.yml b/config/metrics/license/20210201124933_uuid.yml
index aab2b3a641c..594fd1b6d7f 100644
--- a/config/metrics/license/20210201124933_uuid.yml
+++ b/config/metrics/license/20210201124933_uuid.yml
@@ -20,3 +20,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/license/20210204124827_hostname.yml b/config/metrics/license/20210204124827_hostname.yml
index 27669c3f6c5..1bc9375b69b 100644
--- a/config/metrics/license/20210204124827_hostname.yml
+++ b/config/metrics/license/20210204124827_hostname.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/license/20210204124829_active_user_count.yml b/config/metrics/license/20210204124829_active_user_count.yml
index 2fa311f119d..b585c027a9f 100644
--- a/config/metrics/license/20210204124829_active_user_count.yml
+++ b/config/metrics/license/20210204124829_active_user_count.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/557
+performance_indicator_type: []
diff --git a/config/metrics/license/20210204124928_version.yml b/config/metrics/license/20210204124928_version.yml
index 8323f5ea760..5233c0cabc6 100644
--- a/config/metrics/license/20210204124928_version.yml
+++ b/config/metrics/license/20210204124928_version.yml
@@ -15,3 +15,4 @@ distribution:
tier:
- free
skip_validation: true
+performance_indicator_type: []
diff --git a/config/metrics/license/20210204124936_pages_version.yml b/config/metrics/license/20210204124936_pages_version.yml
index d589255399c..4f8e8439b6a 100644
--- a/config/metrics/license/20210204124936_pages_version.yml
+++ b/config/metrics/license/20210204124936_pages_version.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/license/20210204124938_recording_ce_finished_at.yml b/config/metrics/license/20210204124938_recording_ce_finished_at.yml
index 532a7861e46..318c9fae50e 100644
--- a/config/metrics/license/20210204124938_recording_ce_finished_at.yml
+++ b/config/metrics/license/20210204124938_recording_ce_finished_at.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/license/20210216175601_version.yml b/config/metrics/license/20210216175601_version.yml
index 3b26ac31a3f..ffcf8d97aa1 100644
--- a/config/metrics/license/20210216175601_version.yml
+++ b/config/metrics/license/20210216175601_version.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
skip_validation: true
+performance_indicator_type: []
diff --git a/config/metrics/license/20210216175602_installation_type.yml b/config/metrics/license/20210216175602_installation_type.yml
index 669f983a505..9767609ffcd 100644
--- a/config/metrics/license/20210216175602_installation_type.yml
+++ b/config/metrics/license/20210216175602_installation_type.yml
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-
+performance_indicator_type: []
diff --git a/config/metrics/license/20210216181053_version.yml b/config/metrics/license/20210216181053_version.yml
index a95dcd5c13f..b18d7360560 100644
--- a/config/metrics/license/20210216181053_version.yml
+++ b/config/metrics/license/20210216181053_version.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/license/20210216183237_version.yml b/config/metrics/license/20210216183237_version.yml
index 33dc3c38a9c..bd1b6158329 100644
--- a/config/metrics/license/20210216183237_version.yml
+++ b/config/metrics/license/20210216183237_version.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210201124935_database_adapter.yml b/config/metrics/settings/20210201124935_database_adapter.yml
index 0a26d0afb68..ca16bec6a08 100644
--- a/config/metrics/settings/20210201124935_database_adapter.yml
+++ b/config/metrics/settings/20210201124935_database_adapter.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml b/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml
index f1426cd220d..45361c5b358 100644
--- a/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml
+++ b/config/metrics/settings/20210204124856_instance_auto_devops_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124858_container_registry_enabled.yml b/config/metrics/settings/20210204124858_container_registry_enabled.yml
index 4f5d2fde9e7..4c640a1de2b 100644
--- a/config/metrics/settings/20210204124858_container_registry_enabled.yml
+++ b/config/metrics/settings/20210204124858_container_registry_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml b/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml
index a567dd3bf51..911b9732a56 100644
--- a/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml
+++ b/config/metrics/settings/20210204124900_dependency_proxy_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml b/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml
index d1737989b80..ae75667134d 100644
--- a/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml
+++ b/config/metrics/settings/20210204124902_gitlab_shared_runners_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124904_gravatar_enabled.yml b/config/metrics/settings/20210204124904_gravatar_enabled.yml
index aa7d697acfd..dfbf70bad87 100644
--- a/config/metrics/settings/20210204124904_gravatar_enabled.yml
+++ b/config/metrics/settings/20210204124904_gravatar_enabled.yml
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124906_ldap_enabled.yml b/config/metrics/settings/20210204124906_ldap_enabled.yml
index d1dcdaec106..a6e4a4fb80a 100644
--- a/config/metrics/settings/20210204124906_ldap_enabled.yml
+++ b/config/metrics/settings/20210204124906_ldap_enabled.yml
@@ -15,3 +15,4 @@ distribution:
tier:
- free
skip_validation: true
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124908_mattermost_enabled.yml b/config/metrics/settings/20210204124908_mattermost_enabled.yml
index ed72e557ad7..9da0e2c604f 100644
--- a/config/metrics/settings/20210204124908_mattermost_enabled.yml
+++ b/config/metrics/settings/20210204124908_mattermost_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124910_omniauth_enabled.yml b/config/metrics/settings/20210204124910_omniauth_enabled.yml
index 2943913bcbb..a9a6bdc0bda 100644
--- a/config/metrics/settings/20210204124910_omniauth_enabled.yml
+++ b/config/metrics/settings/20210204124910_omniauth_enabled.yml
@@ -15,3 +15,4 @@ distribution:
tier:
- free
skip_validation: true
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124912_prometheus_enabled.yml b/config/metrics/settings/20210204124912_prometheus_enabled.yml
index bf33f8e4454..8a8a44056ce 100644
--- a/config/metrics/settings/20210204124912_prometheus_enabled.yml
+++ b/config/metrics/settings/20210204124912_prometheus_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml b/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml
index df4a4f1edaa..0aff4171cfc 100644
--- a/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml
+++ b/config/metrics/settings/20210204124914_prometheus_metrics_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124916_reply_by_email_enabled.yml b/config/metrics/settings/20210204124916_reply_by_email_enabled.yml
index 35f834511b2..9edc06cdd18 100644
--- a/config/metrics/settings/20210204124916_reply_by_email_enabled.yml
+++ b/config/metrics/settings/20210204124916_reply_by_email_enabled.yml
@@ -11,9 +11,10 @@ status: data_available
time_frame: none
data_source: system
distribution:
- - ce
- - ee
+- ce
+- ee
tier:
- - free
- - premium
- - ultimate
+- free
+- premium
+- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124918_signup_enabled.yml b/config/metrics/settings/20210204124918_signup_enabled.yml
index 40b16f33b0b..bc2f2097d41 100644
--- a/config/metrics/settings/20210204124918_signup_enabled.yml
+++ b/config/metrics/settings/20210204124918_signup_enabled.yml
@@ -18,3 +18,4 @@ tier:
- premium
- ultimate
skip_validation: true
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml b/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml
index 869f7c89483..758c7ee62bf 100644
--- a/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml
+++ b/config/metrics/settings/20210204124920_web_ide_clientside_preview_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124922_grafana_link_enabled.yml b/config/metrics/settings/20210204124922_grafana_link_enabled.yml
index 9660614bd46..4680f4b152c 100644
--- a/config/metrics/settings/20210204124922_grafana_link_enabled.yml
+++ b/config/metrics/settings/20210204124922_grafana_link_enabled.yml
@@ -14,3 +14,4 @@ distribution:
- ce
tier:
- free
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210204124934_pages_enabled.yml b/config/metrics/settings/20210204124934_pages_enabled.yml
index 14a2ea4bc76..907dd4b454c 100644
--- a/config/metrics/settings/20210204124934_pages_enabled.yml
+++ b/config/metrics/settings/20210204124934_pages_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216174829_smtp_server.yml b/config/metrics/settings/20210216174829_smtp_server.yml
index 1b264834821..46e3396eef6 100644
--- a/config/metrics/settings/20210216174829_smtp_server.yml
+++ b/config/metrics/settings/20210216174829_smtp_server.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml b/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml
index 603064a301d..fa6ccaf67b2 100644
--- a/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml
+++ b/config/metrics/settings/20210216175459_ingress_modsecurity_enabled.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216175604_edition.yml b/config/metrics/settings/20210216175604_edition.yml
index 0571097c5be..03f013e9c98 100644
--- a/config/metrics/settings/20210216175604_edition.yml
+++ b/config/metrics/settings/20210216175604_edition.yml
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml b/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml
index 2cd0949c9f5..9d156e327ea 100644
--- a/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml
+++ b/config/metrics/settings/20210216175606_ldap_encrypted_secrets_enabled.yml
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216175609_version.yml b/config/metrics/settings/20210216175609_version.yml
index 468a8998637..31f6dcece3d 100644
--- a/config/metrics/settings/20210216175609_version.yml
+++ b/config/metrics/settings/20210216175609_version.yml
@@ -17,4 +17,4 @@ tier:
- free
- premium
- ultimate
-
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180314_gitpod_enabled.yml b/config/metrics/settings/20210216180314_gitpod_enabled.yml
index 71ceb75ab84..a42042a8200 100644
--- a/config/metrics/settings/20210216180314_gitpod_enabled.yml
+++ b/config/metrics/settings/20210216180314_gitpod_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180836_enabled.yml b/config/metrics/settings/20210216180836_enabled.yml
index 9a52788d2e3..01a7731d6f9 100644
--- a/config/metrics/settings/20210216180836_enabled.yml
+++ b/config/metrics/settings/20210216180836_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180838_enabled.yml b/config/metrics/settings/20210216180838_enabled.yml
index 1e8c0bf8d30..7f62d345288 100644
--- a/config/metrics/settings/20210216180838_enabled.yml
+++ b/config/metrics/settings/20210216180838_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180840_direct_upload.yml b/config/metrics/settings/20210216180840_direct_upload.yml
index a0859d7d5a6..9932494a421 100644
--- a/config/metrics/settings/20210216180840_direct_upload.yml
+++ b/config/metrics/settings/20210216180840_direct_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180841_background_upload.yml b/config/metrics/settings/20210216180841_background_upload.yml
index 9386a1a8301..fb0e02b108a 100644
--- a/config/metrics/settings/20210216180841_background_upload.yml
+++ b/config/metrics/settings/20210216180841_background_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180843_provider.yml b/config/metrics/settings/20210216180843_provider.yml
index 2c9e074f9ef..702f5eab679 100644
--- a/config/metrics/settings/20210216180843_provider.yml
+++ b/config/metrics/settings/20210216180843_provider.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180845_enabled.yml b/config/metrics/settings/20210216180845_enabled.yml
index a9c33827861..ab92282eafd 100644
--- a/config/metrics/settings/20210216180845_enabled.yml
+++ b/config/metrics/settings/20210216180845_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180847_enabled.yml b/config/metrics/settings/20210216180847_enabled.yml
index ca404dc8b66..c59efae2129 100644
--- a/config/metrics/settings/20210216180847_enabled.yml
+++ b/config/metrics/settings/20210216180847_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180849_direct_upload.yml b/config/metrics/settings/20210216180849_direct_upload.yml
index 37e77067336..17eb30c1441 100644
--- a/config/metrics/settings/20210216180849_direct_upload.yml
+++ b/config/metrics/settings/20210216180849_direct_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180851_background_upload.yml b/config/metrics/settings/20210216180851_background_upload.yml
index 5c231d544bf..dc51d8ae733 100644
--- a/config/metrics/settings/20210216180851_background_upload.yml
+++ b/config/metrics/settings/20210216180851_background_upload.yml
@@ -18,3 +18,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180852_provider.yml b/config/metrics/settings/20210216180852_provider.yml
index 8675e023caf..44bc38ea5fd 100644
--- a/config/metrics/settings/20210216180852_provider.yml
+++ b/config/metrics/settings/20210216180852_provider.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180854_enabled.yml b/config/metrics/settings/20210216180854_enabled.yml
index 51aebd0f029..275c26a1478 100644
--- a/config/metrics/settings/20210216180854_enabled.yml
+++ b/config/metrics/settings/20210216180854_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180856_enabled.yml b/config/metrics/settings/20210216180856_enabled.yml
index 842a6042ae6..da972595ff9 100644
--- a/config/metrics/settings/20210216180856_enabled.yml
+++ b/config/metrics/settings/20210216180856_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180858_direct_upload.yml b/config/metrics/settings/20210216180858_direct_upload.yml
index c2d680102e6..120537b8af0 100644
--- a/config/metrics/settings/20210216180858_direct_upload.yml
+++ b/config/metrics/settings/20210216180858_direct_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180900_background_upload.yml b/config/metrics/settings/20210216180900_background_upload.yml
index 9d4b16ba441..5c885d29061 100644
--- a/config/metrics/settings/20210216180900_background_upload.yml
+++ b/config/metrics/settings/20210216180900_background_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180902_provider.yml b/config/metrics/settings/20210216180902_provider.yml
index 1ec1949ef11..97dd62b8eca 100644
--- a/config/metrics/settings/20210216180902_provider.yml
+++ b/config/metrics/settings/20210216180902_provider.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180903_enabled.yml b/config/metrics/settings/20210216180903_enabled.yml
index 7ebcbd04837..55cd0967931 100644
--- a/config/metrics/settings/20210216180903_enabled.yml
+++ b/config/metrics/settings/20210216180903_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180905_enabled.yml b/config/metrics/settings/20210216180905_enabled.yml
index f967861ae0b..438a4ea5ff9 100644
--- a/config/metrics/settings/20210216180905_enabled.yml
+++ b/config/metrics/settings/20210216180905_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180907_direct_upload.yml b/config/metrics/settings/20210216180907_direct_upload.yml
index ca8cfa003c3..14d6ff17106 100644
--- a/config/metrics/settings/20210216180907_direct_upload.yml
+++ b/config/metrics/settings/20210216180907_direct_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180909_background_upload.yml b/config/metrics/settings/20210216180909_background_upload.yml
index 783baa1f30d..738148fd0eb 100644
--- a/config/metrics/settings/20210216180909_background_upload.yml
+++ b/config/metrics/settings/20210216180909_background_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180911_provider.yml b/config/metrics/settings/20210216180911_provider.yml
index 4066f83afdb..60cc2a56573 100644
--- a/config/metrics/settings/20210216180911_provider.yml
+++ b/config/metrics/settings/20210216180911_provider.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180913_enabled.yml b/config/metrics/settings/20210216180913_enabled.yml
index e19001746d8..38a5a3d61ca 100644
--- a/config/metrics/settings/20210216180913_enabled.yml
+++ b/config/metrics/settings/20210216180913_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180915_enabled.yml b/config/metrics/settings/20210216180915_enabled.yml
index 0cb84815e26..6aef961d6db 100644
--- a/config/metrics/settings/20210216180915_enabled.yml
+++ b/config/metrics/settings/20210216180915_enabled.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180916_direct_upload.yml b/config/metrics/settings/20210216180916_direct_upload.yml
index 41adb02d6c6..29a8c3559f4 100644
--- a/config/metrics/settings/20210216180916_direct_upload.yml
+++ b/config/metrics/settings/20210216180916_direct_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180918_background_upload.yml b/config/metrics/settings/20210216180918_background_upload.yml
index 9c5ded4f956..b9820da5e42 100644
--- a/config/metrics/settings/20210216180918_background_upload.yml
+++ b/config/metrics/settings/20210216180918_background_upload.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216180920_provider.yml b/config/metrics/settings/20210216180920_provider.yml
index da5d1dc0c1b..bc24892c115 100644
--- a/config/metrics/settings/20210216180920_provider.yml
+++ b/config/metrics/settings/20210216180920_provider.yml
@@ -17,3 +17,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216183241_filesystems.yml b/config/metrics/settings/20210216183241_filesystems.yml
index 242f2818ac6..0f00292b2cc 100644
--- a/config/metrics/settings/20210216183241_filesystems.yml
+++ b/config/metrics/settings/20210216183241_filesystems.yml
@@ -15,3 +15,4 @@ distribution:
tier:
- free
skip_validation: true
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210216183248_pg_system_id.yml b/config/metrics/settings/20210216183248_pg_system_id.yml
index 19b920ea7e3..e605a2df4e7 100644
--- a/config/metrics/settings/20210216183248_pg_system_id.yml
+++ b/config/metrics/settings/20210216183248_pg_system_id.yml
@@ -5,7 +5,7 @@ description: TBD
product_section: enablement
product_stage: enablement
product_group: group::distribution
-product_category:
+product_category:
value_type: number
status: data_available
time_frame: all
@@ -15,3 +15,4 @@ distribution:
tier:
- free
skip_validation: true
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210225045628_operating_system.yml b/config/metrics/settings/20210225045628_operating_system.yml
index 6f1cd9be724..cc75a6dff68 100644
--- a/config/metrics/settings/20210225045628_operating_system.yml
+++ b/config/metrics/settings/20210225045628_operating_system.yml
@@ -19,3 +19,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210321224827_gitaly_apdex.yml b/config/metrics/settings/20210321224827_gitaly_apdex.yml
index f760abae6dc..509371b6a24 100644
--- a/config/metrics/settings/20210321224827_gitaly_apdex.yml
+++ b/config/metrics/settings/20210321224827_gitaly_apdex.yml
@@ -19,3 +19,4 @@ tier:
- free
- premium
- ultimate
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210323120839_topology.yml b/config/metrics/settings/20210323120839_topology.yml
index c998b37d039..be761c7f555 100644
--- a/config/metrics/settings/20210323120839_topology.yml
+++ b/config/metrics/settings/20210323120839_topology.yml
@@ -5,7 +5,7 @@ description: Topology data
product_section: enablement
product_stage: enablement
product_group: group::memory
-product_category:
+product_category:
value_type: object
status: data_available
milestone: "13.11"
@@ -20,3 +20,4 @@ tier:
- premium
- ultimate
value_json_schema: 'config/metrics/objects_schemas/topology_schema.json'
+performance_indicator_type: []
diff --git a/config/metrics/settings/20210702140138_collected_data_categories.yml b/config/metrics/settings/20210702140138_collected_data_categories.yml
index 697be4e8dd1..74697132091 100644
--- a/config/metrics/settings/20210702140138_collected_data_categories.yml
+++ b/config/metrics/settings/20210702140138_collected_data_categories.yml
@@ -22,3 +22,4 @@ tier:
- premium
- ultimate
value_json_schema: 'config/metrics/objects_schemas/collected_data_categories_schema.json'
+performance_indicator_type: []
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 90c059e646d..f145e91dae7 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -426,6 +426,8 @@ In `include` sections in your `.gitlab-ci.yml` file, you can use:
- Project [predefined variables](../variables/predefined_variables.md).
- [Custom instance, group, and project variables](../variables/index.md#custom-cicd-variables)
in GitLab 14.2 and later.
+- `$CI_COMMIT_REF_NAME` [predefined variable](../variables/predefined_variables.md) in GitLab 14.2
+ and later.
```yaml
include:
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index 4d2007f548f..f542b11e864 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -578,11 +578,12 @@ context is fresh in memory, and improves contributors' experience significantly.
To ensure swift feedback to ready-to-review code, we maintain a `Review-response` Service-level Objective (SLO). The SLO is defined as:
-> - review-response SLO = (time when first review response is provided) - (time MR is assigned to reviewer) < 2 business days
+> Review-response SLO = (time when first review is provided) - (time MR is assigned to reviewer) < 2 business days
If you don't think you can review a merge request in the `Review-response` SLO
-time frame, let the author know as soon as possible and try to help them find
-another reviewer or maintainer who is able to, so that they can be unblocked
+time frame, let the author know as soon as possible in the comments
+(no later than 36 hours after first receiving the review request)
+and try to help them find another reviewer or maintainer who is able to, so that they can be unblocked
and get on with their work quickly. Remove yourself as a reviewer.
If you think you are at capacity and are unable to accept any more reviews until
diff --git a/doc/development/service_ping/index.md b/doc/development/service_ping/index.md
index bb02dcedda8..8ae023f5255 100644
--- a/doc/development/service_ping/index.md
+++ b/doc/development/service_ping/index.md
@@ -220,178 +220,6 @@ We also collect metrics specific to [Geo](../../administration/geo/index.md) sec
]
```
-## Service Ping Metric Life cycle
-
-### 1. New metrics addition
-
-Please follow the [Implementing Service Ping](#implementing-service-ping) guide.
-
-### 2. Existing metric change
-
-Because we do not control when customers update their self-managed instances of GitLab,
-we **STRONGLY DISCOURAGE** changes to the logic used to calculate any metric.
-Any such changes lead to inconsistent reports from multiple GitLab instances.
-If there is a problem with an existing metric, it's best to deprecate the existing metric,
-and use it, side by side, with the desired new metric.
-
-Example:
-Consider following change. Before GitLab 12.6, the `example_metric` was implemented as:
-
-```ruby
-{
- ...
- example_metric: distinct_count(Project, :creator_id)
-}
-```
-
-For GitLab 12.6, the metric was changed to filter out archived projects:
-
-```ruby
-{
- ...
- example_metric: distinct_count(Project.non_archived, :creator_id)
-}
-```
-
-In this scenario all instances running up to GitLab 12.5 continue to report `example_metric`,
-including all archived projects, while all instances running GitLab 12.6 and higher filters
-out such projects. As Service Ping data is collected from all reporting instances, the
-resulting dataset includes mixed data, which distorts any following business analysis.
-
-The correct approach is to add a new metric for GitLab 12.6 release with updated logic:
-
-```ruby
-{
- ...
- example_metric_without_archived: distinct_count(Project.non_archived, :creator_id)
-}
-```
-
-and update existing business analysis artefacts to use `example_metric_without_archived` instead of `example_metric`
-
-### 3. Deprecate a metric
-
-If a metric is obsolete and you no longer use it, you can mark it as deprecated.
-
-For an example of the metric deprecation process take a look at this [example merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59899)
-
-To deprecate a metric:
-
-1. Check the following YAML files and verify the metric is not used in an aggregate:
- - [`config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/aggregates/)
- - [`ee/config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/aggregates/)
-
-1. Create an issue in the [GitLab Data Team
- project](https://gitlab.com/gitlab-data/analytics/-/issues). Ask for
- confirmation that the metric is not used by other teams, or in any of the SiSense
- dashboards.
-
-1. Verify the metric is not used to calculate the conversational index. The
- conversational index is a measure that reports back to self-managed instances
- to inform administrators of the progress of DevOps adoption for the instance.
-
- You can check
- [`CalculateConvIndexService`](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/calculate_conv_index_service.rb)
- to view the metrics that are used. The metrics are represented
- as the keys that are passed as a field argument into the `get_value` method.
-
-1. Document the deprecation in the metric's YAML definition. Set
- the `status:` attribute to `deprecated`, for example:
-
- ```yaml
- ---
- key_path: analytics_unique_visits.analytics_unique_visits_for_any_target_monthly
- description: Visits to any of the pages listed above per month
- product_section: dev
- product_stage: manage
- product_group: group::analytics
- product_category:
- value_type: number
- status: deprecated
- time_frame: 28d
- data_source:
- distribution:
- - ce
- tier:
- - free
- ```
-
-1. Replace the metric's instrumentation with a fixed value. This avoids wasting
- resources to calculate the deprecated metric. In
- [`lib/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb)
- or
- [`ee/lib/ee/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/ee/gitlab/usage_data.rb),
- replace the code that calculates the metric's value with a fixed value that
- indicates it's deprecated:
-
- ```ruby
- module Gitlab
- class UsageData
- DEPRECATED_VALUE = -1000
-
- def analytics_unique_visits_data
- results['analytics_unique_visits_for_any_target'] = redis_usage_data { unique_visit_service.unique_visits_for(targets: :analytics) }
- results['analytics_unique_visits_for_any_target_monthly'] = DEPRECATED_VALUE
-
- { analytics_unique_visits: results }
- end
- # ...
- end
- end
- ```
-
-### 4. Remove a metric
-
-Only deprecated metrics can be removed from Service Ping.
-
-For an example of the metric removal process take a look at this [example issue](https://gitlab.com/gitlab-org/gitlab/-/issues/297029)
-
-To remove a deprecated metric:
-
-1. Verify that removing the metric from the Service Ping payload does not cause
- errors in [Version App](https://gitlab.com/gitlab-services/version-gitlab-com)
- when the updated payload is collected and processed. Version App collects
- and persists all Service Ping reports. To do that you can modify
- [fixtures](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/spec/support/usage_data_helpers.rb#L540)
- used to test
- [`UsageDataController#create`](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/3760ef28/spec/controllers/usage_data_controller_spec.rb#L75)
- endpoint, and assure that test suite does not fail when metric that you wish to remove is not included into test payload.
-
-1. Create an issue in the
- [GitLab Data Team project](https://gitlab.com/gitlab-data/analytics/-/issues).
- Ask for confirmation that the metric is not referred to in any SiSense dashboards and
- can be safely removed from Service Ping. Use this
- [example issue](https://gitlab.com/gitlab-data/analytics/-/issues/7539) for guidance.
- This step can be skipped if verification done during [deprecation process](#3-deprecate-a-metric)
- reported that metric is not required by any data transformation in Snowflake data warehouse nor it is
- used by any of SiSense dashboards.
-
-1. After you verify the metric can be safely removed,
- update the attributes of the metric's YAML definition:
-
- - Set the `status:` to `removed`.
- - Set `milestone_removed:` to the number of the
- milestone in which the metric was removed.
-
- Do not remove the metric's YAML definition altogether. Some self-managed
- instances might not immediately update to the latest version of GitLab, and
- therefore continue to report the removed metric. The Product Intelligence team
- requires a record of all removed metrics in order to identify and filter them.
-
- For example please take a look at this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60149/diffs#b01f429a54843feb22265100c0e4fec1b7da1240_10_10).
-
-1. After you verify the metric can be safely removed,
- remove the metric's instrumentation from
- [`lib/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb)
- or
- [`ee/lib/ee/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/ee/gitlab/usage_data.rb).
-
- For example please take a look at this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60149/diffs#6335dc533bd21df26db9de90a02dd66278c2390d_167_167).
-
-1. Remove any other records related to the metric:
- - The feature flag YAML file at [`config/feature_flags/*/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/config/feature_flags).
- - The entry in the known events YAML file at [`lib/gitlab/usage_data_counters/known_events/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/usage_data_counters/known_events).
-
## Implementing Service Ping
Service Ping consists of two kinds of data, counters and observations. Counters track how often a certain event
diff --git a/doc/development/service_ping/metrics_dictionary.md b/doc/development/service_ping/metrics_dictionary.md
index b969286e053..d3eeaedd91d 100644
--- a/doc/development/service_ping/metrics_dictionary.md
+++ b/doc/development/service_ping/metrics_dictionary.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Metrics Dictionary Guide
-This guide describes Metrics Dictionary and how it's implemented
+This guide describes the [Metrics Dictionary](https://gitlab-org.gitlab.io/growth/product-intelligence/metric-dictionary) and how it's implemented.
## Metrics Definition and validation
diff --git a/doc/development/service_ping/metrics_lifecycle.md b/doc/development/service_ping/metrics_lifecycle.md
new file mode 100644
index 00000000000..87e5c796c97
--- /dev/null
+++ b/doc/development/service_ping/metrics_lifecycle.md
@@ -0,0 +1,179 @@
+---
+stage: Growth
+group: Product Intelligence
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Service Ping metric lifecycle
+
+The following guidelines explain the steps to follow at each stage of a metric's lifecycle.
+
+## Add a new metric
+
+Please follow the [Implementing Service Ping](index.md#implementing-service-ping) guide.
+
+## Change an existing metric
+
+Because we do not control when customers update their self-managed instances of GitLab,
+we **STRONGLY DISCOURAGE** changes to the logic used to calculate any metric.
+Any such changes lead to inconsistent reports from multiple GitLab instances.
+If there is a problem with an existing metric, it's best to deprecate the existing metric,
+and use it, side by side, with the desired new metric.
+
+Example:
+Consider following change. Before GitLab 12.6, the `example_metric` was implemented as:
+
+```ruby
+{
+ ...
+ example_metric: distinct_count(Project, :creator_id)
+}
+```
+
+For GitLab 12.6, the metric was changed to filter out archived projects:
+
+```ruby
+{
+ ...
+ example_metric: distinct_count(Project.non_archived, :creator_id)
+}
+```
+
+In this scenario all instances running up to GitLab 12.5 continue to report `example_metric`,
+including all archived projects, while all instances running GitLab 12.6 and higher filters
+out such projects. As Service Ping data is collected from all reporting instances, the
+resulting dataset includes mixed data, which distorts any following business analysis.
+
+The correct approach is to add a new metric for GitLab 12.6 release with updated logic:
+
+```ruby
+{
+ ...
+ example_metric_without_archived: distinct_count(Project.non_archived, :creator_id)
+}
+```
+
+and update existing business analysis artefacts to use `example_metric_without_archived` instead of `example_metric`
+
+## Deprecate a metric
+
+If a metric is obsolete and you no longer use it, you can mark it as deprecated.
+
+For an example of the metric deprecation process take a look at this [example merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59899)
+
+To deprecate a metric:
+
+1. Check the following YAML files and verify the metric is not used in an aggregate:
+ - [`config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/aggregates/)
+ - [`ee/config/metrics/aggregates/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/aggregates/)
+
+1. Create an issue in the [GitLab Data Team
+ project](https://gitlab.com/gitlab-data/analytics/-/issues). Ask for
+ confirmation that the metric is not used by other teams, or in any of the SiSense
+ dashboards.
+
+1. Verify the metric is not used to calculate the conversational index. The
+ conversational index is a measure that reports back to self-managed instances
+ to inform administrators of the progress of DevOps adoption for the instance.
+
+ You can check
+ [`CalculateConvIndexService`](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/calculate_conv_index_service.rb)
+ to view the metrics that are used. The metrics are represented
+ as the keys that are passed as a field argument into the `get_value` method.
+
+1. Document the deprecation in the metric's YAML definition. Set
+ the `status:` attribute to `deprecated`, for example:
+
+ ```yaml
+ ---
+ key_path: analytics_unique_visits.analytics_unique_visits_for_any_target_monthly
+ description: Visits to any of the pages listed above per month
+ product_section: dev
+ product_stage: manage
+ product_group: group::analytics
+ product_category:
+ value_type: number
+ status: deprecated
+ time_frame: 28d
+ data_source:
+ distribution:
+ - ce
+ tier:
+ - free
+ ```
+
+1. Replace the metric's instrumentation with a fixed value. This avoids wasting
+ resources to calculate the deprecated metric. In
+ [`lib/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb)
+ or
+ [`ee/lib/ee/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/ee/gitlab/usage_data.rb),
+ replace the code that calculates the metric's value with a fixed value that
+ indicates it's deprecated:
+
+ ```ruby
+ module Gitlab
+ class UsageData
+ DEPRECATED_VALUE = -1000
+
+ def analytics_unique_visits_data
+ results['analytics_unique_visits_for_any_target'] = redis_usage_data { unique_visit_service.unique_visits_for(targets: :analytics) }
+ results['analytics_unique_visits_for_any_target_monthly'] = DEPRECATED_VALUE
+
+ { analytics_unique_visits: results }
+ end
+ # ...
+ end
+ end
+ ```
+
+## Remove a metric
+
+Only deprecated metrics can be removed from Service Ping.
+
+For an example of the metric removal process take a look at this [example issue](https://gitlab.com/gitlab-org/gitlab/-/issues/297029)
+
+To remove a deprecated metric:
+
+1. Verify that removing the metric from the Service Ping payload does not cause
+ errors in [Version App](https://gitlab.com/gitlab-services/version-gitlab-com)
+ when the updated payload is collected and processed. Version App collects
+ and persists all Service Ping reports. To do that you can modify
+ [fixtures](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/spec/support/usage_data_helpers.rb#L540)
+ used to test
+ [`UsageDataController#create`](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/3760ef28/spec/controllers/usage_data_controller_spec.rb#L75)
+ endpoint, and assure that test suite does not fail when metric that you wish to remove is not included into test payload.
+
+1. Create an issue in the
+ [GitLab Data Team project](https://gitlab.com/gitlab-data/analytics/-/issues).
+ Ask for confirmation that the metric is not referred to in any SiSense dashboards and
+ can be safely removed from Service Ping. Use this
+ [example issue](https://gitlab.com/gitlab-data/analytics/-/issues/7539) for guidance.
+ This step can be skipped if verification done during [deprecation process](#deprecate-a-metric)
+ reported that metric is not required by any data transformation in Snowflake data warehouse nor it is
+ used by any of SiSense dashboards.
+
+1. After you verify the metric can be safely removed,
+ update the attributes of the metric's YAML definition:
+
+ - Set the `status:` to `removed`.
+ - Set `milestone_removed:` to the number of the
+ milestone in which the metric was removed.
+
+ Do not remove the metric's YAML definition altogether. Some self-managed
+ instances might not immediately update to the latest version of GitLab, and
+ therefore continue to report the removed metric. The Product Intelligence team
+ requires a record of all removed metrics in order to identify and filter them.
+
+ For example please take a look at this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60149/diffs#b01f429a54843feb22265100c0e4fec1b7da1240_10_10).
+
+1. After you verify the metric can be safely removed,
+ remove the metric's instrumentation from
+ [`lib/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data.rb)
+ or
+ [`ee/lib/ee/gitlab/usage_data.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/ee/gitlab/usage_data.rb).
+
+ For example please take a look at this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60149/diffs#6335dc533bd21df26db9de90a02dd66278c2390d_167_167).
+
+1. Remove any other records related to the metric:
+ - The feature flag YAML file at [`config/feature_flags/*/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/config/feature_flags).
+ - The entry in the known events YAML file at [`lib/gitlab/usage_data_counters/known_events/*.yaml`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/usage_data_counters/known_events).
diff --git a/doc/user/clusters/agent/ci_cd_tunnel.md b/doc/user/clusters/agent/ci_cd_tunnel.md
index 1f794bac37f..09123fdd472 100644
--- a/doc/user/clusters/agent/ci_cd_tunnel.md
+++ b/doc/user/clusters/agent/ci_cd_tunnel.md
@@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# CI/CD Tunnel
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327409) in GitLab 14.1.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327409) in GitLab 14.1.
+> - Pre-configured `KUBECONFIG` [added](https://gitlab.com/gitlab-org/gitlab/-/issues/324275) in GitLab 14.2.
The CI/CD Tunnel enables users to access Kubernetes clusters from GitLab CI/CD jobs even if there is no network
connectivity between GitLab Runner and a cluster. GitLab Runner does not have to be running in the same cluster.
@@ -21,47 +22,22 @@ Prerequisites:
- An [Agent record](index.md#create-an-agent-record-in-gitlab).
- The agent is [installed in the cluster](index.md#install-the-agent-into-the-cluster).
-To access your cluster from a CI/CD job through the tunnel:
+If your project has one or more Agent records, a `KUBECONFIG` variable that is compatible with `kubectl` is provided to your CI/CD jobs. A separate context (`kubecontext`) is available for each configured Agent. By default, no context is selected.
-1. In your `.gitlab-ci.yml` add a section that creates a `kubectl` compatible configuration file (`kubecontext`) and use it in one
- or more jobs:
+Contexts are named in the following format: `<agent-configuration-project-path>:<agent-name>`.
- ```yaml
- variables:
- AGENT_ID: 4 # agent id that you got when you created the agent record
- KUBE_CFG_FILE: "$CI_PROJECT_DIR/.kubeconfig.agent.yaml"
+To access your cluster from a CI/CD job through the tunnel:
- .kubectl_config: &kubectl_config
- - |
- cat << EOF > "$KUBE_CFG_FILE"
- apiVersion: v1
- kind: Config
- clusters:
- - name: agent
- cluster:
- server: https://kas.gitlab.com/k8s-proxy/
- users:
- - name: agent
- user:
- token: "ci:$AGENT_ID:$CI_JOB_TOKEN"
- contexts:
- - name: agent
- context:
- cluster: agent
- user: agent
- current-context: agent
- EOF
+1. In your `.gitlab-ci.yml` select the context for the agent you wish to use:
+ ```yaml
deploy:
image:
name: bitnami/kubectl:latest
entrypoint: [""]
script:
- - *kubectl_config
- - kubectl --kubeconfig="$KUBE_CFG_FILE" get pods
+ - kubectl config use-context path/to/agent-configuration-project:your-agent-name
+ - kubectl get pods
```
1. Execute `kubectl` commands directly against your cluster with this CI/CD job you just created.
-
-We are working on [creating the configuration file automatically](https://gitlab.com/gitlab-org/gitlab/-/issues/324275)
-to simplify the process.
diff --git a/doc/user/project/merge_requests/status_checks.md b/doc/user/project/merge_requests/status_checks.md
index 70e2d718406..1576b639a76 100644
--- a/doc/user/project/merge_requests/status_checks.md
+++ b/doc/user/project/merge_requests/status_checks.md
@@ -11,9 +11,6 @@ disqus_identifier: 'https://docs.gitlab.com/ee/user/project/merge_requests/statu
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3869) in GitLab 14.0, disabled behind the `:ff_external_status_checks` feature flag.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/320783) in GitLab 14.1.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
You can create a status check that sends merge request data to third-party tools.
When users create, change, or close merge requests, GitLab sends a notification. The users or automated workflows
can then update the status of merge requests from outside of GitLab.
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 2a34a579dc5..e2c9d8d41ab 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -60,14 +60,9 @@ read-only view to discourage this behavior.
#### Compliance pipeline configuration **(ULTIMATE)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3156) in GitLab 13.9.
-> - [Deployed behind a feature flag](../../feature_flags.md).
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3156) in GitLab 13.9, disabled behind `ff_evaluate_group_level_compliance_pipeline` [feature flag](../../../administration/feature_flags.md).
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/300324) in GitLab 13.11.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/331231) in GitLab 14.2.
Group owners can use the compliance pipeline configuration to define compliance requirements
such as scans or tests, and enforce them in individual projects.
diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb
index 305ffc6ab96..aceaf012f7e 100644
--- a/lib/gitlab/ci/config.rb
+++ b/lib/gitlab/ci/config.rb
@@ -121,17 +121,26 @@ module Gitlab
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break variables unless project
- # The order of the next 4 lines is important as priority of CI variables is
+ # The order of the following lines is important as priority of CI variables is
# defined globally within GitLab.
#
# See more detail in the docs: https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
variables.concat(project.predefined_variables)
+ variables.concat(pipeline_predefined_variables(ref: ref))
variables.concat(project.ci_instance_variables_for(ref: ref))
variables.concat(project.group.ci_variables_for(ref, project)) if project.group
variables.concat(project.ci_variables_for(ref: ref))
end
end
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/337633 aims to add all predefined variables
+ # to this list, but only CI_COMMIT_REF_NAME is available right now to support compliance pipelines.
+ def pipeline_predefined_variables(ref:)
+ Gitlab::Ci::Variables::Collection.new.tap do |v|
+ v.append(key: 'CI_COMMIT_REF_NAME', value: ref)
+ end
+ end
+
def track_and_raise_for_dev_exception(error)
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error, @context.sentry_payload)
end
diff --git a/lib/gitlab/git/remote_mirror.rb b/lib/gitlab/git/remote_mirror.rb
index eb368af199d..2f618294e8e 100644
--- a/lib/gitlab/git/remote_mirror.rb
+++ b/lib/gitlab/git/remote_mirror.rb
@@ -5,11 +5,10 @@ module Gitlab
class RemoteMirror
include Gitlab::Git::WrapsGitalyErrors
- attr_reader :repository, :ref_name, :remote_url, :only_branches_matching, :ssh_key, :known_hosts, :keep_divergent_refs
+ attr_reader :repository, :remote_url, :only_branches_matching, :ssh_key, :known_hosts, :keep_divergent_refs
- def initialize(repository, ref_name, remote_url, only_branches_matching: [], ssh_key: nil, known_hosts: nil, keep_divergent_refs: false)
+ def initialize(repository, remote_url, only_branches_matching: [], ssh_key: nil, known_hosts: nil, keep_divergent_refs: false)
@repository = repository
- @ref_name = ref_name
@remote_url = remote_url
@only_branches_matching = only_branches_matching
@ssh_key = ssh_key
@@ -20,7 +19,6 @@ module Gitlab
def update
wrapped_gitaly_errors do
repository.gitaly_remote_client.update_remote_mirror(
- ref_name,
remote_url,
only_branches_matching,
ssh_key: ssh_key,
diff --git a/lib/gitlab/gitaly_client/remote_service.rb b/lib/gitlab/gitaly_client/remote_service.rb
index 7e8dafe8500..535b987f91c 100644
--- a/lib/gitlab/gitaly_client/remote_service.rb
+++ b/lib/gitlab/gitaly_client/remote_service.rb
@@ -37,18 +37,13 @@ module Gitlab
encode_utf8(response.ref)
end
- def update_remote_mirror(ref_name, remote_url, only_branches_matching, ssh_key: nil, known_hosts: nil, keep_divergent_refs: false)
+ def update_remote_mirror(remote_url, only_branches_matching, ssh_key: nil, known_hosts: nil, keep_divergent_refs: false)
req_enum = Enumerator.new do |y|
first_request = Gitaly::UpdateRemoteMirrorRequest.new(
repository: @gitaly_repo
)
- if remote_url
- first_request.remote = Gitaly::UpdateRemoteMirrorRequest::Remote.new(url: remote_url)
- else
- first_request.ref_name = ref_name
- end
-
+ first_request.remote = Gitaly::UpdateRemoteMirrorRequest::Remote.new(url: remote_url)
first_request.ssh_key = ssh_key if ssh_key.present?
first_request.known_hosts = known_hosts if known_hosts.present?
first_request.keep_divergent_refs = keep_divergent_refs
diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
index 597df9936ea..cd27c2f8b8d 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
@@ -117,7 +117,7 @@ module Gitlab
private
def track(values, event_name, context: '', time: Time.zone.now)
- return unless usage_ping_enabled?
+ return unless ::ServicePing::ServicePingSettings.enabled?
event = event_for(event_name)
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(UnknownEvent.new("Unknown event #{event_name}")) unless event.present?
@@ -131,10 +131,6 @@ module Gitlab
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
end
- def usage_ping_enabled?
- Gitlab::CurrentSettings.usage_ping_enabled?
- end
-
# The array of valid context on which we allow tracking
def valid_context_list
Plan.all_plans
diff --git a/lib/gitlab/usage_data_counters/redis_counter.rb b/lib/gitlab/usage_data_counters/redis_counter.rb
index 2406f771fd8..591e431c871 100644
--- a/lib/gitlab/usage_data_counters/redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/redis_counter.rb
@@ -4,13 +4,13 @@ module Gitlab
module UsageDataCounters
module RedisCounter
def increment(redis_counter_key)
- return unless Gitlab::CurrentSettings.usage_ping_enabled
+ return unless ::ServicePing::ServicePingSettings.enabled?
Gitlab::Redis::SharedState.with { |redis| redis.incr(redis_counter_key) }
end
def increment_by(redis_counter_key, incr)
- return unless Gitlab::CurrentSettings.usage_ping_enabled
+ return unless ::ServicePing::ServicePingSettings.enabled?
Gitlab::Redis::SharedState.with { |redis| redis.incrby(redis_counter_key, incr) }
end
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index 412f66f17c0..9f793934dc9 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -15,11 +15,6 @@ module QA
element :group_package_settings_link
end
- view 'app/views/layouts/nav/sidebar/_analytics_links.html.haml' do
- element :analytics_link
- element :analytics_sidebar_submenu
- end
-
def click_group_members_item
hover_group_information do
within_submenu do
@@ -42,14 +37,6 @@ module QA
end
end
- def click_contribution_analytics_item
- hover_element(:analytics_link) do
- within_submenu(:analytics_sidebar_submenu) do
- click_element(:contribution_analytics_link)
- end
- end
- end
-
def click_group_general_settings_item
hover_element(:group_settings) do
within_submenu(:group_sidebar_submenu) do
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 7f330681a82..fb86f4672bc 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -265,7 +265,6 @@ FactoryBot.define do
trait :remote_mirror do
transient do
- remote_name { "remote_mirror_#{SecureRandom.hex}" }
url { "http://foo.com" }
enabled { true }
end
diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb
index 20c07f4d6ac..32caad775e4 100644
--- a/spec/features/clusters/cluster_health_dashboard_spec.rb
+++ b/spec/features/clusters/cluster_health_dashboard_spec.rb
@@ -63,21 +63,33 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
context 'connected, prometheus returns data' do
before do
stub_connected
- end
- it 'renders charts' do
visit cluster_path
click_link 'Health'
wait_for_requests
+ end
+ it 'renders charts' do
expect(page).to have_css('.prometheus-graphs')
expect(page).to have_css('.prometheus-graph')
expect(page).to have_css('.prometheus-graph-title')
expect(page).to have_css('[_echarts_instance_]')
+ expect(page).to have_css('.prometheus-graph', count: 2)
expect(page).to have_content('Avg')
end
+
+ it 'focuses the single panel on toggle' do
+ click_button('More actions')
+ click_button('Expand panel')
+
+ expect(page).to have_css('.prometheus-graph', count: 1)
+
+ click_button('Collapse panel')
+
+ expect(page).to have_css('.prometheus-graph', count: 2)
+ end
end
def stub_empty_response
diff --git a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
index 79e55db30cd..188e6580dc6 100644
--- a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
+++ b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js
@@ -25,7 +25,6 @@ describe('content_editor/extensions/code_block_highlight', () => {
expect(tiptapEditor.getJSON().content[0].attrs).toMatchObject({
language,
- params: language,
});
});
diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js
index 13498cfb823..a17efdd61a9 100644
--- a/spec/frontend/tracking_spec.js
+++ b/spec/frontend/tracking_spec.js
@@ -387,11 +387,13 @@ describe('Tracking', () => {
beforeEach(() => {
eventSpy = jest.spyOn(Tracking, 'event');
setHTMLFixture(`
- <input data-track-${term}="render" data-track-label="label1" value=1 data-track-property="_property_"/>
- <span data-track-${term}="render" data-track-label="label2" data-track-value=1>
- Something
- </span>
- <input data-track-${term}="_render_bogus_" data-track-label="label3" value="_value_" data-track-property="_property_"/>
+ <div data-track-${term}="click_link" data-track-label="all_nested_links">
+ <input data-track-${term}="render" data-track-label="label1" value=1 data-track-property="_property_"/>
+ <span data-track-${term}="render" data-track-label="label2" data-track-value=1>
+ <a href="#" id="link">Something</a>
+ </span>
+ <input data-track-${term}="_render_bogus_" data-track-label="label3" value="_value_" data-track-property="_property_"/>
+ </div>
`);
Tracking.trackLoadEvents('_category_'); // only happens once
});
@@ -417,6 +419,35 @@ describe('Tracking', () => {
],
]);
});
+
+ describe.each`
+ event | actionSuffix
+ ${'click'} | ${''}
+ ${'show.bs.dropdown'} | ${'_show'}
+ ${'hide.bs.dropdown'} | ${'_hide'}
+ `(`auto-tracking $event events on nested elements`, ({ event, actionSuffix }) => {
+ let link;
+
+ beforeEach(() => {
+ link = document.querySelector('#link');
+ eventSpy.mockClear();
+ });
+
+ it(`avoids using ancestor [data-track-${term}="render"] tracking configurations`, () => {
+ link.dispatchEvent(new Event(event, { bubbles: true }));
+
+ expect(eventSpy).not.toHaveBeenCalledWith(
+ '_category_',
+ `render${actionSuffix}`,
+ expect.any(Object),
+ );
+ expect(eventSpy).toHaveBeenCalledWith(
+ '_category_',
+ `click_link${actionSuffix}`,
+ expect.objectContaining({ label: 'all_nested_links' }),
+ );
+ });
+ });
});
describe('tracking mixin', () => {
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
index 46a11bc28d8..90bc1980ac3 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
@@ -1,6 +1,6 @@
import { GlLoadingIcon, GlLink } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
+import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -14,7 +14,7 @@ jest.mock('~/flash');
const colors = Object.keys(mockSuggestedColors);
const localVue = createLocalVue();
-Vue.use(VueApollo);
+localVue.use(VueApollo);
const userRecoverableError = {
...createLabelSuccessfulResponse,
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
index 51301387c99..8bd944a3d54 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
@@ -1,357 +1,213 @@
-import { GlIntersectionObserver, GlLoadingIcon, GlSearchBoxByType, GlLink } from '@gitlab/ui';
+import { GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
-import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
+import { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
+import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_widget/constants';
import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue';
+import projectLabelsQuery from '~/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql';
import LabelItem from '~/vue_shared/components/sidebar/labels_select_widget/label_item.vue';
+import { mockConfig, labelsQueryResponse } from './mock_data';
-import * as actions from '~/vue_shared/components/sidebar/labels_select_widget/store/actions';
-import * as getters from '~/vue_shared/components/sidebar/labels_select_widget/store/getters';
-import mutations from '~/vue_shared/components/sidebar/labels_select_widget/store/mutations';
-import defaultState from '~/vue_shared/components/sidebar/labels_select_widget/store/state';
-
-import { mockConfig, mockLabels, mockRegularLabel } from './mock_data';
+jest.mock('~/flash');
const localVue = createLocalVue();
-localVue.use(Vuex);
+localVue.use(VueApollo);
+
+const selectedLabels = [
+ {
+ id: 28,
+ title: 'Bug',
+ description: 'Label for bugs',
+ color: '#FF0000',
+ textColor: '#FFFFFF',
+ },
+];
describe('DropdownContentsLabelsView', () => {
let wrapper;
- const createComponent = (initialState = mockConfig) => {
- const store = new Vuex.Store({
- getters,
- mutations,
- state: {
- ...defaultState(),
- footerCreateLabelTitle: 'Create label',
- footerManageLabelTitle: 'Manage labels',
- },
- actions: {
- ...actions,
- fetchLabels: jest.fn(),
- },
- });
+ const successfulQueryHandler = jest.fn().mockResolvedValue(labelsQueryResponse);
- store.dispatch('setInitialState', initialState);
- store.dispatch('receiveLabelsSuccess', mockLabels);
+ const createComponent = ({
+ initialState = mockConfig,
+ queryHandler = successfulQueryHandler,
+ injected = {},
+ } = {}) => {
+ const mockApollo = createMockApollo([[projectLabelsQuery, queryHandler]]);
wrapper = shallowMount(DropdownContentsLabelsView, {
localVue,
- store,
+ apolloProvider: mockApollo,
+ provide: {
+ projectPath: 'test',
+ iid: 1,
+ allowLabelCreate: true,
+ labelsManagePath: '/gitlab-org/my-project/-/labels',
+ variant: DropdownVariant.Sidebar,
+ ...injected,
+ },
+ propsData: {
+ ...initialState,
+ selectedLabels,
+ },
+ stubs: {
+ GlSearchBoxByType,
+ },
});
};
- beforeEach(() => {
- createComponent();
- });
-
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
- const findDropdownContent = () => wrapper.find('[data-testid="dropdown-content"]');
+ const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType);
+ const findLabels = () => wrapper.findAllComponents(LabelItem);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+
+ const findLabelsList = () => wrapper.find('[data-testid="labels-list"]');
+ const findDropdownWrapper = () => wrapper.find('[data-testid="dropdown-wrapper"]');
const findDropdownFooter = () => wrapper.find('[data-testid="dropdown-footer"]');
- const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
-
- describe('computed', () => {
- describe('visibleLabels', () => {
- it('returns matching labels filtered with `searchKey`', () => {
- wrapper.setData({
- searchKey: 'bug',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(1);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
- });
-
- it('returns matching labels with fuzzy filtering', () => {
- wrapper.setData({
- searchKey: 'bg',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(2);
- expect(wrapper.vm.visibleLabels[0].title).toBe('Bug');
- expect(wrapper.vm.visibleLabels[1].title).toBe('Boog');
- });
-
- it('returns all labels when `searchKey` is empty', () => {
- wrapper.setData({
- searchKey: '',
- });
-
- expect(wrapper.vm.visibleLabels.length).toBe(mockLabels.length);
- });
- });
+ const findNoResultsMessage = () => wrapper.find('[data-testid="no-results"]');
+ const findCreateLabelButton = () => wrapper.find('[data-testid="create-label-button"]');
- describe('showNoMatchingResultsMessage', () => {
- it.each`
- searchKey | labels | labelsDescription | returnValue
- ${''} | ${[]} | ${'empty'} | ${false}
- ${'bug'} | ${[]} | ${'empty'} | ${true}
- ${''} | ${mockLabels} | ${'not empty'} | ${false}
- ${'bug'} | ${mockLabels} | ${'not empty'} | ${false}
- `(
- 'returns $returnValue when searchKey is "$searchKey" and visibleLabels is $labelsDescription',
- async ({ searchKey, labels, returnValue }) => {
- wrapper.setData({
- searchKey,
- });
-
- wrapper.vm.$store.dispatch('receiveLabelsSuccess', labels);
-
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.showNoMatchingResultsMessage).toBe(returnValue);
- },
- );
+ describe('when loading labels', () => {
+ it('renders disabled search input field', async () => {
+ createComponent();
+ expect(findSearchInput().props('disabled')).toBe(true);
});
- });
-
- describe('methods', () => {
- describe('isLabelSelected', () => {
- it('returns true when provided `label` param is one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockRegularLabel)).toBe(true);
- });
- it('returns false when provided `label` param is not one of the selected labels', () => {
- expect(wrapper.vm.isLabelSelected(mockLabels[2])).toBe(false);
- });
+ it('renders loading icon', async () => {
+ createComponent();
+ expect(findLoadingIcon().exists()).toBe(true);
});
- describe('handleComponentAppear', () => {
- it('calls `focusInput` on searchInput field', async () => {
- wrapper.vm.$refs.searchInput.focusInput = jest.fn();
-
- await wrapper.vm.handleComponentAppear();
-
- expect(wrapper.vm.$refs.searchInput.focusInput).toHaveBeenCalled();
- });
+ it('does not render labels list', async () => {
+ createComponent();
+ expect(findLabelsList().exists()).toBe(false);
});
+ });
- describe('handleComponentDisappear', () => {
- it('calls action `receiveLabelsSuccess` with empty array', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
-
- wrapper.vm.handleComponentDisappear();
-
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
- });
+ describe('when labels are loaded', () => {
+ beforeEach(async () => {
+ createComponent();
+ await waitForPromises();
});
- describe('handleCreateLabelClick', () => {
- it('calls actions `receiveLabelsSuccess` with empty array and `toggleDropdownContentsCreateView`', () => {
- jest.spyOn(wrapper.vm, 'receiveLabelsSuccess');
- jest.spyOn(wrapper.vm, 'toggleDropdownContentsCreateView');
-
- wrapper.vm.handleCreateLabelClick();
-
- expect(wrapper.vm.receiveLabelsSuccess).toHaveBeenCalledWith([]);
- expect(wrapper.vm.toggleDropdownContentsCreateView).toHaveBeenCalled();
- });
+ it('renders enabled search input field', async () => {
+ expect(findSearchInput().props('disabled')).toBe(false);
});
- describe('handleKeyDown', () => {
- it('decreases `currentHighlightItem` value by 1 when Up arrow key is pressed', () => {
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: UP_KEY_CODE,
- });
-
- expect(wrapper.vm.currentHighlightItem).toBe(0);
- });
-
- it('increases `currentHighlightItem` value by 1 when Down arrow key is pressed', () => {
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
-
- expect(wrapper.vm.currentHighlightItem).toBe(2);
- });
-
- it('resets the search text when the Enter key is pressed', () => {
- wrapper.setData({
- currentHighlightItem: 1,
- searchKey: 'bug',
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- });
-
- expect(wrapper.vm.searchKey).toBe('');
- });
-
- it('calls action `updateSelectedLabels` with currently highlighted label when Enter key is pressed', () => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ENTER_KEY_CODE,
- });
-
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([
- {
- ...mockLabels[1],
- set: true,
- },
- ]);
- });
-
- it('calls action `toggleDropdownContents` when Esc key is pressed', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents').mockImplementation();
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: ESC_KEY_CODE,
- });
-
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
- });
-
- it('calls action `scrollIntoViewIfNeeded` in next tick when any key is pressed', () => {
- jest.spyOn(wrapper.vm, 'scrollIntoViewIfNeeded').mockImplementation();
- wrapper.setData({
- currentHighlightItem: 1,
- });
-
- wrapper.vm.handleKeyDown({
- keyCode: DOWN_KEY_CODE,
- });
-
- return wrapper.vm.$nextTick(() => {
- expect(wrapper.vm.scrollIntoViewIfNeeded).toHaveBeenCalled();
- });
- });
+ it('does not render loading icon', async () => {
+ expect(findLoadingIcon().exists()).toBe(false);
});
- describe('handleLabelClick', () => {
- beforeEach(() => {
- jest.spyOn(wrapper.vm, 'updateSelectedLabels').mockImplementation();
- });
-
- it('calls action `updateSelectedLabels` with provided `label` param', () => {
- wrapper.vm.handleLabelClick(mockRegularLabel);
-
- expect(wrapper.vm.updateSelectedLabels).toHaveBeenCalledWith([mockRegularLabel]);
- });
+ it('renders labels list', async () => {
+ expect(findLabelsList().exists()).toBe(true);
+ expect(findLabels()).toHaveLength(2);
+ });
- it('calls action `toggleDropdownContents` when `state.allowMultiselect` is false', () => {
- jest.spyOn(wrapper.vm, 'toggleDropdownContents');
- wrapper.vm.$store.state.allowMultiselect = false;
+ it('changes highlighted label correctly on pressing down button', async () => {
+ expect(findLabels().at(0).attributes('highlight')).toBeUndefined();
- wrapper.vm.handleLabelClick(mockRegularLabel);
+ await findDropdownWrapper().trigger('keydown.down');
+ expect(findLabels().at(0).attributes('highlight')).toBe('true');
- expect(wrapper.vm.toggleDropdownContents).toHaveBeenCalled();
- });
+ await findDropdownWrapper().trigger('keydown.down');
+ expect(findLabels().at(1).attributes('highlight')).toBe('true');
+ expect(findLabels().at(0).attributes('highlight')).toBeUndefined();
});
- });
- describe('template', () => {
- it('renders gl-intersection-observer as component root', () => {
- expect(wrapper.find(GlIntersectionObserver).exists()).toBe(true);
- });
+ it('changes highlighted label correctly on pressing up button', async () => {
+ await findDropdownWrapper().trigger('keydown.down');
+ await findDropdownWrapper().trigger('keydown.down');
+ expect(findLabels().at(1).attributes('highlight')).toBe('true');
- it('renders gl-loading-icon component when `labelsFetchInProgress` prop is true', () => {
- wrapper.vm.$store.dispatch('requestLabels');
+ await findDropdownWrapper().trigger('keydown.up');
+ expect(findLabels().at(0).attributes('highlight')).toBe('true');
+ });
- return wrapper.vm.$nextTick(() => {
- const loadingIconEl = findLoadingIcon();
+ it('changes label selected state when Enter is pressed', async () => {
+ expect(findLabels().at(0).attributes('islabelset')).toBeUndefined();
+ await findDropdownWrapper().trigger('keydown.down');
+ await findDropdownWrapper().trigger('keydown.enter');
- expect(loadingIconEl.exists()).toBe(true);
- expect(loadingIconEl.attributes('class')).toContain('labels-fetch-loading');
- });
+ expect(findLabels().at(0).attributes('islabelset')).toBe('true');
});
- it('renders label search input element', () => {
- const searchInputEl = wrapper.find(GlSearchBoxByType);
+ it('emits `closeDropdown event` when Esc button is pressed', () => {
+ findDropdownWrapper().trigger('keydown.esc');
- expect(searchInputEl.exists()).toBe(true);
+ expect(wrapper.emitted('closeDropdown')).toEqual([[selectedLabels]]);
});
+ });
- it('renders label elements for all labels', () => {
- expect(wrapper.findAll(LabelItem)).toHaveLength(mockLabels.length);
+ it('when search returns 0 results', async () => {
+ createComponent({
+ queryHandler: jest.fn().mockResolvedValue({
+ data: {
+ workspace: {
+ labels: {
+ nodes: [],
+ },
+ },
+ },
+ }),
});
+ findSearchInput().vm.$emit('input', '123');
+ await waitForPromises();
+ await nextTick();
- it('renders label element with `highlight` set to true when value of `currentHighlightItem` is more than -1', () => {
- wrapper.setData({
- currentHighlightItem: 0,
- });
+ expect(findNoResultsMessage().isVisible()).toBe(true);
+ });
- return wrapper.vm.$nextTick(() => {
- const labelItemEl = findDropdownContent().find(LabelItem);
+ it('calls `createFlash` when fetching labels failed', async () => {
+ createComponent({ queryHandler: jest.fn().mockRejectedValue('Houston, we have a problem!') });
+ jest.advanceTimersByTime(DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
+ await waitForPromises();
+ expect(createFlash).toHaveBeenCalled();
+ });
- expect(labelItemEl.attributes('highlight')).toBe('true');
- });
- });
+ it('does not render footer on standalone dropdown', () => {
+ createComponent({ injected: { variant: DropdownVariant.Standalone } });
- it('renders element containing "No matching results" when `searchKey` does not match with any label', () => {
- wrapper.setData({
- searchKey: 'abc',
- });
+ expect(findDropdownFooter().exists()).toBe(false);
+ });
- return wrapper.vm.$nextTick(() => {
- const noMatchEl = findDropdownContent().find('li');
+ it('renders footer on sidebar dropdown', () => {
+ createComponent();
- expect(noMatchEl.isVisible()).toBe(true);
- expect(noMatchEl.text()).toContain('No matching results');
- });
- });
+ expect(findDropdownFooter().exists()).toBe(true);
+ });
- it('renders empty content while loading', () => {
- wrapper.vm.$store.state.labelsFetchInProgress = true;
+ it('renders footer on embedded dropdown', () => {
+ createComponent({ injected: { variant: DropdownVariant.Embedded } });
- return wrapper.vm.$nextTick(() => {
- const dropdownContent = findDropdownContent();
- const loadingIcon = findLoadingIcon();
+ expect(findDropdownFooter().exists()).toBe(true);
+ });
- expect(dropdownContent.exists()).toBe(true);
- expect(dropdownContent.isVisible()).toBe(true);
- expect(loadingIcon.exists()).toBe(true);
- expect(loadingIcon.isVisible()).toBe(true);
- });
- });
+ it('does not render create label button if `allowLabelCreate` is false', () => {
+ createComponent({ injected: { allowLabelCreate: false } });
- it('renders footer list items', () => {
- const footerLinks = findDropdownFooter().findAll(GlLink);
- const createLabelLink = footerLinks.at(0);
- const manageLabelsLink = footerLinks.at(1);
+ expect(findCreateLabelButton().exists()).toBe(false);
+ });
- expect(createLabelLink.exists()).toBe(true);
- expect(createLabelLink.text()).toBe('Create label');
- expect(manageLabelsLink.exists()).toBe(true);
- expect(manageLabelsLink.text()).toBe('Manage labels');
+ describe('when `allowLabelCreate` is true', () => {
+ beforeEach(() => {
+ createComponent();
});
- it('does not render "Create label" footer link when `state.allowLabelCreate` is `false`', () => {
- wrapper.vm.$store.state.allowLabelCreate = false;
-
- return wrapper.vm.$nextTick(() => {
- const createLabelLink = findDropdownFooter().findAll(GlLink).at(0);
-
- expect(createLabelLink.text()).not.toBe('Create label');
- });
+ it('renders create label button', () => {
+ expect(findCreateLabelButton().exists()).toBe(true);
});
- it('does not render footer list items when `state.variant` is "standalone"', () => {
- createComponent({ ...mockConfig, variant: 'standalone' });
- expect(findDropdownFooter().exists()).toBe(false);
- });
+ it('emits `toggleDropdownContentsCreateView` event on create label button click', () => {
+ findCreateLabelButton().vm.$emit('click');
- it('renders footer list items when `state.variant` is "embedded"', () => {
- expect(findDropdownFooter().exists()).toBe(true);
+ expect(wrapper.emitted('toggleDropdownContentsCreateView')).toEqual([[]]);
});
});
});
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
index 8273bbdf7a7..3c2fd0c5acc 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
@@ -5,7 +5,7 @@ import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_w
import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue';
import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store';
-import { mockConfig } from './mock_data';
+import { mockConfig, mockLabels } from './mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -19,6 +19,11 @@ const createComponent = (initialState = mockConfig, defaultProps = {}) => {
propsData: {
...defaultProps,
labelsCreateTitle: 'test',
+ selectedLabels: mockLabels,
+ allowMultiselect: true,
+ labelsListTitle: 'Assign labels',
+ footerCreateLabelTitle: 'create',
+ footerManageLabelTitle: 'manage',
},
localVue,
store,
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
index 66971446f47..e17dfd93efc 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
@@ -50,58 +50,6 @@ describe('LabelsSelectRoot', () => {
});
describe('methods', () => {
- describe('handleVuexActionDispatch', () => {
- it('calls `handleDropdownClose` when params `action.type` is `toggleDropdownContents` and state has `showDropdownButton` & `showDropdownContents` props `false`', () => {
- createComponent();
- jest.spyOn(wrapper.vm, 'handleDropdownClose').mockImplementation();
-
- wrapper.vm.handleVuexActionDispatch(
- { type: 'toggleDropdownContents' },
- {
- showDropdownButton: false,
- showDropdownContents: false,
- labels: [{ id: 1 }, { id: 2, touched: true }],
- },
- );
-
- expect(wrapper.vm.handleDropdownClose).toHaveBeenCalledWith(
- expect.arrayContaining([
- {
- id: 2,
- touched: true,
- },
- ]),
- );
- });
-
- it('calls `handleDropdownClose` with state.labels filterd using `set` prop when dropdown variant is `embedded`', () => {
- createComponent({
- ...mockConfig,
- variant: 'embedded',
- });
-
- jest.spyOn(wrapper.vm, 'handleDropdownClose').mockImplementation();
-
- wrapper.vm.handleVuexActionDispatch(
- { type: 'toggleDropdownContents' },
- {
- showDropdownButton: false,
- showDropdownContents: false,
- labels: [{ id: 1 }, { id: 2, set: true }],
- },
- );
-
- expect(wrapper.vm.handleDropdownClose).toHaveBeenCalledWith(
- expect.arrayContaining([
- {
- id: 2,
- set: true,
- },
- ]),
- );
- });
- });
-
describe('handleDropdownClose', () => {
beforeEach(() => {
createComponent();
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
index 9e29030fb56..5dd8fc1b8b2 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
@@ -48,6 +48,8 @@ export const mockConfig = {
labelsManagePath: '/gitlab-org/my-project/-/labels',
labelsFilterBasePath: '/gitlab-org/my-project/issues',
labelsFilterParam: 'label_name',
+ footerCreateLabelTitle: 'create',
+ footerManageLabelTitle: 'manage',
};
export const mockSuggestedColors = {
@@ -91,3 +93,26 @@ export const createLabelSuccessfulResponse = {
},
},
};
+
+export const labelsQueryResponse = {
+ data: {
+ workspace: {
+ labels: {
+ nodes: [
+ {
+ color: '#330066',
+ description: null,
+ id: 'gid://gitlab/ProjectLabel/1',
+ title: 'Label1',
+ },
+ {
+ color: '#2f7b2e',
+ description: null,
+ id: 'gid://gitlab/ProjectLabel/2',
+ title: 'Label2',
+ },
+ ],
+ },
+ },
+ },
+};
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
index 27de7de2411..ee905410ffa 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js
@@ -1,8 +1,4 @@
-import MockAdapter from 'axios-mock-adapter';
-
import testAction from 'helpers/vuex_action_helper';
-import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
import * as actions from '~/vue_shared/components/sidebar/labels_select_widget/store/actions';
import * as types from '~/vue_shared/components/sidebar/labels_select_widget/store/mutation_types';
import defaultState from '~/vue_shared/components/sidebar/labels_select_widget/store/state';
@@ -72,90 +68,6 @@ describe('LabelsSelect Actions', () => {
});
});
- describe('requestLabels', () => {
- it('sets value of `state.labelsFetchInProgress` to `true`', (done) => {
- testAction(actions.requestLabels, {}, state, [{ type: types.REQUEST_LABELS }], [], done);
- });
- });
-
- describe('receiveLabelsSuccess', () => {
- it('sets provided labels to `state.labels`', (done) => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
-
- testAction(
- actions.receiveLabelsSuccess,
- labels,
- state,
- [{ type: types.RECEIVE_SET_LABELS_SUCCESS, payload: labels }],
- [],
- done,
- );
- });
- });
-
- describe('receiveLabelsFailure', () => {
- it('sets value `state.labelsFetchInProgress` to `false`', (done) => {
- testAction(
- actions.receiveLabelsFailure,
- {},
- state,
- [{ type: types.RECEIVE_SET_LABELS_FAILURE }],
- [],
- done,
- );
- });
-
- it('shows flash error', () => {
- actions.receiveLabelsFailure({ commit: () => {} });
-
- expect(createFlash).toHaveBeenCalledWith({ message: 'Error fetching labels.' });
- });
- });
-
- describe('fetchLabels', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- state.labelsFetchPath = 'labels.json';
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('on success', () => {
- it('dispatches `requestLabels` & `receiveLabelsSuccess` actions', (done) => {
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
- mock.onGet(/labels.json/).replyOnce(200, labels);
-
- testAction(
- actions.fetchLabels,
- {},
- state,
- [],
- [{ type: 'requestLabels' }, { type: 'receiveLabelsSuccess', payload: labels }],
- done,
- );
- });
- });
-
- describe('on failure', () => {
- it('dispatches `requestLabels` & `receiveLabelsFailure` actions', (done) => {
- mock.onGet(/labels.json/).replyOnce(500, {});
-
- testAction(
- actions.fetchLabels,
- {},
- state,
- [],
- [{ type: 'requestLabels' }, { type: 'receiveLabelsFailure' }],
- done,
- );
- });
- });
- });
-
describe('updateSelectedLabels', () => {
it('updates `state.labels` based on provided `labels` param', (done) => {
const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
index 9e965cb33e8..1f0e0eee420 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js
@@ -67,58 +67,6 @@ describe('LabelsSelect Mutations', () => {
});
});
- describe(`${types.REQUEST_LABELS}`, () => {
- it('sets value of `state.labelsFetchInProgress` to true', () => {
- const state = {
- labelsFetchInProgress: false,
- };
- mutations[types.REQUEST_LABELS](state);
-
- expect(state.labelsFetchInProgress).toBe(true);
- });
- });
-
- describe(`${types.RECEIVE_SET_LABELS_SUCCESS}`, () => {
- const selectedLabels = [{ id: 2 }, { id: 4 }];
- const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
-
- it('sets value of `state.labelsFetchInProgress` to false', () => {
- const state = {
- selectedLabels,
- labelsFetchInProgress: true,
- };
- mutations[types.RECEIVE_SET_LABELS_SUCCESS](state, labels);
-
- expect(state.labelsFetchInProgress).toBe(false);
- });
-
- it('sets provided `labels` to `state.labels` along with `set` prop based on `state.selectedLabels`', () => {
- const selectedLabelIds = selectedLabels.map((label) => label.id);
- const state = {
- selectedLabels,
- labelsFetchInProgress: true,
- };
- mutations[types.RECEIVE_SET_LABELS_SUCCESS](state, labels);
-
- state.labels.forEach((label) => {
- if (selectedLabelIds.includes(label.id)) {
- expect(label.set).toBe(true);
- }
- });
- });
- });
-
- describe(`${types.RECEIVE_SET_LABELS_FAILURE}`, () => {
- it('sets value of `state.labelsFetchInProgress` to false', () => {
- const state = {
- labelsFetchInProgress: true,
- };
- mutations[types.RECEIVE_SET_LABELS_FAILURE](state);
-
- expect(state.labelsFetchInProgress).toBe(false);
- });
- });
-
describe(`${types.UPDATE_SELECTED_LABELS}`, () => {
let labels;
diff --git a/spec/javascripts/monitoring/components/dashboard_resize_browser_spec.js b/spec/javascripts/monitoring/components/dashboard_resize_browser_spec.js
deleted file mode 100644
index b85f50ec998..00000000000
--- a/spec/javascripts/monitoring/components/dashboard_resize_browser_spec.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * This file should only contain browser specific specs.
- * If you need to add or update a spec, please see spec/frontend/monitoring/components/*.js
- * https://gitlab.com/gitlab-org/gitlab/-/issues/194244#note_343427737
- * https://gitlab.com/groups/gitlab-org/-/epics/895#what-if-theres-a-karma-spec-which-is-simply-unmovable-to-jest-ie-it-is-dependent-on-a-running-browser-environment
- */
-
-import { createLocalVue } from '@vue/test-utils';
-import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
-import axios from '~/lib/utils/axios_utils';
-import Dashboard from '~/monitoring/components/dashboard.vue';
-import { createStore } from '~/monitoring/stores';
-import { metricsDashboardPayload, dashboardProps } from '../fixture_data';
-import { mockApiEndpoint } from '../mock_data';
-import { setupStoreWithData } from '../store_utils';
-
-const localVue = createLocalVue();
-
-describe('Dashboard', () => {
- let DashboardComponent;
- let mock;
- let store;
- let component;
- let wrapper;
-
- beforeEach(() => {
- setFixtures(`
- <div class="prometheus-graphs"></div>
- <div class="layout-page"></div>
- `);
-
- store = createStore();
- mock = new MockAdapter(axios);
- DashboardComponent = localVue.extend(Dashboard);
- });
-
- afterEach(() => {
- if (component) {
- component.$destroy();
- }
- if (wrapper) {
- wrapper.destroy();
- }
- mock.restore();
- });
-
- describe('responds to window resizes', () => {
- let promPanel;
- let promGroup;
- let panelToggle;
- let chart;
- beforeEach(() => {
- mock.onGet(mockApiEndpoint).reply(200, metricsDashboardPayload);
-
- component = new DashboardComponent({
- el: document.querySelector('.prometheus-graphs'),
- propsData: {
- ...dashboardProps,
- hasMetrics: true,
- showPanels: true,
- },
- store,
- provide: { hasManagedPrometheus: false },
- });
-
- setupStoreWithData(component.$store);
-
- return Vue.nextTick().then(() => {
- [promPanel] = component.$el.querySelectorAll('.prometheus-panel');
- promGroup = promPanel.querySelector('.prometheus-graph-group');
- panelToggle = promPanel.querySelector('.js-graph-group-toggle');
- chart = promGroup.querySelector('.position-relative svg');
- });
- });
-
- it('setting chart size to zero when panel group is hidden', () => {
- expect(promGroup.style.display).toBe('');
- expect(chart.clientWidth).toBeGreaterThan(0);
-
- panelToggle.click();
- return Vue.nextTick().then(() => {
- expect(promGroup.style.display).toBe('none');
- expect(chart.clientWidth).toBe(0);
- promPanel.style.width = '500px';
- });
- });
-
- it('expanding chart panel group after resize displays chart', () => {
- panelToggle.click();
-
- expect(chart.clientWidth).toBeGreaterThan(0);
- });
- });
-});
diff --git a/spec/javascripts/monitoring/fixture_data.js b/spec/javascripts/monitoring/fixture_data.js
deleted file mode 100644
index 1375c27cdde..00000000000
--- a/spec/javascripts/monitoring/fixture_data.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../frontend/monitoring/fixture_data';
diff --git a/spec/javascripts/monitoring/mock_data.js b/spec/javascripts/monitoring/mock_data.js
deleted file mode 100644
index c80401e8c1d..00000000000
--- a/spec/javascripts/monitoring/mock_data.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// No new code should be added to this file. Instead, modify the
-// file this one re-exports from. For more detail about why, see:
-// https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/31349
-
-export * from '../../frontend/monitoring/mock_data';
diff --git a/spec/javascripts/monitoring/store_utils.js b/spec/javascripts/monitoring/store_utils.js
deleted file mode 100644
index 1222716c829..00000000000
--- a/spec/javascripts/monitoring/store_utils.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../frontend/monitoring/store_utils';
diff --git a/spec/lib/gitlab/git/remote_mirror_spec.rb b/spec/lib/gitlab/git/remote_mirror_spec.rb
index 0954879f6bd..4b827e5d2d0 100644
--- a/spec/lib/gitlab/git/remote_mirror_spec.rb
+++ b/spec/lib/gitlab/git/remote_mirror_spec.rb
@@ -6,30 +6,17 @@ RSpec.describe Gitlab::Git::RemoteMirror do
describe '#update' do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
- let(:ref_name) { 'foo' }
let(:url) { 'https://example.com' }
let(:options) { { only_branches_matching: ['master'], ssh_key: 'KEY', known_hosts: 'KNOWN HOSTS', keep_divergent_refs: true } }
- subject(:remote_mirror) { described_class.new(repository, ref_name, url, **options) }
+ subject(:remote_mirror) { described_class.new(repository, url, **options) }
- shared_examples 'an update' do
- it 'delegates to the Gitaly client' do
- expect(repository.gitaly_remote_client)
- .to receive(:update_remote_mirror)
- .with(ref_name, url, ['master'], ssh_key: 'KEY', known_hosts: 'KNOWN HOSTS', keep_divergent_refs: true)
-
- remote_mirror.update # rubocop:disable Rails/SaveBang
- end
- end
-
- context 'with url' do
- it_behaves_like 'an update'
- end
-
- context 'without url' do
- let(:url) { nil }
+ it 'delegates to the Gitaly client' do
+ expect(repository.gitaly_remote_client)
+ .to receive(:update_remote_mirror)
+ .with(url, ['master'], ssh_key: 'KEY', known_hosts: 'KNOWN HOSTS', keep_divergent_refs: true)
- it_behaves_like 'an update'
+ remote_mirror.update # rubocop:disable Rails/SaveBang
end
it 'wraps gitaly errors' do
diff --git a/spec/lib/gitlab/gitaly_client/remote_service_spec.rb b/spec/lib/gitlab/gitaly_client/remote_service_spec.rb
index c01a070fcb8..3d0f8358406 100644
--- a/spec/lib/gitlab/gitaly_client/remote_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/remote_service_spec.rb
@@ -35,34 +35,19 @@ RSpec.describe Gitlab::GitalyClient::RemoteService do
end
describe '#update_remote_mirror' do
- let(:ref_name) { 'remote_mirror_1' }
let(:only_branches_matching) { %w[my-branch master] }
let(:ssh_key) { 'KEY' }
let(:known_hosts) { 'KNOWN HOSTS' }
+ let(:url) { 'http:://git.example.com/my-repo.git' }
+ let(:expected_params) { { remote: Gitaly::UpdateRemoteMirrorRequest::Remote.new(url: url) } }
- shared_examples 'an update' do
- it 'sends an update_remote_mirror message' do
- expect_any_instance_of(Gitaly::RemoteService::Stub)
- .to receive(:update_remote_mirror)
- .with(array_including(gitaly_request_with_params(expected_params)), kind_of(Hash))
- .and_return(double(:update_remote_mirror_response))
-
- client.update_remote_mirror(ref_name, url, only_branches_matching, ssh_key: ssh_key, known_hosts: known_hosts, keep_divergent_refs: true)
- end
- end
-
- context 'with remote name' do
- let(:url) { nil }
- let(:expected_params) { { ref_name: ref_name } }
-
- it_behaves_like 'an update'
- end
-
- context 'with remote URL' do
- let(:url) { 'http:://git.example.com/my-repo.git' }
- let(:expected_params) { { remote: Gitaly::UpdateRemoteMirrorRequest::Remote.new(url: url) } }
+ it 'sends an update_remote_mirror message' do
+ expect_any_instance_of(Gitaly::RemoteService::Stub)
+ .to receive(:update_remote_mirror)
+ .with(array_including(gitaly_request_with_params(expected_params)), kind_of(Hash))
+ .and_return(double(:update_remote_mirror_response))
- it_behaves_like 'an update'
+ client.update_remote_mirror(url, only_branches_matching, ssh_key: ssh_key, known_hosts: known_hosts, keep_divergent_refs: true)
end
end
diff --git a/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb
index b1d5d106082..d4148b57348 100644
--- a/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/ci_template_unique_counter_spec.rb
@@ -60,7 +60,7 @@ RSpec.describe Gitlab::UsageDataCounters::CiTemplateUniqueCounter do
Gitlab::Ci::Pipeline::Chain::Config::Content::AutoDevops.new(pipeline, command).content,
project: project,
user: double,
- sha: double
+ sha: 'd310cc759caaa20cd05a9e0983d6017896d9c34c'
).execute
config_source = :auto_devops_source
diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
index d89202ae7fe..887759014f5 100644
--- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
@@ -143,7 +143,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
context 'when usage_ping is disabled' do
it 'does not track the event' do
- stub_application_setting(usage_ping_enabled: false)
+ allow(::ServicePing::ServicePingSettings).to receive(:enabled?).and_return(false)
described_class.track_event(weekly_event, values: entity1, time: Date.current)
@@ -153,7 +153,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
context 'when usage_ping is enabled' do
before do
- stub_application_setting(usage_ping_enabled: true)
+ allow(::ServicePing::ServicePingSettings).to receive(:enabled?).and_return(true)
end
it 'tracks event when using symbol' do
diff --git a/spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb
index d4f6110b3df..753e09731bf 100644
--- a/spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb
@@ -8,12 +8,12 @@ RSpec.describe Gitlab::UsageDataCounters::RedisCounter, :clean_gitlab_redis_shar
subject { Class.new.extend(described_class) }
before do
- stub_application_setting(usage_ping_enabled: setting_value)
+ allow(::ServicePing::ServicePingSettings).to receive(:enabled?).and_return(service_ping_enabled)
end
describe '.increment' do
context 'when usage_ping is disabled' do
- let(:setting_value) { false }
+ let(:service_ping_enabled) { false }
it 'counter is not increased' do
expect do
@@ -23,7 +23,7 @@ RSpec.describe Gitlab::UsageDataCounters::RedisCounter, :clean_gitlab_redis_shar
end
context 'when usage_ping is enabled' do
- let(:setting_value) { true }
+ let(:service_ping_enabled) { true }
it 'counter is increased' do
expect do
@@ -35,7 +35,7 @@ RSpec.describe Gitlab::UsageDataCounters::RedisCounter, :clean_gitlab_redis_shar
describe '.increment_by' do
context 'when usage_ping is disabled' do
- let(:setting_value) { false }
+ let(:service_ping_enabled) { false }
it 'counter is not increased' do
expect do
@@ -45,7 +45,7 @@ RSpec.describe Gitlab::UsageDataCounters::RedisCounter, :clean_gitlab_redis_shar
end
context 'when usage_ping is enabled' do
- let(:setting_value) { true }
+ let(:service_ping_enabled) { true }
it 'counter is increased' do
expect do
diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb
index 058cc2c5925..382359ccb17 100644
--- a/spec/models/remote_mirror_spec.rb
+++ b/spec/models/remote_mirror_spec.rb
@@ -105,35 +105,6 @@ RSpec.describe RemoteMirror, :mailer do
end
end
- describe '#remote_name' do
- context 'when remote name is persisted in the database' do
- it 'returns remote name with random value' do
- allow(SecureRandom).to receive(:hex).and_return('secret')
-
- remote_mirror = create(:remote_mirror)
-
- expect(remote_mirror.remote_name).to eq('remote_mirror_secret')
- end
- end
-
- context 'when remote name is not persisted in the database' do
- it 'returns remote name with remote mirror id' do
- remote_mirror = create(:remote_mirror)
- remote_mirror.remote_name = nil
-
- expect(remote_mirror.remote_name).to eq("remote_mirror_#{remote_mirror.id}")
- end
- end
-
- context 'when remote is not persisted in the database' do
- it 'returns nil' do
- remote_mirror = build(:remote_mirror, remote_name: nil)
-
- expect(remote_mirror.remote_name).to be_nil
- end
- end
- end
-
describe '#bare_url' do
it 'returns the URL without any credentials' do
remote_mirror = build(:remote_mirror, url: 'http://user:pass@example.com/foo')
@@ -158,7 +129,6 @@ RSpec.describe RemoteMirror, :mailer do
expect(git_remote_mirror).to have_received(:new).with(
mirror.project.repository.raw,
- mirror.remote_name,
mirror.url,
keep_divergent_refs: true
)
diff --git a/spec/services/git/branch_hooks_service_spec.rb b/spec/services/git/branch_hooks_service_spec.rb
index 19694a0a354..6e9404166f3 100644
--- a/spec/services/git/branch_hooks_service_spec.rb
+++ b/spec/services/git/branch_hooks_service_spec.rb
@@ -134,7 +134,7 @@ RSpec.describe Git::BranchHooksService, :clean_gitlab_redis_shared_state do
context 'when usage ping is disabled' do
before do
- stub_application_setting(usage_ping_enabled: false)
+ allow(::ServicePing::ServicePingSettings).to receive(:enabled?).and_return(false)
end
it 'does not track the event' do
diff --git a/spec/services/projects/update_remote_mirror_service_spec.rb b/spec/services/projects/update_remote_mirror_service_spec.rb
index 686b204c726..f4a6d1b19e7 100644
--- a/spec/services/projects/update_remote_mirror_service_spec.rb
+++ b/spec/services/projects/update_remote_mirror_service_spec.rb
@@ -7,8 +7,6 @@ RSpec.describe Projects::UpdateRemoteMirrorService do
let_it_be(:remote_project) { create(:forked_project_with_submodules) }
let_it_be(:remote_mirror) { create(:remote_mirror, project: project, enabled: true) }
- let(:remote_name) { remote_mirror.remote_name }
-
subject(:service) { described_class.new(project, project.creator) }
describe '#execute' do
diff --git a/spec/services/service_ping/service_ping_settings_spec.rb b/spec/services/service_ping/service_ping_settings_spec.rb
index 8446fee36c5..90a5c6b30eb 100644
--- a/spec/services/service_ping/service_ping_settings_spec.rb
+++ b/spec/services/service_ping/service_ping_settings_spec.rb
@@ -27,4 +27,20 @@ RSpec.describe ServicePing::ServicePingSettings do
end
end
end
+
+ describe '#enabled?' do
+ describe 'has the correct enabled' do
+ it 'when false' do
+ stub_config_setting(usage_ping_enabled: false)
+
+ expect(described_class.enabled?).to eq(false)
+ end
+
+ it 'when true' do
+ stub_config_setting(usage_ping_enabled: true)
+
+ expect(described_class.enabled?).to eq(true)
+ end
+ end
+ end
end