Add latest changes from gitlab-org/gitlab@master
|
|
@ -3006,6 +3006,7 @@ Gitlab/BoundedContexts:
|
|||
- 'ee/app/models/package_metadata/advisory.rb'
|
||||
- 'ee/app/models/package_metadata/affected_package.rb'
|
||||
- 'ee/app/models/package_metadata/checkpoint.rb'
|
||||
- 'ee/app/models/package_metadata/epss.rb'
|
||||
- 'ee/app/models/package_metadata/license.rb'
|
||||
- 'ee/app/models/package_metadata/package.rb'
|
||||
- 'ee/app/models/package_metadata/package_version.rb'
|
||||
|
|
|
|||
|
|
@ -344,7 +344,6 @@ Gitlab/StrongMemoizeAttr:
|
|||
- 'ee/app/services/projects/restore_service.rb'
|
||||
- 'ee/app/services/protected_environments/base_service.rb'
|
||||
- 'ee/app/services/security/ingestion/tasks/ingest_vulnerabilities/mark_resolved_as_detected.rb'
|
||||
- 'ee/app/services/security/report_fetch_service.rb'
|
||||
- 'ee/app/services/security/report_summary_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service.rb'
|
||||
- 'ee/app/services/security/security_orchestration_policies/operational_vulnerabilities_configuration_service.rb'
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 775 B |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 973 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
|
@ -290,7 +290,7 @@
|
|||
"coverage_format": {
|
||||
"description": "Code coverage format used by the test framework.",
|
||||
"enum": [
|
||||
"cobertura"
|
||||
"cobertura", "jacoco"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,17 @@ export const PLACEHOLDER_STATUS_FAILED = 'FAILED';
|
|||
export const PLACEHOLDER_STATUS_KEPT_AS_PLACEHOLDER = 'KEEP_AS_PLACEHOLDER';
|
||||
export const PLACEHOLDER_STATUS_COMPLETED = 'COMPLETED';
|
||||
|
||||
export const PLACEHOLDER_USER_STATUS = {
|
||||
UNASSIGNED: [
|
||||
PLACEHOLDER_STATUS_PENDING_REASSIGNMENT,
|
||||
PLACEHOLDER_STATUS_AWAITING_APPROVAL,
|
||||
PLACEHOLDER_STATUS_REJECTED,
|
||||
PLACEHOLDER_STATUS_REASSIGNING,
|
||||
PLACEHOLDER_STATUS_FAILED,
|
||||
],
|
||||
REASSIGNED: [PLACEHOLDER_STATUS_COMPLETED, PLACEHOLDER_STATUS_KEPT_AS_PLACEHOLDER],
|
||||
};
|
||||
|
||||
export const placeholderUserBadges = {
|
||||
[PLACEHOLDER_STATUS_PENDING_REASSIGNMENT]: {
|
||||
text: __('Not started'),
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ export const AVAILABLE_FILTERED_SEARCH_TOKENS = [
|
|||
|
||||
export const AVATAR_SIZE = 48;
|
||||
|
||||
export const DEFAULT_PAGE_SIZE = 20;
|
||||
|
||||
export const MEMBERS_TAB_TYPES = Object.freeze({
|
||||
user: 'user',
|
||||
group: 'group',
|
||||
|
|
|
|||
|
|
@ -2,22 +2,19 @@
|
|||
// eslint-disable-next-line no-restricted-imports
|
||||
import { mapState } from 'vuex';
|
||||
import { GlBadge, GlTab, GlTabs, GlButton, GlModalDirective } from '@gitlab/ui';
|
||||
import { createAlert } from '~/alert';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import { getParameterByName } from '~/lib/utils/url_utility';
|
||||
import {
|
||||
PLACEHOLDER_STATUS_FAILED,
|
||||
QUERY_PARAM_FAILED,
|
||||
PLACEHOLDER_USER_STATUS,
|
||||
} from '~/import_entities/import_groups/constants';
|
||||
|
||||
import importSourceUsersQuery from '../graphql/queries/import_source_users.query.graphql';
|
||||
import PlaceholdersTable from './placeholders_table.vue';
|
||||
import CsvUploadModal from './csv_upload_modal.vue';
|
||||
|
||||
const UPLOAD_CSV_PLACEHOLDERS_MODAL_ID = 'upload-placeholders-csv-modal';
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 20;
|
||||
|
||||
export default {
|
||||
name: 'PlaceholdersTabApp',
|
||||
components: {
|
||||
|
|
@ -31,59 +28,24 @@ export default {
|
|||
directives: {
|
||||
GlModal: GlModalDirective,
|
||||
},
|
||||
inject: ['group'],
|
||||
data() {
|
||||
return {
|
||||
selectedTabIndex: 0,
|
||||
unassignedCount: null,
|
||||
reassignedCount: null,
|
||||
cursor: {
|
||||
before: null,
|
||||
after: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
sourceUsers: {
|
||||
query: importSourceUsersQuery,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.group.path,
|
||||
...this.cursor,
|
||||
[this.cursor.before ? 'last' : 'first']: DEFAULT_PAGE_SIZE,
|
||||
statuses: this.queryStatuses,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
return data.namespace?.importSourceUsers;
|
||||
},
|
||||
error() {
|
||||
createAlert({
|
||||
message: s__('UserMapping|There was a problem fetching placeholder users.'),
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState('placeholder', ['pagination']),
|
||||
isLoading() {
|
||||
return Boolean(this.$apollo.queries.sourceUsers.loading);
|
||||
},
|
||||
nodes() {
|
||||
return this.sourceUsers?.nodes || [];
|
||||
},
|
||||
pageInfo() {
|
||||
return this.sourceUsers?.pageInfo || {};
|
||||
},
|
||||
statusParamValue() {
|
||||
return getParameterByName('status');
|
||||
},
|
||||
queryStatuses() {
|
||||
unassignedUserStatuses() {
|
||||
if (getParameterByName('status') === QUERY_PARAM_FAILED) {
|
||||
return [PLACEHOLDER_STATUS_FAILED];
|
||||
}
|
||||
|
||||
return [];
|
||||
return PLACEHOLDER_USER_STATUS.UNASSIGNED;
|
||||
},
|
||||
reassignedUserStatuses() {
|
||||
return PLACEHOLDER_USER_STATUS.REASSIGNED;
|
||||
},
|
||||
},
|
||||
|
||||
|
|
@ -129,12 +91,9 @@ export default {
|
|||
|
||||
<placeholders-table
|
||||
key="unassigned"
|
||||
:items="nodes"
|
||||
:page-info="pageInfo"
|
||||
:is-loading="isLoading"
|
||||
data-testid="placeholders-table-unassigned"
|
||||
:query-statuses="unassignedUserStatuses"
|
||||
@confirm="onConfirm"
|
||||
@prev="onPrevPage"
|
||||
@next="onNextPage"
|
||||
/>
|
||||
</gl-tab>
|
||||
|
||||
|
|
@ -146,12 +105,9 @@ export default {
|
|||
|
||||
<placeholders-table
|
||||
key="reassigned"
|
||||
data-testid="placeholders-table-reassigned"
|
||||
:query-statuses="reassignedUserStatuses"
|
||||
reassigned
|
||||
:items="nodes"
|
||||
:page-info="pageInfo"
|
||||
:is-loading="isLoading"
|
||||
@prev="onPrevPage"
|
||||
@next="onNextPage"
|
||||
/>
|
||||
</gl-tab>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,17 @@ import {
|
|||
GlTable,
|
||||
GlTooltipDirective,
|
||||
} from '@gitlab/ui';
|
||||
import { createAlert } from '~/alert';
|
||||
import { s__ } from '~/locale';
|
||||
|
||||
import { DEFAULT_PAGE_SIZE } from '~/members/constants';
|
||||
|
||||
import {
|
||||
PLACEHOLDER_STATUS_KEPT_AS_PLACEHOLDER,
|
||||
PLACEHOLDER_STATUS_COMPLETED,
|
||||
placeholderUserBadges,
|
||||
} from '~/import_entities/import_groups/constants';
|
||||
import importSourceUsersQuery from '../graphql/queries/import_source_users.query.graphql';
|
||||
import PlaceholderActions from './placeholder_actions.vue';
|
||||
|
||||
export default {
|
||||
|
|
@ -29,20 +33,11 @@ export default {
|
|||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
inject: ['group'],
|
||||
props: {
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
items: {
|
||||
queryStatuses: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
pageInfo: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
required: true,
|
||||
},
|
||||
reassigned: {
|
||||
type: Boolean,
|
||||
|
|
@ -50,6 +45,36 @@ export default {
|
|||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cursor: {
|
||||
before: null,
|
||||
after: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
sourceUsers: {
|
||||
query: importSourceUsersQuery,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.group.path,
|
||||
...this.cursor,
|
||||
[this.cursor.before ? 'last' : 'first']: DEFAULT_PAGE_SIZE,
|
||||
statuses: this.queryStatuses,
|
||||
};
|
||||
},
|
||||
|
||||
update(data) {
|
||||
return data.namespace?.importSourceUsers;
|
||||
},
|
||||
error() {
|
||||
createAlert({
|
||||
message: s__('UserMapping|There was a problem fetching placeholder users.'),
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
fields() {
|
||||
|
|
@ -75,6 +100,15 @@ export default {
|
|||
},
|
||||
];
|
||||
},
|
||||
isLoading() {
|
||||
return this.$apollo.queries.sourceUsers.loading;
|
||||
},
|
||||
nodes() {
|
||||
return this.sourceUsers?.nodes || [];
|
||||
},
|
||||
pageInfo() {
|
||||
return this.sourceUsers?.pageInfo || {};
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
@ -98,6 +132,19 @@ export default {
|
|||
|
||||
return {};
|
||||
},
|
||||
onPrevPage() {
|
||||
this.cursor = {
|
||||
before: this.sourceUsers.pageInfo.startCursor,
|
||||
after: null,
|
||||
};
|
||||
},
|
||||
|
||||
onNextPage() {
|
||||
this.cursor = {
|
||||
after: this.sourceUsers.pageInfo.endCursor,
|
||||
before: null,
|
||||
};
|
||||
},
|
||||
|
||||
onConfirm(item) {
|
||||
this.$emit('confirm', item);
|
||||
|
|
@ -108,7 +155,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<gl-table :items="items" :fields="fields" :busy="isLoading">
|
||||
<gl-table :items="nodes" :fields="fields" :busy="isLoading">
|
||||
<template #table-busy>
|
||||
<gl-loading-icon size="lg" class="gl-my-5" />
|
||||
</template>
|
||||
|
|
@ -155,8 +202,8 @@ export default {
|
|||
v-bind="pageInfo"
|
||||
:prev-text="__('Prev')"
|
||||
:next-text="__('Next')"
|
||||
@prev="$emit('prev')"
|
||||
@next="$emit('next')"
|
||||
@prev="onPrevPage"
|
||||
@next="onNextPage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
<script>
|
||||
import { GlButton, GlTooltipDirective, GlSprintf, GlSkeletonLoader } from '@gitlab/ui';
|
||||
import { GlButton, GlTooltipDirective, GlSprintf, GlSkeletonLoader, GlBadge } from '@gitlab/ui';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { n__ } from '~/locale';
|
||||
import { n__, s__ } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import ListItem from '~/vue_shared/components/registry/list_item.vue';
|
||||
import { joinPaths } from '~/lib/utils/url_utility';
|
||||
import PublishMessage from '~/packages_and_registries/shared/components/publish_message.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import {
|
||||
LIST_DELETE_BUTTON_DISABLED,
|
||||
LIST_DELETE_BUTTON_DISABLED_FOR_MIGRATION,
|
||||
|
|
@ -33,11 +34,12 @@ export default {
|
|||
GlSkeletonLoader,
|
||||
CleanupStatus,
|
||||
PublishMessage,
|
||||
GlBadge,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
mixins: [Tracking.mixin()],
|
||||
mixins: [Tracking.mixin(), glFeatureFlagsMixin()],
|
||||
inject: ['config'],
|
||||
props: {
|
||||
item: {
|
||||
|
|
@ -60,6 +62,9 @@ export default {
|
|||
ROW_SCHEDULED_FOR_DELETION,
|
||||
COPY_IMAGE_PATH_TITLE,
|
||||
IMAGE_FULL_PATH_LABEL,
|
||||
badgeProtectedTooltipText: s__(
|
||||
'ContainerRegistry|A protection rule exists for this container repository.',
|
||||
),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -109,6 +114,12 @@ export default {
|
|||
projectUrl() {
|
||||
return this.config.isGroupPage ? this.item.project?.webUrl : '';
|
||||
},
|
||||
showBadgeProtected() {
|
||||
return (
|
||||
Boolean(this.glFeatures.containerRegistryProtectedContainers) &&
|
||||
Boolean(this.item.protectionRuleExists)
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hideButton() {
|
||||
|
|
@ -175,6 +186,17 @@ export default {
|
|||
:status="item.expirationPolicyCleanupStatus"
|
||||
:expiration-policy="expirationPolicy"
|
||||
/>
|
||||
|
||||
<gl-badge
|
||||
v-if="showBadgeProtected"
|
||||
v-gl-tooltip
|
||||
:title="$options.i18n.badgeProtectedTooltipText"
|
||||
class="gl-ml-3"
|
||||
size="sm"
|
||||
variant="neutral"
|
||||
>
|
||||
{{ __('protected') }}
|
||||
</gl-badge>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ export default {
|
|||
:show-divider="index !== 0"
|
||||
:title="statusCheck.name"
|
||||
:status-check-url="statusCheck.externalUrl"
|
||||
:hmac="statusCheck.hmac"
|
||||
/>
|
||||
</gl-card>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { GlAvatarsInline, GlAvatar, GlAvatarLink, GlTooltipDirective, GlBadge } from '@gitlab/ui';
|
||||
import { n__ } from '~/locale';
|
||||
import { n__, __ } from '~/locale';
|
||||
import { accessLevelsConfig } from './constants';
|
||||
|
||||
const AVATAR_TOOLTIP_MAX_CHARS = 100;
|
||||
|
|
@ -8,6 +8,9 @@ export const MAX_VISIBLE_AVATARS = 4;
|
|||
export const AVATAR_SIZE = 24;
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
sharedSecret: __('HMAC enabled'),
|
||||
},
|
||||
name: 'ProtectionRow',
|
||||
AVATAR_TOOLTIP_MAX_CHARS,
|
||||
MAX_VISIBLE_AVATARS,
|
||||
|
|
@ -48,6 +51,11 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
hmac: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
avatarBadgeSrOnlyText() {
|
||||
|
|
@ -104,6 +112,10 @@ export default {
|
|||
</template>
|
||||
</gl-avatars-inline>
|
||||
|
||||
<gl-badge v-if="hmac" data-testid="shared-secret" class="gl-mr-2">{{
|
||||
$options.i18n.sharedSecret
|
||||
}}</gl-badge>
|
||||
|
||||
<gl-badge
|
||||
v-for="(item, index) in accessLevels"
|
||||
:key="index"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export default {
|
|||
ACCESS_LEVEL_DEVELOPER_INTEGER,
|
||||
ACCESS_LEVEL_MAINTAINER_INTEGER,
|
||||
ACCESS_LEVEL_ADMIN_INTEGER,
|
||||
ACCESS_LEVEL_NO_ACCESS_INTEGER,
|
||||
components: {
|
||||
GlDrawer,
|
||||
GlButton,
|
||||
|
|
@ -66,6 +67,7 @@ export default {
|
|||
isAdminSelected: null,
|
||||
isMaintainersSelected: null,
|
||||
isDevelopersAndMaintainersSelected: null,
|
||||
isNoOneSelected: null,
|
||||
isRuleUpdated: false,
|
||||
};
|
||||
},
|
||||
|
|
@ -73,25 +75,29 @@ export default {
|
|||
getDrawerHeaderHeight() {
|
||||
return getContentWrapperHeight();
|
||||
},
|
||||
isNoOneSelected() {
|
||||
return (
|
||||
!this.isAdminSelected &&
|
||||
!this.isMaintainersSelected &&
|
||||
!this.isDevelopersAndMaintainersSelected
|
||||
);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
isOpen() {
|
||||
this.isAdminSelected = this.roles.includes(ACCESS_LEVEL_ADMIN_INTEGER);
|
||||
this.isMaintainersSelected = this.roles.includes(ACCESS_LEVEL_MAINTAINER_INTEGER);
|
||||
this.isDevelopersAndMaintainersSelected = this.roles.includes(ACCESS_LEVEL_DEVELOPER_INTEGER);
|
||||
this.isNoOneSelected = this.roles.includes(ACCESS_LEVEL_NO_ACCESS_INTEGER);
|
||||
|
||||
this.updatedGroups = this.groups;
|
||||
this.updatedUsers = this.users;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleNoOneSelected() {
|
||||
this.isRuleUpdated = true;
|
||||
this.isAdminSelected = false;
|
||||
this.isMaintainersSelected = false;
|
||||
this.isDevelopersAndMaintainersSelected = false;
|
||||
},
|
||||
handleAccessLevelSelected() {
|
||||
this.isRuleUpdated = true;
|
||||
this.isNoOneSelected = false;
|
||||
},
|
||||
handleRuleDataUpdate(namespace, items) {
|
||||
this.isRuleUpdated = true;
|
||||
this[namespace] = items;
|
||||
|
|
@ -100,23 +106,24 @@ export default {
|
|||
return items.map((item) => ({ [keyName]: convertToGraphQLId(type, item.id) }));
|
||||
},
|
||||
getRuleEditData() {
|
||||
let ruleEditData = [
|
||||
const ruleEditRoles = [
|
||||
...this.formatItemsData(this.updatedUsers, 'userId', 'User'), // eslint-disable-line @gitlab/require-i18n-strings
|
||||
...this.formatItemsData(this.updatedGroups, 'groupId', 'Group'), // eslint-disable-line @gitlab/require-i18n-strings
|
||||
];
|
||||
let ruleEditAccessLevels = [];
|
||||
if (this.isAdminSelected) {
|
||||
ruleEditData.push({ accessLevel: ACCESS_LEVEL_ADMIN_INTEGER });
|
||||
ruleEditAccessLevels.push({ accessLevel: ACCESS_LEVEL_ADMIN_INTEGER });
|
||||
}
|
||||
if (this.isMaintainersSelected) {
|
||||
ruleEditData.push({ accessLevel: ACCESS_LEVEL_MAINTAINER_INTEGER });
|
||||
ruleEditAccessLevels.push({ accessLevel: ACCESS_LEVEL_MAINTAINER_INTEGER });
|
||||
}
|
||||
if (this.isDevelopersAndMaintainersSelected) {
|
||||
ruleEditData.push({ accessLevel: ACCESS_LEVEL_DEVELOPER_INTEGER });
|
||||
ruleEditAccessLevels.push({ accessLevel: ACCESS_LEVEL_DEVELOPER_INTEGER });
|
||||
}
|
||||
if (this.isNoOneSelected) {
|
||||
ruleEditData = [{ accessLevel: ACCESS_LEVEL_NO_ACCESS_INTEGER }];
|
||||
ruleEditAccessLevels = [{ accessLevel: ACCESS_LEVEL_NO_ACCESS_INTEGER }];
|
||||
}
|
||||
return ruleEditData;
|
||||
return [...ruleEditRoles, ...ruleEditAccessLevels];
|
||||
},
|
||||
formatItemsIds(items) {
|
||||
return items.map((item) => ({ ...item, id: getIdFromGraphQLId(item.id) }));
|
||||
|
|
@ -156,22 +163,27 @@ export default {
|
|||
</template>
|
||||
<template #default>
|
||||
<gl-form-group class="gl-border-none">
|
||||
<gl-form-checkbox v-model="isAdminSelected" @change="isRuleUpdated = true">
|
||||
<gl-form-checkbox v-model="isAdminSelected" @change="handleAccessLevelSelected">
|
||||
{{ $options.accessLevelsConfig[$options.ACCESS_LEVEL_ADMIN_INTEGER].accessLevelLabel }}
|
||||
</gl-form-checkbox>
|
||||
<gl-form-checkbox v-model="isMaintainersSelected" @change="isRuleUpdated = true">
|
||||
<gl-form-checkbox v-model="isMaintainersSelected" @change="handleAccessLevelSelected">
|
||||
{{
|
||||
$options.accessLevelsConfig[$options.ACCESS_LEVEL_MAINTAINER_INTEGER].accessLevelLabel
|
||||
}}
|
||||
</gl-form-checkbox>
|
||||
<gl-form-checkbox
|
||||
v-model="isDevelopersAndMaintainersSelected"
|
||||
@change="isRuleUpdated = true"
|
||||
@change="handleAccessLevelSelected"
|
||||
>
|
||||
{{
|
||||
$options.accessLevelsConfig[$options.ACCESS_LEVEL_DEVELOPER_INTEGER].accessLevelLabel
|
||||
}}
|
||||
</gl-form-checkbox>
|
||||
<gl-form-checkbox v-model="isNoOneSelected" @change="handleNoOneSelected">
|
||||
{{
|
||||
$options.accessLevelsConfig[$options.ACCESS_LEVEL_NO_ACCESS_INTEGER].accessLevelLabel
|
||||
}}
|
||||
</gl-form-checkbox>
|
||||
|
||||
<items-selector
|
||||
type="users"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import {
|
|||
I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_LABEL,
|
||||
I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_TOOLTIP,
|
||||
WORK_ITEM_TYPE_VALUE_EPIC,
|
||||
I18N_MAX_WORK_ITEMS_ERROR_MESSAGE,
|
||||
MAX_WORK_ITEMS,
|
||||
sprintfWorkItem,
|
||||
} from '../../constants';
|
||||
import WorkItemProjectsListbox from './work_item_projects_listbox.vue';
|
||||
|
|
@ -240,10 +242,10 @@ export default {
|
|||
: [];
|
||||
},
|
||||
areWorkItemsToAddValid() {
|
||||
return this.invalidWorkItemsToAdd.length === 0;
|
||||
return this.invalidWorkItemsToAdd.length === 0 && this.areWorkItemsToAddWithinLimit;
|
||||
},
|
||||
showWorkItemsToAddInvalidMessage() {
|
||||
return !this.isCreateForm && !this.areWorkItemsToAddValid;
|
||||
return !this.isCreateForm && this.invalidWorkItemsToAdd.length > 0;
|
||||
},
|
||||
workItemsToAddInvalidMessage() {
|
||||
return sprintf(
|
||||
|
|
@ -257,6 +259,9 @@ export default {
|
|||
},
|
||||
);
|
||||
},
|
||||
areWorkItemsToAddWithinLimit() {
|
||||
return this.workItemsToAdd.length <= MAX_WORK_ITEMS;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
workItemsToAdd() {
|
||||
|
|
@ -358,6 +363,7 @@ export default {
|
|||
titleInputPlaceholder: s__('WorkItem|Add a title'),
|
||||
projectInputPlaceholder: s__('WorkItem|Select a project'),
|
||||
titleInputValidationMessage: __('Maximum of 255 characters'),
|
||||
maxItemsErrorMessage: I18N_MAX_WORK_ITEMS_ERROR_MESSAGE,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -438,6 +444,13 @@ export default {
|
|||
<div v-if="error" class="gl-text-red-500 gl-mt-3" data-testid="work-items-error">
|
||||
{{ error }}
|
||||
</div>
|
||||
<div
|
||||
v-if="!areWorkItemsToAddWithinLimit"
|
||||
class="gl-mb-2 gl-text-red-500"
|
||||
data-testid="work-items-limit-error"
|
||||
>
|
||||
{{ $options.i18n.maxItemsErrorMessage }}
|
||||
</div>
|
||||
</div>
|
||||
<gl-button
|
||||
category="primary"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module Groups
|
|||
push_frontend_feature_flag(:show_container_registry_tag_signatures, group)
|
||||
end
|
||||
|
||||
before_action only: [:show] do
|
||||
before_action only: [:index, :show] do
|
||||
push_frontend_feature_flag(:container_registry_protected_containers, group)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,11 @@ module Projects
|
|||
push_frontend_feature_flag(:show_container_registry_tag_signatures, project)
|
||||
end
|
||||
|
||||
before_action only: [:index, :show] do
|
||||
push_frontend_feature_flag(:container_registry_protected_containers, project)
|
||||
end
|
||||
|
||||
before_action :authorize_update_container_image!, only: [:destroy]
|
||||
before_action :set_feature_flag_container_registry_protected_containers, only: [:show]
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
|
|
@ -55,10 +58,6 @@ module Projects
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_feature_flag_container_registry_protected_containers
|
||||
push_frontend_feature_flag(:container_registry_protected_containers, project)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ query getProjectContainerRepositories(
|
|||
id
|
||||
path
|
||||
}
|
||||
protectionRuleExists
|
||||
userPermissions {
|
||||
destroyContainerRepository
|
||||
}
|
||||
|
|
@ -78,6 +79,7 @@ query getProjectContainerRepositories(
|
|||
path
|
||||
webUrl
|
||||
}
|
||||
protectionRuleExists
|
||||
userPermissions {
|
||||
destroyContainerRepository
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,24 @@ module Resolvers
|
|||
description: 'Filter by reviewer presence. Incompatible with reviewerUsername.'
|
||||
end
|
||||
|
||||
argument :approved_by, [GraphQL::Types::String],
|
||||
required: false,
|
||||
as: :approved_by_usernames,
|
||||
description: 'Usernames of the approvers.'
|
||||
|
||||
argument :release_tag, GraphQL::Types::String,
|
||||
required: false,
|
||||
description: 'Filter by release tag.'
|
||||
|
||||
argument :merged_by, GraphQL::Types::String,
|
||||
required: false,
|
||||
as: :merge_user_username,
|
||||
description: 'Username of the merger.'
|
||||
|
||||
argument :my_reaction_emoji, GraphQL::Types::String,
|
||||
required: false,
|
||||
description: 'Filter by your reaction emoji.'
|
||||
|
||||
argument :iids, [GraphQL::Types::String],
|
||||
required: false,
|
||||
description: 'Array of IIDs of merge requests, for example `[1, 2]`.'
|
||||
|
|
@ -124,6 +142,10 @@ module Resolvers
|
|||
default_value: :created_desc
|
||||
|
||||
negated do
|
||||
argument :approved_by, [GraphQL::Types::String],
|
||||
required: false,
|
||||
as: :approved_by_usernames,
|
||||
description: 'Usernames of approvers to exclude.'
|
||||
argument :assignee_usernames, [GraphQL::Types::String],
|
||||
as: :assignee_username,
|
||||
required: false,
|
||||
|
|
@ -134,10 +156,16 @@ module Resolvers
|
|||
description: 'Array of label names. All resolved merge requests will not have these labels.'
|
||||
argument :milestone_title, GraphQL::Types::String,
|
||||
required: false,
|
||||
description: 'Title of the milestone.'
|
||||
description: 'Title of the milestone to exclude.'
|
||||
argument :my_reaction_emoji, GraphQL::Types::String,
|
||||
required: false,
|
||||
description: 'Filter by reaction emoji to exclude.'
|
||||
argument :release_tag, GraphQL::Types::String,
|
||||
required: false,
|
||||
description: 'Filter by release tag to exclude.'
|
||||
argument :reviewer_username, GraphQL::Types::String,
|
||||
required: false,
|
||||
description: 'Username of the reviewer.'
|
||||
description: 'Username of the reviewer to exclude.'
|
||||
end
|
||||
|
||||
validates mutually_exclusive: [:assignee_username, :assignee_wildcard_id]
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ module MergeRequestsHelper
|
|||
|
||||
def project_merge_requests_list_data(project, current_user)
|
||||
{
|
||||
autocomplete_award_emojis_path: autocomplete_award_emojis_path,
|
||||
full_path: project.full_path,
|
||||
has_any_merge_requests: project_merge_requests(project).exists?.to_s,
|
||||
initial_sort: current_user&.user_preference&.issues_sort,
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ module Avatarable
|
|||
return uncached_avatar_path(only_path: only_path, size: size)
|
||||
end
|
||||
|
||||
if self.try(:should_use_security_policy_bot_avatar?)
|
||||
return self.security_policy_bot_static_avatar_path(size)
|
||||
end
|
||||
|
||||
# Cache this avatar path only within the request because avatars in
|
||||
# object storage may be generated with time-limited, signed URLs.
|
||||
key = "#{self.class.name}:#{self.id}:#{only_path}:#{size}"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module Enums
|
|||
secret_detection: %w[secret_detection],
|
||||
test: %w[junit],
|
||||
accessibility: %w[accessibility],
|
||||
coverage: %w[cobertura],
|
||||
coverage: %w[cobertura jacoco],
|
||||
codequality: %w[codequality],
|
||||
terraform: %w[terraform]
|
||||
}.freeze
|
||||
|
|
@ -38,6 +38,7 @@ module Enums
|
|||
lsif: 'lsif.json',
|
||||
dotenv: '.env',
|
||||
cobertura: 'cobertura-coverage.xml',
|
||||
jacoco: 'jacoco-coverage.xml',
|
||||
terraform: 'tfplan.json',
|
||||
cluster_applications: 'gl-cluster-applications.json', # DEPRECATED: https://gitlab.com/gitlab-org/gitlab/-/issues/361094
|
||||
requirements: 'requirements.json', # Will be DEPRECATED soon: https://gitlab.com/groups/gitlab-org/-/epics/9203
|
||||
|
|
@ -62,6 +63,7 @@ module Enums
|
|||
network_referee: :gzip,
|
||||
dotenv: :gzip,
|
||||
cobertura: :gzip,
|
||||
jacoco: :gzip,
|
||||
cluster_applications: :gzip, # DEPRECATED: https://gitlab.com/gitlab-org/gitlab/-/issues/361094
|
||||
lsif: :zip,
|
||||
cyclonedx: :gzip,
|
||||
|
|
@ -98,6 +100,7 @@ module Enums
|
|||
api_fuzzing
|
||||
archive
|
||||
cobertura
|
||||
jacoco
|
||||
codequality
|
||||
container_scanning
|
||||
dast
|
||||
|
|
@ -180,7 +183,8 @@ module Enums
|
|||
cyclonedx: 28, ## EE-specific
|
||||
requirements_v2: 29, ## EE-specific
|
||||
annotations: 30,
|
||||
repository_xray: 31 ## EE-specific
|
||||
repository_xray: 31, ## EE-specific
|
||||
jacoco: 32
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
- remove_form_id = local_assigns.fetch(:remove_form_id, nil)
|
||||
|
||||
= render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card' }, header_options: { class: 'gl-new-card-header' }, body_options: { class: 'gl-new-card-body gl-bg-red-50 gl-px-5 gl-py-4' }) do |c|
|
||||
= render Pajamas::CardComponent.new(header_options: { class: 'gl-px-5 gl-py-4 gl-border-b-1 gl-border-b-solid gl-border-gray-100' }, body_options: { class: 'gl-bg-red-50 gl-px-5 gl-py-4' }) do |c|
|
||||
- c.with_header do
|
||||
.gl-new-card-title-wrapper
|
||||
%h4.gl-new-card-title.danger-title= _('Delete group')
|
||||
.gl-flex.gl-grow
|
||||
%h4.gl-text-base.gl-leading-24.gl-m-0.gl-text-red-500= _('Delete group')
|
||||
|
||||
- c.with_body do
|
||||
= form_tag(group, method: :delete, id: remove_form_id) do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: jacoco_coverage_reports
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/227345
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/161168
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/475025
|
||||
milestone: '17.3'
|
||||
group: group::pipeline execution
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
table_name: pm_epss
|
||||
classes:
|
||||
- PackageMetadata::Epss
|
||||
feature_categories:
|
||||
- software_composition_analysis
|
||||
- container_scanning
|
||||
description: Stores EPSS data (https://www.first.org/epss/).
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158908
|
||||
milestone: '17.3'
|
||||
gitlab_schema: gitlab_sec
|
||||
exempt_from_sharding: true # See discussion on keys for pm_ tables https://gitlab.com/gitlab-org/gitlab/-/issues/434988#note_1827421068
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreatePackageMetadataEpss < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.3'
|
||||
|
||||
def change
|
||||
create_table :pm_epss do |t|
|
||||
t.float :score, null: false
|
||||
t.timestamps_with_timezone null: false
|
||||
t.text :cve, limit: 24, null: false, index: { unique: true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
6865c7c37f109d62ad8a85c794ee5dbccbeee45397fc89bb8b4f63ff2af8b9a2
|
||||
|
|
@ -15298,6 +15298,24 @@ CREATE SEQUENCE pm_checkpoints_id_seq
|
|||
|
||||
ALTER SEQUENCE pm_checkpoints_id_seq OWNED BY pm_checkpoints.id;
|
||||
|
||||
CREATE TABLE pm_epss (
|
||||
id bigint NOT NULL,
|
||||
score double precision NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
cve text NOT NULL,
|
||||
CONSTRAINT check_33a7364ae2 CHECK ((char_length(cve) <= 24))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE pm_epss_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE pm_epss_id_seq OWNED BY pm_epss.id;
|
||||
|
||||
CREATE TABLE pm_licenses (
|
||||
id bigint NOT NULL,
|
||||
spdx_identifier text NOT NULL,
|
||||
|
|
@ -21574,6 +21592,8 @@ ALTER TABLE ONLY pm_affected_packages ALTER COLUMN id SET DEFAULT nextval('pm_af
|
|||
|
||||
ALTER TABLE ONLY pm_checkpoints ALTER COLUMN id SET DEFAULT nextval('pm_checkpoints_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY pm_epss ALTER COLUMN id SET DEFAULT nextval('pm_epss_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY pm_licenses ALTER COLUMN id SET DEFAULT nextval('pm_licenses_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY pm_package_version_licenses ALTER COLUMN id SET DEFAULT nextval('pm_package_version_licenses_id_seq'::regclass);
|
||||
|
|
@ -24058,6 +24078,9 @@ ALTER TABLE ONLY pm_affected_packages
|
|||
ALTER TABLE ONLY pm_checkpoints
|
||||
ADD CONSTRAINT pm_checkpoints_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY pm_epss
|
||||
ADD CONSTRAINT pm_epss_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY pm_licenses
|
||||
ADD CONSTRAINT pm_licenses_pkey PRIMARY KEY (id);
|
||||
|
||||
|
|
@ -28934,6 +28957,8 @@ CREATE INDEX index_pm_affected_packages_on_pm_advisory_id ON pm_affected_package
|
|||
|
||||
CREATE INDEX index_pm_affected_packages_on_purl_type_and_package_name ON pm_affected_packages USING btree (purl_type, package_name);
|
||||
|
||||
CREATE UNIQUE INDEX index_pm_epss_on_cve ON pm_epss USING btree (cve);
|
||||
|
||||
CREATE INDEX index_pm_package_version_licenses_on_pm_license_id ON pm_package_version_licenses USING btree (pm_license_id);
|
||||
|
||||
CREATE INDEX index_pm_package_version_licenses_on_pm_package_version_id ON pm_package_version_licenses USING btree (pm_package_version_id);
|
||||
|
|
|
|||
|
|
@ -480,6 +480,18 @@ because it only deletes untagged images.
|
|||
Implement cleanup policies to remove unneeded tags, which eventually causes images
|
||||
to be removed through garbage collection and storage space being recovered.
|
||||
|
||||
## Backup with metadata database
|
||||
|
||||
When the metadata database is enabled, backups must capture both the object storage
|
||||
used by the registry, as before, but also the database. Backups of object storage
|
||||
and the database should be coordinated to capture the state of the registry as close as possible
|
||||
to each other. To restore the registry, you must apply both backups together.
|
||||
|
||||
## Downgrade a registry
|
||||
|
||||
To downgrade the registry to a previous version after the migration is complete,
|
||||
you must restore to a backup of the desired version in order to downgrade.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### `there are pending database migrations` error
|
||||
|
|
|
|||
|
|
@ -1087,6 +1087,20 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="querysnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
|
||||
| <a id="querysnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
|
||||
|
||||
### `Query.standardRoles`
|
||||
|
||||
Standard roles available for the instance, available only for self-managed.
|
||||
|
||||
DETAILS:
|
||||
**Introduced** in GitLab 17.3.
|
||||
**Status**: Experiment.
|
||||
|
||||
Returns [`StandardRoleConnection`](#standardroleconnection).
|
||||
|
||||
This field returns a [connection](#connections). It accepts the
|
||||
four standard [pagination arguments](#pagination-arguments):
|
||||
`before: String`, `after: String`, `first: Int`, and `last: Int`.
|
||||
|
||||
### `Query.subscriptionFutureEntries`
|
||||
|
||||
Fields related to entries in future subscriptions.
|
||||
|
|
@ -15548,6 +15562,29 @@ The edge type for [`SnippetRepositoryRegistry`](#snippetrepositoryregistry).
|
|||
| <a id="snippetrepositoryregistryedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| <a id="snippetrepositoryregistryedgenode"></a>`node` | [`SnippetRepositoryRegistry`](#snippetrepositoryregistry) | The item at the end of the edge. |
|
||||
|
||||
#### `StandardRoleConnection`
|
||||
|
||||
The connection type for [`StandardRole`](#standardrole).
|
||||
|
||||
##### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="standardroleconnectionedges"></a>`edges` | [`[StandardRoleEdge]`](#standardroleedge) | A list of edges. |
|
||||
| <a id="standardroleconnectionnodes"></a>`nodes` | [`[StandardRole]`](#standardrole) | A list of nodes. |
|
||||
| <a id="standardroleconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
||||
#### `StandardRoleEdge`
|
||||
|
||||
The edge type for [`StandardRole`](#standardrole).
|
||||
|
||||
##### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="standardroleedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| <a id="standardroleedgenode"></a>`node` | [`StandardRole`](#standardrole) | The item at the end of the edge. |
|
||||
|
||||
#### `SubmoduleConnection`
|
||||
|
||||
The connection type for [`Submodule`](#submodule).
|
||||
|
|
@ -16599,6 +16636,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="addonuserassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="addonuserassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="addonuserassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="addonuserassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="addonuserassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -16612,11 +16650,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="addonuserassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="addonuserassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="addonuserassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="addonuserassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="addonuserassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="addonuserassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="addonuserassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="addonuserassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="addonuserassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="addonuserassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="addonuserassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="addonuserassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="addonuserassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="addonuserassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -16643,6 +16684,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="addonuserauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="addonuserauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="addonuserauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="addonuserauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="addonuserauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -16657,11 +16699,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="addonuserauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="addonuserauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="addonuserauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="addonuserauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="addonuserauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="addonuserauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="addonuserauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="addonuserauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="addonuserauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="addonuserauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="addonuserauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="addonuserauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="addonuserauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="addonuserauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -16741,6 +16786,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="addonuserreviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -16756,11 +16802,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="addonuserreviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="addonuserreviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="addonuserreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -17437,6 +17486,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="autocompleteduserassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="autocompleteduserassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="autocompleteduserassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="autocompleteduserassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="autocompleteduserassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -17450,11 +17500,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="autocompleteduserassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="autocompleteduserassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="autocompleteduserassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="autocompleteduserassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="autocompleteduserassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="autocompleteduserassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="autocompleteduserassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="autocompleteduserassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="autocompleteduserassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="autocompleteduserassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="autocompleteduserassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="autocompleteduserassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="autocompleteduserassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="autocompleteduserassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -17481,6 +17534,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="autocompleteduserauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="autocompleteduserauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -17495,11 +17549,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="autocompleteduserauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="autocompleteduserauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -17591,6 +17648,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -17606,11 +17664,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="autocompleteduserreviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="autocompleteduserreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -19713,6 +19774,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="currentuserassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="currentuserassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="currentuserassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="currentuserassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="currentuserassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -19726,11 +19788,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="currentuserassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="currentuserassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="currentuserassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="currentuserassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="currentuserassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="currentuserassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="currentuserassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="currentuserassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="currentuserassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="currentuserassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="currentuserassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="currentuserassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="currentuserassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="currentuserassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -19757,6 +19822,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="currentuserauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="currentuserauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="currentuserauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="currentuserauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="currentuserauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -19771,11 +19837,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="currentuserauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="currentuserauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="currentuserauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="currentuserauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="currentuserauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="currentuserauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="currentuserauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="currentuserauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="currentuserauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="currentuserauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="currentuserauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="currentuserauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="currentuserauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="currentuserauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -19855,6 +19924,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="currentuserreviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -19870,11 +19940,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="currentuserreviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="currentuserreviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="currentuserreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -23140,6 +23213,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="groupmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="groupmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="groupmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="groupmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="groupmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -23156,9 +23230,12 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="groupmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="groupmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="groupmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="groupmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="groupmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="groupmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="groupmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="groupmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="groupmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="groupmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="groupmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="groupmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -25188,6 +25265,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -25201,11 +25279,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestassigneeassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestassigneeassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -25232,6 +25313,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -25246,11 +25328,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestassigneeauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestassigneeauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -25330,6 +25415,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -25345,11 +25431,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestassigneereviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestassigneereviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -25555,6 +25644,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestauthorassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="mergerequestauthorassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="mergerequestauthorassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -25568,11 +25658,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestauthorassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestauthorassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -25599,6 +25692,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -25613,11 +25707,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestauthorauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestauthorauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -25697,6 +25794,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -25712,11 +25810,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestauthorreviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestauthorreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -25968,6 +26069,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -25981,11 +26083,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestparticipantassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestparticipantassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -26012,6 +26117,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -26026,11 +26132,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestparticipantauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestparticipantauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -26110,6 +26219,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -26125,11 +26235,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestparticipantreviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestparticipantreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -26354,6 +26467,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -26367,11 +26481,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestreviewerassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestreviewerassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -26398,6 +26515,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -26412,11 +26530,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestreviewerauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestreviewerauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -26496,6 +26617,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -26511,11 +26633,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="mergerequestreviewerreviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="mergerequestreviewerreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -29553,6 +29678,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="projectmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="projectmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="projectmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="projectmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="projectmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -29567,9 +29693,12 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="projectmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="projectmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="projectmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="projectmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="projectmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="projectmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="projectmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="projectmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="projectmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="projectmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="projectmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="projectmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -31854,6 +31983,18 @@ SSH signature for a signed commit.
|
|||
| <a id="sshsignatureuser"></a>`user` | [`UserCore`](#usercore) | User associated with the key. |
|
||||
| <a id="sshsignatureverificationstatus"></a>`verificationStatus` | [`VerificationStatus`](#verificationstatus) | Indicates verification status of the associated key or certificate. |
|
||||
|
||||
### `StandardRole`
|
||||
|
||||
Represents a standard role.
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="standardroleaccesslevel"></a>`accessLevel` | [`Int!`](#int) | Access level as a number. |
|
||||
| <a id="standardrolememberscount"></a>`membersCount` **{warning-solid}** | [`Int!`](#int) | **Introduced** in GitLab 17.3. **Status**: Experiment. Total number of members with the standard role. |
|
||||
| <a id="standardrolename"></a>`name` | [`String!`](#string) | Access level as a string. |
|
||||
|
||||
### `StandardsAdherenceChecksStatus`
|
||||
|
||||
Progress of standards adherence checks.
|
||||
|
|
@ -32539,6 +32680,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="usercoreassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="usercoreassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="usercoreassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="usercoreassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="usercoreassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -32552,11 +32694,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="usercoreassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="usercoreassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="usercoreassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="usercoreassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="usercoreassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="usercoreassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="usercoreassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="usercoreassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="usercoreassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="usercoreassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="usercoreassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="usercoreassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="usercoreassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="usercoreassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -32583,6 +32728,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="usercoreauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="usercoreauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="usercoreauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="usercoreauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="usercoreauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -32597,11 +32743,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="usercoreauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="usercoreauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="usercoreauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="usercoreauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="usercoreauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="usercoreauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="usercoreauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="usercoreauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="usercoreauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="usercoreauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="usercoreauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="usercoreauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="usercoreauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="usercoreauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -32681,6 +32830,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="usercorereviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="usercorereviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="usercorereviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="usercorereviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="usercorereviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -32696,11 +32846,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="usercorereviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="usercorereviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="usercorereviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="usercorereviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="usercorereviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="usercorereviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="usercorereviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="usercorereviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="usercorereviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="usercorereviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="usercorereviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="usercorereviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="usercorereviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="usercorereviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -35868,6 +36021,7 @@ Iteration ID wildcard values.
|
|||
| <a id="jobartifactfiletypedast"></a>`DAST` | DAST job artifact file type. |
|
||||
| <a id="jobartifactfiletypedependency_scanning"></a>`DEPENDENCY_SCANNING` | DEPENDENCY SCANNING job artifact file type. |
|
||||
| <a id="jobartifactfiletypedotenv"></a>`DOTENV` | DOTENV job artifact file type. |
|
||||
| <a id="jobartifactfiletypejacoco"></a>`JACOCO` | JACOCO job artifact file type. |
|
||||
| <a id="jobartifactfiletypejunit"></a>`JUNIT` | JUNIT job artifact file type. |
|
||||
| <a id="jobartifactfiletypelicense_scanning"></a>`LICENSE_SCANNING` | LICENSE SCANNING job artifact file type. |
|
||||
| <a id="jobartifactfiletypeload_performance"></a>`LOAD_PERFORMANCE` | LOAD PERFORMANCE job artifact file type. |
|
||||
|
|
@ -39224,6 +39378,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="userassignedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="userassignedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="userassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
| <a id="userassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
| <a id="userassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before the timestamp. |
|
||||
|
|
@ -39237,11 +39392,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="userassignedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="userassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="userassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="userassignedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="userassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="userassignedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="userassignedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="userassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="userassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="userassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="userassignedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="userassignedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="userassignedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="userassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -39268,6 +39426,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="userauthoredmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="userauthoredmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="userauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="userauthoredmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="userauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after the timestamp. |
|
||||
|
|
@ -39282,11 +39441,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="userauthoredmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="userauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="userauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="userauthoredmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="userauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="userauthoredmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="userauthoredmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="userauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="userauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="userauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="userauthoredmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="userauthoredmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="userauthoredmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="userauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
|
|
@ -39366,6 +39528,7 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="userreviewrequestedmergerequestsapproved"></a>`approved` | [`Boolean`](#boolean) | Limit results to approved merge requests. Available only when the feature flag `mr_approved_filter` is enabled. |
|
||||
| <a id="userreviewrequestedmergerequestsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of the approvers. |
|
||||
| <a id="userreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
|
||||
| <a id="userreviewrequestedmergerequestsassigneewildcardid"></a>`assigneeWildcardId` | [`AssigneeWildcardId`](#assigneewildcardid) | Filter by assignee presence. Incompatible with assigneeUsernames and assigneeUsername. |
|
||||
| <a id="userreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
|
||||
|
|
@ -39381,11 +39544,14 @@ four standard [pagination arguments](#pagination-arguments):
|
|||
| <a id="userreviewrequestedmergerequestslabels"></a>`labels` **{warning-solid}** | [`[String!]`](#string) | **Deprecated** in GitLab 17.1. Use `labelName`. |
|
||||
| <a id="userreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after the date. |
|
||||
| <a id="userreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before the date. |
|
||||
| <a id="userreviewrequestedmergerequestsmergedby"></a>`mergedBy` | [`String`](#string) | Username of the merger. |
|
||||
| <a id="userreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. Incompatible with milestoneWildcardId. |
|
||||
| <a id="userreviewrequestedmergerequestsmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter issues by milestone ID wildcard. Incompatible with milestoneTitle. |
|
||||
| <a id="userreviewrequestedmergerequestsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by your reaction emoji. |
|
||||
| <a id="userreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
|
||||
| <a id="userreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
|
||||
| <a id="userreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
|
||||
| <a id="userreviewrequestedmergerequestsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
|
||||
| <a id="userreviewrequestedmergerequestsreviewstate"></a>`reviewState` **{warning-solid}** | [`MergeRequestReviewState`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer state of the merge request. |
|
||||
| <a id="userreviewrequestedmergerequestsreviewstates"></a>`reviewStates` **{warning-solid}** | [`[MergeRequestReviewState!]`](#mergerequestreviewstate) | **Introduced** in GitLab 17.0. **Status**: Experiment. Reviewer states of the merge request. |
|
||||
| <a id="userreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by the criteria. |
|
||||
|
|
@ -39977,10 +40143,13 @@ Defines which user roles, users, or groups can merge into a protected branch.
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mergerequestsresolvernegatedparamsapprovedby"></a>`approvedBy` | [`[String!]`](#string) | Usernames of approvers to exclude. |
|
||||
| <a id="mergerequestsresolvernegatedparamsassigneeusernames"></a>`assigneeUsernames` | [`[String!]`](#string) | Usernames of the assignee to exclude. |
|
||||
| <a id="mergerequestsresolvernegatedparamslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will not have these labels. |
|
||||
| <a id="mergerequestsresolvernegatedparamsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. |
|
||||
| <a id="mergerequestsresolvernegatedparamsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
|
||||
| <a id="mergerequestsresolvernegatedparamsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone to exclude. |
|
||||
| <a id="mergerequestsresolvernegatedparamsmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji to exclude. |
|
||||
| <a id="mergerequestsresolvernegatedparamsreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag to exclude. |
|
||||
| <a id="mergerequestsresolvernegatedparamsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer to exclude. |
|
||||
|
||||
### `MonthSelectionInput`
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ that have the functionality you need in the [CI/CD Catalog](#cicd-catalog).
|
|||
For an introduction and hands-on examples, see [Efficient DevSecOps workflows with reusable CI/CD components](https://www.youtube.com/watch?v=-yvfSFKAgbA).
|
||||
<!-- Video published on 2024-01-22. DRI: Developer Relations, https://gitlab.com/groups/gitlab-com/marketing/developer-relations/-/epics/399 -->
|
||||
|
||||
For common questions and additional support, see the [FAQ: GitLab CI/CD Catalog](https://about.gitlab.com/blog/2024/08/01/faq-gitlab-ci-cd-catalog/)
|
||||
blog post.
|
||||
|
||||
## Component project
|
||||
|
||||
> - The maximum number of components per project [changed](https://gitlab.com/gitlab-org/gitlab/-/issues/436565) from 10 to 30 in GitLab 16.9.
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@ Maintainer role.
|
|||
|
||||
Prerequisites:
|
||||
|
||||
- When granting the **Allowed to deploy** permission to a group or subgroup, the user configuring the protected environment must be a **direct member** of the group or subgroup to be added. Otherwise, the group or subgroup does not show up in the dropdown list. For more information see [issue #345140](https://gitlab.com/gitlab-org/gitlab/-/issues/345140).
|
||||
- When granting **Allowed to deploy** permissions to a group or project by using the settings UI, only direct members of the group or project receive these permissions. To grant these permissions to inherited members also, [use the API](../../api/protected_environments.md#group-inheritance-types). For more information see [issue #422392](https://gitlab.com/gitlab-org/gitlab/-/issues/422392).
|
||||
- When granting the **Allowed to deploy** permission to an approver group, the user configuring the protected environment must be a **direct member** of the approver group to be added. Otherwise, the group or subgroup does not show up in the dropdown list. For more information see [issue #345140](https://gitlab.com/gitlab-org/gitlab/-/issues/345140).
|
||||
- When granting **Approvers** permissions to an approver group or project, by default only direct members of the approver group or project receive these permissions. To also grant these permissions to inherited members of the approver group or project:
|
||||
- Select the **Enable group inheritance** checkbox.
|
||||
- [Use the API](../../api/protected_environments.md#group-inheritance-types).
|
||||
|
||||
To protect an environment:
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ For example, the `[redis]` section in the configuration file could contain:
|
|||
[redis]
|
||||
URL = "unix:///var/run/gitlab/redis.sock"
|
||||
Password = "my_awesome_password"
|
||||
Sentinel = [ "tcp://sentinel1:23456", "tcp://sentinel2:23456" ]
|
||||
SentinelMaster = "mymaster"
|
||||
```
|
||||
|
||||
- `URL` - A string in the format `unix://path/to/redis.sock` or `tcp://host:port`.
|
||||
|
|
@ -160,28 +162,6 @@ addr = "localhost:9229"
|
|||
max_version = "tls1.3"
|
||||
```
|
||||
|
||||
## Sentinel support
|
||||
|
||||
```plaintext
|
||||
[redis]
|
||||
Sentinel = [ "tcp://sentinel1:23456", "tcp://sentinel2:23456" ]
|
||||
SentinelMaster = "mymaster"
|
||||
```
|
||||
|
||||
## Sentinel TLS support
|
||||
|
||||
```plaintext
|
||||
[redis]
|
||||
Sentinel = [ "tcp://sentinel1:23456", "tcp://sentinel2:23456" ]
|
||||
SentinelMaster = "mymaster"
|
||||
[Sentinel.tls]
|
||||
certificate = "/path/to/certificate"
|
||||
key = "/path/to/private/key"
|
||||
ca_certificate = "/path/to/ca_certificate" # optional
|
||||
min_version = "tls1.2" # optional
|
||||
max_version = "tls1.3" # optional
|
||||
```
|
||||
|
||||
## Interaction of `authBackend` and `authSocket`
|
||||
|
||||
The interaction between `authBackend` and `authSocket` can be confusing.
|
||||
|
|
|
|||
|
|
@ -65,6 +65,49 @@ A user is not counted as a billable user if:
|
|||
|
||||
The amount of **Billable users** is reported once a day in the **Admin** area.
|
||||
|
||||
#### Check daily and historical billable users
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator.
|
||||
|
||||
You can get a list of daily and historical billable users in your GitLab instance:
|
||||
|
||||
1. [Start a Rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session).
|
||||
1. Count the number of users in the instance:
|
||||
|
||||
```ruby
|
||||
User.billable.count
|
||||
```
|
||||
|
||||
1. Get the historical maximum number of users on the instance from the past year:
|
||||
|
||||
```ruby
|
||||
::HistoricalData.max_historical_user_count(from: 1.year.ago.beginning_of_day, to: Time.current.end_of_day)
|
||||
```
|
||||
|
||||
#### Update daily and hitorical billable users
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator.
|
||||
|
||||
You can trigger a manual update of the daily and historical billable users in your GitLab instance.
|
||||
|
||||
1. [Start a Rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session).
|
||||
1. Force an update of the daily billable users:
|
||||
|
||||
```ruby
|
||||
identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users]
|
||||
::Analytics::UsageTrends::CounterJobWorker.new.perform(identifier, User.minimum(:id), User.maximum(:id), Time.zone.now)
|
||||
```
|
||||
|
||||
1. Force an update of the historical max billable users:
|
||||
|
||||
```ruby
|
||||
::HistoricalDataWorker.new.perform
|
||||
```
|
||||
|
||||
### Maximum users
|
||||
|
||||
The number of _maximum users_ reflects the highest peak of billable users for the current license period.
|
||||
|
|
@ -505,38 +548,3 @@ You might get the error `Attempt_Exceed_Limitation - Attempt exceed the limitati
|
|||
This issue occurs when the credit card form is re-submitted too quickly within a specific time frame (three submissions within one minute or six submissions within one hour).
|
||||
|
||||
To resolve this issue, wait a few minutes and try the purchase process again.
|
||||
|
||||
### Check daily and historical billable users
|
||||
|
||||
Administrators can get a list of daily and historical billable users in your GitLab instance.
|
||||
|
||||
1. [Start a Rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session).
|
||||
1. Count the number of users in the instance:
|
||||
|
||||
```ruby
|
||||
User.billable.count
|
||||
```
|
||||
|
||||
1. Get the historical maximum number of users on the instance from the past year:
|
||||
|
||||
```ruby
|
||||
::HistoricalData.max_historical_user_count(from: 1.year.ago.beginning_of_day, to: Time.current.end_of_day)
|
||||
```
|
||||
|
||||
### Update daily billable and historical users
|
||||
|
||||
Administrators can trigger a manual update of the daily and historical billable users in your GitLab instance.
|
||||
|
||||
1. [Start a Rails console session](../../administration/operations/rails_console.md#starting-a-rails-console-session).
|
||||
1. Force an update of the daily billable users:
|
||||
|
||||
```ruby
|
||||
identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users]
|
||||
::Analytics::UsageTrends::CounterJobWorker.new.perform(identifier, User.minimum(:id), User.maximum(:id), Time.zone.now)
|
||||
```
|
||||
|
||||
1. Force an update of the historical max billable users:
|
||||
|
||||
```ruby
|
||||
::HistoricalDataWorker.new.perform
|
||||
```
|
||||
|
|
|
|||
|
|
@ -295,12 +295,13 @@ To create a thread:
|
|||
> - Resolvable threads for issues [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31114) in GitLab 16.3 [with a flag](../../administration/feature_flags.md) named `resolvable_issue_threads`. Disabled by default.
|
||||
> - Resolvable threads for issues [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/31114) in GitLab 16.4.
|
||||
> - Resolvable threads for issues [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/31114) in GitLab 16.7. Feature flag `resolvable_issue_threads` removed.
|
||||
> - Resolvable threads for tasks, objectives, and key results [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/458818) in GitLab 17.3.
|
||||
|
||||
You can resolve a thread when you want to finish a conversation.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be in an issue or merge request.
|
||||
- You must be in an issue, task, objective, key result, or merge request.
|
||||
- You must have at least the Developer role or be the author of the issue or merge request.
|
||||
|
||||
To resolve a thread:
|
||||
|
|
|
|||
|
|
@ -60,11 +60,12 @@ In the GitLab UI, GitLab Duo Chat knows about these areas:
|
|||
|
||||
In the IDEs, GitLab Duo Chat knows about these areas:
|
||||
|
||||
| Area | How to ask Chat |
|
||||
|---------|------------------|
|
||||
| Selected lines in the editor | With the lines selected, ask about `this code` or `this file`. Chat is not aware of the file; you must select the lines you want to ask about. |
|
||||
| Epics | Ask about the URL. |
|
||||
| Issues | Ask about the URL. |
|
||||
| Area | How to ask Chat |
|
||||
|-------------------------------|-----------------------|
|
||||
| Selected lines in the editor | With the lines selected, ask about `this code` or `this file`. Chat is not aware of the file; you must select the lines you want to ask about. |
|
||||
| Epics | Ask about the URL. |
|
||||
| Issues | Ask about the URL. |
|
||||
| Open files | Start working in a file, making sure that you have opened the files you want as used as context. For details, see [open tabs as context](../project/repository/code_suggestions/index.md#open-tabs-as-context). |
|
||||
|
||||
In addition, in the IDEs, when you use any of the slash commands,
|
||||
like `/explain`, `/refactor`, `/fix`, or `/tests,` Duo Chat has access to the
|
||||
|
|
|
|||
|
|
@ -104,11 +104,9 @@ you might write something like:
|
|||
AI is non-deterministic, so you may not get the same suggestion every time with the same input.
|
||||
To generate quality code, write clear, descriptive, specific tasks.
|
||||
|
||||
### Best practice examples
|
||||
|
||||
For use cases and best practices, follow the [GitLab Duo examples documentation](../../../gitlab_duo_examples.md).
|
||||
|
||||
#### Use open tabs as context
|
||||
## Open tabs as context
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/464767) in GitLab 17.2 [with a flag](../../../../administration/feature_flags.md) named `advanced_context_resolver`. Disabled by default.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/462750) in GitLab 17.2 [with a flag](../../../../administration/feature_flags.md) named `code_suggestions_context`. Disabled by default.
|
||||
|
|
@ -120,30 +118,54 @@ FLAG:
|
|||
The availability of this feature is controlled by a feature flag.
|
||||
For more information, see the history.
|
||||
|
||||
For better results from GitLab Duo Code Suggestions, ensure that Open Tabs Context is enabled in your IDE settings.
|
||||
This feature uses the contents of the files currently open in your IDE to get more
|
||||
accurate and relevant results from Code Suggestions. Like prompt engineering, these files
|
||||
To get more accurate and relevant results from Code Suggestions and Code Generation, you can use
|
||||
the contents of the files open in tabs in your IDE. Similar to prompt engineering, these files
|
||||
give GitLab Duo more information about the standards and practices in your code project.
|
||||
|
||||
To get the most benefit from using your open tabs as context, open the files relevant to the code
|
||||
you want to create, including configuration files. When you start work in a new file,
|
||||
Code Suggestions offers you suggestions in the new file.
|
||||
### Enable open tabs as context
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Requires GitLab 17.2 and later. Earlier GitLab versions that support Code Suggestions
|
||||
cannot weight the content of open tabs more heavily than other files in your project.
|
||||
- Requires a [supported code language](#advanced-context-supported-languages).
|
||||
- GitLab Duo Code Suggestions must be enabled for your project.
|
||||
- For GitLab self-managed instances, the `code_suggestions_context`and the
|
||||
`advanced_context_resolver` [feature flags](../../../feature_flags.md) must be enabled.
|
||||
- Use a supported code language:
|
||||
- Code Completion: All configured languages.
|
||||
- Code Generation: Go, Java, JavaScript, Kotlin, Python, Ruby, Rust, TypeScript (`.ts` and `.tsx` files),
|
||||
Vue, and YAML.
|
||||
|
||||
1. Open the files you want to provide for context. Advanced Context uses the most recently
|
||||
opened or changed files for context. If you don’t want a file sent as additional context, close it.
|
||||
1. To fine-tune your Code Generation results, add code comments to your file that explain
|
||||
what you want to build. Code Generation treats your code comments like chat. Your code comments
|
||||
update the `user_instruction`, and then improve the next results you receive.
|
||||
::Tabs
|
||||
|
||||
As you work, GitLab Duo provides code suggestions that use your other open files
|
||||
(within [truncation limits](#truncation-of-file-content))
|
||||
as extra context.
|
||||
:::TabTitle Visual Studio Code
|
||||
|
||||
1. Install the [GitLab Workflow extension version 4.14.2 or later](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow)
|
||||
from the Visual Studio Marketplace.
|
||||
1. Configure the [extension settings](https://gitlab.com/gitlab-org/gitlab-vscode-extension#extension-settings).
|
||||
1. Enable the feature by turning on the `gitlab.aiAssistedCodeSuggestions.enabledSupportedLanguages` setting.
|
||||
|
||||
:::TabTitle JetBrains IDEs
|
||||
|
||||
For installation instructions for JetBrains IDEs, see the
|
||||
[GitLab JetBrains Plugin documentation](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin#toggle-sending-open-tabs-as-context).
|
||||
|
||||
::EndTabs
|
||||
|
||||
### Use open tabs as context
|
||||
|
||||
Open the files you want to provide for context:
|
||||
|
||||
- Open tabs uses the most recently opened or changed files.
|
||||
- If you do not want a file used as additional context, close that file.
|
||||
|
||||
When you start working in a file, GitLab Duo uses your open files
|
||||
as extra context, within [truncation limits](#truncation-of-file-content).
|
||||
|
||||
You can adjust your Code Generation results by adding code comments to your file
|
||||
that explain what you want to build. Code Generation treats your code comments
|
||||
like chat. Your code comments update the `user_instruction`, and then improve
|
||||
the next results you receive.
|
||||
|
||||
### Related topics
|
||||
|
||||
To learn about the code that builds the prompt, see these files:
|
||||
|
||||
|
|
@ -151,19 +173,11 @@ To learn about the code that builds the prompt, see these files:
|
|||
[`ee/lib/api/code_suggestions.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/api/code_suggestions.rb#L76)
|
||||
in the `gitlab` repository.
|
||||
- **Code Completion**:
|
||||
[`ai_gateway/code_suggestions/processing/completions.py`](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/fcb3f485a8f047a86a8166aad81f93b6d82106a7/ai_gateway/code_suggestions/processing/completions.py#L273)
|
||||
in the `modelops` repository.
|
||||
[`ai_gateway/code_suggestions/processing/completions.py`](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/fcb3f485a8f047a86a8166aad81f93b6d82106a7/ai_gateway/code_suggestions/processing/completions.py#L273) in the `modelops` repository.
|
||||
|
||||
We'd love your feedback about the Advanced Context feature in
|
||||
You can provide feedback about this feature in
|
||||
[issue 258](https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/issues/258).
|
||||
|
||||
### Advanced Context supported languages
|
||||
|
||||
The Advanced Context feature supports these languages:
|
||||
|
||||
- Code Completion: all configured languages.
|
||||
- Code Generation: Go, Java, JavaScript, Kotlin, Python, Ruby, Rust, TypeScript (`.ts` and `.tsx` files), Vue, and YAML.
|
||||
|
||||
## Response time
|
||||
|
||||
Code Suggestions is powered by a generative AI model.
|
||||
|
|
|
|||
|
|
@ -70,57 +70,6 @@ plugin support. Refer to the JetBrains documentation for specifics on your IDE.
|
|||
|
||||
For languages not listed in the table, Code Suggestions might not function as expected.
|
||||
|
||||
## Use open tabs as context
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/issues/206) in GitLab 17.2.
|
||||
|
||||
To enhance the accuracy and relevance of GitLab Duo Code Suggestions, enable the use of
|
||||
open tabs as context in your IDE settings. This feature uses the contents of files most recently
|
||||
opened or changed in your IDE to provide more tailored code suggestions, within certain truncation limits.
|
||||
This extra context gives you:
|
||||
|
||||
- More accurate and relevant code suggestions
|
||||
- Better alignment with your project's standards and practices
|
||||
- Improved context for new file creation
|
||||
|
||||
Open tabs as context supports these languages:
|
||||
|
||||
- Code Completion: All configured languages.
|
||||
- Code Generation: Go, Java, JavaScript, Kotlin, Python, Ruby, Rust, TypeScript (`.ts` and `.tsx` files),
|
||||
Vue, and YAML.
|
||||
|
||||
## Enable open tabs as context
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Requires GitLab 17.1 or later.
|
||||
- For GitLab self-managed instances, enable the `code_suggestions_context`and the
|
||||
`advanced_context_resolver` [feature flags](../../../feature_flags.md).
|
||||
- GitLab Duo Code Suggestions enabled for your project
|
||||
- For Visual Studio Code, requires the GitLab Workflow extension, version 4.14.2 or later.
|
||||
|
||||
::Tabs
|
||||
|
||||
:::TabTitle Visual Studio Code
|
||||
|
||||
1. Install the [GitLab Workflow extension](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow)
|
||||
from the Visual Studio Marketplace.
|
||||
1. Configure the extension following the
|
||||
[setup instructions](https://gitlab.com/gitlab-org/gitlab-vscode-extension#extension-settings).
|
||||
1. Enable the feature by toggling the `gitlab.aiAssistedCodeSuggestions.enabledSupportedLanguages` setting.
|
||||
|
||||
:::TabTitle JetBrains IDEs
|
||||
|
||||
For installation instructions for JetBrains IDEs, see the
|
||||
[GitLab JetBrains Plugin documentation](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin#toggle-sending-open-tabs-as-context).
|
||||
|
||||
::EndTabs
|
||||
|
||||
When you're ready to start coding:
|
||||
|
||||
1. Open relevant files, including configuration files, to provide better context.
|
||||
1. Close any files you don't want to be used as context.
|
||||
|
||||
## View multiple code suggestions
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/1325) in GitLab 17.1.
|
||||
|
|
|
|||
|
|
@ -612,3 +612,30 @@ Prerequisites:
|
|||
ellipsis (**{ellipsis_v}**) and then select **Remove**.
|
||||
|
||||
Due to the bi-directional relationship, the relationship no longer appears in either item.
|
||||
|
||||
### Add a merge request and automatically close tasks
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/440851) in GitLab 17.3.
|
||||
|
||||
You can set a task to close when a merge request merges.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have at least a Developer role for the project containing the merge request.
|
||||
- You must have at least a Reporter role for the project containing the task.
|
||||
|
||||
1. Edit your merge request.
|
||||
1. In the **Description** box, find and add the task.
|
||||
- Use the [closing pattern](project/issues/managing_issues.md#closing-issues-automatically) that you would for adding a merge request to an issue.
|
||||
- If your task is in the same project as your merge request, you can search for your task by typing <kbd>#</kbd> followed by the task's ID or title.
|
||||
- If your task is in a different project, with a task open, copy the URL from the browser or
|
||||
copy the task's reference by selecting the vertical ellipsis (**{ellipsis_v}**) in the upper-right corner, then **Copy Reference**.
|
||||
|
||||
The merge requests are now visible on the right sidebar, in the **Development** section.
|
||||
|
||||
You must use the exact closing pattern to add the merge request to the task. Other text will not work.
|
||||
|
||||
If [automatic issue closing](project/issues/managing_issues.md#disable-automatic-issue-closing) is enabled in your project settings, the task will be automatically closed when either:
|
||||
|
||||
- The added merge request is merged.
|
||||
- A commit referencing a task with the closing pattern is committed to your project's default branch.
|
||||
|
|
|
|||
|
|
@ -11,13 +11,15 @@ module Banzai
|
|||
#
|
||||
# Extends HTML::Pipeline::SanitizationFilter with common rules.
|
||||
class BaseSanitizationFilter < HTML::Pipeline::SanitizationFilter
|
||||
include Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::TimeoutFilterHandler
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
extend Gitlab::Utils::SanitizeNodeLink
|
||||
|
||||
RENDER_TIMEOUT = 5.seconds
|
||||
|
||||
UNSAFE_PROTOCOLS = %w[data javascript vbscript].freeze
|
||||
|
||||
def call_with_timeout
|
||||
def call
|
||||
Sanitize.clean_node!(doc, allowlist)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# issue: https://gitlab.com/gitlab-org/gitlab/-/issues/454601
|
||||
module Banzai
|
||||
module Filter
|
||||
class BlockquoteFenceLegacyFilter < TimeoutTextPipelineFilter
|
||||
class BlockquoteFenceLegacyFilter < HTML::Pipeline::TextFilter
|
||||
MARKDOWN_CODE_BLOCK_REGEX = %r{
|
||||
(?<code>
|
||||
# Code blocks:
|
||||
|
|
@ -74,7 +74,7 @@ module Banzai
|
|||
super text, context, result
|
||||
end
|
||||
|
||||
def call_with_timeout
|
||||
def call
|
||||
return @text if MarkdownFilter.glfm_markdown?(context)
|
||||
|
||||
@text.gsub(REGEX) do
|
||||
|
|
|
|||
|
|
@ -32,29 +32,30 @@ module Banzai
|
|||
HTML
|
||||
|
||||
def call
|
||||
return call_with_timeout if Gitlab::RenderTimeout.banzai_timeout_disabled?
|
||||
return super if Gitlab::RenderTimeout.banzai_timeout_disabled?
|
||||
|
||||
Gitlab::RenderTimeout.timeout(foreground: render_timeout, background: render_timeout) { call_with_timeout }
|
||||
Gitlab::RenderTimeout.timeout(foreground: render_timeout, background: render_timeout) { super }
|
||||
rescue Timeout::Error => e
|
||||
class_name = self.class.name.demodulize
|
||||
Gitlab::ErrorTracking.track_exception(e, project_id: context[:project]&.id, class_name: class_name)
|
||||
Gitlab::ErrorTracking.track_exception(e, project_id: context[:project]&.id, group_id: context[:group]&.id,
|
||||
class_name: class_name)
|
||||
|
||||
# we've timed out, but some work may have already been completed,
|
||||
# so return what we can
|
||||
returned_timeout_value
|
||||
end
|
||||
|
||||
def call_with_timeout
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_timeout
|
||||
return super if defined?(super)
|
||||
|
||||
RENDER_TIMEOUT
|
||||
end
|
||||
|
||||
def returned_timeout_value
|
||||
return super if defined?(super)
|
||||
|
||||
if is_a?(HTML::Pipeline::TextFilter)
|
||||
text
|
||||
else
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
module Banzai
|
||||
module Filter
|
||||
class CustomEmojiFilter < HTML::Pipeline::Filter
|
||||
include Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::PipelineTimingCheck
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
IGNORED_ANCESTOR_TAGS = %w[pre code tt].to_set
|
||||
|
||||
def call_with_timeout
|
||||
def call
|
||||
return doc unless resource_parent
|
||||
|
||||
doc.xpath('descendant-or-self::text()').each do |node|
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ module Banzai
|
|||
#
|
||||
# Based on HTML::Pipeline::EmojiFilter
|
||||
class EmojiFilter < HTML::Pipeline::Filter
|
||||
include Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::PipelineTimingCheck
|
||||
|
||||
IGNORED_ANCESTOR_TAGS = %w[pre code tt].to_set
|
||||
|
||||
def call_with_timeout
|
||||
def call
|
||||
@emoji_count = 0
|
||||
|
||||
doc.xpath('descendant-or-self::text()').each do |node|
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ module Banzai
|
|||
module Filter
|
||||
# HTML Filter to modify the attributes of external links
|
||||
class ExternalLinkFilter < HTML::Pipeline::Filter
|
||||
include Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::PipelineTimingCheck
|
||||
|
||||
SCHEMES = ['http', 'https', nil].freeze
|
||||
RTLO = "\u202E"
|
||||
ENCODED_RTLO = '%E2%80%AE'
|
||||
|
||||
def call_with_timeout
|
||||
def call
|
||||
links.each do |node|
|
||||
# URI.parse does stricter checking on the url than Addressable,
|
||||
# such as on `mailto:` links. Since we've been using it, do an
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ module Banzai
|
|||
# similar functionality in reference filtering.
|
||||
class AbstractReferenceFilter < ReferenceFilter
|
||||
include CrossProjectReference
|
||||
prepend Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::PipelineTimingCheck
|
||||
|
||||
RENDER_TIMEOUT = 2.seconds
|
||||
|
|
@ -122,64 +123,53 @@ module Banzai
|
|||
def call
|
||||
return doc unless project || group || user
|
||||
|
||||
# protect against certain reference_patterns that are difficult to optimize
|
||||
# against malicious input, such as Commit.reference_pattern
|
||||
Gitlab::RenderTimeout.timeout(foreground: RENDER_TIMEOUT, background: RENDER_TIMEOUT) do
|
||||
reference_cache.load_reference_cache(nodes) if respond_to?(:parent_records) && nodes.present?
|
||||
reference_cache.load_reference_cache(nodes) if respond_to?(:parent_records) && nodes.present?
|
||||
|
||||
ref_pattern = object_reference_pattern
|
||||
link_pattern = object_class.link_reference_pattern
|
||||
ref_pattern = object_reference_pattern
|
||||
link_pattern = object_class.link_reference_pattern
|
||||
|
||||
# Compile often used regexps only once outside of the loop
|
||||
ref_pattern_anchor = /\A#{ref_pattern}\z/
|
||||
link_pattern_start = /\A#{link_pattern}/
|
||||
link_pattern_anchor = /\A#{link_pattern}\z/
|
||||
# Compile often used regexps only once outside of the loop
|
||||
ref_pattern_anchor = /\A#{ref_pattern}\z/
|
||||
link_pattern_start = /\A#{link_pattern}/
|
||||
link_pattern_anchor = /\A#{link_pattern}\z/
|
||||
|
||||
nodes.each_with_index do |node, index|
|
||||
if text_node?(node) && ref_pattern
|
||||
replace_text_when_pattern_matches(node, index, ref_pattern) do |content|
|
||||
object_link_filter(content, ref_pattern)
|
||||
nodes.each_with_index do |node, index|
|
||||
if text_node?(node) && ref_pattern
|
||||
replace_text_when_pattern_matches(node, index, ref_pattern) do |content|
|
||||
object_link_filter(content, ref_pattern)
|
||||
end
|
||||
|
||||
elsif element_node?(node)
|
||||
yield_valid_link(node) do |link, inner_html|
|
||||
if ref_pattern && link =~ ref_pattern_anchor
|
||||
replace_link_node_with_href(node, index, link) do
|
||||
object_link_filter(link, ref_pattern_anchor, link_content: inner_html)
|
||||
end
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
elsif element_node?(node)
|
||||
yield_valid_link(node) do |link, inner_html|
|
||||
if ref_pattern && link =~ ref_pattern_anchor
|
||||
replace_link_node_with_href(node, index, link) do
|
||||
object_link_filter(link, ref_pattern_anchor, link_content: inner_html)
|
||||
end
|
||||
next unless link_pattern
|
||||
|
||||
next
|
||||
if link == inner_html && inner_html =~ link_pattern_start
|
||||
replace_link_node_with_text(node, index) do
|
||||
object_link_filter(inner_html, link_pattern_start, link_reference: true)
|
||||
end
|
||||
|
||||
next unless link_pattern
|
||||
next
|
||||
end
|
||||
|
||||
if link == inner_html && inner_html =~ link_pattern_start
|
||||
replace_link_node_with_text(node, index) do
|
||||
object_link_filter(inner_html, link_pattern_start, link_reference: true)
|
||||
end
|
||||
|
||||
next
|
||||
if link =~ link_pattern_anchor
|
||||
replace_link_node_with_href(node, index, link) do
|
||||
object_link_filter(link, link_pattern_anchor, link_content: inner_html, link_reference: true)
|
||||
end
|
||||
|
||||
if link =~ link_pattern_anchor
|
||||
replace_link_node_with_href(node, index, link) do
|
||||
object_link_filter(link, link_pattern_anchor, link_content: inner_html, link_reference: true)
|
||||
end
|
||||
|
||||
next
|
||||
end
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
doc
|
||||
rescue Timeout::Error => e
|
||||
class_name = self.class.name.demodulize
|
||||
Gitlab::ErrorTracking.track_exception(e, project_id: context[:project]&.id, class_name: class_name)
|
||||
|
||||
# we've timed out, but some work may have already been completed,
|
||||
# so go ahead and return the document
|
||||
doc
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ module Banzai
|
|||
module Filter
|
||||
# HTML Filter to highlight fenced code blocks
|
||||
#
|
||||
class SyntaxHighlightFilter < TimeoutHtmlPipelineFilter
|
||||
class SyntaxHighlightFilter < HTML::Pipeline::Filter
|
||||
prepend Concerns::TimeoutFilterHandler
|
||||
prepend Concerns::PipelineTimingCheck
|
||||
include Concerns::OutputSafety
|
||||
|
||||
|
|
@ -18,7 +19,7 @@ module Banzai
|
|||
CSS = 'pre:not([data-kroki-style]) > code:only-child'
|
||||
XPATH = Gitlab::Utils::Nokogiri.css_to_xpath(CSS).freeze
|
||||
|
||||
def call_with_timeout
|
||||
def call
|
||||
doc.xpath(XPATH).each do |node|
|
||||
highlight_node(node)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Banzai
|
||||
module Filter
|
||||
# HTML Filter that wraps a filter in a Gitlab::RenderTimeout.
|
||||
# This way partial results can be returned, and the entire pipeline
|
||||
# is not killed.
|
||||
#
|
||||
# This should not be used for any filter that must be allowed to complete,
|
||||
# like a `ReferenceRedactorFilter`
|
||||
#
|
||||
class TimeoutHtmlPipelineFilter < HTML::Pipeline::Filter
|
||||
RENDER_TIMEOUT = 10.seconds
|
||||
|
||||
def call
|
||||
Gitlab::RenderTimeout.timeout(foreground: RENDER_TIMEOUT, background: RENDER_TIMEOUT) { call_with_timeout }
|
||||
rescue Timeout::Error => e
|
||||
class_name = self.class.name.demodulize
|
||||
Gitlab::ErrorTracking.track_exception(e, project_id: context[:project]&.id, class_name: class_name)
|
||||
|
||||
# we've timed out, but some work may have already been completed,
|
||||
# so go ahead and return the document
|
||||
doc
|
||||
end
|
||||
|
||||
def call_with_timeout
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Banzai
|
||||
module Filter
|
||||
# Text Filter that wraps a filter in a Gitlab::RenderTimeout.
|
||||
# This way partial results can be returned, and the entire pipeline
|
||||
# is not killed.
|
||||
#
|
||||
# This should not be used for any filter that must be allowed to complete,
|
||||
# like a `ReferenceRedactorFilter`
|
||||
#
|
||||
class TimeoutTextPipelineFilter < HTML::Pipeline::TextFilter
|
||||
RENDER_TIMEOUT = 10.seconds
|
||||
|
||||
def call
|
||||
Gitlab::RenderTimeout.timeout(foreground: RENDER_TIMEOUT, background: RENDER_TIMEOUT) { call_with_timeout }
|
||||
rescue Timeout::Error => e
|
||||
class_name = self.class.name.demodulize
|
||||
Gitlab::ErrorTracking.track_exception(e, project_id: context[:project]&.id, class_name: class_name)
|
||||
|
||||
# we've timed out, but some work may have already been completed,
|
||||
# so go ahead and return the text
|
||||
@text
|
||||
end
|
||||
|
||||
def call_with_timeout
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@ module Gitlab
|
|||
include ::Gitlab::Config::Entry::Attributable
|
||||
|
||||
ALLOWED_KEYS = %i[coverage_format path].freeze
|
||||
SUPPORTED_COVERAGE = %w[cobertura].freeze
|
||||
SUPPORTED_COVERAGE = %w[cobertura jacoco].freeze
|
||||
|
||||
attributes ALLOWED_KEYS
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ module Gitlab
|
|||
cobertura: ::Gitlab::Ci::Parsers::Coverage::Cobertura,
|
||||
terraform: ::Gitlab::Ci::Parsers::Terraform::Tfplan,
|
||||
accessibility: ::Gitlab::Ci::Parsers::Accessibility::Pa11y,
|
||||
jacoco: ::Gitlab::Ci::Parsers::Coverage::Jacoco,
|
||||
codequality: ::Gitlab::Ci::Parsers::Codequality::CodeClimate,
|
||||
sast: ::Gitlab::Ci::Parsers::Security::Sast,
|
||||
secret_detection: ::Gitlab::Ci::Parsers::Security::SecretDetection,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ module Gitlab
|
|||
InvalidXMLError = Class.new(Gitlab::Ci::Parsers::ParserError)
|
||||
InvalidLineInformationError = Class.new(Gitlab::Ci::Parsers::ParserError)
|
||||
|
||||
def parse!(xml_data, coverage_report, project_path: nil, worktree_paths: nil)
|
||||
def parse!(xml_data, coverage_report, project_path: nil, worktree_paths: nil, **_kwargs)
|
||||
Nokogiri::XML::SAX::Parser.new(Documents::CoberturaDocument.new(coverage_report, project_path, worktree_paths)).parse(xml_data)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
module Parsers
|
||||
module Coverage
|
||||
module Documents
|
||||
class JacocoDocument < Nokogiri::XML::SAX::Document
|
||||
PATH_TAGS = %w[group package sourcefile].freeze
|
||||
|
||||
def initialize(coverage_report, merge_request_file_paths)
|
||||
@coverage_report = coverage_report
|
||||
@merge_request_file_paths = merge_request_file_paths
|
||||
|
||||
@current_path_array = []
|
||||
end
|
||||
|
||||
def error(error)
|
||||
raise Jacoco::InvalidXMLError, "XML parsing failed with error: #{error}"
|
||||
end
|
||||
|
||||
def start_element(node_name, attrs = [])
|
||||
return unless node_name
|
||||
|
||||
node_attrs = attrs.to_h
|
||||
|
||||
if PATH_TAGS.include?(node_name) && node_attrs["name"].present?
|
||||
current_path_array << unixify(node_attrs["name"])
|
||||
elsif node_name == 'line'
|
||||
parse_line(node_attrs)
|
||||
end
|
||||
end
|
||||
|
||||
def end_element(node_name)
|
||||
# remove the element from the current path, as if leaving the current directory
|
||||
return unless PATH_TAGS.include?(node_name)
|
||||
|
||||
current_path_array.pop
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_accessor :coverage_report, :merge_request_file_paths,
|
||||
:current_path_array
|
||||
|
||||
def parse_line(node_attrs)
|
||||
coverage_data = { node_attrs.fetch('nr').to_i => node_attrs.fetch('ci').to_i }
|
||||
coverage_report.add_file(matched_full_path, coverage_data)
|
||||
rescue KeyError
|
||||
raise Jacoco::InvalidLineInformationError, "Line information had invalid attributes"
|
||||
end
|
||||
|
||||
def current_path
|
||||
File.join(current_path_array)
|
||||
end
|
||||
|
||||
# Jacoco reports only provide the relative path
|
||||
# so we need to match the files against the ones changed on the MR
|
||||
# and provide the full path in our reports
|
||||
def matched_full_path
|
||||
matched_path = merge_request_file_paths.find do |full_path|
|
||||
full_path.include?(current_path)
|
||||
end
|
||||
|
||||
Gitlab::AppLogger.info(message: "Missing merge request changes for #{current_path}") unless matched_path
|
||||
|
||||
matched_path
|
||||
end
|
||||
|
||||
def unixify(path)
|
||||
path.tr('\\', '/')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Ci
|
||||
module Parsers
|
||||
module Coverage
|
||||
class Jacoco
|
||||
InvalidXMLError = Class.new(Gitlab::Ci::Parsers::ParserError)
|
||||
FeatureDisabledError = Class.new(Gitlab::Ci::Parsers::ParserError)
|
||||
InvalidLineInformationError = Class.new(Gitlab::Ci::Parsers::ParserError)
|
||||
|
||||
def parse!(xml_data, coverage_report, project:, merge_request_paths:, **_kwargs)
|
||||
unless Feature.enabled?(:jacoco_coverage_reports, project)
|
||||
raise FeatureDisabledError, "Feature jacoco_coverage_reports is disabled for project #{project.full_name}"
|
||||
end
|
||||
|
||||
Nokogiri::XML::SAX::Parser.new(Documents::JacocoDocument.new(coverage_report,
|
||||
merge_request_paths)).parse(xml_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -18,6 +18,8 @@ module Gitlab
|
|||
# we are only interested in the coverage report from the root pipeline.
|
||||
return coverage_report if @pipeline.child?
|
||||
|
||||
return coverage_report if merge_request_file_paths.empty?
|
||||
|
||||
coverage_report.tap do |coverage_report|
|
||||
report_builds.find_each do |build|
|
||||
build.each_report(::Ci::JobArtifact.file_types_for_report(:coverage)) do |file_type, blob|
|
||||
|
|
@ -25,7 +27,9 @@ module Gitlab
|
|||
blob,
|
||||
coverage_report,
|
||||
project_path: @pipeline.project.full_path,
|
||||
worktree_paths: @pipeline.all_worktree_paths
|
||||
worktree_paths: @pipeline.all_worktree_paths,
|
||||
merge_request_paths: merge_request_file_paths,
|
||||
project: @pipeline.project
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -37,6 +41,17 @@ module Gitlab
|
|||
def report_builds
|
||||
@pipeline.latest_report_builds_in_self_and_project_descendants(::Ci::JobArtifact.of_report_type(:coverage))
|
||||
end
|
||||
|
||||
def merge_request_file_paths
|
||||
merge_request_paths = Set.new
|
||||
|
||||
@pipeline.merge_requests_as_head_pipeline.each do |merge_request|
|
||||
merge_request_paths += merge_request.modified_paths
|
||||
end
|
||||
|
||||
merge_request_paths
|
||||
end
|
||||
strong_memoize_attr :merge_request_file_paths
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ module QA
|
|||
:import,
|
||||
:import_status,
|
||||
:import_error,
|
||||
:description
|
||||
:description,
|
||||
:created_at
|
||||
|
||||
attribute :group do
|
||||
Group.fabricate! do |group|
|
||||
|
|
@ -577,7 +578,8 @@ module QA
|
|||
:snippets_enabled,
|
||||
:shared_runners_enabled,
|
||||
:request_access_enabled,
|
||||
:avatar_url
|
||||
:avatar_url,
|
||||
:created_at
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ module QA
|
|||
toggle_local_requests(false)
|
||||
end
|
||||
|
||||
it 'integrates and displays build status for MR pipeline in GitLab',
|
||||
it 'integrates and displays build status for MR pipeline in GitLab', :blocking,
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347788' do
|
||||
setup_project_integration
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,16 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :jacoco do
|
||||
file_type { :jacoco }
|
||||
file_format { :gzip }
|
||||
|
||||
after(:build) do |artifact, evaluator|
|
||||
artifact.file = fixture_file_upload(
|
||||
Rails.root.join('spec/fixtures/jacoco/coverage.xml.gz'), 'application/x-gzip')
|
||||
end
|
||||
end
|
||||
|
||||
trait :terraform do
|
||||
file_type { :terraform }
|
||||
file_format { :raw }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.1//EN" "report.dtd">
|
||||
<report name="gitlab-jacoco-coverage-test">
|
||||
<sessioninfo id="runner--azerasq-project-36665609-concurrent-0-54d28570" start="1654178605407" dump="1654178652125" />
|
||||
<package name="org/acme">
|
||||
<class name="org/acme/ExampleResource" sourcefilename="ExampleResource.java">
|
||||
<method name="<init>" desc="()V" line="9">
|
||||
<counter type="INSTRUCTION" missed="0" covered="3" />
|
||||
<counter type="LINE" missed="0" covered="1" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="1" />
|
||||
<counter type="METHOD" missed="0" covered="1" />
|
||||
</method>
|
||||
<method name="hello" desc="()Ljava/lang/String;" line="14">
|
||||
<counter type="INSTRUCTION" missed="0" covered="2" />
|
||||
<counter type="LINE" missed="0" covered="1" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="1" />
|
||||
<counter type="METHOD" missed="0" covered="1" />
|
||||
</method>
|
||||
<counter type="INSTRUCTION" missed="0" covered="5" />
|
||||
<counter type="LINE" missed="0" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="2" />
|
||||
<counter type="METHOD" missed="0" covered="2" />
|
||||
<counter type="CLASS" missed="0" covered="1" />
|
||||
</class>
|
||||
<class name="org/acme/AnotherResource" sourcefilename="AnotherResource.java">
|
||||
<method name="<init>" desc="()V" line="9">
|
||||
<counter type="INSTRUCTION" missed="3" covered="0" />
|
||||
<counter type="LINE" missed="1" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="1" covered="0" />
|
||||
</counter type="METHOD" missed="1" covered="0" />
|
||||
</method>
|
||||
<method name="coucou" desc="()Ljava/lang/String;" line="14">
|
||||
<counter type="INSTRUCTION" missed="2" covered="0" />
|
||||
<counter type="LINE" missed="1" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="1" covered="0" />
|
||||
<counter type="METHOD" missed="1" covered="0" />
|
||||
</method>
|
||||
<counter type="INSTRUCTION" missed="5" covered="0" />
|
||||
<counter type="LINE" missed="2" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="0" />
|
||||
<counter type="METHOD" missed="2" covered="0" />
|
||||
<counter type="CLASS" missed="1" covered="0" />
|
||||
</class>
|
||||
<sourcefile name="AnotherResource.java">
|
||||
<line nr="9" mi="3" ci="0" mb="0" cb="0" />
|
||||
<line nr="14" mi="2" ci="0" mb="0" cb="0" />
|
||||
<counter type="INSTRUCTION" missed="5" covered="0" />
|
||||
<counter type="LINE" missed="2" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="0" />
|
||||
<counter type="METHOD" missed="2" covered="0" />
|
||||
<counter type="CLASS" missed="1" covered="0" />
|
||||
</sourcefile>
|
||||
<sourcefile name="ExampleResource.java">
|
||||
<line mi="0" mb="0" cb="0" />
|
||||
<lad nr="14" mi="0" mb="0" cb="0" />
|
||||
<counter type="INSTRUCTION" missed="0" covered="5" />
|
||||
<counter type="LINE" missed="0" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="2" />
|
||||
<counter type="METHOD" missed="0" covered="2" />
|
||||
<counter type="CLASS" missed="0" covered="1" />
|
||||
</sourcefile>
|
||||
<counter type="INSTRUCTION" missed="5" covered="5" />
|
||||
<counter type="LINE" missed="2" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="2" />
|
||||
<counter type="METHOD" missed="2" covered="2" />
|
||||
<counter type="CLASS" missed="1" covered="1" />
|
||||
</package>
|
||||
<counter type="INSTRUCTION" missed="5" covered="5" />
|
||||
<counter type="LINE" missed="2" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="2" />
|
||||
<counter type="METHOD" missed="2" covered="2" />
|
||||
<counter type="CLASS" missed="1" covered="1" />
|
||||
</report>
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.1//EN" "report.dtd">
|
||||
<report name="gitlab-jacoco-coverage-test">
|
||||
<sessioninfo id="runner--azerasq-project-36665609-concurrent-0-54d28570" start="1654178605407" dump="1654178652125" />
|
||||
<package name="org/acme">
|
||||
<class name="org/acme/ExampleResource" sourcefilename="ExampleResource.java">
|
||||
<method name="<init>" desc="()V" line="9">
|
||||
<counter type="INSTRUCTION" missed="0" covered="3" />
|
||||
<counter type="LINE" missed="0" covered="1" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="1" />
|
||||
<counter type="METHOD" missed="0" covered="1" />
|
||||
</method>
|
||||
<method name="hello" desc="()Ljava/lang/String;" line="14">
|
||||
<counter type="INSTRUCTION" missed="0" covered="2" />
|
||||
<counter type="LINE" missed="0" covered="1" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="1" />
|
||||
<counter type="METHOD" missed="0" covered="1" />
|
||||
</method>
|
||||
<counter type="INSTRUCTION" missed="0" covered="5" />
|
||||
<counter type="LINE" missed="0" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="2" />
|
||||
<counter type="METHOD" missed="0" covered="2" />
|
||||
<counter type="CLASS" missed="0" covered="1" />
|
||||
</class>
|
||||
<class name="org/acme/AnotherResource" sourcefilename="AnotherResource.java">
|
||||
<method name="<init>" desc="()V" line="9">
|
||||
<counter type="INSTRUCTION" missed="3" covered="0" />
|
||||
<counter type="LINE" missed="1" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="1" covered="0" />
|
||||
<counter type="METHOD" missed="1" covered="0" />
|
||||
</method>
|
||||
<method name="coucou" desc="()Ljava/lang/String;" line="14">
|
||||
<counter type="INSTRUCTION" missed="2" covered="0" />
|
||||
<counter type="LINE" missed="1" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="1" covered="0" />
|
||||
<counter type="METHOD" missed="1" covered="0" />
|
||||
</method>
|
||||
<counter type="INSTRUCTION" missed="5" covered="0" />
|
||||
<counter type="LINE" missed="2" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="0" />
|
||||
<counter type="METHOD" missed="2" covered="0" />
|
||||
<counter type="CLASS" missed="1" covered="0" />
|
||||
</class>
|
||||
<sourcefile name="AnotherResource.java">
|
||||
<line nr="9" mi="3" ci="0" mb="0" cb="0" />
|
||||
<line nr="14" mi="2" ci="0" mb="0" cb="0" />
|
||||
<counter type="INSTRUCTION" missed="5" covered="0" />
|
||||
<counter type="LINE" missed="2" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="0" />
|
||||
<counter type="METHOD" missed="2" covered="0" />
|
||||
<counter type="CLASS" missed="1" covered="0" />
|
||||
</sourcefile>
|
||||
<sourcefile name="ExampleResource.java">
|
||||
<line mi="0" mb="0" cb="0" />
|
||||
<line nr="14" mi="0" mb="0" cb="0" />
|
||||
<counter type="INSTRUCTION" missed="0" covered="5" />
|
||||
<counter type="LINE" missed="0" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="2" />
|
||||
<counter type="METHOD" missed="0" covered="2" />
|
||||
<counter type="CLASS" missed="0" covered="1" />
|
||||
</sourcefile>
|
||||
<counter type="INSTRUCTION" missed="5" covered="5" />
|
||||
<counter type="LINE" missed="2" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="2" />
|
||||
<counter type="METHOD" missed="2" covered="2" />
|
||||
<counter type="CLASS" missed="1" covered="1" />
|
||||
</package>
|
||||
<counter type="INSTRUCTION" missed="5" covered="5" />
|
||||
<counter type="LINE" missed="2" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="2" />
|
||||
<counter type="METHOD" missed="2" covered="2" />
|
||||
<counter type="CLASS" missed="1" covered="1" />
|
||||
</report>
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.1//EN" "report.dtd">
|
||||
<report name="gitlab-jacoco-coverage-test">
|
||||
<sessioninfo id="runner--azerasq-project-36665609-concurrent-0-54d28570" start="1654178605407" dump="1654178652125" />
|
||||
<package name="org/acme">
|
||||
<class name="org/acme/ExampleResource" sourcefilename="ExampleResource.java">
|
||||
<method name="<init>" desc="()V" line="9">
|
||||
<counter type="INSTRUCTION" missed="0" covered="3" />
|
||||
<counter type="LINE" missed="0" covered="1" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="1" />
|
||||
<counter type="METHOD" missed="0" covered="1" />
|
||||
</method>
|
||||
<method name="hello" desc="()Ljava/lang/String;" line="14">
|
||||
<counter type="INSTRUCTION" missed="0" covered="2" />
|
||||
<counter type="LINE" missed="0" covered="1" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="1" />
|
||||
<counter type="METHOD" missed="0" covered="1" />
|
||||
</method>
|
||||
<counter type="INSTRUCTION" missed="0" covered="5" />
|
||||
<counter type="LINE" missed="0" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="2" />
|
||||
<counter type="METHOD" missed="0" covered="2" />
|
||||
<counter type="CLASS" missed="0" covered="1" />
|
||||
</class>
|
||||
<class name="org/acme/AnotherResource" sourcefilename="AnotherResource.java">
|
||||
<method name="<init>" desc="()V" line="9">
|
||||
<counter type="INSTRUCTION" missed="3" covered="0" />
|
||||
<counter type="LINE" missed="1" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="1" covered="0" />
|
||||
<counter type="METHOD" missed="1" covered="0" />
|
||||
</method>
|
||||
<method name="coucou" desc="()Ljava/lang/String;" line="14">
|
||||
<counter type="INSTRUCTION" missed="2" covered="0" />
|
||||
<counter type="LINE" missed="1" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="1" covered="0" />
|
||||
<counter type="METHOD" missed="1" covered="0" />
|
||||
</method>
|
||||
<counter type="INSTRUCTION" missed="5" covered="0" />
|
||||
<counter type="LINE" missed="2" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="0" />
|
||||
<counter type="METHOD" missed="2" covered="0" />
|
||||
<counter type="CLASS" missed="1" covered="0" />
|
||||
</class>
|
||||
<sourcefile name="AnotherResource.java">
|
||||
<line nr="9" mi="3" ci="0" mb="0" cb="0" />
|
||||
<line nr="14" mi="2" ci="0" mb="0" cb="0" />
|
||||
<counter type="INSTRUCTION" missed="5" covered="0" />
|
||||
<counter type="LINE" missed="2" covered="0" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="0" />
|
||||
<counter type="METHOD" missed="2" covered="0" />
|
||||
<counter type="CLASS" missed="1" covered="0" />
|
||||
</sourcefile>
|
||||
<sourcefile name="ExampleResource.java">
|
||||
<line nr="9" mi="0" ci="3" mb="0" cb="0" />
|
||||
<line nr="14" mi="0" ci="2" mb="0" cb="0" />
|
||||
<counter type="INSTRUCTION" missed="0" covered="5" />
|
||||
<counter type="LINE" missed="0" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="0" covered="2" />
|
||||
<counter type="METHOD" missed="0" covered="2" />
|
||||
<counter type="CLASS" missed="0" covered="1" />
|
||||
</sourcefile>
|
||||
<counter type="INSTRUCTION" missed="5" covered="5" />
|
||||
<counter type="LINE" missed="2" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="2" />
|
||||
<counter type="METHOD" missed="2" covered="2" />
|
||||
<counter type="CLASS" missed="1" covered="1" />
|
||||
</package>
|
||||
<counter type="INSTRUCTION" missed="5" covered="5" />
|
||||
<counter type="LINE" missed="2" covered="2" />
|
||||
<counter type="COMPLEXITY" missed="2" covered="2" />
|
||||
<counter type="METHOD" missed="2" covered="2" />
|
||||
<counter type="CLASS" missed="1" covered="1" />
|
||||
</report>
|
||||
|
|
@ -3,23 +3,20 @@ import Vue, { nextTick } from 'vue';
|
|||
import Vuex from 'vuex';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { GlTab, GlTabs, GlModal } from '@gitlab/ui';
|
||||
import { createAlert } from '~/alert';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { stubComponent, RENDER_ALL_SLOTS_TEMPLATE } from 'helpers/stub_component';
|
||||
import PlaceholdersTabApp from '~/members/placeholders/components/app.vue';
|
||||
import PlaceholdersTable from '~/members/placeholders/components/placeholders_table.vue';
|
||||
import CsvUploadModal from '~/members/placeholders/components/csv_upload_modal.vue';
|
||||
import importSourceUsersQuery from '~/members/placeholders/graphql/queries/import_source_users.query.graphql';
|
||||
import { MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import {
|
||||
mockSourceUsersQueryResponse,
|
||||
mockSourceUsersFailedStatusResponse,
|
||||
mockSourceUsers,
|
||||
pagination,
|
||||
} from '../mock_data';
|
||||
PLACEHOLDER_STATUS_FAILED,
|
||||
QUERY_PARAM_FAILED,
|
||||
PLACEHOLDER_USER_STATUS,
|
||||
} from '~/import_entities/import_groups/constants';
|
||||
import { mockSourceUsersQueryResponse, mockSourceUsers, pagination } from '../mock_data';
|
||||
|
||||
Vue.use(Vuex);
|
||||
Vue.use(VueApollo);
|
||||
|
|
@ -30,15 +27,16 @@ describe('PlaceholdersTabApp', () => {
|
|||
let store;
|
||||
let mockApollo;
|
||||
|
||||
const mockGroup = {
|
||||
path: 'imported-group',
|
||||
name: 'Imported group',
|
||||
};
|
||||
const sourceUsersQueryHandler = jest.fn().mockResolvedValue(mockSourceUsersQueryResponse());
|
||||
const $toast = {
|
||||
show: jest.fn(),
|
||||
};
|
||||
|
||||
const mockGroup = {
|
||||
path: 'imported-group',
|
||||
name: 'Imported group',
|
||||
};
|
||||
|
||||
const createComponent = ({
|
||||
queryHandler = sourceUsersQueryHandler,
|
||||
mountFn = shallowMountExtended,
|
||||
|
|
@ -60,8 +58,8 @@ describe('PlaceholdersTabApp', () => {
|
|||
apolloProvider: mockApollo,
|
||||
store,
|
||||
provide: {
|
||||
group: mockGroup,
|
||||
reassignmentCsvDownloadPath: 'foo/bar',
|
||||
group: mockGroup,
|
||||
},
|
||||
mocks: { $toast },
|
||||
stubs: {
|
||||
|
|
@ -78,7 +76,8 @@ describe('PlaceholdersTabApp', () => {
|
|||
|
||||
const findTabs = () => wrapper.findComponent(GlTabs);
|
||||
const findTabAt = (index) => wrapper.findAllComponents(GlTab).at(index);
|
||||
const findPlaceholdersTable = () => wrapper.findComponent(PlaceholdersTable);
|
||||
const findUnassignedTable = () => wrapper.findByTestId('placeholders-table-unassigned');
|
||||
const findReassignedTable = () => wrapper.findByTestId('placeholders-table-reassigned');
|
||||
const findReassignCsvButton = () => wrapper.findByTestId('reassign-csv-button');
|
||||
const findCsvModal = () => wrapper.findComponent(CsvUploadModal);
|
||||
|
||||
|
|
@ -105,7 +104,7 @@ describe('PlaceholdersTabApp', () => {
|
|||
createComponent();
|
||||
await nextTick();
|
||||
|
||||
findPlaceholdersTable().vm.$emit('confirm', mockSourceUser);
|
||||
findUnassignedTable().vm.$emit('confirm', mockSourceUser);
|
||||
await nextTick();
|
||||
});
|
||||
|
||||
|
|
@ -123,152 +122,40 @@ describe('PlaceholdersTabApp', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when sourceUsers query is loading', () => {
|
||||
it('renders placeholders table as loading', () => {
|
||||
describe('passes the correct queryStatuses to PlaceholdersTable', () => {
|
||||
it('awaiting Reassignment - when the url includes the query param failed', () => {
|
||||
setWindowLocation(`?status=${QUERY_PARAM_FAILED}`);
|
||||
createComponent();
|
||||
|
||||
expect(findPlaceholdersTable().props('isLoading')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when sourceUsers query fails', () => {
|
||||
beforeEach(async () => {
|
||||
const sourceUsersFailedQueryHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
|
||||
|
||||
createComponent({
|
||||
queryHandler: sourceUsersFailedQueryHandler,
|
||||
});
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('creates an alert', () => {
|
||||
expect(createAlert).toHaveBeenCalledWith({
|
||||
message: 'There was a problem fetching placeholder users.',
|
||||
const placeholdersTable = findUnassignedTable();
|
||||
expect(placeholdersTable.props()).toMatchObject({
|
||||
queryStatuses: [PLACEHOLDER_STATUS_FAILED],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when sourceUsers query succeeds', () => {
|
||||
beforeEach(async () => {
|
||||
it('awaiting Reassignment - when the url does not include query param', () => {
|
||||
createComponent();
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('fetches sourceUsers', () => {
|
||||
expect(sourceUsersQueryHandler).toHaveBeenCalledTimes(1);
|
||||
expect(sourceUsersQueryHandler).toHaveBeenCalledWith({
|
||||
after: null,
|
||||
before: null,
|
||||
fullPath: mockGroup.path,
|
||||
first: 20,
|
||||
statuses: [],
|
||||
const placeholdersTable = findUnassignedTable();
|
||||
expect(placeholdersTable.props()).toMatchObject({
|
||||
queryStatuses: PLACEHOLDER_USER_STATUS.UNASSIGNED,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders placeholders table', () => {
|
||||
const sourceUsers = mockSourceUsersQueryResponse().data.namespace.importSourceUsers;
|
||||
it('reassigned', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findPlaceholdersTable().props()).toMatchObject({
|
||||
isLoading: false,
|
||||
items: sourceUsers.nodes,
|
||||
pageInfo: sourceUsers.pageInfo,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when sourceUsers query succeeds and has pagination', () => {
|
||||
const sourceUsersPaginatedQueryHandler = jest.fn();
|
||||
const mockPageInfo = {
|
||||
endCursor: 'end834',
|
||||
hasNextPage: true,
|
||||
hasPreviousPage: true,
|
||||
startCursor: 'start971',
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
sourceUsersPaginatedQueryHandler
|
||||
.mockResolvedValueOnce(mockSourceUsersQueryResponse({ pageInfo: mockPageInfo }))
|
||||
.mockResolvedValueOnce(mockSourceUsersQueryResponse());
|
||||
|
||||
createComponent({
|
||||
queryHandler: sourceUsersPaginatedQueryHandler,
|
||||
});
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
describe('when "prev" event is emitted', () => {
|
||||
beforeEach(() => {
|
||||
findPlaceholdersTable().vm.$emit('prev');
|
||||
});
|
||||
|
||||
it('fetches sourceUsers with previous results', () => {
|
||||
expect(sourceUsersPaginatedQueryHandler).toHaveBeenCalledTimes(2);
|
||||
expect(sourceUsersPaginatedQueryHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
after: null,
|
||||
before: mockPageInfo.startCursor,
|
||||
last: 20,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "next" event is emitted', () => {
|
||||
beforeEach(() => {
|
||||
findPlaceholdersTable().vm.$emit('next');
|
||||
});
|
||||
|
||||
it('fetches sourceUsers with next results', () => {
|
||||
expect(sourceUsersPaginatedQueryHandler).toHaveBeenCalledTimes(2);
|
||||
expect(sourceUsersPaginatedQueryHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
after: mockPageInfo.endCursor,
|
||||
before: null,
|
||||
first: 20,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('correctly filters users', () => {
|
||||
const sourceUsersFailureQueryHandler = jest
|
||||
.fn()
|
||||
.mockResolvedValue(mockSourceUsersFailedStatusResponse);
|
||||
|
||||
beforeEach(async () => {
|
||||
setWindowLocation('?status=failed');
|
||||
|
||||
createComponent({ queryHandler: sourceUsersFailureQueryHandler });
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('when the url includes the query param failed', () => {
|
||||
const sourceUsersWithFailedStatus =
|
||||
mockSourceUsersFailedStatusResponse.data.namespace.importSourceUsers;
|
||||
const tableProps = findPlaceholdersTable().props();
|
||||
|
||||
expect(findPlaceholdersTable().props()).toMatchObject({
|
||||
isLoading: false,
|
||||
items: sourceUsersWithFailedStatus.nodes,
|
||||
pageInfo: sourceUsersWithFailedStatus.pageInfo,
|
||||
});
|
||||
expect(tableProps.items.length).toBe(1);
|
||||
expect(tableProps.items[0].status).toBe('FAILED');
|
||||
expect(sourceUsersFailureQueryHandler).toHaveBeenCalledTimes(1);
|
||||
expect(sourceUsersFailureQueryHandler).toHaveBeenCalledWith({
|
||||
after: null,
|
||||
before: null,
|
||||
fullPath: mockGroup.path,
|
||||
first: 20,
|
||||
statuses: ['FAILED'],
|
||||
const placeholdersTable = findReassignedTable();
|
||||
expect(placeholdersTable.props()).toMatchObject({
|
||||
reassigned: true,
|
||||
queryStatuses: PLACEHOLDER_USER_STATUS.REASSIGNED,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reassign CSV button', () => {
|
||||
it('renders the button and the modal', () => {
|
||||
createComponent();
|
||||
createComponent({ mountFn: mountExtended });
|
||||
|
||||
expect(findReassignCsvButton().exists()).toBe(true);
|
||||
expect(findCsvModal().exists()).toBe(true);
|
||||
|
|
@ -276,7 +163,6 @@ describe('PlaceholdersTabApp', () => {
|
|||
|
||||
it('shows modal when button is clicked', async () => {
|
||||
createComponent({ mountFn: mountExtended });
|
||||
|
||||
findReassignCsvButton().trigger('click');
|
||||
|
||||
await nextTick();
|
||||
|
|
|
|||
|
|
@ -1,27 +1,58 @@
|
|||
import Vue from 'vue';
|
||||
import Vue, { nextTick } from 'vue';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import Vuex from 'vuex';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { mount, shallowMount } from '@vue/test-utils';
|
||||
import { GlAvatarLabeled, GlBadge, GlKeysetPagination, GlLoadingIcon, GlTable } from '@gitlab/ui';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import { stubComponent } from 'helpers/stub_component';
|
||||
|
||||
import PlaceholdersTable from '~/members/placeholders/components/placeholders_table.vue';
|
||||
import PlaceholderActions from '~/members/placeholders/components/placeholder_actions.vue';
|
||||
import { mockSourceUsers } from '../mock_data';
|
||||
import { createAlert } from '~/alert';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
|
||||
import {
|
||||
PLACEHOLDER_STATUS_FAILED,
|
||||
QUERY_PARAM_FAILED,
|
||||
PLACEHOLDER_USER_STATUS,
|
||||
} from '~/import_entities/import_groups/constants';
|
||||
|
||||
import importSourceUsersQuery from '~/members/placeholders/graphql/queries/import_source_users.query.graphql';
|
||||
import { mockSourceUsersQueryResponse, mockSourceUsers } from '../mock_data';
|
||||
|
||||
Vue.use(Vuex);
|
||||
Vue.use(VueApollo);
|
||||
jest.mock('~/alert');
|
||||
|
||||
describe('PlaceholdersTable', () => {
|
||||
let wrapper;
|
||||
let mockApollo;
|
||||
|
||||
const defaultProps = {
|
||||
isLoading: false,
|
||||
items: mockSourceUsers,
|
||||
const mockGroup = {
|
||||
path: 'imported-group',
|
||||
name: 'Imported group',
|
||||
};
|
||||
|
||||
const createComponent = ({ mountFn = shallowMount, props = {} } = {}) => {
|
||||
mockApollo = createMockApollo();
|
||||
const defaultProps = {
|
||||
queryStatuses: PLACEHOLDER_USER_STATUS.UNASSIGNED,
|
||||
reassigned: false,
|
||||
};
|
||||
|
||||
const sourceUsersQueryHandler = jest.fn().mockResolvedValue(mockSourceUsersQueryResponse());
|
||||
const $toast = {
|
||||
show: jest.fn(),
|
||||
};
|
||||
|
||||
const createComponent = ({
|
||||
mountFn = shallowMount,
|
||||
queryHandler = sourceUsersQueryHandler,
|
||||
props = {},
|
||||
options = {},
|
||||
} = {}) => {
|
||||
mockApollo = createMockApollo([[importSourceUsersQuery, queryHandler]]);
|
||||
|
||||
wrapper = mountFn(PlaceholdersTable, {
|
||||
apolloProvider: mockApollo,
|
||||
|
|
@ -29,9 +60,14 @@ describe('PlaceholdersTable', () => {
|
|||
...defaultProps,
|
||||
...props,
|
||||
},
|
||||
provide: {
|
||||
group: mockGroup,
|
||||
},
|
||||
mocks: { $toast },
|
||||
directives: {
|
||||
GlTooltip: createMockDirective('gl-tooltip'),
|
||||
},
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -44,111 +80,135 @@ describe('PlaceholdersTable', () => {
|
|||
.props('fields')
|
||||
.map((f) => f.label);
|
||||
|
||||
it('renders table', () => {
|
||||
createComponent({ mountFn: mount });
|
||||
|
||||
expect(findTable().exists()).toBe(true);
|
||||
expect(findTableRows().length).toBe(mockSourceUsers.length);
|
||||
expect(findTableFields()).toEqual([
|
||||
'Placeholder user',
|
||||
'Source',
|
||||
'Reassignment status',
|
||||
'Reassign placeholder to',
|
||||
]);
|
||||
});
|
||||
|
||||
it('renders loading icon when table is loading', () => {
|
||||
createComponent({
|
||||
props: { isLoading: true },
|
||||
});
|
||||
|
||||
expect(findLoadingIcon().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders avatar for placeholder user', () => {
|
||||
createComponent({ mountFn: mount });
|
||||
|
||||
const avatar = findTableRows().at(0).findComponent(GlAvatarLabeled);
|
||||
const { placeholderUser } = mockSourceUsers[0];
|
||||
|
||||
expect(avatar.props()).toMatchObject({
|
||||
label: placeholderUser.name,
|
||||
subLabel: `@${placeholderUser.username}`,
|
||||
});
|
||||
expect(avatar.attributes('src')).toBe(placeholderUser.avatarUrl);
|
||||
});
|
||||
|
||||
it('renders source info', () => {
|
||||
createComponent({ mountFn: mount });
|
||||
|
||||
expect(findTableRows().at(0).text()).toContain(mockSourceUsers[0].sourceHostname);
|
||||
expect(findTableRows().at(0).text()).toContain(mockSourceUsers[0].sourceUsername);
|
||||
});
|
||||
|
||||
it('renders status badge with tooltip', () => {
|
||||
createComponent({ mountFn: mount });
|
||||
|
||||
const firstRow = findTableRows().at(0);
|
||||
const badge = firstRow.findComponent(GlBadge);
|
||||
const badgeTooltip = getBinding(badge.element, 'gl-tooltip');
|
||||
|
||||
expect(badge.text()).toBe('Not started');
|
||||
expect(badgeTooltip.value).toBe('Reassignment has not started.');
|
||||
});
|
||||
|
||||
it('renders actions when item is not reassigned', () => {
|
||||
createComponent({ mountFn: mount });
|
||||
|
||||
const firstRow = findTableRows().at(0);
|
||||
const actions = firstRow.findComponent(PlaceholderActions);
|
||||
|
||||
expect(actions.props('sourceUser')).toEqual(mockSourceUsers[0]);
|
||||
});
|
||||
|
||||
it('renders avatar for placeholderUser when item status is KEEP_AS_PLACEHOLDER', () => {
|
||||
createComponent({ mountFn: mount });
|
||||
|
||||
const reassignedItemRow = findTableRows().at(5);
|
||||
const actionsAvatar = reassignedItemRow.findAllComponents(GlAvatarLabeled).at(1);
|
||||
const { placeholderUser } = mockSourceUsers[5];
|
||||
|
||||
expect(actionsAvatar.props()).toMatchObject({
|
||||
label: placeholderUser.name,
|
||||
subLabel: `@${placeholderUser.username}`,
|
||||
describe('when sourceUsers query is loading', () => {
|
||||
it('renders table as loading', () => {
|
||||
createComponent();
|
||||
expect(findLoadingIcon().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders avatar for reassignToUser when item status is COMPLETED', () => {
|
||||
createComponent({ mountFn: mount });
|
||||
describe('when sourceUsers query fails', () => {
|
||||
beforeEach(async () => {
|
||||
const sourceUsersFailedQueryHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
|
||||
|
||||
const reassignedItemRow = findTableRows().at(6);
|
||||
const actionsAvatar = reassignedItemRow.findAllComponents(GlAvatarLabeled).at(1);
|
||||
const { reassignToUser } = mockSourceUsers[6];
|
||||
|
||||
expect(actionsAvatar.props()).toMatchObject({
|
||||
label: reassignToUser.name,
|
||||
subLabel: `@${reassignToUser.username}`,
|
||||
});
|
||||
});
|
||||
|
||||
describe('when is "Re-assigned" table variant', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
props: {
|
||||
reassigned: true,
|
||||
},
|
||||
queryHandler: sourceUsersFailedQueryHandler,
|
||||
});
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('creates an alert', () => {
|
||||
expect(createAlert).toHaveBeenCalledWith({
|
||||
message: 'There was a problem fetching placeholder users.',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when sourceUsers query succeeds', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
mountFn: mount,
|
||||
});
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('fetches sourceUsers', () => {
|
||||
expect(sourceUsersQueryHandler).toHaveBeenCalledTimes(1);
|
||||
expect(sourceUsersQueryHandler).toHaveBeenCalledWith({
|
||||
after: null,
|
||||
before: null,
|
||||
fullPath: mockGroup.path,
|
||||
first: 20,
|
||||
statuses: PLACEHOLDER_USER_STATUS.UNASSIGNED,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders table', () => {
|
||||
expect(findTable().exists()).toBe(true);
|
||||
it('renders table', async () => {
|
||||
await waitForPromises();
|
||||
expect(findLoadingIcon().exists()).toBe(false);
|
||||
expect(findTableRows()).toHaveLength(mockSourceUsers.length);
|
||||
|
||||
expect(findTableFields()).toEqual([
|
||||
'Placeholder user',
|
||||
'Source',
|
||||
'Reassignment status',
|
||||
'Reassigned to',
|
||||
'Reassign placeholder to',
|
||||
]);
|
||||
});
|
||||
|
||||
it('renders avatar for placeholder user', async () => {
|
||||
await waitForPromises();
|
||||
|
||||
const avatar = findTableRows().at(0).findComponent(GlAvatarLabeled);
|
||||
const { placeholderUser } = mockSourceUsers[0];
|
||||
|
||||
expect(avatar.props()).toMatchObject({
|
||||
label: placeholderUser.name,
|
||||
subLabel: `@${placeholderUser.username}`,
|
||||
});
|
||||
expect(avatar.attributes('src')).toBe(placeholderUser.avatarUrl);
|
||||
});
|
||||
|
||||
it('renders source info', async () => {
|
||||
await waitForPromises();
|
||||
|
||||
expect(findTableRows().at(0).text()).toContain(mockSourceUsers[0].sourceHostname);
|
||||
expect(findTableRows().at(0).text()).toContain(mockSourceUsers[0].sourceUsername);
|
||||
});
|
||||
|
||||
it('renders status badge with tooltip', async () => {
|
||||
await waitForPromises();
|
||||
|
||||
const firstRow = findTableRows().at(0);
|
||||
const badge = firstRow.findComponent(GlBadge);
|
||||
const badgeTooltip = getBinding(badge.element, 'gl-tooltip');
|
||||
|
||||
expect(badge.text()).toBe('Not started');
|
||||
expect(badgeTooltip.value).toBe('Reassignment has not started.');
|
||||
});
|
||||
|
||||
it('renders avatar for placeholderUser when item status is KEEP_AS_PLACEHOLDER', async () => {
|
||||
await waitForPromises();
|
||||
|
||||
const reassignedItemRow = findTableRows().at(5);
|
||||
const actionsAvatar = reassignedItemRow.findAllComponents(GlAvatarLabeled).at(1);
|
||||
const { placeholderUser } = mockSourceUsers[5];
|
||||
|
||||
expect(actionsAvatar.props()).toMatchObject({
|
||||
label: placeholderUser.name,
|
||||
subLabel: `@${placeholderUser.username}`,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders actions when item is not reassigned', async () => {
|
||||
await waitForPromises();
|
||||
|
||||
const firstRow = findTableRows().at(0);
|
||||
const actions = firstRow.findComponent(PlaceholderActions);
|
||||
|
||||
expect(actions.props('sourceUser')).toEqual(mockSourceUsers[0]);
|
||||
});
|
||||
|
||||
it('renders avatar for reassignToUser when item status is COMPLETED', async () => {
|
||||
await waitForPromises();
|
||||
|
||||
const reassignedItemRow = findTableRows().at(6);
|
||||
const actionsAvatar = reassignedItemRow.findAllComponents(GlAvatarLabeled).at(1);
|
||||
const { reassignToUser } = mockSourceUsers[6];
|
||||
|
||||
expect(actionsAvatar.props()).toMatchObject({
|
||||
label: reassignToUser.name,
|
||||
subLabel: `@${reassignToUser.username}`,
|
||||
});
|
||||
});
|
||||
|
||||
it('table actions emit "confirm" event with item', () => {
|
||||
const actions = findTableRows().at(2).findComponent(PlaceholderActions);
|
||||
|
||||
actions.vm.$emit('confirm');
|
||||
|
||||
expect(wrapper.emitted('confirm')[0]).toEqual([mockSourceUsers[2]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('pagination', () => {
|
||||
|
|
@ -161,63 +221,149 @@ describe('PlaceholdersTable', () => {
|
|||
`(
|
||||
'when hasNextPage=$hasNextPage and hasPreviousPage=$hasPreviousPage',
|
||||
({ hasNextPage, hasPreviousPage, expectPagination }) => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
props: {
|
||||
beforeEach(async () => {
|
||||
const customHandler = jest.fn().mockResolvedValue(
|
||||
mockSourceUsersQueryResponse({
|
||||
pageInfo: {
|
||||
hasNextPage,
|
||||
hasPreviousPage,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
createComponent({
|
||||
queryHandler: customHandler,
|
||||
});
|
||||
await nextTick();
|
||||
});
|
||||
|
||||
it(`${expectPagination ? 'renders' : 'does not render'} pagination`, () => {
|
||||
expect(findPagination().exists()).toBe(expectPagination);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it('emits "prev" event', () => {
|
||||
createComponent({
|
||||
props: {
|
||||
pageInfo: {
|
||||
hasPreviousPage: true,
|
||||
},
|
||||
},
|
||||
describe('buttons', () => {
|
||||
const mockPageInfo = {
|
||||
endCursor: 'end834',
|
||||
hasNextPage: true,
|
||||
hasPreviousPage: true,
|
||||
startCursor: 'start971',
|
||||
};
|
||||
const customHandler = jest.fn().mockResolvedValue(
|
||||
mockSourceUsersQueryResponse({
|
||||
pageInfo: mockPageInfo,
|
||||
}),
|
||||
);
|
||||
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
mountFn: mount,
|
||||
queryHandler: customHandler,
|
||||
});
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
findPagination().vm.$emit('prev');
|
||||
|
||||
expect(wrapper.emitted('prev')[0]).toEqual([]);
|
||||
});
|
||||
|
||||
it('emits "next" event', () => {
|
||||
createComponent({
|
||||
props: {
|
||||
pageInfo: {
|
||||
hasNextPage: true,
|
||||
},
|
||||
},
|
||||
it('requests the next page on "prev" click with the correct data', async () => {
|
||||
const paginated = findPagination();
|
||||
await paginated.vm.$emit('prev');
|
||||
expect(customHandler).toHaveBeenCalledTimes(2);
|
||||
expect(customHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
after: null,
|
||||
before: mockPageInfo.startCursor,
|
||||
last: 20,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
findPagination().vm.$emit('next');
|
||||
|
||||
expect(wrapper.emitted('next')[0]).toEqual([]);
|
||||
it('requests the next page on "next" click the correct data', async () => {
|
||||
const paginated = findPagination();
|
||||
await paginated.vm.$emit('next');
|
||||
expect(customHandler).toHaveBeenCalledTimes(2);
|
||||
expect(customHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
after: mockPageInfo.endCursor,
|
||||
before: null,
|
||||
first: 20,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('actions events', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ mountFn: mount });
|
||||
describe('correctly filters users with failed status', () => {
|
||||
const sourceUsersFailureQueryHandler = jest
|
||||
.fn()
|
||||
.mockResolvedValue(mockSourceUsersQueryResponse({ nodes: [mockSourceUsers[4]] }));
|
||||
|
||||
beforeEach(async () => {
|
||||
setWindowLocation(`?status=${QUERY_PARAM_FAILED}`);
|
||||
await waitForPromises();
|
||||
|
||||
createComponent({
|
||||
mountFn: shallowMount,
|
||||
queryHandler: sourceUsersFailureQueryHandler,
|
||||
props: { queryStatuses: [PLACEHOLDER_STATUS_FAILED] },
|
||||
options: {
|
||||
stubs: {
|
||||
GlTable: stubComponent(GlTable, {
|
||||
props: ['fields', 'items', 'busy'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('emits "confirm" event with item', () => {
|
||||
const actions = findTableRows().at(2).findComponent(PlaceholderActions);
|
||||
it('when the url includes the query param failed', () => {
|
||||
expect(findTable().props('items')).toHaveLength(1);
|
||||
expect(findTable().props('items')[0].status).toBe(PLACEHOLDER_STATUS_FAILED);
|
||||
expect(sourceUsersFailureQueryHandler).toHaveBeenCalledTimes(1);
|
||||
expect(sourceUsersFailureQueryHandler).toHaveBeenCalledWith({
|
||||
after: null,
|
||||
before: null,
|
||||
fullPath: mockGroup.path,
|
||||
first: 20,
|
||||
statuses: [PLACEHOLDER_STATUS_FAILED],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
actions.vm.$emit('confirm');
|
||||
describe('when is "Re-assigned" table variant', () => {
|
||||
const reassignedQueryHandler = jest
|
||||
.fn()
|
||||
.mockResolvedValue(
|
||||
mockSourceUsersQueryResponse({ nodes: [mockSourceUsers[5], mockSourceUsers[6]] }),
|
||||
);
|
||||
|
||||
expect(wrapper.emitted('confirm')[0]).toEqual([mockSourceUsers[2]]);
|
||||
beforeEach(async () => {
|
||||
createComponent({
|
||||
mountFn: shallowMount,
|
||||
queryHandler: reassignedQueryHandler,
|
||||
props: { reassigned: true, queryStatus: PLACEHOLDER_USER_STATUS.REASSIGNED },
|
||||
options: {
|
||||
stubs: {
|
||||
GlTable: stubComponent(GlTable, {
|
||||
props: ['fields', 'items', 'busy'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await waitForPromises();
|
||||
});
|
||||
|
||||
it('renders table', () => {
|
||||
expect(findTable().exists()).toBe(true);
|
||||
expect(findTableFields()).toEqual([
|
||||
'Placeholder user',
|
||||
'Source',
|
||||
'Reassignment status',
|
||||
'Reassigned to',
|
||||
]);
|
||||
});
|
||||
|
||||
it('only displays items that have been already assigned', () => {
|
||||
expect(findTable().props('items')).toEqual([mockSourceUsers[5], mockSourceUsers[6]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -63,14 +63,14 @@ export const mockSourceUsers = [
|
|||
}),
|
||||
];
|
||||
|
||||
export const mockSourceUsersQueryResponse = ({ pageInfo = {} } = {}) => ({
|
||||
export const mockSourceUsersQueryResponse = ({ nodes = mockSourceUsers, pageInfo = {} } = {}) => ({
|
||||
data: {
|
||||
namespace: {
|
||||
__typename: 'Namespace',
|
||||
id: 'gid://gitlab/Group/1',
|
||||
importSourceUsers: {
|
||||
__typename: 'ImportSourceUserConnection',
|
||||
nodes: mockSourceUsers,
|
||||
nodes,
|
||||
pageInfo: {
|
||||
__typename: 'PageInfo',
|
||||
hasNextPage: false,
|
||||
|
|
@ -84,26 +84,6 @@ export const mockSourceUsersQueryResponse = ({ pageInfo = {} } = {}) => ({
|
|||
},
|
||||
});
|
||||
|
||||
export const mockSourceUsersFailedStatusResponse = {
|
||||
data: {
|
||||
namespace: {
|
||||
__typename: 'Namespace',
|
||||
id: 'gid://gitlab/Group/1',
|
||||
importSourceUsers: {
|
||||
__typename: 'ImportSourceUserConnection',
|
||||
nodes: [mockSourceUsers[4]],
|
||||
pageInfo: {
|
||||
__typename: 'PageInfo',
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
startCursor: '',
|
||||
endCursor: '',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const mockReassignMutationResponse = {
|
||||
data: {
|
||||
importSourceUserReassign: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { GlSprintf, GlSkeletonLoader, GlButton } from '@gitlab/ui';
|
||||
import { GlSprintf, GlSkeletonLoader, GlButton, GlBadge } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { createMockDirective } from 'helpers/vue_mock_directive';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import { mockTracking } from 'helpers/tracking_helper';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import DeleteButton from '~/packages_and_registries/container_registry/explorer/components/delete_button.vue';
|
||||
|
|
@ -34,20 +34,23 @@ describe('Image List Row', () => {
|
|||
const findListItemComponent = () => wrapper.findComponent(ListItem);
|
||||
const findShowFullPathButton = () => wrapper.findComponent(GlButton);
|
||||
const findPublishMessage = () => wrapper.findComponent(PublishMessage);
|
||||
const findProtectedBadge = () => wrapper.findComponent(GlBadge);
|
||||
|
||||
const mountComponent = ({ props = {}, config = {} } = {}) => {
|
||||
const mountComponent = ({ props = {}, config = {}, provide = {} } = {}) => {
|
||||
wrapper = shallowMountExtended(Component, {
|
||||
stubs: {
|
||||
RouterLink,
|
||||
ListItem,
|
||||
GlButton,
|
||||
GlSprintf,
|
||||
GlBadge,
|
||||
},
|
||||
propsData: {
|
||||
item,
|
||||
...props,
|
||||
},
|
||||
provide: {
|
||||
...provide,
|
||||
config: {
|
||||
...config,
|
||||
},
|
||||
|
|
@ -270,4 +273,54 @@ describe('Image List Row', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('badge "protected"', () => {
|
||||
const mountComponentForProtectedBadge = ({
|
||||
itemProtectionRuleExists = true,
|
||||
glFeaturesContainerRegistryProtectedContainers = true,
|
||||
} = {}) => {
|
||||
return mountComponent({
|
||||
props: { item: { ...item, protectionRuleExists: itemProtectionRuleExists } },
|
||||
provide: {
|
||||
glFeatures: {
|
||||
containerRegistryProtectedContainers: glFeaturesContainerRegistryProtectedContainers,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
describe('when image has new badge', () => {
|
||||
beforeEach(() => {
|
||||
mountComponentForProtectedBadge();
|
||||
});
|
||||
|
||||
it('shows badge', () => {
|
||||
expect(findProtectedBadge().text()).toBe('protected');
|
||||
});
|
||||
|
||||
it('binds tooltip directive', () => {
|
||||
const ProtectedBadgeTooltipBinding = getBinding(findProtectedBadge().element, 'gl-tooltip');
|
||||
expect(ProtectedBadgeTooltipBinding).toBeDefined();
|
||||
expect(findProtectedBadge().attributes('title')).toMatch(
|
||||
'A protection rule exists for this container repository.',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when image does not have new badge', () => {
|
||||
it('does not show badge', () => {
|
||||
mountComponentForProtectedBadge({ itemProtectionRuleExists: false });
|
||||
|
||||
expect(findProtectedBadge().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when feature flag "containerRegistryProtectedContainers" disabled', () => {
|
||||
it('does not show badge', () => {
|
||||
mountComponentForProtectedBadge({ glFeaturesContainerRegistryProtectedContainers: false });
|
||||
|
||||
expect(findProtectedBadge().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export const imagesListResponse = [
|
|||
path: 'GITLAB-TEST',
|
||||
webUrl: 'http://localhost:3000/gitlab-org/gitlab-test',
|
||||
},
|
||||
protectionRuleExists: false,
|
||||
...userPermissionsData,
|
||||
},
|
||||
{
|
||||
|
|
@ -41,6 +42,7 @@ export const imagesListResponse = [
|
|||
path: 'GITLAB-TEST',
|
||||
webUrl: 'http://localhost:3000/gitlab-org/gitlab-test',
|
||||
},
|
||||
protectionRuleExists: false,
|
||||
...userPermissionsData,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -286,4 +286,6 @@ export const allowedToMergeDrawerProps = {
|
|||
|
||||
export const editRuleData = [{ accessLevel: 60 }, { accessLevel: 40 }, { accessLevel: 30 }];
|
||||
|
||||
export const editRuleDataNoAccessLevels = [];
|
||||
|
||||
export const editRuleDataNoOne = [{ accessLevel: 0 }];
|
||||
|
|
|
|||
|
|
@ -9,9 +9,12 @@ import { protectionRowPropsMock } from './mock_data';
|
|||
describe('Branch rule protection row', () => {
|
||||
let wrapper;
|
||||
|
||||
const createComponent = () => {
|
||||
const createComponent = ({ propsData = {} } = {}) => {
|
||||
wrapper = shallowMountExtended(ProtectionRow, {
|
||||
propsData: protectionRowPropsMock,
|
||||
propsData: {
|
||||
...protectionRowPropsMock,
|
||||
...propsData,
|
||||
},
|
||||
stubs: { GlAvatarsInline },
|
||||
});
|
||||
};
|
||||
|
|
@ -23,6 +26,7 @@ describe('Branch rule protection row', () => {
|
|||
const findAvatarLinks = () => wrapper.findAllComponents(GlAvatarLink);
|
||||
const findAvatars = () => wrapper.findAllComponents(GlAvatar);
|
||||
const findAccessLevels = () => wrapper.findAllByTestId('access-level');
|
||||
const findSharedSecretBadge = () => wrapper.findByTestId('shared-secret');
|
||||
const findStatusChecksUrl = () => wrapper.findByText(protectionRowPropsMock.statusCheckUrl);
|
||||
|
||||
it('renders a title', () => {
|
||||
|
|
@ -35,6 +39,7 @@ describe('Branch rule protection row', () => {
|
|||
...protectionRowPropsMock.groups,
|
||||
]);
|
||||
expect(findAvatarsInline().props('badgeSrOnlyText')).toBe('1 additional user');
|
||||
expect(findSharedSecretBadge().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('renders avatar-link components', () => {
|
||||
|
|
@ -63,4 +68,14 @@ describe('Branch rule protection row', () => {
|
|||
it('renders status checks URL', () => {
|
||||
expect(findStatusChecksUrl().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders status checks hmac enabled badge', () => {
|
||||
createComponent({
|
||||
propsData: {
|
||||
hmac: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(findSharedSecretBadge().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { GlDrawer, GlFormCheckbox } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
|
||||
|
|
@ -6,6 +7,7 @@ import RuleDrawer from '~/projects/settings/branch_rules/components/view/rule_dr
|
|||
import {
|
||||
allowedToMergeDrawerProps,
|
||||
editRuleData,
|
||||
editRuleDataNoAccessLevels,
|
||||
editRuleDataNoOne,
|
||||
} from 'ee_else_ce_jest/projects/settings/branch_rules/components/view/mock_data';
|
||||
|
||||
|
|
@ -21,6 +23,10 @@ describe('Edit Rule Drawer', () => {
|
|||
const findHeader = () => wrapper.find('h2');
|
||||
const findSaveButton = () => wrapper.findByTestId('save-allowed-to-merge');
|
||||
const findCheckboxes = () => wrapper.findAllComponents(GlFormCheckbox);
|
||||
const findAdministratorsCheckbox = () => findCheckboxes().at(0);
|
||||
const findMaintainersCheckbox = () => findCheckboxes().at(1);
|
||||
const findDevelopersAndMaintainersCheckbox = () => findCheckboxes().at(2);
|
||||
const findNoOneCheckbox = () => findCheckboxes().at(3);
|
||||
|
||||
const createComponent = (props = allowedToMergeDrawerProps) => {
|
||||
wrapper = shallowMountExtended(RuleDrawer, {
|
||||
|
|
@ -64,27 +70,61 @@ describe('Edit Rule Drawer', () => {
|
|||
});
|
||||
|
||||
it('renders checkboxes with expected text', () => {
|
||||
expect(findCheckboxes().length).toBe(3);
|
||||
expect(findCheckboxes().at(0).text()).toBe('Administrators');
|
||||
expect(findCheckboxes().at(1).text()).toBe('Maintainers');
|
||||
expect(findCheckboxes().at(2).text()).toBe('Developers and Maintainers');
|
||||
expect(findCheckboxes().length).toBe(4);
|
||||
expect(findAdministratorsCheckbox().text()).toBe('Administrators');
|
||||
expect(findMaintainersCheckbox().text()).toBe('Maintainers');
|
||||
expect(findDevelopersAndMaintainersCheckbox().text()).toBe('Developers and Maintainers');
|
||||
expect(findNoOneCheckbox().text()).toBe('No one');
|
||||
});
|
||||
|
||||
it('emits expected data', () => {
|
||||
findCheckboxes().at(0).vm.$emit('input', true);
|
||||
findCheckboxes().at(1).vm.$emit('input', true);
|
||||
findCheckboxes().at(2).vm.$emit('input', true);
|
||||
findAdministratorsCheckbox().vm.$emit('input', true);
|
||||
findMaintainersCheckbox().vm.$emit('input', true);
|
||||
findDevelopersAndMaintainersCheckbox().vm.$emit('input', true);
|
||||
findSaveButton().vm.$emit('click');
|
||||
|
||||
expect(wrapper.emitted('editRule')).toHaveLength(1);
|
||||
expect(wrapper.emitted('editRule')[0][0]).toEqual(editRuleData);
|
||||
});
|
||||
|
||||
it('when all roles unchecked it sends `No one` as a role', () => {
|
||||
findCheckboxes().at(0).vm.$emit('input', false);
|
||||
findCheckboxes().at(1).vm.$emit('input', false);
|
||||
findCheckboxes().at(2).vm.$emit('input', false);
|
||||
it('when `No one` is selected, it sets other access level checkboxes to false', async () => {
|
||||
createComponent({ ...allowedToMergeDrawerProps, roles: [30, 40, 60], isOpen: true });
|
||||
findNoOneCheckbox().vm.$emit('input', true);
|
||||
await nextTick();
|
||||
|
||||
expect(findAdministratorsCheckbox().attributes('checked')).toBeUndefined();
|
||||
expect(findMaintainersCheckbox().attributes('checked')).toBeUndefined();
|
||||
expect(findDevelopersAndMaintainersCheckbox().attributes('checked')).toBeUndefined();
|
||||
expect(findNoOneCheckbox().attributes('checked')).toBe('true');
|
||||
});
|
||||
|
||||
it('when `No one` is initially selected, selecting another role unchecks `No one', async () => {
|
||||
createComponent({ ...allowedToMergeDrawerProps, roles: [0], isOpen: true });
|
||||
findAdministratorsCheckbox().vm.$emit('input', true);
|
||||
await nextTick();
|
||||
|
||||
expect(findNoOneCheckbox().attributes('checked')).toBeUndefined();
|
||||
expect(findAdministratorsCheckbox().attributes('checked')).toBe('true');
|
||||
});
|
||||
|
||||
it('when all roles are checked it sends `No one` as a role', () => {
|
||||
findAdministratorsCheckbox().vm.$emit('input', true);
|
||||
findMaintainersCheckbox().vm.$emit('input', true);
|
||||
findDevelopersAndMaintainersCheckbox().vm.$emit('input', true);
|
||||
findNoOneCheckbox().vm.$emit('input', true);
|
||||
|
||||
findSaveButton().vm.$emit('click');
|
||||
expect(wrapper.emitted('editRule')).toHaveLength(1);
|
||||
expect(wrapper.emitted('editRule')[0][0]).toEqual(editRuleDataNoOne);
|
||||
});
|
||||
|
||||
it('when all roles are unchecked it does not send any role', () => {
|
||||
findAdministratorsCheckbox().vm.$emit('input', false);
|
||||
findMaintainersCheckbox().vm.$emit('input', false);
|
||||
findDevelopersAndMaintainersCheckbox().vm.$emit('input', false);
|
||||
findNoOneCheckbox().vm.$emit('input', false);
|
||||
|
||||
findSaveButton().vm.$emit('click');
|
||||
expect(wrapper.emitted('editRule')[0][0]).toEqual(editRuleDataNoAccessLevels);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -176,7 +176,13 @@ describe('MrWidgetOptions', () => {
|
|||
${'shaMismatch'} | ${'ShaMismatch'} | ${ShaMismatch}
|
||||
`('should translate $state into $componentName component', async ({ state, component }) => {
|
||||
await createComponent();
|
||||
Vue.set(wrapper.vm.mr, 'state', state);
|
||||
|
||||
wrapper.vm.mr = {
|
||||
...wrapper.vm.mr,
|
||||
setGraphqlData: jest.fn(),
|
||||
state,
|
||||
};
|
||||
|
||||
await nextTick();
|
||||
expect(wrapper.findComponent(component).exists()).toBe(true);
|
||||
});
|
||||
|
|
@ -249,7 +255,12 @@ describe('MrWidgetOptions', () => {
|
|||
},
|
||||
});
|
||||
await nextTick();
|
||||
Vue.set(wrapper.vm.mr, 'mergePipelinesEnabled', true);
|
||||
wrapper.vm.mt = {
|
||||
...wrapper.vm.mr,
|
||||
setGraphqlData: jest.fn(),
|
||||
mergePipelinesEnabled: true,
|
||||
};
|
||||
|
||||
await nextTick();
|
||||
expect(findMergePipelineForkAlert().exists()).toBe(false);
|
||||
});
|
||||
|
|
@ -273,7 +284,13 @@ describe('MrWidgetOptions', () => {
|
|||
},
|
||||
});
|
||||
await nextTick();
|
||||
Vue.set(wrapper.vm.mr, 'mergePipelinesEnabled', true);
|
||||
|
||||
wrapper.vm.mr = {
|
||||
...wrapper.vm.mr,
|
||||
setGraphqlData: jest.fn(),
|
||||
mergePipelinesEnabled: true,
|
||||
};
|
||||
|
||||
await nextTick();
|
||||
expect(findMergePipelineForkAlert().exists()).toBe(true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import {
|
|||
I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_TOOLTIP,
|
||||
SEARCH_DEBOUNCE,
|
||||
WORK_ITEM_TYPE_ENUM_EPIC,
|
||||
MAX_WORK_ITEMS,
|
||||
I18N_MAX_WORK_ITEMS_ERROR_MESSAGE,
|
||||
} from '~/work_items/constants';
|
||||
import projectWorkItemsQuery from '~/work_items/graphql/project_work_items.query.graphql';
|
||||
import namespaceWorkItemTypesQuery from '~/work_items/graphql/namespace_work_item_types.query.graphql';
|
||||
|
|
@ -32,6 +34,7 @@ import {
|
|||
updateWorkItemMutationResponse,
|
||||
mockIterationWidgetResponse,
|
||||
namespaceProjectsList,
|
||||
generateWorkItemsListWithId,
|
||||
} from '../../mock_data';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
|
@ -127,6 +130,7 @@ describe('WorkItemLinksForm', () => {
|
|||
const findTooltip = () => wrapper.findComponent(GlTooltip);
|
||||
const findAddChildButton = () => wrapper.findByTestId('add-child-button');
|
||||
const findValidationElement = () => wrapper.findByTestId('work-items-invalid');
|
||||
const findWorkItemLimitValidationMessage = () => wrapper.findByTestId('work-items-limit-error');
|
||||
const findErrorMessageElement = () => wrapper.findByTestId('work-items-error');
|
||||
const findProjectSelector = () => wrapper.findComponent(WorkItemProjectsListbox);
|
||||
|
||||
|
|
@ -465,6 +469,17 @@ describe('WorkItemLinksForm', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('disables button ans shows validation error when more than 10 work items are selected', async () => {
|
||||
await selectAvailableWorkItemTokens(generateWorkItemsListWithId(MAX_WORK_ITEMS + 1));
|
||||
|
||||
expect(findWorkItemTokenInput().props('areWorkItemsToAddValid')).toBe(false);
|
||||
expect(findAddChildButton().attributes('disabled')).toBe('true');
|
||||
expect(findWorkItemLimitValidationMessage().exists()).toBe(true);
|
||||
expect(findWorkItemLimitValidationMessage().text()).toContain(
|
||||
I18N_MAX_WORK_ITEMS_ERROR_MESSAGE,
|
||||
);
|
||||
});
|
||||
|
||||
it('clears form error when token input is updated', async () => {
|
||||
await createComponent({ formType: FORM_TYPES.add, updateMutation: updateMutationRejection });
|
||||
await selectAvailableWorkItemTokens();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ require 'spec_helper'
|
|||
RSpec.describe Resolvers::MergeRequestsResolver, feature_category: :code_review_workflow do
|
||||
include GraphqlHelpers
|
||||
include SortingHelper
|
||||
include MrResolverHelpers
|
||||
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let_it_be(:other_project) { create(:project, :repository) }
|
||||
|
|
@ -240,6 +241,107 @@ RSpec.describe Resolvers::MergeRequestsResolver, feature_category: :code_review_
|
|||
end
|
||||
end
|
||||
|
||||
context 'with merged_by argument' do
|
||||
before_all do
|
||||
merge_request_1.metrics.update!(merged_by: other_user)
|
||||
end
|
||||
|
||||
context "for matching arguments" do
|
||||
it 'returns merge requests merged by user' do
|
||||
result = resolve_mr(project, merged_by: other_user.username)
|
||||
|
||||
expect(result).to contain_exactly(merge_request_1)
|
||||
end
|
||||
|
||||
it 'does not return anything' do
|
||||
result = resolve_mr(project, merged_by: "cool_guy_123")
|
||||
|
||||
expect(result).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with release argument' do
|
||||
let_it_be(:release_in_project) { create(:release, :with_milestones, project: merge_request_1.project) }
|
||||
let_it_be(:milestone) { release_in_project.milestones.last }
|
||||
|
||||
before_all do
|
||||
merge_request_1.update!(milestone: milestone)
|
||||
end
|
||||
|
||||
it 'returns merge requests in release' do
|
||||
result = resolve_mr(project, release_tag: release_in_project.name)
|
||||
|
||||
expect(result).to contain_exactly(merge_request_1)
|
||||
end
|
||||
|
||||
it 'does not return anything' do
|
||||
result = resolve_mr(project, release_tag: "8675309.0")
|
||||
|
||||
expect(result).to be_empty
|
||||
end
|
||||
|
||||
it 'filters out merge requests with given milestone title' do
|
||||
result = resolve_mr(project, not: { release_tag: release_in_project.name })
|
||||
|
||||
expect(result).not_to include(merge_request_1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with approved_by argument' do
|
||||
let(:username) { other_user.username }
|
||||
|
||||
before_all do
|
||||
merge_request_1.approvals.create!(user: other_user)
|
||||
end
|
||||
|
||||
it 'returns merge requests approved by user' do
|
||||
result = resolve_mr(project, approved_by: [username])
|
||||
|
||||
expect(result).to contain_exactly(merge_request_1)
|
||||
end
|
||||
|
||||
it 'does not return anything' do
|
||||
result = resolve_mr(project, approved_by: ["cool_guy_123"])
|
||||
|
||||
expect(result).to be_empty
|
||||
end
|
||||
|
||||
context 'with negated approved by argument' do
|
||||
it 'filters out merge requests with given approved user' do
|
||||
result = resolve_mr(project, not: { approved_by: [username] })
|
||||
|
||||
expect(result).not_to include(merge_request_1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with my_reaction_emoji argument' do
|
||||
before_all do
|
||||
merge_request_1.award_emoji.create!(name: "poop", user: current_user)
|
||||
end
|
||||
|
||||
it 'returns merge requests with a reaction emoji set by user' do
|
||||
result = resolve_mr(project, my_reaction_emoji: "poop")
|
||||
|
||||
expect(result).to contain_exactly(merge_request_1)
|
||||
end
|
||||
|
||||
it 'does not return anything' do
|
||||
result = resolve_mr(project, my_reaction_emoji: "thumbsup")
|
||||
|
||||
expect(result).to be_empty
|
||||
end
|
||||
|
||||
context 'with negated my_reaction_emoji argument' do
|
||||
it 'filters out merge requests with given reaction emoji' do
|
||||
result = resolve_mr(project, not: { my_reaction_emoji: "poop" })
|
||||
|
||||
expect(result).not_to include(merge_request_1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering by the merge request deployments' do
|
||||
let_it_be(:gstg) { create(:environment, project: project, name: 'gstg') }
|
||||
let_it_be(:gprd) { create(:environment, project: project, name: 'gprd') }
|
||||
|
|
@ -501,8 +603,4 @@ RSpec.describe Resolvers::MergeRequestsResolver, feature_category: :code_review_
|
|||
def resolve_mr_single(project, iid)
|
||||
resolve_mr(project, resolver: described_class.single, iid: iid.to_s)
|
||||
end
|
||||
|
||||
def resolve_mr(project, resolver: described_class, user: current_user, **args)
|
||||
resolve(resolver, obj: project, args: args, ctx: { current_user: user }, arg_style: :internal)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -356,6 +356,10 @@ RSpec.describe GitlabSchema.types['Project'], feature_category: :groups_and_proj
|
|||
:updated_after,
|
||||
:updated_before,
|
||||
:author_username,
|
||||
:approved_by,
|
||||
:my_reaction_emoji,
|
||||
:merged_by,
|
||||
:release_tag,
|
||||
:assignee_username,
|
||||
:assignee_wildcard_id,
|
||||
:reviewer_username,
|
||||
|
|
|
|||
|
|
@ -333,6 +333,7 @@ RSpec.describe MergeRequestsHelper, feature_category: :code_review_workflow do
|
|||
|
||||
it 'returns the correct data' do
|
||||
expected_data = {
|
||||
autocomplete_award_emojis_path: autocomplete_award_emojis_path,
|
||||
full_path: project.full_path,
|
||||
is_public_visibility_restricted: 'false',
|
||||
is_signed_in: 'true',
|
||||
|
|
|
|||
|
|
@ -37,8 +37,4 @@ RSpec.describe Banzai::Filter::BlockquoteFenceLegacyFilter, feature_category: :t
|
|||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'text filter timeout' do
|
||||
let(:text) { ">>>\ntest\n>>>" }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -214,5 +214,6 @@ RSpec.describe Banzai::Filter::ExternalLinkFilter, feature_category: :team_plann
|
|||
it_behaves_like 'a filter timeout' do
|
||||
let(:text) { 'text' }
|
||||
let(:expected_result) { described_class::COMPLEX_MARKDOWN_MESSAGE }
|
||||
let(:expected_timeout) { described_class::SANITIZATION_RENDER_TIMEOUT }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,16 +3,18 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Banzai::Filter::References::AbstractReferenceFilter, feature_category: :team_planning do
|
||||
include FilterSpecHelper
|
||||
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
let_it_be(:doc) { Nokogiri::HTML.fragment('') }
|
||||
let_it_be(:filter) { described_class.new(doc, project: project) }
|
||||
let_it_be(:filter_instance) { described_class.new(doc, project: project) }
|
||||
|
||||
describe '#data_attributes_for' do
|
||||
it 'is not an XSS vector' do
|
||||
allow(described_class).to receive(:object_class).and_return(Issue)
|
||||
|
||||
data_attributes = filter.data_attributes_for('xss <img onerror=alert(1) src=x>', project, issue, link_content: true)
|
||||
data_attributes = filter_instance.data_attributes_for('xss <img onerror=alert(1) src=x>', project, issue, link_content: true)
|
||||
|
||||
expect(data_attributes[:original]).to eq('xss &lt;img onerror=alert(1) src=x&gt;')
|
||||
end
|
||||
|
|
@ -22,29 +24,32 @@ RSpec.describe Banzai::Filter::References::AbstractReferenceFilter, feature_cate
|
|||
allow(described_class).to receive(:object_class).and_return(Issue)
|
||||
expect(Gitlab::RenderTimeout).to receive(:timeout).and_call_original
|
||||
|
||||
filter.call
|
||||
filter(doc)
|
||||
end
|
||||
|
||||
it 'uses gsub_with_limit' do
|
||||
allow(described_class).to receive(:object_class).and_return(Issue)
|
||||
expect(Gitlab::Utils::Gsub).to receive(:gsub_with_limit).with(anything, anything, limit: Banzai::Filter::FILTER_ITEM_LIMIT).and_call_original
|
||||
|
||||
filter.references_in('text')
|
||||
filter_instance.references_in('text')
|
||||
end
|
||||
|
||||
context 'abstract methods' do
|
||||
describe '#find_object' do
|
||||
it 'raises NotImplementedError' do
|
||||
expect { filter.find_object(nil, nil) }.to raise_error(NotImplementedError)
|
||||
expect { filter_instance.find_object(nil, nil) }.to raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#url_for_object' do
|
||||
it 'raises NotImplementedError' do
|
||||
expect { filter.url_for_object(nil, nil) }.to raise_error(NotImplementedError)
|
||||
expect { filter_instance.url_for_object(nil, nil) }.to raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'pipeline timing check', context: { project: nil }
|
||||
it_behaves_like 'a filter timeout' do
|
||||
let(:text) { 'text' }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -227,5 +227,6 @@ RSpec.describe Banzai::Filter::SanitizationFilter, feature_category: :team_plann
|
|||
it_behaves_like 'a filter timeout' do
|
||||
let(:text) { 'text' }
|
||||
let(:expected_result) { described_class::COMPLEX_MARKDOWN_MESSAGE }
|
||||
let(:expected_timeout) { described_class::SANITIZATION_RENDER_TIMEOUT }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter, feature_category: :team_pl
|
|||
include_examples "XSS prevention", "ruby"
|
||||
end
|
||||
|
||||
it_behaves_like "html filter timeout" do
|
||||
it_behaves_like 'a filter timeout' do
|
||||
let(:text) { '<pre data-canonical-lang="ruby"><code>def fun end</code></pre>' }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Banzai::Filter::TimeoutHtmlPipelineFilter, feature_category: :team_planning do
|
||||
include FilterSpecHelper
|
||||
|
||||
it_behaves_like 'html filter timeout' do
|
||||
let(:text) { '<p>some text</p>' }
|
||||
end
|
||||
|
||||
it 'raises NotImplementedError' do
|
||||
expect { filter('test') }.to raise_error NotImplementedError
|
||||
end
|
||||
end
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Banzai::Filter::TimeoutTextPipelineFilter, feature_category: :team_planning do
|
||||
include FilterSpecHelper
|
||||
|
||||
it_behaves_like 'text filter timeout' do
|
||||
let(:text) { '<p>some text</p>' }
|
||||
end
|
||||
|
||||
it 'raises NotImplementedError' do
|
||||
expect { filter('test') }.to raise_error NotImplementedError
|
||||
end
|
||||
end
|
||||
|
|
@ -25,13 +25,21 @@ RSpec.describe Gitlab::Ci::Config::Entry::Reports::CoverageReport, feature_categ
|
|||
end
|
||||
|
||||
context 'with unsupported coverage format' do
|
||||
let(:config) { { coverage_format: 'jacoco', path: 'jacoco.xml' } }
|
||||
let(:config) { { coverage_format: 'anotherformat', path: 'anotherformat.xml' } }
|
||||
|
||||
it { expect(entry).not_to be_valid }
|
||||
|
||||
it { expect(entry.errors).to include(/format must be one of supported formats/) }
|
||||
end
|
||||
|
||||
context 'with jacoco coverage format' do
|
||||
let(:config) { { coverage_format: 'jacoco', path: 'jacoco.xml' } }
|
||||
|
||||
it { expect(entry).to be_valid }
|
||||
|
||||
it { expect(entry.value).to eq(config) }
|
||||
end
|
||||
|
||||
context 'without coverage format' do
|
||||
let(:config) { { path: 'cobertura-coverage.xml' } }
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Ci::Parsers::Coverage::Documents::JacocoDocument,
|
||||
feature_category: :code_testing do
|
||||
subject(:parse_report) do
|
||||
Nokogiri::XML::SAX::Parser.new(described_class.new(coverage_report,
|
||||
modified_files)).parse(xml)
|
||||
end
|
||||
|
||||
describe '#parse!' do
|
||||
let(:coverage_report) { Gitlab::Ci::Reports::CoverageReport.new }
|
||||
let(:modified_files) { %w[src/main/org/acme/AnotherResource.java src/main/org/acme/ExampleResource.java] }
|
||||
let(:project_path) { 'root/someproject' }
|
||||
let(:xml) { fixture_file_upload(Rails.root.join('spec/fixtures/jacoco/coverage.xml'), 'text/xml') }
|
||||
|
||||
it 'parses the file' do
|
||||
parse_report
|
||||
|
||||
expect(coverage_report.files).to match({
|
||||
"src/main/org/acme/AnotherResource.java" => { 9 => 0, 14 => 0 },
|
||||
"src/main/org/acme/ExampleResource.java" => { 9 => 3, 14 => 2 }
|
||||
})
|
||||
end
|
||||
|
||||
context 'when the report format is invalid' do
|
||||
context 'when the xml syntax is invalid' do
|
||||
let(:xml) do
|
||||
fixture_file_upload(Rails.root.join('spec/fixtures/jacoco/coverage-invalid-format.xml'), 'text/xml')
|
||||
end
|
||||
|
||||
it 'returns an error' do
|
||||
expect { parse_report }.to raise_error(Gitlab::Ci::Parsers::Coverage::Jacoco::InvalidXMLError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the line does not contain the required info' do
|
||||
let(:xml) { fixture_file_upload(Rails.root.join('spec/fixtures/jacoco/coverage-no-line-info.xml'), 'text/xml') }
|
||||
|
||||
it 'returns an error' do
|
||||
expect { parse_report }.to raise_error(Gitlab::Ci::Parsers::Coverage::Jacoco::InvalidLineInformationError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the merge request paths do not exist' do
|
||||
let(:modified_files) { %w[src/test/org/acme/ExampleResource.java] }
|
||||
|
||||
it 'returns an error' do
|
||||
expect(Gitlab::AppLogger).to receive(:info).twice
|
||||
|
||||
parse_report
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Ci::Parsers::Coverage::Jacoco, feature_category: :code_testing do
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let(:xml_data) { double }
|
||||
let(:coverage_report) { double }
|
||||
let(:paths) { double }
|
||||
let(:merge_request_paths) { double }
|
||||
|
||||
subject(:parse_report) do
|
||||
described_class.new.parse!(xml_data,
|
||||
coverage_report,
|
||||
project: project,
|
||||
worktree_paths: paths,
|
||||
merge_request_paths: merge_request_paths)
|
||||
end
|
||||
|
||||
before do
|
||||
allow_next_instance_of(Nokogiri::XML::SAX::Parser) do |document|
|
||||
allow(document).to receive(:parse)
|
||||
end
|
||||
end
|
||||
|
||||
it 'uses Jacoco parser' do
|
||||
expect(Gitlab::Ci::Parsers::Coverage::Documents::JacocoDocument).to receive(:new)
|
||||
|
||||
parse_report
|
||||
end
|
||||
|
||||
context 'when the feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(jacoco_coverage_reports: false)
|
||||
end
|
||||
|
||||
it 'returns an error' do
|
||||
expect { parse_report }.to raise_error(described_class::FeatureDisabledError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -22,6 +22,14 @@ RSpec.describe Gitlab::Ci::Parsers do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when file_type is jacoco' do
|
||||
let(:file_type) { 'jacoco' }
|
||||
|
||||
it 'fabricates the class' do
|
||||
is_expected.to be_a(described_class::Coverage::Jacoco)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when file_type is accessibility' do
|
||||
let(:file_type) { 'accessibility' }
|
||||
|
||||
|
|
|
|||