Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-07-05 15:27:42 +00:00
parent 0e958d77e8
commit 6222deebe9
78 changed files with 1015 additions and 264 deletions

View File

@ -1,13 +1,9 @@
<script>
import { GlCollapsibleListbox } from '@gitlab/ui';
import { s__ } from '~/locale';
import { setUrlParams, visitUrl } from '~/lib/utils/url_utility';
export default {
name: 'BackgroundMigrationsDatabaseListbox',
i18n: {
database: s__('BackgroundMigrations|Database'),
},
components: {
GlCollapsibleListbox,
},
@ -35,8 +31,7 @@ export default {
</script>
<template>
<div class="gl-display-flex gl-align-items-center">
<label id="label" class="gl-font-bold gl-mr-4 gl-mb-0">{{ $options.i18n.database }}</label>
<div class="gl-flex gl-align-items-center gl-grow gl-justify-end">
<gl-collapsible-listbox
v-model="selected"
:items="databases"

View File

@ -1,6 +1,6 @@
<script>
import { GlButton, GlIcon, GlAvatar } from '@gitlab/ui';
import { __ } from '~/locale';
import { GlButton, GlIcon, GlAvatar, GlTooltipDirective } from '@gitlab/ui';
import { sprintf, s__ } from '~/locale';
export default {
name: 'ExclusionsListItem',
@ -9,13 +9,22 @@ export default {
GlAvatar,
GlIcon,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
exclusion: {
type: Object,
required: true,
},
},
i18n: { remove: __('Remove') },
computed: {
deleteButtonLabel() {
return sprintf(s__('Integrations|Remove exclusion for %{name}'), {
name: this.exclusion.name,
});
},
},
};
</script>
@ -37,8 +46,9 @@ export default {
</span>
<gl-button
v-gl-tooltip="s__('Integrations|Remove exclusion')"
icon="remove"
:aria-label="$options.i18n.remove"
:aria-label="deleteButtonLabel"
category="tertiary"
@click="() => $emit('remove')"
/>

View File

@ -9,3 +9,5 @@ export const unicodeLetters =
export const semverRegex =
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
export const noSpacesRegex = /^\S+$/;

View File

@ -12,6 +12,7 @@ import {
import { __, s__ } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility';
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { semverRegex, noSpacesRegex } from '~/lib/utils/regexp';
import { uploadModel } from '../services/upload_model';
import createModelVersionMutation from '../graphql/mutations/create_model_version.mutation.graphql';
import createModelMutation from '../graphql/mutations/create_model.mutation.graphql';
@ -49,6 +50,36 @@ export default {
showImportArtifactZone() {
return this.version && this.name;
},
modelNameIsValid() {
return this.name && noSpacesRegex.test(this.name);
},
isSemver() {
return semverRegex.test(this.version);
},
isVersionValid() {
return !this.version || this.isSemver;
},
submitButtonDisabled() {
return !this.isVersionValid || !this.modelNameIsValid;
},
actionPrimary() {
return {
text: s__('MlModelRegistry|Create'),
attributes: { variant: 'confirm', disabled: this.submitButtonDisabled },
};
},
validVersionFeedback() {
if (this.isSemver) {
return this.$options.modal.versionValid;
}
return null;
},
modelNameDescription() {
return !this.name || this.modelNameIsValid ? this.$options.modal.nameDescription : '';
},
versionDescriptionText() {
return !this.version ? this.$options.modal.versionDescription : '';
},
},
methods: {
async createModel() {
@ -138,29 +169,28 @@ export default {
i18n: {},
modal: {
id: MODEL_CREATION_MODAL_ID,
actionPrimary: {
text: __('Create'),
attributes: { variant: 'confirm' },
},
actionSecondary: {
text: __('Cancel'),
attributes: { variant: 'default' },
},
nameDescription: s__(
'MlModelRegistry|Model name must not contain spaces or upper case letter.',
),
namePlaceholder: s__('MlModelRegistry|For example my-model'),
versionDescription: s__('MlModelRegistry|Leave empty to skip version creation.'),
versionPlaceholder: s__('MlModelRegistry|For example 1.0.0. Must be a semantic version.'),
descriptionPlaceholder: s__('MlModelRegistry|Enter a model description'),
nameDescriptionLabel: s__('MlModelRegistry|Must be unique. May not contain spaces.'),
nameDescription: s__('MlModelRegistry|Example: my-model'),
nameInvalid: s__('MlModelRegistry|May not contain spaces.'),
namePlaceholder: s__('MlModelRegistry|Enter a model name'),
versionDescription: s__('MlModelRegistry|Example: 1.0.0'),
versionPlaceholder: s__('MlModelRegistry|Enter a semantic version'),
nameDescriptionPlaceholder: s__('MlModelRegistry|Enter a model description'),
versionDescriptionTitle: s__('MlModelRegistry|Version description'),
versionDescriptionPlaceholder: s__(
'MlModelRegistry|Enter a description for this version of the model.',
versionDescriptionLabel: s__(
'MlModelRegistry|Must be a semantic version. Leave blank to skip version creation.',
),
versionValid: s__('MlModelRegistry|Version is a valid semantic version.'),
versionInvalid: s__('MlModelRegistry|Must be a semantic version. Example: 1.0.0'),
versionDescriptionPlaceholder: s__('MlModelRegistry|Enter a version description'),
buttonTitle: s__('MlModelRegistry|Create model'),
title: s__('MlModelRegistry|Create model, version & import artifacts'),
modelName: s__('MlModelRegistry|Model name'),
modelDescription: __('Description'),
modelDescription: __('Model description'),
version: __('Version'),
uploadLabel: __('Upload artifacts'),
modelSuccessButVersionArtifactFailAlert: {
@ -170,6 +200,7 @@ export default {
),
variant: 'warning',
},
optionalText: s__('MlModelRegistry|Optional'),
},
};
</script>
@ -180,7 +211,7 @@ export default {
<gl-modal
:modal-id="$options.modal.id"
:title="$options.modal.title"
:action-primary="$options.modal.actionPrimary"
:action-primary="actionPrimary"
:action-secondary="$options.modal.actionSecondary"
size="sm"
@primary="create"
@ -189,8 +220,12 @@ export default {
<gl-form>
<gl-form-group
:label="$options.modal.modelName"
:label-description="$options.modal.nameDescriptionLabel"
label-for="nameId"
:description="$options.modal.nameDescription"
data-testid="nameGroupId"
:state="modelNameIsValid"
:invalid-feedback="$options.modal.nameInvalid"
:description="modelNameDescription"
>
<gl-form-input
id="nameId"
@ -200,18 +235,30 @@ export default {
:placeholder="$options.modal.namePlaceholder"
/>
</gl-form-group>
<gl-form-group :label="$options.modal.modelDescription" label-for="descriptionId">
<gl-form-group
:label="$options.modal.modelDescription"
label-for="descriptionId"
optional
:optional-text="$options.modal.optionalText"
>
<gl-form-textarea
id="descriptionId"
v-model="description"
data-testid="descriptionId"
:placeholder="$options.modal.descriptionPlaceholder"
:placeholder="$options.modal.nameDescriptionPlaceholder"
/>
</gl-form-group>
<gl-form-group
:label="$options.modal.version"
:label-description="$options.modal.versionDescriptionLabel"
data-testid="versionGroupId"
label-for="versionId"
:description="$options.modal.versionDescription"
:state="isVersionValid"
:invalid-feedback="$options.modal.versionInvalid"
:valid-feedback="validVersionFeedback"
:description="versionDescriptionText"
optional
:optional-text="$options.modal.optionalText"
>
<gl-form-input
id="versionId"
@ -225,6 +272,8 @@ export default {
<gl-form-group
:label="$options.modal.versionDescriptionTitle"
label-for="versionDescriptionId"
optional
:optional-text="$options.modal.optionalText"
>
<gl-form-textarea
id="versionDescriptionId"
@ -251,11 +300,11 @@ export default {
<gl-alert
v-if="errorMessage"
data-testid="modal-create-alert"
data-testid="modalCreateAlert"
variant="danger"
@dismiss="hideAlert"
>{{ errorMessage }}</gl-alert
>
>{{ errorMessage }}
</gl-alert>
</gl-modal>
</div>
</template>

View File

@ -176,17 +176,16 @@ export default {
<items-selector
type="users"
:items="formatItemsIds(users)"
disable-namespace-dropdown
:users-options="$options.projectUsersOptions"
data-testid="users-selector"
@change="handleRuleDataUpdate('updatedUsers', $event)"
/>
<items-selector
type="groups"
:items="formatItemsIds(groups)"
:group-id="groupId"
data-testid="groups-selector"
disable-namespace-dropdown
is-project-scoped
:items="formatItemsIds(groups)"
data-testid="groups-selector"
@change="handleRuleDataUpdate('updatedGroups', $event)"
/>
</gl-form-group>

View File

@ -1,5 +1,6 @@
<script>
import { GlButton, GlDrawer, GlFormTextarea, GlModal, GlFormInput, GlSprintf } from '@gitlab/ui';
import { InternalEvents } from '~/tracking';
import { visitUrl } from '~/lib/utils/url_utility';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
@ -7,6 +8,8 @@ import { s__ } from '~/locale';
import { createAlert, VARIANT_WARNING } from '~/alert';
import replaceTextMutation from './graphql/mutations/replace_text.mutation.graphql';
const trackingMixin = InternalEvents.mixin();
const i18n = {
redactText: s__('ProjectMaintenance|Redact text'),
redactMatchingStrings: s__('ProjectMaintenance|Redact matching strings'),
@ -37,6 +40,7 @@ export default {
DRAWER_Z_INDEX,
modalCancel: { text: i18n.modalCancelText },
components: { GlButton, GlDrawer, GlFormTextarea, GlModal, GlFormInput, GlSprintf },
mixins: [trackingMixin],
inject: { projectPath: { default: '' }, housekeepingPath: { default: '' } },
data() {
return {
@ -83,6 +87,7 @@ export default {
},
redactTextConfirm() {
this.isLoading = true;
this.trackEvent('click_redact_text_button_repository_settings');
this.$apollo
.mutate({
mutation: replaceTextMutation,

View File

@ -1,7 +1,9 @@
import api from '~/api';
import createEventHub from '~/helpers/event_hub_factory';
import { InternalEvents } from '~/tracking';
import {
TELEMETRY_WIDGET_VIEWED,
VIEW_MERGE_REQUEST_WIDGET,
TELEMETRY_WIDGET_EXPANDED,
TELEMETRY_WIDGET_FULL_REPORT_CLICKED,
} from '../../constants';
@ -14,6 +16,10 @@ function simplifyWidgetName(componentName) {
return tierlessName;
}
function baseWidgetName(extensionName) {
return extensionName.replace(/([A-Z])/g, '_$1').toLowerCase();
}
function baseRedisEventName(extensionName) {
const redisEventName = extensionName.replace(/([A-Z])/g, '_$1').toLowerCase();
@ -36,7 +42,6 @@ function whenable(bus) {
function defaultBehaviorEvents({ bus, config }) {
const when = whenable(bus);
const isViewed = when(TELEMETRY_WIDGET_VIEWED);
const isExpanded = when(TELEMETRY_WIDGET_EXPANDED);
const fullReportIsClicked = when(TELEMETRY_WIDGET_FULL_REPORT_CLICKED);
const toHll = config?.uniqueUser || {};
@ -44,13 +49,6 @@ function defaultBehaviorEvents({ bus, config }) {
const user = api.trackRedisHllUserEvent.bind(api);
const count = api.trackRedisCounterEvent.bind(api);
if (toHll.view) {
isViewed({ execute: user, track: toHll.view });
}
if (toCounts.view) {
isViewed({ execute: count, track: toCounts.view });
}
if (toHll.expand) {
isExpanded({
execute: user,
@ -102,12 +100,10 @@ function baseTelemetry(componentName) {
*/
return {
uniqueUser: {
view: [`${baseRedisEventName(simpleExtensionName)}_view`],
expand: [`${baseRedisEventName(simpleExtensionName)}_expand`],
clickFullReport: [`${baseRedisEventName(simpleExtensionName)}_click_full_report`],
},
counter: {
view: [`${baseRedisEventName(simpleExtensionName)}_count_view`],
expand: [`${baseRedisEventName(simpleExtensionName)}_count_expand`],
clickFullReport: [`${baseRedisEventName(simpleExtensionName)}_count_click_full_report`],
},
@ -122,7 +118,9 @@ export function createTelemetryHub(componentName) {
return {
viewed() {
bus.$emit(TELEMETRY_WIDGET_VIEWED);
InternalEvents.trackEvent(VIEW_MERGE_REQUEST_WIDGET, {
label: baseWidgetName(simplifyWidgetName(componentName)),
});
},
expanded({ type }) {
bus.$emit(TELEMETRY_WIDGET_EXPANDED, { type });

View File

@ -180,7 +180,7 @@ export const EXTENSION_ICON_CLASS = {
severityUnknown: 'gl-text-gray-400',
};
export const TELEMETRY_WIDGET_VIEWED = 'WIDGET_VIEWED';
export const VIEW_MERGE_REQUEST_WIDGET = 'view_merge_request_widget';
export const TELEMETRY_WIDGET_EXPANDED = 'WIDGET_EXPANDED';
export const TELEMETRY_WIDGET_FULL_REPORT_CLICKED = 'WIDGET_FULL_REPORT_CLICKED';

View File

@ -1,5 +1,5 @@
<script>
import { GlAvatar, GlButton } from '@gitlab/ui';
import { GlAvatar, GlButton, GlTooltipDirective } from '@gitlab/ui';
import { sprintf, __ } from '~/locale';
export default {
@ -9,6 +9,9 @@ export default {
GlButton,
HiddenGroupsItem: () => import('ee_component/approvals/components/hidden_groups_item.vue'),
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
data: {
type: Object,
@ -59,6 +62,7 @@ export default {
<gl-button
v-if="canDelete"
v-gl-tooltip="deleteButtonLabel"
icon="remove"
:aria-label="deleteButtonLabel"
category="tertiary"

View File

@ -65,11 +65,16 @@ export default {
required: false,
default: false,
},
isProjectScoped: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
searchValue: '',
isProjectNamespace: this.disableNamespaceDropdown ? 'false' : 'true',
isProjectNamespace: this.isProjectScoped ? 'true' : 'false',
selected: [],
items: [],
isLoading: false,

View File

@ -1,5 +1,5 @@
<script>
import { GlAvatar, GlButton } from '@gitlab/ui';
import { GlAvatar, GlButton, GlTooltipDirective } from '@gitlab/ui';
import { sprintf, __ } from '~/locale';
export default {
@ -8,6 +8,9 @@ export default {
GlAvatar,
GlButton,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
data: {
type: Object,
@ -21,7 +24,7 @@ export default {
},
computed: {
deleteButtonLabel() {
return sprintf(__('Remove exclusion for %{name}'), { name: this.name });
return sprintf(__('Delete %{name}'), { name: this.name });
},
name() {
return this.data.name;
@ -47,6 +50,7 @@ export default {
<gl-button
v-if="canDelete"
v-gl-tooltip="deleteButtonLabel"
icon="remove"
:aria-label="deleteButtonLabel"
category="tertiary"

View File

@ -1,5 +1,5 @@
<script>
import { GlAvatar, GlButton } from '@gitlab/ui';
import { GlAvatar, GlButton, GlTooltipDirective } from '@gitlab/ui';
import { sprintf, __ } from '~/locale';
export default {
@ -8,6 +8,9 @@ export default {
GlAvatar,
GlButton,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
data: {
type: Object,
@ -46,6 +49,7 @@ export default {
<gl-button
v-if="canDelete"
v-gl-tooltip="deleteButtonLabel"
icon="remove"
:aria-label="deleteButtonLabel"
category="tertiary"

View File

@ -282,3 +282,5 @@ class Projects::JobsController < Projects::ApplicationController
push_frontend_feature_flag(:ai_build_failure_cause, @project)
end
end
Projects::JobsController.prepend_mod_with('Projects::JobsController')

View File

@ -3,6 +3,8 @@
- add_page_specific_style 'page_bundles/settings'
- @force_desktop_expanded_sidebar = true
%div{ data: { event_tracking_load: 'true', event_tracking: 'view_admin_application_settings_network_pageload' } }
= render ::Layouts::SettingsBlockComponent.new(_('Performance optimization'),
id: 'js-performance-settings',
expanded: expanded_by_default?) do |c|

View File

@ -1,6 +1,6 @@
%tr{ role: 'row' }
%td{ role: 'cell', data: { label: _('Migration') } }
= link_to admin_background_migration_path(migration, database: params[:database]) do
= link_to admin_background_migration_path(migration, database: params[:database]), class: 'gl-break-anywhere' do
= migration.job_class_name + ': ' + migration.table_name
%td{ role: 'cell', data: { label: _('Progress') } }
- progress = batched_migration_progress(migration, @successful_rows_counts[migration.id])

View File

@ -1,17 +1,13 @@
- page_title s_('BackgroundMigrations|Background Migrations')
- @breadcrumb_link = admin_background_migrations_path(database: params[:database])
- learnmore_link = help_page_path('update/background_migrations')
- learnmore_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: learnmore_link }
- page_description = html_escape(s_('BackgroundMigrations|Background migrations are used to perform data migrations when a migration exceeds the time limits set by GitLab. %{linkStart}Learn more%{linkEnd}')) % { linkStart: learnmore_link_start, linkEnd: '</a>'.html_safe }
.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-sm-align-items-flex-end.gl-pb-5.gl-border-b-1.gl-border-b-solid.gl-border-b-gray-100{ data: { event_tracking_load: 'true', event_tracking: 'view_admin_background_migrations_pageload' } }
.gl-flex-grow-1
%h3= s_('BackgroundMigrations|Background Migrations')
%p.light.gl-mb-0
- learnmore_link = help_page_path('update/background_migrations')
- learnmore_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: learnmore_link }
= html_escape(s_('BackgroundMigrations|Background migrations are used to perform data migrations whenever a migration exceeds the time limits in our guidelines. %{linkStart}Learn more%{linkEnd}')) % { linkStart: learnmore_link_start, linkEnd: '</a>'.html_safe }
- if @databases.size > 1
.gl-display-flex.gl-align-items-center.gl-flex-grow-0.gl-flex-basis-0.gl-sm-mt-0.gl-mt-5.gl-sm-ml-7.gl-ml-0
#js-database-listbox{ data: { databases: @databases, selected_database: @selected_database } }
= render ::Layouts::PageHeadingComponent.new(s_('BackgroundMigrations|Background Migrations'),
description: page_description,
options: { data: { event_tracking_load: 'true', event_tracking: 'view_admin_background_migrations_pageload' } })
= gl_tabs_nav do
= gl_tab_link_to admin_background_migrations_path({ tab: nil, database: params[:database] }), item_active: @current_tab == 'queued' do
@ -26,17 +22,22 @@
= gl_tab_link_to admin_background_migrations_path({ tab: 'finished', database: params[:database] }), item_active: @current_tab == 'finished' do
= _('Finished')
= gl_tab_counter_badge limited_counter_with_delimiter(@relations_by_tab['finished'])
- if @databases.size > 1
#js-database-listbox{ data: { databases: @databases, selected_database: @selected_database } }
.tab-content.gl-tab-content
.tab-pane.active{ role: 'tabpanel' }
%table.table.b-table.gl-table.b-table-stacked-md{ role: 'table' }
%thead{ role: 'rowgroup' }
%tr{ role: 'row' }
%th.border-bottom{ role: 'cell' }= _('Migration')
%th.border-bottom{ role: 'cell' }= _('Progress')
%th.border-bottom{ role: 'cell' }= _('Status')
%th.border-bottom{ role: 'cell' }
%tbody{ role: 'rowgroup' }
= render partial: 'migration', collection: @migrations
.tab-content.gl-tab-content.gl-pt-0
- if @migrations.any?
.tab-pane.active{ role: 'tabpanel' }
%table.table.b-table.gl-table.b-table-stacked-md.gl-table-no-top-border.gl-mb-7
%thead
%tr{ role: 'row' }
%th.border-bottom{ role: 'cell' }= _('Migration')
%th.border-bottom{ role: 'cell' }= _('Progress')
%th.border-bottom{ role: 'cell' }= _('Status')
%th.border-bottom{ role: 'cell' }
%tbody
= render partial: 'migration', collection: @migrations
= paginate_collection @migrations
- else
= render Pajamas::EmptyStateComponent.new(svg_path: 'illustrations/empty-state/empty-milestone-md.svg',
title: s_('BackgroundMigrations|No background migrations'))

View File

@ -0,0 +1,18 @@
---
description: Tracks when the redact text feature is used.
internal_events: true
action: click_redact_text_button_repository_settings
identifiers:
- project
- namespace
- user
product_group: source_code
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158034
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,16 @@
---
description: Tracks pageviews for the admin application settings network page
internal_events: true
action: view_admin_application_settings_network_pageload
identifiers:
- user
product_group: personal_productivity
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158235
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,22 @@
---
description: Tracks views of merge request widgets
internal_events: true
action: view_merge_request_widget
identifiers:
- project
- namespace
- user
additional_properties:
label:
description: Type of widget like accessibility, code quality etc.
product_group: code_review
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156609
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -1,9 +0,0 @@
---
name: ci_expand_variables_in_compare_to
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/369916
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157147
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/466374
milestone: '17.2'
group: group::pipeline security
type: gitlab_com_derisk
default_enabled: false

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.2"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
time_frame: 28d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: test_summary
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_test_summary_view
distribution:
- ce
- ee

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93232"
time_frame: 28d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: accessibility
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_accessibility_view
distribution:
- ce
- ee

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93333"
time_frame: 28d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: code_quality
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_code_quality_view
distribution:
- ce
- ee

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93340"
time_frame: 28d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: terraform
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_terraform_view
distribution:
- ce
- ee

View File

@ -9,12 +9,13 @@ milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 28d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: license_compliance
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_license_compliance_view
distribution:
- ce
- ee

View File

@ -7,13 +7,14 @@ status: active
milestone: "15.7"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104578
time_frame: 28d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: security_reports
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
options:
events:
- i_code_review_merge_request_widget_security_reports_view
distribution:
- ce
- ee

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_click_redact_text_button_repository_settings_monthly
description: Monthly count of unique users who redact text.
product_group: source_code
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158034
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: click_redact_text_button_repository_settings
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_application_settings_network_pageload_monthly
description: Monthly count of unique users who visisted the admin application settings network page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158235
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_application_settings_network_pageload
unique: user.id

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_application_settings_network_pageload_monthly
description: Monthly count of total users who visisted the admin application settings network page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158235
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_application_settings_network_pageload

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.2"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
time_frame: 7d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: test_summary
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_test_summary_view
distribution:
- ce
- ee

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93232"
time_frame: 7d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: accessibility
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_accessibility_view
distribution:
- ce
- ee

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93333"
time_frame: 7d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: code_quality
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_code_quality_view
distribution:
- ce
- ee

View File

@ -7,12 +7,13 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93340"
time_frame: 7d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: terraform
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_terraform_view
distribution:
- ce
- ee

View File

@ -9,12 +9,13 @@ milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 7d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: license_compliance
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- i_code_review_merge_request_widget_license_compliance_view
distribution:
- ce
- ee

View File

@ -7,13 +7,14 @@ status: active
milestone: "15.7"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104578
time_frame: 7d
data_source: redis_hll
data_source: internal_events
events:
- name: view_merge_request_widget
unique: user.id
filter:
label: security_reports
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
options:
events:
- i_code_review_merge_request_widget_security_reports_view
distribution:
- ce
- ee

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_click_redact_text_button_repository_settings_weekly
description: Weekly count of unique users who redact text.
product_group: source_code
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158034
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: click_redact_text_button_repository_settings
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_view_admin_application_settings_network_pageload_weekly
description: Weekly count of unique users who visisted the admin application settings network page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158235
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_application_settings_network_pageload
unique: user.id

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_view_admin_application_settings_network_pageload_weekly
description: Weekly count of total users who visisted the admin application settings network page
product_group: personal_productivity
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158235
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: view_admin_application_settings_network_pageload

View File

@ -7,12 +7,12 @@ status: active
milestone: "15.2"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91831"
time_frame: all
data_source: redis
data_source: internal_events
data_category: optional
instrumentation_class: MergeRequestWidgetExtensionMetric
options:
event: view
widget: test_summary
events:
- name: view_merge_request_widget
filter:
label: test_summary
distribution:
- ce
- ee

View File

@ -7,12 +7,12 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93232"
time_frame: all
data_source: redis
data_source: internal_events
data_category: optional
instrumentation_class: MergeRequestWidgetExtensionMetric
options:
event: view
widget: accessibility
events:
- name: view_merge_request_widget
filter:
label: accessibility
distribution:
- ce
- ee

View File

@ -7,12 +7,12 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93333"
time_frame: all
data_source: redis
data_source: internal_events
data_category: optional
instrumentation_class: MergeRequestWidgetExtensionMetric
options:
event: view
widget: code_quality
events:
- name: view_merge_request_widget
filter:
label: code_quality
distribution:
- ce
- ee

View File

@ -7,12 +7,12 @@ status: active
milestone: "15.3"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93340"
time_frame: all
data_source: redis
data_source: internal_events
events:
- name: view_merge_request_widget
filter:
label: terraform
data_category: optional
instrumentation_class: MergeRequestWidgetExtensionMetric
options:
event: view
widget: terraform
distribution:
- ce
- ee

View File

@ -9,12 +9,12 @@ milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: all
data_source: redis
data_source: internal_events
data_category: optional
instrumentation_class: MergeRequestWidgetExtensionMetric
options:
event: view
widget: license_compliance
events:
- name: view_merge_request_widget
filter:
label: license_compliance
distribution:
- ce
- ee

View File

@ -7,13 +7,13 @@ status: active
milestone: "15.7"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104578
time_frame: all
data_source: redis
data_source: internal_events
data_category: optional
instrumentation_class: MergeRequestWidgetExtensionMetric
events:
- name: view_merge_request_widget
filter:
label: security_reports
performance_indicator_type: []
options:
event: view
widget: security_reports
distribution:
- ce
- ee

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_click_redact_text_button_repository_settings
description: Total count of users who redact text.
product_group: source_code
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158034
time_frame: all
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: click_redact_text_button_repository_settings

View File

@ -6,4 +6,4 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153442
milestone: '17.1'
queued_migration_version: 20240517141003
finalize_after: '2024-06-13'
finalized_by: # version of the migration that finalized this BBM
finalized_by: 20240701195831

View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
class AddWorkspaceTerminationTimeoutsToRemoteDevelopmentAgentConfigs < Gitlab::Database::Migration[2.2]
milestone '17.2'
def change
add_column :remote_development_agent_configs, :default_max_hours_before_termination, :smallint, default: 24,
null: false
add_column :remote_development_agent_configs, :max_hours_before_termination_limit, :smallint, default: 120,
null: false
end
end

View File

@ -0,0 +1,41 @@
# frozen_string_literal: true
class SetInternalBotsToHavePrivateProfiles < Gitlab::Database::Migration[2.2]
milestone '17.2'
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
# NOTE: There are some other internal users defined else where, but we'd like to
# just focus on bots that are defined in Users::Internal
BOT_TYPES = {
support_bot: 1,
alert_bot: 2,
visual_review_bot: 3,
migration_bot: 7,
security_bot: 8,
automation_bot: 9,
admin_bot: 11,
suggested_reviewers_bot: 12,
llm_bot: 14,
duo_code_review_bot: 16
}
class User < MigrationRecord
self.table_name = 'users'
end
def up
# We would have only 1 user per bot type so simple iteration should be fine
User.where(user_type: BOT_TYPES.values).find_each do |user|
user.private_profile = true
# I suppose it won't matter much, but preserve existing value just in case
user.confirmed_at = Time.zone.now unless user.confirmed_at.present?
user.save
end
end
def down
# no op
end
end

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
class FinalizeBackfillWorkItemHierarchyForEpics < Gitlab::Database::Migration[2.2]
milestone '17.2'
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
def up
ensure_batched_background_migration_is_finished(
job_class_name: 'BackfillWorkItemHierarchyForEpics',
table_name: :epics,
column_name: 'id',
job_arguments: [],
finalize: true
)
end
def down
# No op
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class IndexSbomOccurrencesOnTraversalIdsAndId < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '17.2'
INDEX_NAME = 'index_sbom_occurrences_on_traversal_ids_and_id'
def up
add_concurrent_index :sbom_occurrences, %i[traversal_ids id], name: INDEX_NAME, where: 'archived = FALSE' # rubocop:disable Migration/PreventIndexCreation -- This index is required for export feature
end
def down
remove_concurrent_index_by_name :sbom_occurrences, INDEX_NAME
end
end

View File

@ -0,0 +1 @@
37cf3c10c9736ec4e37646bb908fba9bcb4235d3c728bdb1cda9e367f82adbcd

View File

@ -0,0 +1 @@
19b0e050a220c584c7e20ea06c35d5620f25a2fa866b1dbf9c0355a875ec7deb

View File

@ -0,0 +1 @@
42a5682dec709c27537549bf4ea2de908df9f283143b795dfc67610438df2ece

View File

@ -0,0 +1 @@
95c97ac3ec128fa56cb1d59119d756432741568d6e6a5b12a5f262de8570e876

View File

@ -16561,6 +16561,8 @@ CREATE TABLE remote_development_agent_configs (
workspaces_quota bigint DEFAULT '-1'::integer NOT NULL,
workspaces_per_user_quota bigint DEFAULT '-1'::integer NOT NULL,
project_id bigint,
default_max_hours_before_termination smallint DEFAULT 24 NOT NULL,
max_hours_before_termination_limit smallint DEFAULT 120 NOT NULL,
CONSTRAINT check_72947a4495 CHECK ((char_length(gitlab_workspaces_proxy_namespace) <= 63)),
CONSTRAINT check_9f5cd54d1c CHECK ((char_length(dns_zone) <= 256))
);
@ -28868,6 +28870,8 @@ CREATE INDEX index_sbom_occurrences_on_project_id_and_package_manager ON sbom_oc
CREATE INDEX index_sbom_occurrences_on_source_id ON sbom_occurrences USING btree (source_id);
CREATE INDEX index_sbom_occurrences_on_traversal_ids_and_id ON sbom_occurrences USING btree (traversal_ids, id) WHERE (archived = false);
CREATE UNIQUE INDEX index_sbom_occurrences_on_uuid ON sbom_occurrences USING btree (uuid);
CREATE INDEX index_sbom_occurrences_vulnerabilities_on_project_id ON sbom_occurrences_vulnerabilities USING btree (project_id);

View File

@ -19176,6 +19176,7 @@ Represents the current license.
| <a id="currentlicensename"></a>`name` | [`String`](#string) | Name of the licensee. |
| <a id="currentlicenseplan"></a>`plan` | [`String!`](#string) | Name of the subscription plan. |
| <a id="currentlicensestartsat"></a>`startsAt` | [`Date`](#date) | Date when the license started. |
| <a id="currentlicensetrial"></a>`trial` | [`Boolean`](#boolean) | Indicates if the license is a trial. |
| <a id="currentlicensetype"></a>`type` | [`String!`](#string) | Type of the license. |
| <a id="currentlicenseusersinlicensecount"></a>`usersInLicenseCount` | [`Int`](#int) | Number of paid users in the license. |
| <a id="currentlicenseusersoverlicensecount"></a>`usersOverLicenseCount` | [`Int`](#int) | Number of users over the paid users in the license. |

View File

@ -75,6 +75,8 @@ For long pages, consider creating a table of contents.
The `[_TOC_]` function is not supported on docs.gitlab.com.
-->
For important terms, see [glossary](#glossary).
## Summary
[EPSS](https://www.first.org/epss/faq) scores specify the likelihood a CVE will be exploited in the next 30 days. This data may be used to improve and simplify prioritization efforts when remediating vulnerabilities in a project. EPSS support requirements are outlined in [the EPSS epic](https://gitlab.com/groups/gitlab-org/-/epics/11544) along with an overview of EPSS. This document focuses on the technical implementation of EPSS support.
@ -259,3 +261,15 @@ each alternative solution/path.
"Do nothing" and its pros and cons could be included in the list too.
-->
## Glossary
- **PMDB** (Package metadata database, also known as License DB): PMDB is a standalone service (and not solely a database), outside of the Rails application, that gathers, stores and exports packages metadata for GitLab instances to consume. See [complete documentation](https://gitlab.com/gitlab-org/security-products/license-db/deployment/-/blob/main/docs/DESIGN.md?ref_type=heads). PMDB components include:
- **Feeder**: a scheduled job called by the PMDB deployment to publish data from the relevant sources to pub/sub messages consumed by PMDB processors.
- **Advisory processor**: Runs as a Cloud Run instance and consumes messages published by the advisory feeder containing advisory related data and stores them to the PMDB database.
- **PMDB database**: a PostgreSQL instance storing license and advisory data.
- **Exporter**: exports license/advisory data from the PMDB database to public GCP buckets.
- **GitLab database**: the database used by GitLab instances.
- **CVE** (Common Vulnerabilities and Exposures): a list of publicly known information-security vulnerabilities. "A CVE" usually refers to a specific vulnerability and its CVE ID.
- **EPSS** (Exploit prediction scoring system) **score**: a score ranging from 0 to 1 representing the probability of exploitation in the wild in the next 30 days of a given vulnerability.
- **EPSS score percentile**: for a given EPSS score (of some vulnerability), the proportion of all scored vulnerabilities with the same or a lower EPSS score.

View File

@ -1047,6 +1047,8 @@ Use `after_script` to define an array of commands to run last, after a job's `be
- Long commands [split over multiple lines](script.md#split-long-commands).
- [YAML anchors](yaml_optimization.md#yaml-anchors-for-scripts).
CI/CD variables [are supported](../variables/where_variables_can_be_used.md#gitlab-ciyml-file).
**Example of `after_script`**:
```yaml
@ -4205,7 +4207,7 @@ In this example, both jobs have the same behavior.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/293645) in GitLab 15.3 [with a flag](../../administration/feature_flags.md) named `ci_rules_changes_compare`. Enabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/366412) in GitLab 15.5. Feature flag `ci_rules_changes_compare` removed.
> - Support for CI/CD variables [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369916) in GitLab 17.2 [with a flag](../../administration/feature_flags.md) named `ci_expand_variables_in_compare_to`. Disabled by default.
> - Support for CI/CD variables [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/369916) in GitLab 17.2.
Use `rules:changes:compare_to` to specify which ref to compare against for changes to the files
listed under [`rules:changes:paths`](#ruleschangespaths).

View File

@ -38,6 +38,17 @@ To view your project's dependencies, ensure you meet the following requirements:
## View project dependencies
> - In GitLab 17.2, the `location` field no longer links to the commit where the dependency was last detected when the feature flag `skip_sbom_occurrences_update_on_pipeline_id_change` is enabled. The flag is disabled by default.
FLAG:
When the feature flag `skip_sbom_occurrences_update_on_pipeline_id_change` is enabled,
GitLab no longer keeps track of the last pipeline and the last commit
where a particular dependency was detected.
As a result, in new projects the `location` field
links to the commit where the dependency was first detected.
When disabled, it links to the last commit where the dependency was detected.
Disabled by default.
To view the dependencies of a project or all projects in a group:
1. On the left sidebar, select **Search or go to** and find your project or group.

View File

@ -98,15 +98,19 @@ All fuzz testing results are reported as Unknown. They should be reviewed and tr
| GitLab analyzer | Outputs severity levels? | Native severity level type | Native severity level example |
|----------------------------------------------------------------------------------------------------------|--------------------------|----------------------------|------------------------------------|
| [`security-code-scan`](https://gitlab.com/gitlab-org/security-products/analyzers/security-code-scan) | **{check-circle}** Yes | String | `CRITICAL`, `HIGH`, `MEDIUM` in [analyzer version 3.2.0 and later](https://gitlab.com/gitlab-org/security-products/analyzers/security-code-scan/-/blob/master/CHANGELOG.md#v320). In earlier versions, hardcoded to `Unknown`. |
| [`brakeman`](https://gitlab.com/gitlab-org/security-products/analyzers/brakeman) | **{check-circle}** Yes | String | `HIGH`, `MEDIUM`, `LOW` |
| [`sobelow`](https://gitlab.com/gitlab-org/security-products/analyzers/sobelow) | **{check-circle}** Yes | Not applicable | Hardcodes all severity levels to `Unknown` |
| [`nodejs-scan`](https://gitlab.com/gitlab-org/security-products/analyzers/nodejs-scan) | **{check-circle}** Yes | String | `INFO`, `WARNING`, `ERROR` |
| [`flawfinder`](https://gitlab.com/gitlab-org/security-products/analyzers/flawfinder) | **{check-circle}** Yes | Integer | `0`, `1`, `2`, `3`, `4`, `5` |
| [`SpotBugs`](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs) | **{check-circle}** Yes | Integer | `1`, `2`, `3`, `11`, `12`, `18` |
| [`phpcs-security-audit`](https://gitlab.com/gitlab-org/security-products/analyzers/phpcs-security-audit) | **{check-circle}** Yes | String | `ERROR`, `WARNING` |
| [`pmd-apex`](https://gitlab.com/gitlab-org/security-products/analyzers/pmd-apex) | **{check-circle}** Yes | Integer | `1`, `2`, `3`, `4`, `5` |
| [`kubesec`](https://gitlab.com/gitlab-org/security-products/analyzers/kubesec) | **{check-circle}** Yes | String | `CriticalSeverity`, `InfoSeverity` |
| [`secrets`](https://gitlab.com/gitlab-org/security-products/analyzers/secrets) | **{check-circle}** Yes | Not applicable | Hardcodes all severity levels to `Critical` |
| [`semgrep`](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep) | **{check-circle}** Yes | String | `error`, `warning`, `note`, `none` |
## IaC Scanning
| GitLab analyzer | Outputs severity levels? | Native severity level type | Native severity level example |
|----------------------------------------------------------------------------------------------------------|--------------------------|----------------------------|------------------------------------|
| [`kics`](https://gitlab.com/gitlab-org/security-products/analyzers/kics) | **{check-circle}** Yes | String | `error`, `warning`, `note`, `none` (gets mapped to `info` in [analyzer version 3.7.0 and later](https://gitlab.com/gitlab-org/security-products/analyzers/kics/-/releases/v3.7.0)) |
## Secret Detection
The GitLab [`secrets`](https://gitlab.com/gitlab-org/security-products/analyzers/secrets) analyzer hardcodes all severity levels to `Critical`.
[Epic 10320](https://gitlab.com/groups/gitlab-org/-/epics/10320) proposes to adopt more granular severity ratings.

View File

@ -61,6 +61,15 @@ This error occurs when you try to access GitLab Duo Chat but do not have the acc
Ensure you have [access to use GitLab Duo Chat](../gitlab_duo/turn_on_off.md).
## `Error M3005`
You might get an error that states
`I'm sorry, this question is not supported in your Duo Pro subscription. You might consider upgrading to Duo Enterprise. Error code: M3005`.
This error occurs when you try to access a tool of GitLab Duo Chat that is not bundled in your GitLab Duo subscription tier.
Ensure your [GitLab Duo subscription tier](https://about.gitlab.com/gitlab-duo/) includes the selected tool.
## `Error M4000`
You might get an error that states

View File

@ -7,6 +7,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Test a new look for epics
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-managed
**Status:** Experiment
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/9290) in GitLab 17.2. This feature is an [experiment](../../../policy/experiment-beta-support.md#experiment).
@ -39,20 +41,21 @@ following blog posts:
- [First look: The new Agile planning experience in GitLab](https://about.gitlab.com/blog/2024/06/18/first-look-the-new-agile-planning-experience-in-gitlab/) (June 2024)
- [Unveiling a new epic experience for improved Agile planning](https://about.gitlab.com/blog/2024/07/03/unveiling-a-new-epic-experience-for-improved-agile-planning/) (July 2024)
## Feature flags
To try out this change on GitLab self-managed, enable the following feature flags.
Because this is an experimental feature,
**we strongly advise to enable the feature flags on a new group that does not contain any critical data**.
| Flag | Description | Actor | Status |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ----- | ------ |
| `work_item_epics` | Consolidated flag that contains all the changes needed to get epic work items to work for a given group. | Group | **Required** |
| `sync_work_item_to_epic` | Synchronizes data from a legacy epic to a corresponding work item. | Group | **Required** |
| `work_items_rolledup_dates` | Calculates the start and due dates in a hierarchy for work items. | Group | **Required** |
| `epic_and_work_item_labels_unification` | Delegates labels between epics and epic work item. | Group | **Required** |
| `epic_and_work_item_associations_unification` | Delegates other epic and work item associations. | Group | **Required** |
| `epic_and_work_item_notes_unification` | Delegates notes between epics and work item. | Group | **Required** |
## Related topics
- [Work items development](../../../development/work_items.md)
## Feature flags
To try out this change on a self-managed instance of GitLab, enable the following feature flags. Because this is an experimental
feature, **it is strongly advised to enable the feature flags on a new group that does not contain any critical data**.
|Flag|Description|Actor|Status|
|---|---|---|---|
|`work_item_epics`| Consolidated flag that contains all the changes needed to get epic work items to work for a given group. |Group|**Required**|
|`sync_work_item_to_epic`| Synchronizes data from a legacy epic to a corresponding work item. |Group|**Required**|
|`work_items_rolledup_dates`| Calculates the start and due dates in a hierarchy for work items. |Group|**Required**|
|`epic_and_work_item_labels_unification`| Delegates labels between epics and epic work item. |Group|**Required**|
|`epic_and_work_item_associations_unification`| Delegates other epic and work item associations. |Group|**Required**|
|`epic_and_work_item_notes_unification`| Delegates notes between epics and work item. |Group|**Required**|

View File

@ -153,7 +153,7 @@ To create a configuration secret for the proxy:
helm upgrade --install gitlab-workspaces-proxy \
gitlab-workspaces-proxy/gitlab-workspaces-proxy \
--version 0.1.12 \
--version 0.1.13 \
--namespace=gitlab-workspaces \
--create-namespace \
--set="auth.client_id=${CLIENT_ID}" \

View File

@ -70,12 +70,7 @@ module Gitlab
def find_compare_to_sha(pipeline, context)
return unless @globs.include?(:compare_to)
compare_to = if Feature.enabled?(:ci_expand_variables_in_compare_to, pipeline.project)
ExpandVariables.expand(@globs[:compare_to], -> { context.variables_hash })
else
@globs[:compare_to]
end
compare_to = ExpandVariables.expand(@globs[:compare_to], -> { context.variables_hash })
commit = pipeline.project.commit(compare_to)
raise Rules::Rule::Clause::ParseError, 'rules:changes:compare_to is not a valid ref' unless commit

View File

@ -129,3 +129,11 @@ value_streams_dashboard_metric_link_clicked-user: value_streams_dashboard_metric
value_streams_dashboard_time_to_restore_service_link_clicked-user: value_streams_dashboard_time_to_restore_service_link_clicked
value_streams_dashboard_vulnerability_critical_link_clicked-user: value_streams_dashboard_vulnerability_critical_link_clicked
value_streams_dashboard_vulnerability_high_link_clicked-user: value_streams_dashboard_vulnerability_high_link_clicked
'view_merge_request_widget-filter:[label:accessibility]-user': i_code_review_merge_request_widget_accessibility_view
'view_merge_request_widget-filter:[label:code_quality]-user': i_code_review_merge_request_widget_code_quality_view
'view_merge_request_widget-filter:[label:license_compliance]-user': i_code_review_merge_request_widget_license_compliance_view
'view_merge_request_widget-filter:[label:status_checks]-user': i_code_review_merge_request_widget_status_checks_view
'view_merge_request_widget-filter:[label:terraform]-user': i_code_review_merge_request_widget_terraform_view
'view_merge_request_widget-filter:[label:test_summary]-user': i_code_review_merge_request_widget_test_summary_view
'view_merge_request_widget-filter:[label:metrics]-user': i_code_review_merge_request_widget_metrics_view
'view_merge_request_widget-filter:[label:security_reports]-user': i_code_review_merge_request_widget_security_reports_view

View File

@ -57,3 +57,11 @@
'{event_counters}_view_productivity_analytics': USAGE_PRODUCTIVITY_ANALYTICS_VIEWS
'{event_counters}_view_wiki_page': USAGE_WIKI_PAGES_VIEW
'{event_counters}_web_ide_viewed': WEB_IDE_VIEWS_COUNT
'{event_counters}_view_merge_request_widget-filter:[label:accessibility]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_ACCESSIBILITY_COUNT_VIEW
'{event_counters}_view_merge_request_widget-filter:[label:code_quality]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_CODE_QUALITY_COUNT_VIEW
'{event_counters}_view_merge_request_widget-filter:[label:license_compliance]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_LICENSE_COMPLIANCE_COUNT_VIEW
'{event_counters}_view_merge_request_widget-filter:[label:status_checks]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_STATUS_CHECKS_COUNT_VIEW
'{event_counters}_view_merge_request_widget-filter:[label:terraform]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_TERRAFORM_COUNT_VIEW
'{event_counters}_view_merge_request_widget-filter:[label:test_summary]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_TEST_SUMMARY_COUNT_VIEW
'{event_counters}_view_merge_request_widget-filter:[label:metrics]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_METRICS_COUNT_VIEW
'{event_counters}_view_merge_request_widget-filter:[label:security_reports]': USAGE_I_CODE_REVIEW_MERGE_REQUEST_WIDGET_SECURITY_REPORTS_COUNT_VIEW

View File

@ -20,7 +20,7 @@ module RemoteDevelopment
max_hours_before_termination_limit: [120, Integer],
project_cloner_image: ['alpine/git:2.36.3', String],
tools_injector_image: [
"registry.gitlab.com/gitlab-org/remote-development/gitlab-workspaces-tools:1.0.0", String
"registry.gitlab.com/gitlab-org/remote-development/gitlab-workspaces-tools:2.0.0", String
],
vscode_extensions_gallery: [
{

View File

@ -23,6 +23,8 @@ module Users
u.bio = 'The GitLab alert bot'
u.name = 'GitLab Alert Bot'
u.avatar = bot_avatar(image: 'alert-bot.png')
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end
@ -33,6 +35,7 @@ module Users
u.bio = 'The GitLab migration bot'
u.name = 'GitLab Migration Bot'
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end
@ -46,6 +49,7 @@ module Users
u.website_url = Gitlab::Routing.url_helpers.help_page_url('user/application_security/security_bot/index.md')
u.avatar = bot_avatar(image: 'security-bot.png')
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end
@ -57,6 +61,7 @@ module Users
u.name = 'GitLab Support Bot'
u.avatar = bot_avatar(image: 'support-bot.png')
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end
@ -67,6 +72,8 @@ module Users
u.bio = 'The GitLab automation bot used for automated workflows and tasks'
u.name = 'GitLab Automation Bot'
u.avatar = bot_avatar(image: 'support-bot.png') # todo: add an avatar for automation-bot
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end
@ -78,6 +85,7 @@ module Users
u.name = 'GitLab LLM Bot'
u.avatar = bot_avatar(image: 'support-bot.png') # todo: add an avatar for llm-bot
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end
@ -89,6 +97,7 @@ module Users
u.name = 'Duo Code Reviewer'
u.avatar = bot_avatar(image: 'support-bot.png') # todo: add an avatar for duo_code_review_bot
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end
@ -101,6 +110,7 @@ module Users
u.avatar = bot_avatar(image: 'admin-bot.png')
u.admin = true
u.confirmed_at = Time.zone.now
u.private_profile = true
end
end

View File

@ -7850,21 +7850,21 @@ msgstr ""
msgid "BackgroundMigrations|Background Migrations"
msgstr ""
msgid "BackgroundMigrations|Background migrations are used to perform data migrations whenever a migration exceeds the time limits in our guidelines. %{linkStart}Learn more%{linkEnd}"
msgid "BackgroundMigrations|Background migrations are used to perform data migrations when a migration exceeds the time limits set by GitLab. %{linkStart}Learn more%{linkEnd}"
msgstr ""
msgid "BackgroundMigrations|Batch size"
msgstr ""
msgid "BackgroundMigrations|Database"
msgstr ""
msgid "BackgroundMigrations|Failed jobs:"
msgstr ""
msgid "BackgroundMigrations|Finished at"
msgstr ""
msgid "BackgroundMigrations|No background migrations"
msgstr ""
msgid "BackgroundMigrations|Started at"
msgstr ""
@ -28145,6 +28145,9 @@ msgstr ""
msgid "Integrations|Remove exclusion"
msgstr ""
msgid "Integrations|Remove exclusion for %{name}"
msgstr ""
msgid "Integrations|Reset integration?"
msgstr ""
@ -33499,6 +33502,9 @@ msgstr ""
msgid "MlModelRegistry|Candidate not linked to a CI build"
msgstr ""
msgid "MlModelRegistry|Create"
msgstr ""
msgid "MlModelRegistry|Create & import"
msgstr ""
@ -33559,10 +33565,13 @@ msgstr ""
msgid "MlModelRegistry|Drop to start upload"
msgstr ""
msgid "MlModelRegistry|Enter a description for this version of the model."
msgid "MlModelRegistry|Enter a model description"
msgstr ""
msgid "MlModelRegistry|Enter a model description"
msgid "MlModelRegistry|Enter a model name"
msgstr ""
msgid "MlModelRegistry|Enter a semantic version"
msgstr ""
msgid "MlModelRegistry|Enter a semantic version."
@ -33574,9 +33583,18 @@ msgstr ""
msgid "MlModelRegistry|Enter a subfolder name to organize your artifacts."
msgstr ""
msgid "MlModelRegistry|Enter a version description"
msgstr ""
msgid "MlModelRegistry|Enter some description"
msgstr ""
msgid "MlModelRegistry|Example: 1.0.0"
msgstr ""
msgid "MlModelRegistry|Example: my-model"
msgstr ""
msgid "MlModelRegistry|Experiment"
msgstr ""
@ -33598,12 +33616,6 @@ msgstr ""
msgid "MlModelRegistry|For example 1.0.0"
msgstr ""
msgid "MlModelRegistry|For example 1.0.0. Must be a semantic version."
msgstr ""
msgid "MlModelRegistry|For example my-model"
msgstr ""
msgid "MlModelRegistry|ID"
msgstr ""
@ -33616,9 +33628,6 @@ msgstr ""
msgid "MlModelRegistry|Latest version"
msgstr ""
msgid "MlModelRegistry|Leave empty to skip version creation."
msgstr ""
msgid "MlModelRegistry|Logging artifacts"
msgstr ""
@ -33634,6 +33643,9 @@ msgstr ""
msgid "MlModelRegistry|Manage versions of your machine learning modelManage versions of your machine learning model"
msgstr ""
msgid "MlModelRegistry|May not contain spaces."
msgstr ""
msgid "MlModelRegistry|Metadata"
msgstr ""
@ -33646,9 +33658,6 @@ msgstr ""
msgid "MlModelRegistry|Model name"
msgstr ""
msgid "MlModelRegistry|Model name must not contain spaces or upper case letter."
msgstr ""
msgid "MlModelRegistry|Model performance"
msgstr ""
@ -33658,6 +33667,15 @@ msgstr ""
msgid "MlModelRegistry|Model version %{versionName} deleted successfully"
msgstr ""
msgid "MlModelRegistry|Must be a semantic version. Example: 1.0.0"
msgstr ""
msgid "MlModelRegistry|Must be a semantic version. Leave blank to skip version creation."
msgstr ""
msgid "MlModelRegistry|Must be unique. May not contain spaces."
msgstr ""
msgid "MlModelRegistry|New model"
msgstr ""
@ -33676,6 +33694,9 @@ msgstr ""
msgid "MlModelRegistry|No registered versions"
msgstr ""
msgid "MlModelRegistry|Optional"
msgstr ""
msgid "MlModelRegistry|Package creation failed"
msgstr ""
@ -33724,6 +33745,9 @@ msgstr ""
msgid "MlModelRegistry|Version description"
msgstr ""
msgid "MlModelRegistry|Version is a valid semantic version."
msgstr ""
msgid "MlModelRegistry|Version is not a valid semantic version."
msgstr ""
@ -33759,6 +33783,9 @@ msgstr ""
msgid "Model"
msgstr ""
msgid "Model description"
msgstr ""
msgid "Model experiments"
msgstr ""
@ -43829,9 +43856,6 @@ msgstr ""
msgid "Remove email participants"
msgstr ""
msgid "Remove exclusion for %{name}"
msgstr ""
msgid "Remove favicon"
msgstr ""
@ -53913,6 +53937,12 @@ msgstr ""
msgid "This command is used for explaining vulnerabilities and can only be invoked from a vulnerability detail page."
msgstr ""
msgid "This command is used for troubleshooting jobs and can only be invoked from a failed job log page."
msgstr ""
msgid "This command is used for troubleshooting jobs and can only be invoked from a job log page."
msgstr ""
msgid "This comment changed after you started editing it. Review the %{startTag}updated comment%{endTag} to ensure information is not lost."
msgstr ""

View File

@ -40,7 +40,9 @@ describe('ExclusionsListItem component', () => {
});
it('renders a remove button', () => {
expect(findFindRemoveButton().attributes('aria-label')).toBe('Remove');
expect(findFindRemoveButton().attributes('aria-label')).toBe(
`Remove exclusion for ${exclusion.name}`,
);
expect(findFindRemoveButton().props()).toMatchObject({
icon: 'remove',

View File

@ -1,4 +1,4 @@
import Vue from 'vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { GlModal } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@ -74,17 +74,19 @@ describe('ModelCreate', () => {
const findModalButton = () => wrapper.findByText('Create model');
const findNameInput = () => wrapper.findByTestId('nameId');
const findVersionInput = () => wrapper.findByTestId('versionId');
const findVersionGroup = () => wrapper.findByTestId('versionGroupId');
const findDescriptionInput = () => wrapper.findByTestId('descriptionId');
const findVersionDescriptionInput = () => wrapper.findByTestId('versionDescriptionId');
const findImportArtifactZone = () => wrapper.findComponent(ImportArtifactZone);
const zone = () => wrapper.findComponent(UploadDropzone);
const findGlModal = () => wrapper.findComponent(GlModal);
const findGlAlert = () => wrapper.findByTestId('modal-create-alert');
const findGlAlert = () => wrapper.findByTestId('modalCreateAlert');
const submitForm = async () => {
findGlModal().vm.$emit('primary', new Event('primary'));
await waitForPromises();
};
const findArtifactZoneLabel = () => wrapper.findByTestId('importArtifactZoneLabel');
const findModelNameGroup = () => wrapper.findByTestId('nameGroupId');
describe('Initial state', () => {
describe('Modal closed', () => {
@ -117,14 +119,46 @@ describe('ModelCreate', () => {
expect(findNameInput().exists()).toBe(true);
});
it('renders the model name group description', () => {
expect(findModelNameGroup().attributes('description')).toBe(
ModelCreate.modal.nameDescription,
);
});
it('renders the name label', () => {
expect(findModelNameGroup().attributes('label')).toBe(ModelCreate.modal.modelName);
});
it('renders the version input', () => {
expect(findVersionInput().exists()).toBe(true);
});
it('renders the version label', () => {
expect(findVersionGroup().attributes('label')).toBe('Version');
});
it('renders the version placeholder', () => {
expect(findVersionInput().attributes('placeholder')).toBe(
ModelCreate.modal.versionPlaceholder,
);
});
it('renders the version group description', () => {
expect(findVersionGroup().attributes('description')).toBe(
ModelCreate.modal.versionDescription,
);
});
it('renders the description input', () => {
expect(findDescriptionInput().exists()).toBe(true);
});
it('renders the description input text', () => {
expect(findVersionGroup().attributes('valid-feedback')).toBe(
ModelCreate.modal.validVersion,
);
});
it('renders the version description input', () => {
expect(findVersionDescriptionInput().exists()).toBe(true);
});
@ -166,7 +200,7 @@ describe('ModelCreate', () => {
it('renders the create button in the modal', () => {
expect(findGlModal().props('actionPrimary')).toEqual({
attributes: { variant: 'confirm' },
attributes: { variant: 'confirm', disabled: true },
text: 'Create',
});
});
@ -183,6 +217,81 @@ describe('ModelCreate', () => {
});
});
describe('It reacts to semantic version input', () => {
beforeEach(() => {
createWrapper();
});
it('renders the version input label for initial state', () => {
expect(findVersionGroup().attributes('state')).toBe('true');
expect(findGlModal().props('actionPrimary')).toEqual({
attributes: { variant: 'confirm', disabled: true },
text: 'Create',
});
});
it.each(['1.0', '1', 'abc', '1.abc', '1.0.0.0'])(
'renders the version input label for invalid state',
async (version) => {
findVersionInput().vm.$emit('input', version);
await nextTick();
expect(findVersionGroup().attributes()).not.toContain('state');
expect(findVersionGroup().attributes('invalid-feedback')).toBe(
ModelCreate.modal.versionInvalid,
);
expect(findVersionGroup().attributes('description')).toBe('');
expect(findGlModal().props('actionPrimary')).toEqual({
attributes: { variant: 'confirm', disabled: true },
text: 'Create',
});
},
);
it.each(['1.0.0', '0.0.0-b', '24.99.99-b99'])(
'renders the version input label for valid state',
async (version) => {
findVersionInput().vm.$emit('input', version);
await nextTick();
expect(findVersionGroup().attributes('state')).toBe('true');
expect(findVersionGroup().attributes('valid-feedback')).toBe(
ModelCreate.modal.versionValid,
);
expect(findVersionGroup().attributes('description')).toBe('');
expect(findGlModal().props('actionPrimary')).toEqual({
attributes: { variant: 'confirm', disabled: true },
text: 'Create',
});
},
);
it.each(['1.0.0', '0.0.0-b', '24.99.99-b99'])(
'renders the version input label for valid state',
async (version) => {
findNameInput().vm.$emit('input', 'gpt-alice-1');
findVersionInput().vm.$emit('input', version);
await nextTick();
expect(findVersionGroup().attributes('state')).toBe('true');
expect(findGlModal().props('actionPrimary')).toEqual({
attributes: { variant: 'confirm', disabled: false },
text: 'Create',
});
},
);
it.each(['model name', ' modelname', 'modelname ', ' ', ''])(
'renders the modelnames as invalid',
async (name) => {
findNameInput().vm.$emit('input', name);
await nextTick();
expect(findModelNameGroup().attributes()).not.toContain('state');
},
);
it.each(['modelname', 'model-name', 'MODELname', 'model_name'])(
'renders the modelnames as invalid',
async (name) => {
findNameInput().vm.$emit('input', name);
await nextTick();
expect(findModelNameGroup().attributes('state')).toBe('true');
},
);
});
it('clicking on secondary button clears the form', async () => {
createWrapper();

View File

@ -5,6 +5,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
import { useMockInternalEventsTracking } from 'helpers/tracking_internal_events_helper';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { createAlert, VARIANT_WARNING } from '~/alert';
import RedactText from '~/projects/settings/repository/maintenance/redact_text.vue';
@ -25,6 +26,7 @@ jest.mock('~/alert');
describe('Redact text', () => {
let wrapper;
let mutationMock;
const { bindInternalEventDocument } = useMockInternalEventsTracking();
const createMockApolloProvider = (resolverMock) => {
return createMockApollo([[replaceTextMutation, resolverMock]]);
@ -131,6 +133,15 @@ describe('Redact text', () => {
});
});
it('tracks click_redact_text_button_repository_settings', () => {
const { trackEventSpy } = bindInternalEventDocument(wrapper.element);
expect(trackEventSpy).toHaveBeenCalledWith(
'click_redact_text_button_repository_settings',
{},
undefined,
);
});
it('closes the drawer when removal is confirmed', async () => {
await waitForPromises();

View File

@ -254,6 +254,11 @@ describe('List Selector spec', () => {
};
beforeEach(async () => {
createComponent({
...GROUPS_MOCK_PROPS,
isProjectScoped: true,
});
findNamespaceDropdown().vm.$emit('select', 'true');
await emitSearchInput();
});

View File

@ -266,25 +266,7 @@ RSpec.describe Gitlab::Ci::Build::Rules::Rule::Clause::Changes, feature_category
allow(context).to receive(:variables_hash).and_return(variables_hash)
end
context 'when ci_expand_variables_in_compare_to is true' do
before do
stub_feature_flags(ci_expand_variables_in_compare_to: true)
end
it { is_expected.to be_truthy }
end
context 'when ci_expand_variables_in_compare_to is false' do
before do
stub_feature_flags(ci_expand_variables_in_compare_to: false)
end
it 'raises ParseError' do
expect { satisfied_by }.to raise_error(
::Gitlab::Ci::Build::Rules::Rule::Clause::ParseError, 'rules:changes:compare_to is not a valid ref'
)
end
end
it { is_expected.to be_truthy }
end
end
end

View File

@ -8,6 +8,7 @@ RSpec.describe 'Code review events' do
it 'the aggregated metrics contain all the code review metrics' do
mr_related_events = %w[
i_code_review_create_mr
view_merge_request_widget
i_code_review_mr_diffs
i_code_review_mr_with_invalid_approvers
i_code_review_mr_single_file_diffs

View File

@ -0,0 +1,146 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe SetInternalBotsToHavePrivateProfiles, feature_category: :user_profile do
let(:users) { table(:users) }
let(:time) { 1.year.ago }
let(:user_types) do
{
support_bot: 1,
alert_bot: 2,
visual_review_bot: 3,
migration_bot: 7,
security_bot: 8,
automation_bot: 9,
admin_bot: 11,
suggested_reviewers_bot: 12,
llm_bot: 14,
duo_code_review_bot: 16
}
end
let!(:alert_bot) do
users.create!(
user_type: user_types[:alert_bot],
projects_limit: 0,
name: 'alert bot',
email: 'alert-bot@example.com')
end
let!(:migration_bot) do
users.create!(
user_type: user_types[:migration_bot],
projects_limit: 0,
name: 'migration bot',
email: 'migration-bot@example.com',
confirmed_at: time)
end
let!(:security_bot) do
users.create!(
user_type: user_types[:security_bot],
projects_limit: 0,
name: 'security bot',
email: 'security-bot@example.com',
confirmed_at: time)
end
let!(:support_bot) do
users.create!(
user_type: user_types[:support_bot],
projects_limit: 0,
name: 'support bot',
email: 'support-bot@example.com',
confirmed_at: time)
end
let!(:automation_bot) do
users.create!(
user_type: user_types[:automation_bot],
projects_limit: 0,
name: 'automation bot',
email: 'automation-bot@example.com')
end
let!(:llm_bot) do
users.create!(
user_type: user_types[:llm_bot],
projects_limit: 0,
name: 'llm bot',
email: 'llm-bot@example.com',
confirmed_at: time,
private_profile: true)
end
let!(:duo_code_review_bot) do
users.create!(
user_type: user_types[:duo_code_review_bot],
projects_limit: 0,
name: 'duo code review bot',
email: 'duo-code-review-bot@example.com',
confirmed_at: time
)
end
let!(:admin_bot) do
users.create!(
user_type: user_types[:admin_bot],
projects_limit: 0,
name: 'admin bot',
email: 'admin-bot@example.com',
confirmed_at: time)
end
let!(:visual_review_bot) do
users.create!(
user_type: user_types[:visual_review_bot],
projects_limit: 0,
name: 'visual review bot',
email: 'visual-review-bot@example.com')
end
let!(:suggested_reviewers_bot) do
users.create!(
user_type: user_types[:suggested_reviewers_bot],
projects_limit: 0,
name: 'suggested reviewers bot',
email: 'suggested-reviewers-bot@example.com')
end
describe "#up" do
it 'sets confirmed_at and private_profile for all internal bots' do
migrate!
bot_users = users.where(user_type: user_types.values)
expect(bot_users.count).to be 10
expect(bot_users.where(confirmed_at: nil, private_profile: false).count).to be 0
end
it 'does not update existing confirmed_at' do
migrate!
[
migration_bot,
security_bot,
support_bot,
llm_bot,
duo_code_review_bot,
admin_bot
].each do |user|
expect(user.confirmed_at).to eq(time)
end
[
alert_bot,
automation_bot,
visual_review_bot,
suggested_reviewers_bot
].each do |user|
expect(user.confirmed_at).not_to eq(time)
end
end
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe FinalizeBackfillWorkItemHierarchyForEpics, feature_category: :database do
describe '#up' do
it 'ensures the migration is completed for self-managed instances' do
# enqueue the migration
QueueBackfillWorkItemHierarchyForEpics.new.up
migration = Gitlab::Database::BackgroundMigration::BatchedMigration.where(
job_class_name: 'BackfillWorkItemHierarchyForEpics',
table_name: 'epics'
).first
expect(migration.status).not_to eq(6) # finalized
migrate!
expect(migration.reload.status).to eq(6)
QueueBackfillWorkItemHierarchyForEpics.new.down
end
end
end

View File

@ -798,20 +798,6 @@ RSpec.describe Ci::CreatePipelineService, :ci_config_feature_flag_correctness, f
)
end
end
context 'when the compare_to variable feature flag is disabled' do
before do
stub_feature_flags(ci_expand_variables_in_compare_to: false)
end
let(:compare_to) { '$VALID_BRANCH_NAME' }
it 'returns an error' do
expect(pipeline.errors.full_messages).to eq(
['Failed to parse rule for job1: rules:changes:compare_to is not a valid ref']
)
end
end
end
end