Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c07f9b1c78
commit
cd9a4ce166
|
|
@ -1405,6 +1405,7 @@ lib/gitlab/checks/**
|
|||
# Overrides for Verify. These files below require approval from teams outside Verify.
|
||||
/**/lib/**/ci/reports/**/ @gitlab-org/maintainers/rails-backend
|
||||
/**/lib/**/ci/parsers/**/ @gitlab-org/maintainers/rails-backend
|
||||
/**/app/views/ci/**/ @gitlab-org/maintainers/rails-backend
|
||||
/ee/lib/gitlab/ci/parsers/license_compliance/ @gitlab-org/secure/composition-analysis-be
|
||||
/ee/lib/gitlab/ci/parsers/security/ @gitlab-org/govern/threat-insights-backend-team
|
||||
/ee/lib/gitlab/ci/reports/coverage_fuzzing/ @gitlab-org/secure/fuzzing-be
|
||||
|
|
|
|||
|
|
@ -2267,7 +2267,6 @@ Gitlab/BoundedContexts:
|
|||
- 'ee/app/experiments/issues_mrs_empty_state_experiment.rb'
|
||||
- 'ee/app/experiments/project_templates_during_registration_experiment.rb'
|
||||
- 'ee/app/experiments/signup_intent_step_one_experiment.rb'
|
||||
- 'ee/app/experiments/trial_discover_page_experiment.rb'
|
||||
- 'ee/app/finders/app_sec/fuzzing/coverage/corpuses_finder.rb'
|
||||
- 'ee/app/finders/approval_rules/group_finder.rb'
|
||||
- 'ee/app/finders/audit_event_finder.rb'
|
||||
|
|
|
|||
|
|
@ -180,19 +180,7 @@ Layout/ArgumentAlignment:
|
|||
- 'lib/api/entities/pull_mirror.rb'
|
||||
- 'lib/api/entities/release.rb'
|
||||
- 'lib/api/entities/resource_access_token.rb'
|
||||
- 'lib/gitlab/ci/yaml_processor/result.rb'
|
||||
- 'lib/gitlab/config/entry/node.rb'
|
||||
- 'lib/gitlab/config_checker/external_database_checker.rb'
|
||||
- 'lib/gitlab/conflict/file.rb'
|
||||
- 'lib/gitlab/cross_project_access.rb'
|
||||
- 'lib/gitlab/data_builder/push.rb'
|
||||
- 'lib/gitlab/database/consistency_checker.rb'
|
||||
- 'lib/gitlab/database/count/reltuples_count_strategy.rb'
|
||||
- 'lib/gitlab/database/load_balancing/configuration.rb'
|
||||
- 'lib/gitlab/database/load_balancing/service_discovery.rb'
|
||||
- 'lib/gitlab/database/migration_helpers.rb'
|
||||
- 'lib/gitlab/database/migrations/base_background_runner.rb'
|
||||
- 'lib/gitlab/database/partitioning/detached_partition_dropper.rb'
|
||||
- 'lib/gitlab/database/partitioning/partition_manager.rb'
|
||||
- 'lib/gitlab/database/partitioning/replace_table.rb'
|
||||
- 'lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb'
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
5449172da31e92e636d7a04bf460e359bc44aa1b
|
||||
42a2e519ca55a42f8cf420012b1f14af0830be59
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div
|
||||
class="gl-display-flex gl-justify-content-end -gl-my-2 gl-mx-n2"
|
||||
class="gl-display-flex gl-justify-content-end -gl-my-2 -gl-mx-2"
|
||||
:data-testid="`user-actions-${user.id}`"
|
||||
>
|
||||
<div v-if="hasEditAction" class="gl-p-2" :class="{ 'gl-mr-3': hasEditActionOnly }">
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ export default {
|
|||
</li>
|
||||
</ul>
|
||||
</gl-card>
|
||||
<div class="-gl-my-2 gl-mx-n2 gl-display-flex gl-flex-wrap">
|
||||
<div class="-gl-my-2 -gl-mx-2 gl-display-flex gl-flex-wrap">
|
||||
<div class="gl-p-2">
|
||||
<clipboard-button
|
||||
:title="$options.i18n.copyButton"
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<div class="gl-text-truncate gl-p-3 -gl-mt-3 gl-mx-n3 -gl-mb-2">
|
||||
<div class="gl-text-truncate gl-p-3 -gl-mt-3 -gl-mx-3 -gl-mb-2">
|
||||
<gl-icon
|
||||
v-if="jobStuck"
|
||||
v-gl-tooltip="$options.i18n.stuckText"
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<div class="gl-p-3 -gl-mt-3 gl-mx-n3">
|
||||
<div class="gl-p-3 -gl-mt-3 -gl-mx-3">
|
||||
<gl-link class="gl-text-truncate" :href="pipelinePath" data-testid="pipeline-id">
|
||||
{{ pipelineId }}
|
||||
</gl-link>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { GlBadge, GlSprintf, GlLink, GlTooltipDirective } from '@gitlab/ui';
|
||||
import {
|
||||
DETACHED_EVENT_TYPE,
|
||||
AUTO_DEVOPS_SOURCE,
|
||||
|
|
@ -12,6 +12,8 @@ export default {
|
|||
name: 'HeaderBadges',
|
||||
components: {
|
||||
GlBadge,
|
||||
GlSprintf,
|
||||
GlLink,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
|
|
@ -47,6 +49,9 @@ export default {
|
|||
yamlErrorMessages() {
|
||||
return this.pipeline?.yamlErrorMessages || '';
|
||||
},
|
||||
triggeredByPath() {
|
||||
return this.pipeline?.triggeredByPath;
|
||||
},
|
||||
badges() {
|
||||
return {
|
||||
schedule: this.isScheduledPipeline,
|
||||
|
|
|
|||
|
|
@ -217,9 +217,6 @@ export default {
|
|||
refText() {
|
||||
return this.pipeline?.refText;
|
||||
},
|
||||
triggeredByPath() {
|
||||
return this.pipeline?.triggeredByPath;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
reportFailure(errorType, errorMessages = []) {
|
||||
|
|
|
|||
|
|
@ -85,14 +85,14 @@ export default {
|
|||
:visible="visible"
|
||||
@hidden="$emit('hidden')"
|
||||
>
|
||||
<div class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
|
||||
<div class="gl-display-flex gl-flex-wrap -gl-mx-4 gl-my-3">
|
||||
<strong class="col-sm-3">{{ $options.text.name }}</strong>
|
||||
<div class="col-sm-9" data-testid="test-case-name">
|
||||
{{ testCase.name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="testCase.file" class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
|
||||
<div v-if="testCase.file" class="gl-display-flex gl-flex-wrap -gl-mx-4 gl-my-3">
|
||||
<strong class="col-sm-3">{{ $options.text.file }}</strong>
|
||||
<div class="col-sm-9" data-testid="test-case-file">
|
||||
<gl-link v-if="testCase.filePath" :href="testCase.filePath">
|
||||
|
|
@ -109,7 +109,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
|
||||
<div class="gl-display-flex gl-flex-wrap -gl-mx-4 gl-my-3">
|
||||
<strong class="col-sm-3">{{ $options.text.duration }}</strong>
|
||||
<div v-if="testCase.formattedTime" class="col-sm-9" data-testid="test-case-duration">
|
||||
{{ testCase.formattedTime }}
|
||||
|
|
@ -119,14 +119,14 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="testCase.recent_failures" class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
|
||||
<div v-if="testCase.recent_failures" class="gl-display-flex gl-flex-wrap -gl-mx-4 gl-my-3">
|
||||
<strong class="col-sm-3">{{ $options.text.history }}</strong>
|
||||
<div class="col-sm-9" data-testid="test-case-recent-failures">
|
||||
<gl-badge variant="warning">{{ failureHistoryMessage }}</gl-badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="testCase.attachment_url" class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
|
||||
<div v-if="testCase.attachment_url" class="gl-display-flex gl-flex-wrap -gl-mx-4 gl-my-3">
|
||||
<strong class="col-sm-3">{{ $options.text.attachment }}</strong>
|
||||
<gl-link
|
||||
class="col-sm-9"
|
||||
|
|
@ -140,7 +140,7 @@ export default {
|
|||
|
||||
<div
|
||||
v-if="testCase.system_output"
|
||||
class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3"
|
||||
class="gl-display-flex gl-flex-wrap -gl-mx-4 gl-my-3"
|
||||
data-testid="test-case-trace"
|
||||
>
|
||||
<strong class="col-sm-3 gl-mb-2">{{ $options.text.trace }}</strong>
|
||||
|
|
|
|||
|
|
@ -3,3 +3,21 @@ export const getModifierKey = (removeSuffix = false) => {
|
|||
const winKey = `Ctrl${removeSuffix ? '' : '+'}`;
|
||||
return window.gl?.client?.isMac ? '⌘' : winKey;
|
||||
};
|
||||
|
||||
// The following default values are for frontend unit tests
|
||||
const DEFAULT_FORUM_URL = 'https://forum.gitlab.com';
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const DEFAULT_DOCS_URL = 'https://docs.gitlab.com';
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const DEFAULT_PROMO_URL = 'https://about.gitlab.com';
|
||||
|
||||
const {
|
||||
forum_url: FORUM_URL = DEFAULT_FORUM_URL,
|
||||
docs_url: DOCS_URL = DEFAULT_DOCS_URL,
|
||||
promo_url: PROMO_URL = DEFAULT_PROMO_URL,
|
||||
} = window.gon;
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
export const DOCS_URL_IN_EE_DIR = `${DOCS_URL}/ee`;
|
||||
|
||||
export { FORUM_URL, DOCS_URL, PROMO_URL };
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ export default {
|
|||
<template>
|
||||
<form class="feature-flags-form">
|
||||
<fieldset>
|
||||
<div class="gl-display-flex gl-flex-wrap gl-mx-n5">
|
||||
<div class="gl-display-flex gl-flex-wrap -gl-mx-5">
|
||||
<div class="gl-mb-5 gl-px-5 gl-w-full md:gl-basis-1/3">
|
||||
<label for="feature-flag-name" class="gl-font-weight-bold"
|
||||
>{{ s__('FeatureFlags|Name') }} *</label
|
||||
|
|
@ -167,7 +167,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gl-display-flex gl-flex-wrap gl-mx-n5">
|
||||
<div class="gl-display-flex gl-flex-wrap -gl-mx-5">
|
||||
<div class="gl-mb-5 gl-px-5 gl-w-full md:gl-basis-1/3">
|
||||
<label for="feature-flag-description" class="gl-font-weight-bold">
|
||||
{{ s__('FeatureFlags|Description') }}
|
||||
|
|
@ -188,7 +188,7 @@ export default {
|
|||
:show-categorized-issues="false"
|
||||
/>
|
||||
|
||||
<div class="gl-display-flex gl-flex-wrap gl-mx-n5">
|
||||
<div class="gl-display-flex gl-flex-wrap -gl-mx-5">
|
||||
<div class="gl-mb-5 gl-px-5 gl-w-full">
|
||||
<h4>{{ s__('FeatureFlags|Strategies') }}</h4>
|
||||
<div class="gl-display-flex gl-align-items-baseline gl-justify-content-space-between">
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div v-if="canCreateSubgroups || canCreateProjects" class="gl-mt-5">
|
||||
<div class="gl-display-flex gl-mx-n3 -gl-my-3 gl-flex-wrap">
|
||||
<div class="gl-display-flex -gl-mx-3 -gl-my-3 gl-flex-wrap">
|
||||
<div v-if="canCreateSubgroups" class="gl-p-3 gl-w-full gl-sm-w-half">
|
||||
<gl-link :href="newSubgroupPath" :class="$options.linkClasses">
|
||||
<div class="svg-content gl-w-15 gl-flex-shrink-0 gl-mr-5">
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ export default {
|
|||
</gl-tab>
|
||||
<template #tabs-end>
|
||||
<li class="gl-flex-grow-1 gl-align-self-center gl-w-full gl-lg-w-auto gl-py-2">
|
||||
<div class="gl-lg-display-flex gl-justify-content-end gl-mx-n2 -gl-my-2">
|
||||
<div class="gl-lg-display-flex gl-justify-content-end -gl-mx-2 -gl-my-2">
|
||||
<div class="gl-p-2 gl-lg-form-input-md gl-w-full">
|
||||
<gl-search-box-by-type
|
||||
:value="search"
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export default {
|
|||
:is-merge-request="true"
|
||||
:pipeline-status="mr.head_pipeline && mr.head_pipeline.detailed_status"
|
||||
path-id-separator="!"
|
||||
class="gl-mx-n2"
|
||||
class="-gl-mx-2"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-flex gl-flex-wrap gl-sm-flex-nowrap gl-mx-n3">
|
||||
<div class="gl-display-flex gl-flex-wrap gl-sm-flex-nowrap -gl-mx-3">
|
||||
<gl-single-stat
|
||||
v-for="(stat, index) in stats"
|
||||
:key="index"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-flex gl-align-items-center gl-justify-content-end gl-mx-n1">
|
||||
<div class="gl-display-flex gl-align-items-center gl-justify-content-end -gl-mx-1">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { GlTabs, GlTab, GlBadge, GlButton } from '@gitlab/ui';
|
|||
// eslint-disable-next-line no-restricted-imports
|
||||
import { mapState } from 'vuex';
|
||||
import { queryToObject } from '~/lib/utils/url_utility';
|
||||
import { MEMBER_TYPES, ACTIVE_TAB_QUERY_PARAM_NAME } from 'ee_else_ce/members/constants';
|
||||
import { MEMBERS_TAB_TYPES, ACTIVE_TAB_QUERY_PARAM_NAME } from 'ee_else_ce/members/constants';
|
||||
import { TABS } from 'ee_else_ce/members/tabs_metadata';
|
||||
import MembersApp from './app.vue';
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
...mapState(
|
||||
Object.values(MEMBER_TYPES).reduce((getters, memberType) => {
|
||||
Object.values(MEMBERS_TAB_TYPES).reduce((getters, memberType) => {
|
||||
return {
|
||||
...getters,
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
|
|
@ -68,7 +68,7 @@ export default {
|
|||
return this[`${namespace}Count`];
|
||||
},
|
||||
showTab(tab, index) {
|
||||
if (tab.namespace === MEMBER_TYPES.user) {
|
||||
if (tab.namespace === MEMBERS_TAB_TYPES.user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { MEMBER_TYPES, EE_ACTION_BUTTONS } from 'ee_else_ce/members/constants';
|
||||
import { MEMBERS_TAB_TYPES, ACTION_BUTTONS } from 'ee_else_ce/members/constants';
|
||||
import AccessRequestActionButtons from '../action_buttons/access_request_action_buttons.vue';
|
||||
import GroupActionButtons from '../action_buttons/group_action_buttons.vue';
|
||||
import InviteActionButtons from '../action_buttons/invite_action_buttons.vue';
|
||||
|
|
@ -36,11 +36,11 @@ export default {
|
|||
computed: {
|
||||
actionButtonComponent() {
|
||||
const dictionary = {
|
||||
[MEMBER_TYPES.user]: 'user-action-dropdown',
|
||||
[MEMBER_TYPES.group]: 'group-action-buttons',
|
||||
[MEMBER_TYPES.invite]: 'invite-action-buttons',
|
||||
[MEMBER_TYPES.accessRequest]: 'access-request-action-buttons',
|
||||
...EE_ACTION_BUTTONS,
|
||||
[MEMBERS_TAB_TYPES.user]: 'user-action-dropdown',
|
||||
[MEMBERS_TAB_TYPES.group]: 'group-action-buttons',
|
||||
[MEMBERS_TAB_TYPES.invite]: 'invite-action-buttons',
|
||||
[MEMBERS_TAB_TYPES.accessRequest]: 'access-request-action-buttons',
|
||||
...ACTION_BUTTONS,
|
||||
};
|
||||
|
||||
return dictionary[this.memberType];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { MEMBER_TYPES } from 'ee_else_ce/members/constants';
|
||||
import { MEMBERS_TAB_TYPES } from 'ee_else_ce/members/constants';
|
||||
import {
|
||||
isGroup,
|
||||
isDirectMember,
|
||||
|
|
@ -31,16 +31,16 @@ export default {
|
|||
},
|
||||
memberType() {
|
||||
if (this.isGroup) {
|
||||
return MEMBER_TYPES.group;
|
||||
return MEMBERS_TAB_TYPES.group;
|
||||
}
|
||||
if (this.isInvite) {
|
||||
return MEMBER_TYPES.invite;
|
||||
return MEMBERS_TAB_TYPES.invite;
|
||||
}
|
||||
if (this.isAccessRequest) {
|
||||
return MEMBER_TYPES.accessRequest;
|
||||
return MEMBERS_TAB_TYPES.accessRequest;
|
||||
}
|
||||
|
||||
return MEMBER_TYPES.user;
|
||||
return MEMBERS_TAB_TYPES.user;
|
||||
},
|
||||
isDirectMember() {
|
||||
return isDirectMember(this.member);
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import { __, s__ } from '~/locale';
|
|||
import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants';
|
||||
|
||||
// Overridden in EE
|
||||
export const EE_GROUPS_APP_OPTIONS = {};
|
||||
export const EE_PROJECTS_APP_OPTIONS = {};
|
||||
export const GROUPS_APP_OPTIONS = {};
|
||||
export const PROJECTS_APP_OPTIONS = {};
|
||||
|
||||
export const EE_ACTION_BUTTONS = {};
|
||||
export const ACTION_BUTTONS = {};
|
||||
|
||||
export const FIELD_KEY_ACCOUNT = 'account';
|
||||
export const FIELD_KEY_SOURCE = 'source';
|
||||
|
|
@ -161,7 +161,7 @@ export const AVAILABLE_FILTERED_SEARCH_TOKENS = [
|
|||
|
||||
export const AVATAR_SIZE = 48;
|
||||
|
||||
export const MEMBER_TYPES = Object.freeze({
|
||||
export const MEMBERS_TAB_TYPES = Object.freeze({
|
||||
user: 'user',
|
||||
group: 'group',
|
||||
invite: 'invite',
|
||||
|
|
|
|||
|
|
@ -1,33 +1,33 @@
|
|||
import { __, s__ } from '~/locale';
|
||||
import PlaceholdersTabApp from './components/placeholders/app.vue';
|
||||
import { MEMBER_TYPES, TAB_QUERY_PARAM_VALUES } from './constants';
|
||||
import { MEMBERS_TAB_TYPES, TAB_QUERY_PARAM_VALUES } from './constants';
|
||||
|
||||
// Overridden in EE
|
||||
export const TABS = [
|
||||
{
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
title: __('Members'),
|
||||
},
|
||||
{
|
||||
namespace: MEMBER_TYPES.group,
|
||||
namespace: MEMBERS_TAB_TYPES.group,
|
||||
title: __('Groups'),
|
||||
attrs: { 'data-testid': 'groups-list-tab' },
|
||||
queryParamValue: TAB_QUERY_PARAM_VALUES.group,
|
||||
},
|
||||
{
|
||||
namespace: MEMBER_TYPES.invite,
|
||||
namespace: MEMBERS_TAB_TYPES.invite,
|
||||
title: s__('Members|Pending invitations'),
|
||||
requiredPermissions: ['canManageMembers'],
|
||||
queryParamValue: TAB_QUERY_PARAM_VALUES.invite,
|
||||
},
|
||||
{
|
||||
namespace: MEMBER_TYPES.accessRequest,
|
||||
namespace: MEMBERS_TAB_TYPES.accessRequest,
|
||||
title: __('Access requests'),
|
||||
requiredPermissions: ['canManageAccessRequests'],
|
||||
queryParamValue: TAB_QUERY_PARAM_VALUES.accessRequest,
|
||||
},
|
||||
{
|
||||
namespace: MEMBER_TYPES.placeholder,
|
||||
namespace: MEMBERS_TAB_TYPES.placeholder,
|
||||
title: s__('UserMapping|Placeholders'),
|
||||
queryParamValue: TAB_QUERY_PARAM_VALUES.placeholder,
|
||||
component: PlaceholdersTabApp,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
<script>
|
||||
import { GlAlert, GlButton, GlFormGroup, GlForm, GlFormInput, GlFormSelect } from '@gitlab/ui';
|
||||
import {
|
||||
GlAlert,
|
||||
GlButton,
|
||||
GlFormGroup,
|
||||
GlForm,
|
||||
GlFormInput,
|
||||
GlFormSelect,
|
||||
GlSprintf,
|
||||
} from '@gitlab/ui';
|
||||
import HelpPageLink from '~/vue_shared/components/help_page_link/help_page_link.vue';
|
||||
import createPackagesProtectionRuleMutation from '~/packages_and_registries/settings/project/graphql/mutations/create_packages_protection_rule.mutation.graphql';
|
||||
import { s__, __ } from '~/locale';
|
||||
|
||||
|
|
@ -20,11 +29,16 @@ export default {
|
|||
GlFormGroup,
|
||||
GlAlert,
|
||||
GlForm,
|
||||
GlSprintf,
|
||||
HelpPageLink,
|
||||
},
|
||||
inject: ['projectPath'],
|
||||
i18n: {
|
||||
PACKAGES_PROTECTION_RULES_SAVED_SUCCESS_MESSAGE,
|
||||
PACKAGES_PROTECTION_RULES_SAVED_ERROR_MESSAGE,
|
||||
packageNamePatternInputHelpText: s__(
|
||||
'PackageRegistry|%{linkStart}Wildcards%{linkEnd} such as `@my-scope/my-package-*` are supported.',
|
||||
),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -132,6 +146,17 @@ export default {
|
|||
required
|
||||
:disabled="isFieldDisabled"
|
||||
/>
|
||||
<template #description>
|
||||
<gl-sprintf :message="$options.i18n.packageNamePatternInputHelpText">
|
||||
<template #link="{ content }">
|
||||
<help-page-link
|
||||
href="user/packages/package_registry/package_protection_rules.md"
|
||||
target="_blank"
|
||||
>{{ content }}</help-page-link
|
||||
>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
</gl-form-group>
|
||||
|
||||
<gl-form-group
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
|
|||
import initInviteGroupsModal from '~/invite_members/init_invite_groups_modal';
|
||||
import { s__ } from '~/locale';
|
||||
import { initMembersApp } from '~/members';
|
||||
import { EE_GROUPS_APP_OPTIONS, MEMBER_TYPES } from 'ee_else_ce/members/constants';
|
||||
import { GROUPS_APP_OPTIONS, MEMBERS_TAB_TYPES } from 'ee_else_ce/members/constants';
|
||||
import { groupLinkRequestFormatter } from '~/members/utils';
|
||||
|
||||
const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
|
||||
const APP_OPTIONS = {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
tableFields: SHARED_FIELDS.concat(['source', 'activity']),
|
||||
tableSortableFields: [
|
||||
'account',
|
||||
|
|
@ -27,7 +27,7 @@ const APP_OPTIONS = {
|
|||
recentSearchesStorageKey: 'group_members',
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.group]: {
|
||||
[MEMBERS_TAB_TYPES.group]: {
|
||||
tableFields: SHARED_FIELDS.concat(['source', 'granted']),
|
||||
requestFormatter: groupLinkRequestFormatter,
|
||||
filteredSearchBar: {
|
||||
|
|
@ -38,7 +38,7 @@ const APP_OPTIONS = {
|
|||
recentSearchesStorageKey: 'group_links_members',
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.invite]: {
|
||||
[MEMBERS_TAB_TYPES.invite]: {
|
||||
tableFields: SHARED_FIELDS.concat('invited'),
|
||||
requestFormatter: groupMemberRequestFormatter,
|
||||
filteredSearchBar: {
|
||||
|
|
@ -49,11 +49,11 @@ const APP_OPTIONS = {
|
|||
recentSearchesStorageKey: 'group_invited_members',
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.accessRequest]: {
|
||||
[MEMBERS_TAB_TYPES.accessRequest]: {
|
||||
tableFields: SHARED_FIELDS.concat('requested'),
|
||||
requestFormatter: groupMemberRequestFormatter,
|
||||
},
|
||||
...EE_GROUPS_APP_OPTIONS,
|
||||
...GROUPS_APP_OPTIONS,
|
||||
};
|
||||
|
||||
initMembersApp(document.querySelector('.js-group-members-list-app'), APP_OPTIONS);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { EE_PROJECTS_APP_OPTIONS, MEMBER_TYPES } from 'ee_else_ce/members/constants';
|
||||
import { PROJECTS_APP_OPTIONS, MEMBERS_TAB_TYPES } from 'ee_else_ce/members/constants';
|
||||
import initImportProjectMembersTrigger from '~/invite_members/init_import_project_members_trigger';
|
||||
import initImportProjectMembersModal from '~/invite_members/init_import_project_members_modal';
|
||||
import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
|
||||
|
|
@ -15,7 +15,7 @@ initImportProjectMembersTrigger();
|
|||
|
||||
const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
|
||||
initMembersApp(document.querySelector('.js-project-members-list-app'), {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
tableFields: SHARED_FIELDS.concat(['source', 'activity']),
|
||||
tableSortableFields: [
|
||||
'account',
|
||||
|
|
@ -34,7 +34,7 @@ initMembersApp(document.querySelector('.js-project-members-list-app'), {
|
|||
recentSearchesStorageKey: 'project_members',
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.group]: {
|
||||
[MEMBERS_TAB_TYPES.group]: {
|
||||
tableFields: SHARED_FIELDS.concat(['source', 'granted']),
|
||||
requestFormatter: groupLinkRequestFormatter,
|
||||
filteredSearchBar: {
|
||||
|
|
@ -45,13 +45,13 @@ initMembersApp(document.querySelector('.js-project-members-list-app'), {
|
|||
recentSearchesStorageKey: 'project_group_links',
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.invite]: {
|
||||
[MEMBERS_TAB_TYPES.invite]: {
|
||||
tableFields: SHARED_FIELDS.concat('invited'),
|
||||
requestFormatter: projectMemberRequestFormatter,
|
||||
},
|
||||
[MEMBER_TYPES.accessRequest]: {
|
||||
[MEMBERS_TAB_TYPES.accessRequest]: {
|
||||
tableFields: SHARED_FIELDS.concat('requested'),
|
||||
requestFormatter: projectMemberRequestFormatter,
|
||||
},
|
||||
...EE_PROJECTS_APP_OPTIONS,
|
||||
...PROJECTS_APP_OPTIONS,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ export default {
|
|||
:title="emptyStateTitle"
|
||||
/>
|
||||
<div v-else>
|
||||
<div class="-gl-my-3 gl-mx-n3 gl-display-flex gl-flex-wrap">
|
||||
<div class="-gl-my-3 -gl-mx-3 gl-display-flex gl-flex-wrap">
|
||||
<div v-for="user in users" :key="user.id" class="gl-p-3 gl-w-full gl-md-w-half gl-lg-w-25p">
|
||||
<gl-avatar-link
|
||||
:href="user.web_url"
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ export default {
|
|||
<gl-alert
|
||||
v-if="alertMessage"
|
||||
variant="warning"
|
||||
class="-gl-mt-5 gl-mb-4 gl-mx-n5"
|
||||
class="-gl-mt-5 gl-mb-4 -gl-mx-5"
|
||||
@dismiss="dismissAlert"
|
||||
>
|
||||
{{ alertMessage }}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ export default {
|
|||
:work-item-type="issue.type"
|
||||
event-namespace="relatedIssue"
|
||||
data-testid="related-issuable-content"
|
||||
class="gl-mx-n2"
|
||||
class="-gl-mx-2"
|
||||
@relatedIssueRemoveRequest="$emit('relatedIssueRemoveRequest', $event)"
|
||||
/>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ export default {
|
|||
<template>
|
||||
<div
|
||||
:id="`${targetId}-flyout`"
|
||||
class="gl-fixed gl-p-4 gl-mx-n1 gl-z-9999 gl-max-h-full gl-overflow-y-auto"
|
||||
class="gl-fixed gl-p-4 -gl-mx-1 gl-z-9999 gl-max-h-full gl-overflow-y-auto"
|
||||
@mouseover="$emit('mouseover')"
|
||||
@mouseleave="$emit('mouseleave')"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
<div class="gl-mt-5">
|
||||
<div class="gl-display-flex gl-align-items-center gl-flex-wrap -gl-my-3 gl-mx-n3">
|
||||
<div class="gl-display-flex gl-align-items-center gl-flex-wrap -gl-my-3 -gl-mx-3">
|
||||
<div
|
||||
v-for="{ id, label, backgroundColor, formattedValue } in computedSections"
|
||||
:key="id"
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ export default {
|
|||
>
|
||||
<a
|
||||
v-if="showBlameLink"
|
||||
class="gl-select-none !gl-shadow-none file-line-blame gl-mx-n2"
|
||||
class="gl-select-none !gl-shadow-none file-line-blame -gl-mx-2"
|
||||
:href="`${blamePath}#L${line}`"
|
||||
></a>
|
||||
<a
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ export default {
|
|||
>
|
||||
<template #meta>
|
||||
<div class="gl-px-2">
|
||||
<div class="gl-mx-n2 gl-display-flex gl-align-items-center gl-flex-wrap">
|
||||
<div class="-gl-mx-2 gl-display-flex gl-align-items-center gl-flex-wrap">
|
||||
<div class="gl-px-2">
|
||||
<gl-icon
|
||||
v-if="visibility"
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ export default {
|
|||
>
|
||||
<template #meta>
|
||||
<div class="gl-px-2">
|
||||
<div class="gl-mx-n2 gl-display-flex gl-align-items-center gl-flex-wrap">
|
||||
<div class="-gl-mx-2 gl-display-flex gl-align-items-center gl-flex-wrap">
|
||||
<div class="gl-px-2">
|
||||
<gl-icon
|
||||
v-if="visibility"
|
||||
|
|
@ -306,7 +306,7 @@ export default {
|
|||
</gl-truncate-text>
|
||||
<div v-if="hasTopics" class="gl-mt-3" data-testid="project-topics">
|
||||
<div
|
||||
class="gl-w-full gl-display-inline-flex gl-flex-wrap gl-font-base gl-font-weight-normal gl-align-items-center gl-mx-n2 -gl-my-2"
|
||||
class="gl-w-full gl-display-inline-flex gl-flex-wrap gl-font-base gl-font-weight-normal gl-align-items-center -gl-mx-2 -gl-my-2"
|
||||
>
|
||||
<span class="gl-p-2 gl-font-sm gl-text-secondary">{{ $options.i18n.topics }}:</span>
|
||||
<div v-for="topic in visibleTopics" :key="topic" class="gl-p-2">
|
||||
|
|
@ -330,7 +330,7 @@ export default {
|
|||
</gl-sprintf>
|
||||
</div>
|
||||
<gl-popover :target="topicsPopoverTarget" :title="$options.i18n.moreTopics">
|
||||
<div class="gl-font-base gl-font-weight-normal gl-mx-n2 -gl-my-2">
|
||||
<div class="gl-font-base gl-font-weight-normal -gl-mx-2 -gl-my-2">
|
||||
<div
|
||||
v-for="topic in popoverTopics"
|
||||
:key="topic"
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default {
|
|||
class="gl-p-0! gl-absolute gl-z-3 diff-line-num gl-border-r gl-display-flex line-links line-numbers"
|
||||
>
|
||||
<a
|
||||
class="gl-select-none !gl-shadow-none file-line-blame gl-mx-n2 gl-flex-grow-1"
|
||||
class="gl-select-none !gl-shadow-none file-line-blame -gl-mx-2 gl-flex-grow-1"
|
||||
:href="`${blamePath}${pageSearchString}#L${number}`"
|
||||
></a>
|
||||
<a
|
||||
|
|
|
|||
|
|
@ -243,10 +243,14 @@ module ApplicationHelper
|
|||
ApplicationHelper.community_forum
|
||||
end
|
||||
|
||||
def promo_url
|
||||
def self.promo_url
|
||||
"https://#{promo_host}"
|
||||
end
|
||||
|
||||
def promo_url
|
||||
ApplicationHelper.promo_url
|
||||
end
|
||||
|
||||
def support_url
|
||||
Gitlab::CurrentSettings.current_application_settings.help_page_support_url.presence || "#{promo_url}/get-help/"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ module EventsHelper
|
|||
end
|
||||
|
||||
def user_profile_activity_classes
|
||||
current_path?('users#activity') ? ' gl-font-weight-semibold gl-text-black-normal' : ''
|
||||
current_path?('users#activity') ? ' gl-font-semibold gl-text-black-normal' : ''
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ListboxHelper
|
||||
DROPDOWN_CONTAINER_CLASSES = %w[dropdown b-dropdown gl-dropdown js-redirect-listbox].freeze
|
||||
DROPDOWN_BUTTON_CLASSES = %w[btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle].freeze
|
||||
DROPDOWN_INNER_CLASS = 'gl-dropdown-button-text'
|
||||
DROPDOWN_ICON_CLASS = 'gl-button-icon dropdown-chevron gl-icon'
|
||||
DROPDOWN_CONTAINER_CLASSES = %w[gl-new-dropdown js-redirect-listbox].freeze
|
||||
DROPDOWN_BUTTON_CLASSES = 'gl-new-dropdown-toggle'
|
||||
DROPDOWN_INNER_CLASS = 'gl-new-dropdown-button-text'
|
||||
DROPDOWN_ICON_CLASS = 'gl-button-icon gl-new-dropdown-chevron gl-icon'
|
||||
|
||||
# Creates a listbox component with redirect behavior.
|
||||
#
|
||||
|
|
@ -46,7 +46,8 @@ module ListboxHelper
|
|||
selected = selected_option[:value]
|
||||
end
|
||||
|
||||
button = button_tag(type: :button, class: DROPDOWN_BUTTON_CLASSES) do
|
||||
button = render Pajamas::ButtonComponent.new(variant: :default,
|
||||
button_options: { class: DROPDOWN_BUTTON_CLASSES }) do
|
||||
content_tag(:span, selected_option[:text], class: DROPDOWN_INNER_CLASS) +
|
||||
sprite_icon('chevron-down', css_class: DROPDOWN_ICON_CLASS)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ module MergeRequestsHelper
|
|||
end
|
||||
|
||||
def merge_request_header(project, merge_request)
|
||||
link_to_author = link_to_member(project, merge_request.author, size: 24, extra_class: 'gl-font-weight-bold gl-mr-2', avatar: false)
|
||||
link_to_author = link_to_member(project, merge_request.author, size: 24, extra_class: 'gl-font-bold gl-mr-2', avatar: false)
|
||||
copy_action_description = _('Copy branch name')
|
||||
copy_action_shortcut = 'b'
|
||||
copy_button_title = "#{copy_action_description} <kbd class='flat ml-1' aria-hidden=true>#{copy_action_shortcut}</kbd>"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
= render_if_exists 'admin/users/auditor_user_badge'
|
||||
= render_if_exists 'admin/users/gma_user_badge'
|
||||
|
||||
.gl-my-3.gl-display-flex.gl-flex-wrap.-gl-my-2.gl-mx-n2
|
||||
.gl-my-3.gl-display-flex.gl-flex-wrap.-gl-my-2.-gl-mx-2
|
||||
- if @user != current_user
|
||||
- if impersonation_enabled?
|
||||
.gl-p-2
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
.todos-filters
|
||||
.issues-details-filters.row-content-block.second-block
|
||||
= form_tag todos_filter_path(without: [:project_id, :author_id, :type, :action_id]), method: :get, class: 'filter-form gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row' do
|
||||
.filter-categories.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-flex-grow-1.gl-flex-wrap.gl-mx-n2
|
||||
.filter-categories.gl-display-flex.gl-flex-direction-column.gl-md-flex-direction-row.gl-flex-grow-1.gl-flex-wrap.-gl-mx-2
|
||||
.filter-item.gl-m-2
|
||||
- if params[:group_id].present?
|
||||
= hidden_field_tag(:group_id, params[:group_id])
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.gl-text-center.gl-pt-5
|
||||
%label.gl-font-weight-normal
|
||||
%label.gl-font-normal
|
||||
= _("Register with:")
|
||||
.gl-display-flex.gl-flex-direction-column.gl-gap-3
|
||||
- providers.each do |provider|
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
= gl_tabs_nav({ class: 'gl-mx-n5 gl-my-5 nav-justified' }) do
|
||||
= gl_tabs_nav({ class: '-gl-mx-5 gl-my-5 nav-justified' }) do
|
||||
= gl_tab_link_to tab_title, '#', { item_active: true, class: 'gl-cursor-default!', tabindex: '-1', data: { testid: 'sign-in-tab' } }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
- render_standard_signin = admin_mode ? allow_admin_mode_password_authentication_for_web? : password_authentication_enabled_for_web?
|
||||
|
||||
= gl_tabs_nav({ class: 'gl-mx-n5 gl-my-5 nav-justified', id: 'js-signin-tabs' }) do
|
||||
= gl_tabs_nav({ class: '-gl-mx-5 gl-my-5 nav-justified', id: 'js-signin-tabs' }) do
|
||||
- if crowd_enabled?
|
||||
= gl_tab_link_to _('Crowd'), '#crowd', { item_active: form_based_auth_provider_has_active_class?(:crowd), data: { toggle: 'tab' } }
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
.gl-mb-5
|
||||
= render Pajamas::CardComponent.new do |c|
|
||||
- c.with_body do
|
||||
%p.gl-mt-0.gl-mb-3.gl-font-weight-bold
|
||||
%p.gl-mt-0.gl-mb-3.gl-font-bold
|
||||
= _("Can't scan the code?")
|
||||
%p.gl-mt-0.gl-mb-3
|
||||
= _("To add the entry manually, provide the following details to the application on your phone.")
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
%ul.related-merge-requests.content-list
|
||||
- @related_branches.each do |branch|
|
||||
%li.list-item{ class: "gl-py-0! gl-border-0!" }
|
||||
.item-body.gl-display-flex.gl-align-items-center.gl-px-3.gl-pr-2.gl-mx-n2
|
||||
.item-body.gl-display-flex.gl-align-items-center.gl-px-3.gl-pr-2.-gl-mx-2
|
||||
.item-contents.gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-flex-grow-1.gl-min-h-7
|
||||
.item-title.gl-display-flex.mb-xl-0.gl-min-w-0.gl-align-items-center
|
||||
- if branch[:pipeline_status].present?
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
- max_project_topic_length = 15
|
||||
|
||||
- if project.topics.present?
|
||||
.gl-w-full.gl-display-inline-flex.gl-flex-wrap.gl-font-base.gl-font-weight-normal.gl-align-items-center.gl-mx-n2.-gl-my-2{ 'data-testid': 'project_topic_list' }
|
||||
.gl-w-full.gl-display-inline-flex.gl-flex-wrap.gl-font-base.gl-font-weight-normal.gl-align-items-center.-gl-mx-2.-gl-my-2{ 'data-testid': 'project_topic_list' }
|
||||
- project.topics_to_show.each do |topic|
|
||||
- explore_project_topic_path = topic_explore_projects_cleaned_path(topic_name: topic[:name])
|
||||
- if topic[:title].length > max_project_topic_length
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ en:
|
|||
email: Allows read-only access to the user's primary email address using OpenID Connect
|
||||
admin_mode: Admin Mode is a functionality designed to limit the access level of administrator's personal access tokens.
|
||||
create_runner: Grants create access to the runners
|
||||
manage_runner: Grants access to manage the runners
|
||||
k8s_proxy: Grants permission to perform Kubernetes API calls using the agent for Kubernetes.
|
||||
ai_features: Access to API endpoints needed for GitLab Duo features
|
||||
read_service_ping: Grant access to download Service Ping payload via API when authenticated as an admin user
|
||||
|
|
@ -113,6 +114,8 @@ en:
|
|||
Grants permission to perform API actions as an administrator, when Admin Mode is enabled.
|
||||
create_runner:
|
||||
Grants create access to the runners.
|
||||
manage_runner:
|
||||
Grants access to manage the runners.
|
||||
k8s_proxy:
|
||||
Grants permission to perform Kubernetes API calls using the agent for Kubernetes.
|
||||
read_service_ping:
|
||||
|
|
@ -150,6 +153,8 @@ en:
|
|||
Grants permission to perform API actions as an administrator, when Admin Mode is enabled.
|
||||
create_runner:
|
||||
Grants permission to create runners in a group.
|
||||
manage_runner:
|
||||
Grants access to manage the runners in a group.
|
||||
k8s_proxy:
|
||||
Grants permission to perform Kubernetes API calls using the agent for Kubernetes in a group.
|
||||
project_access_token_scope_desc:
|
||||
|
|
@ -171,6 +176,8 @@ en:
|
|||
Grants write access to GitLab Observability.
|
||||
create_runner:
|
||||
Grants create access to the runners.
|
||||
manage_runner:
|
||||
Grants access to manage the runners.
|
||||
k8s_proxy:
|
||||
Grants permission to perform Kubernetes API calls using the agent for Kubernetes.
|
||||
ai_features:
|
||||
|
|
|
|||
|
|
@ -11,5 +11,7 @@ description: a temporary table to store the orphaned notes records that have bee
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/146023
|
||||
milestone: "16.10"
|
||||
gitlab_schema: gitlab_main_cell
|
||||
removed_in_milestone: "17.1"
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154317
|
||||
sharding_key:
|
||||
project_id: projects
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddAllSeatsUsedNotificationAtColumnToNamespaceLimit < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
|
||||
def change
|
||||
add_column :namespace_limits, :last_seat_all_used_seats_notification_at, :datetime_with_timezone
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DropTempNotesBackupTable < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.1'
|
||||
|
||||
TABLE_NAME = :temp_notes_backup
|
||||
|
||||
def up
|
||||
drop_table TABLE_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
execute "CREATE TABLE IF NOT EXISTS #{TABLE_NAME} (LIKE notes);"
|
||||
execute "ALTER TABLE #{TABLE_NAME} ADD PRIMARY KEY (id);"
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
7e59489752226c7f2832be54db5887db50519d894f308a4d405a904cfc5aed52
|
||||
|
|
@ -0,0 +1 @@
|
|||
77bc16c84599f4ec935eacc20cc1e4b58dc0f9b78c2c9f2d8b093e381ab06818
|
||||
|
|
@ -12240,7 +12240,8 @@ CREATE TABLE namespace_limits (
|
|||
temporary_storage_increase_ends_on date,
|
||||
pre_enforcement_notification_at timestamp with time zone,
|
||||
first_enforced_at timestamp with time zone,
|
||||
last_enforced_at timestamp with time zone
|
||||
last_enforced_at timestamp with time zone,
|
||||
last_seat_all_used_seats_notification_at timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE namespace_package_settings (
|
||||
|
|
@ -17040,40 +17041,6 @@ CREATE SEQUENCE target_branch_rules_id_seq
|
|||
|
||||
ALTER SEQUENCE target_branch_rules_id_seq OWNED BY target_branch_rules.id;
|
||||
|
||||
CREATE TABLE temp_notes_backup (
|
||||
note text,
|
||||
noteable_type character varying,
|
||||
author_id integer,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
project_id integer,
|
||||
attachment character varying,
|
||||
line_code character varying,
|
||||
commit_id character varying,
|
||||
noteable_id integer,
|
||||
system boolean NOT NULL,
|
||||
st_diff text,
|
||||
updated_by_id integer,
|
||||
type character varying,
|
||||
"position" text,
|
||||
original_position text,
|
||||
resolved_at timestamp without time zone,
|
||||
resolved_by_id integer,
|
||||
discussion_id character varying,
|
||||
note_html text,
|
||||
cached_markdown_version integer,
|
||||
change_position text,
|
||||
resolved_by_push boolean,
|
||||
review_id bigint,
|
||||
confidential boolean,
|
||||
last_edited_at timestamp with time zone,
|
||||
internal boolean NOT NULL,
|
||||
id bigint NOT NULL,
|
||||
namespace_id bigint,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE term_agreements (
|
||||
id integer NOT NULL,
|
||||
term_id integer NOT NULL,
|
||||
|
|
@ -22975,9 +22942,6 @@ ALTER TABLE ONLY tags
|
|||
ALTER TABLE ONLY target_branch_rules
|
||||
ADD CONSTRAINT target_branch_rules_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY temp_notes_backup
|
||||
ADD CONSTRAINT temp_notes_backup_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY term_agreements
|
||||
ADD CONSTRAINT term_agreements_pkey PRIMARY KEY (id);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ To set up your self-hosted model deployment infrastructure:
|
|||
1. Install the large language model (LLM) serving infrastructure.
|
||||
1. Install the GitLab AI Gateway.
|
||||
|
||||
- [Installation video guide](https://youtu.be/UNmD9-sgUvw)
|
||||
- [Installation video guide (French version)](https://www.youtube.com/watch?v=aU5vnzO-MSM)
|
||||
|
||||
## Step 1: Install LLM serving infrastructure
|
||||
|
||||
Install one of the following GitLab-approved LLM models:
|
||||
|
|
|
|||
|
|
@ -49,6 +49,11 @@ GitLab and the runner are then connected.
|
|||
|
||||
Get a list of runners available to the user.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator of or have the Owner role in the target namespace or project.
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
|
||||
```plaintext
|
||||
GET /runners
|
||||
GET /runners?scope=active
|
||||
|
|
@ -127,6 +132,11 @@ DETAILS:
|
|||
Get a list of all runners in the GitLab instance (project and shared). Access
|
||||
is restricted to users with administrator access.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator of or have the Owner role in the target namespace or project.
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
|
||||
```plaintext
|
||||
GET /runners/all
|
||||
GET /runners/all?scope=online
|
||||
|
|
@ -226,11 +236,13 @@ To view more than the first 20 runners, use [pagination](rest/index.md#paginatio
|
|||
|
||||
Get details of a runner.
|
||||
|
||||
At least the Maintainer role is required to get runner details at the
|
||||
project and group level.
|
||||
|
||||
Instance-level runner details via this endpoint are available to all authenticated users.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must at least the Developer role in the target namespace or project.
|
||||
- An access token with the `manage_runner` scope and the appropriate role.
|
||||
|
||||
```plaintext
|
||||
GET /runners/:id
|
||||
```
|
||||
|
|
@ -313,6 +325,13 @@ Update details of a runner.
|
|||
PUT /runners/:id
|
||||
```
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
- For `group_type`, you must have the Owner role in the target namespace.
|
||||
- For `project_type`, you must have at least the Maintainer role in the target project.
|
||||
- An access token with the `manage_runner` scope and the appropriate role.
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|--------------------|---------|----------|-------------------------------------------------------------------------------------------------|
|
||||
| `id` | integer | yes | The ID of a runner |
|
||||
|
|
@ -390,6 +409,13 @@ Example response:
|
|||
|
||||
Pause a runner.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
- For `group_type`, you must have the Owner role in the target namespace.
|
||||
- For `project_type`, you must have at least the Maintainer role in the target project.
|
||||
- An access token with the `manage_runner` scope and the appropriate role.
|
||||
|
||||
```plaintext
|
||||
PUT --form "paused=true" /runners/:runner_id
|
||||
|
||||
|
|
@ -515,6 +541,10 @@ Example response:
|
|||
|
||||
List all runners available in the project, including from ancestor groups and [any allowed shared runners](../ci/runners/runners_scope.md#enable-instance-runners-for-a-project).
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator of or have at least the Maintainer role in the target project.
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/runners
|
||||
GET /projects/:id/runners?scope=active
|
||||
|
|
@ -589,6 +619,12 @@ Example response:
|
|||
|
||||
Enable an available project runner in the project.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
- For `group_type`, you must have the Owner role in the target namespace.
|
||||
- For `project_type`, you must have at least the Maintainer role in the target project.
|
||||
|
||||
```plaintext
|
||||
POST /projects/:id/runners
|
||||
```
|
||||
|
|
@ -633,6 +669,12 @@ Disable a project runner from the project. It works only if the project isn't
|
|||
the only project associated with the specified runner. If so, an error is
|
||||
returned. Use the call to [delete a runner](#delete-a-runner) instead.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
- For `group_type`, you must have the Owner role in the target namespace.
|
||||
- For `project_type`, you must have at least the Maintainer role in the target project.
|
||||
|
||||
```plaintext
|
||||
DELETE /projects/:id/runners/:runner_id
|
||||
```
|
||||
|
|
@ -650,6 +692,10 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git
|
|||
|
||||
List all runners available in the group as well as its ancestor groups, including [any allowed shared runners](../ci/runners/runners_scope.md#enable-instance-runners-for-a-group).
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator or have the Maintainer role of the target namespace.
|
||||
|
||||
```plaintext
|
||||
GET /groups/:id/runners
|
||||
GET /groups/:id/runners?type=group_type
|
||||
|
|
@ -788,6 +834,13 @@ There are two ways to delete a runner:
|
|||
|
||||
To delete the runner by ID, use your access token with the runner's ID:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
- For `group_type`, you must have the Owner role in the target namespace.
|
||||
- For `project_type`, you must have at least the Maintainer role in the target project.
|
||||
- An access token with the `manage_runner` scope and the appropriate role.
|
||||
|
||||
```plaintext
|
||||
DELETE /runners/:id
|
||||
```
|
||||
|
|
@ -804,6 +857,11 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git
|
|||
|
||||
To delete the runner by using its authentication token:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator of or have the Owner role in the target namespace or project.
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
|
||||
```plaintext
|
||||
DELETE /runners
|
||||
```
|
||||
|
|
@ -910,6 +968,13 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
|
|||
|
||||
Reset the runner's authentication token by using its runner ID.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
- For `group_type`, you must have the Owner role in the target namespace.
|
||||
- For `project_type`, you must have at least the Maintainer role in the target project.
|
||||
- An access token with the `manage_runner` scope and the appropriate role.
|
||||
|
||||
```plaintext
|
||||
POST /runners/:id/reset_authentication_token
|
||||
```
|
||||
|
|
@ -936,6 +1001,11 @@ Example response:
|
|||
|
||||
Reset the runner's authentication token by using the current token's value as an input.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator of or have the Owner role in the target namespace or project.
|
||||
- For `instance_type`, you must be an administrator of the GitLab instance.
|
||||
|
||||
```plaintext
|
||||
POST /runners/reset_authentication_token
|
||||
```
|
||||
|
|
|
|||
|
|
@ -42,6 +42,79 @@ This change makes the order distinct so we have "stable" sorting.
|
|||
NOTE:
|
||||
To make the query efficient, we need an index covering both columns: `(created_at, id)`. The order of the columns **should match** the columns in the `ORDER BY` clause.
|
||||
|
||||
### Incremental sorting
|
||||
|
||||
In PostgreSQL 13 incremental sorting was added which can help introducing a tie-breaker column to the `ORDER BY` clause without adding or replacing an index. Also, with incremental sorting, introducing a new keyset-paginated database query can happen before the new index is built (async indexes). Incremental sorting is enabled by default.
|
||||
|
||||
Consider the following database query:
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM merge_requests
|
||||
WHERE author_id = 1
|
||||
ORDER BY created_at ASC
|
||||
LIMIT 20
|
||||
```
|
||||
|
||||
The query will read 20 rows using the following index:
|
||||
|
||||
```plaintext
|
||||
"index_merge_requests_on_author_id_and_created_at" btree (author_id, created_at)
|
||||
```
|
||||
|
||||
Using this query with keyset pagination is not possible because the `created_at` column is not unique. Let's add a tie-breaker column:
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM merge_requests
|
||||
WHERE author_id = 1
|
||||
ORDER BY created_at ASC, id ASC
|
||||
LIMIT 20
|
||||
```
|
||||
|
||||
Execution plan:
|
||||
|
||||
```plaintext
|
||||
Limit (cost=1.99..30.97 rows=20 width=910) (actual time=1.217..1.220 rows=20 loops=1)
|
||||
Buffers: shared hit=33 read=2
|
||||
I/O Timings: read=0.983 write=0.000
|
||||
-> Incremental Sort (cost=1.99..919.33 rows=633 width=910) (actual time=1.215..1.216 rows=20 loops=1)
|
||||
Sort Key: merge_requests.created_at, merge_requests.id
|
||||
Buffers: shared hit=33 read=2
|
||||
I/O Timings: read=0.983 write=0.000
|
||||
-> Index Scan using index_merge_requests_on_author_id_and_created_at on public.merge_requests (cost=0.57..890.84 rows=633 width=910) (actual time=0.038..1.139 rows=22 loops=1)
|
||||
Index Cond: (merge_requests.author_id = 1)
|
||||
Buffers: shared hit=24 read=2
|
||||
I/O Timings: read=0.983 write=0.000
|
||||
```
|
||||
|
||||
As you can see the query read 22 rows using the same index. The database compared the 20th, 21th and 22th value of the `created_at` column and determined that the 22th value differ thus checking the next record is not needed. In this example the 20th and 21th column had the same `created_at` value.
|
||||
|
||||
Incremental sorting works well with timestamp columns where duplicated values are unlikely hence the incremental sorting will perform badly or won't be used at all when the column has very few distinct values (like an enum).
|
||||
|
||||
As an example, when incremental sorting is disabled, the database reads all merge requests records by the author and sorts data in memory.
|
||||
|
||||
```sql
|
||||
set enable_incremental_sort=off;
|
||||
```
|
||||
|
||||
```plaintext
|
||||
Limit (cost=907.69..907.74 rows=20 width=910) (actual time=2.911..2.917 rows=20 loops=1)
|
||||
Buffers: shared hit=1004
|
||||
-> Sort (cost=907.69..909.27 rows=633 width=910) (actual time=2.908..2.911 rows=20 loops=1)
|
||||
Sort Key: created_at, id
|
||||
Sort Method: top-N heapsort Memory: 52kB
|
||||
Buffers: shared hit=1004
|
||||
-> Index Scan using index_merge_requests_on_author_id_and_created_at on merge_requests (cost=0.57..890.84 rows=633 width=910) (actual time=0.042..1.974 rows=1111 loops=1)
|
||||
Index Cond: (author_id = 1)
|
||||
Buffers: shared hit=1111
|
||||
Planning Time: 0.386 ms
|
||||
Execution Time: 3.000 ms
|
||||
(11 rows)
|
||||
```
|
||||
|
||||
In this example the database read 1111 rows and sorted the rows in memory.
|
||||
|
||||
## Ordering by joined table column
|
||||
|
||||
Oftentimes, we want to order the data by a column on a joined database table. The following example orders `issues` records by the `first_mentioned_in_commit_at` metric column:
|
||||
|
|
|
|||
|
|
@ -401,11 +401,11 @@ adds the start and end tags with the correct styling classes.
|
|||
|
||||
| Placeholder | Style |
|
||||
|-------------|-----------------------------------------|
|
||||
| success | `gl-font-weight-bold gl-text-green-500` |
|
||||
| danger | `gl-font-weight-bold gl-text-red-500` |
|
||||
| critical | `gl-font-weight-bold gl-text-red-800` |
|
||||
| same | `gl-font-weight-bold gl-text-gray-700` |
|
||||
| strong | `gl-font-weight-bold` |
|
||||
| success | `gl-font-bold gl-text-green-500` |
|
||||
| danger | `gl-font-bold gl-text-red-500` |
|
||||
| critical | `gl-font-bold gl-text-red-800` |
|
||||
| same | `gl-font-bold gl-text-gray-700` |
|
||||
| strong | `gl-font-bold` |
|
||||
| small | `gl-font-sm` |
|
||||
|
||||
## Action buttons
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ for a description on what each tag semantically means.
|
|||
<!-- good - prefer semantic classes used accurately -->
|
||||
<section class="...">
|
||||
<p>
|
||||
Simply visit your <span class="gl-font-weight-bold">Settings</span> to say hello to the world.
|
||||
Simply visit your <span class="gl-font-bold">Settings</span> to say hello to the world.
|
||||
</p>
|
||||
<footer class="...">...</footer>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ different actions. See the following table for all available scopes.
|
|||
| `profile` | Grants read-only access to the user's profile data using [OpenID Connect](openid_connect_provider.md). |
|
||||
| `email` | Grants read-only access to the user's primary email address using [OpenID Connect](openid_connect_provider.md). |
|
||||
| `create_runner` | Grants permission to create runners. |
|
||||
| `manage_runner` | Grants permission to manage runners. |
|
||||
| `k8s_proxy` | Grants permission to perform Kubernetes API calls using the agent for Kubernetes. |
|
||||
|
||||
At any time you can revoke any access by selecting **Revoke**.
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ DETAILS:
|
|||
**Tier:** Premium and Ultimate with [GitLab Duo Pro or Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Helps you write code more efficiently by showing code suggestions as you type.
|
||||
- LLM for code completion: Vertex AI Codey [`code-gecko`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-completion)
|
||||
- Helps you write code more efficiently by generating code and showing suggestions as you type.
|
||||
- Large language model (LLM) for code completion: Vertex AI Codey [`code-gecko`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-completion)
|
||||
- LLM for code generation: Anthropic [`claude-3-sonnet-20240229`](https://docs.anthropic.com/claude/docs/models-overview)
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://youtu.be/ds7SG1wgcVM)
|
||||
- [View documentation](project/repository/code_suggestions/index.md).
|
||||
|
|
@ -44,9 +44,8 @@ DETAILS:
|
|||
**Tier:** GitLab.com and Self-managed: For a limited time, Premium and Ultimate. In the future, [GitLab Duo Pro or Enterprise](../subscriptions/subscription-add-ons.md). <br>GitLab Dedicated: GitLab Duo Pro or Enterprise.
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Processes and generates text and code in a conversational manner.
|
||||
Help you write and understand code faster, get up to speed on the status of projects,
|
||||
and quickly learn about GitLab.
|
||||
- Help you write and understand code faster, get up to speed on the status of projects,
|
||||
and quickly learn about GitLab by answering your questions in a chat window.
|
||||
- LLM: Anthropic [`claude-3-sonnet-20240229`](https://docs.anthropic.com/en/docs/models-overview#claude-3-a-new-generation-of-ai),
|
||||
Anthropic [`claude-3-haiku-20240307`](https://docs.anthropic.com/en/docs/models-overview#claude-3-a-new-generation-of-ai),
|
||||
[`claude-2.1`](https://docs.anthropic.com/en/docs/legacy-model-guide#anthropics-legacy-models),
|
||||
|
|
@ -66,7 +65,7 @@ DETAILS:
|
|||
**Tier:** Ultimate
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Assists in creating faster and higher-quality reviews by automatically suggesting reviewers for your merge request.
|
||||
- Helps create faster and higher-quality reviews by automatically suggesting reviewers for your merge request.
|
||||
- LLM: GitLab creates a machine learning model for each project, which is used to generate reviewers. [View the issue](https://gitlab.com/gitlab-org/modelops/applied-ml/applied-ml-updates/-/issues/10).
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=ivwZQgh4Rxw)
|
||||
- [View documentation](project/merge_requests/reviews/index.md#gitlab-duo-suggested-reviewers).
|
||||
|
|
@ -77,7 +76,7 @@ DETAILS:
|
|||
**Tier:** GitLab.com and Self-managed: For a limited time, Premium and Ultimate. In the future, [GitLab Duo Pro or Enterprise](../subscriptions/subscription-add-ons.md). <br>GitLab Dedicated: GitLab Duo Pro or Enterprise.
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Automates repetitive tasks and helps catch bugs early.
|
||||
- Helps catch bugs early by generating tests for the selected code.
|
||||
- LLM: Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison)
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=zWhwuixUkYU&list=PLFGfElNsQthYDx0A_FaNNfUm9NHsK6zED)
|
||||
- [View documentation](gitlab_duo_chat_examples.md#write-tests-in-the-ide).
|
||||
|
|
@ -88,7 +87,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Premium and Ultimate. In the future, [GitLab Duo Pro or Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Helps you understand code by explaining it in English language.
|
||||
- Helps you understand the selected code by explaining it more clearly.
|
||||
- LLM: Anthropic: [`claude-3-haiku-20240307`](https://docs.anthropic.com/en/docs/models-overview#claude-3-a-new-generation-of-ai)
|
||||
- View documentation for [explaining code in the IDE](../user/gitlab_duo_chat_examples.md#explain-code-in-the-ide).
|
||||
|
||||
|
|
@ -100,7 +99,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Efficiently communicates the impact of your merge request changes.
|
||||
- Helps populate a merge request more quickly by generating a description based on the code changes.
|
||||
- LLM: Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text)
|
||||
- [View documentation](project/merge_requests/ai_in_merge_requests.md#generate-a-description-by-summarizing-code-changes).
|
||||
|
||||
|
|
@ -110,7 +109,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Generates a description for the merge request based on the contents of the template.
|
||||
- Helps populate a merge request more quickly by generating a description based on the contents of the template.
|
||||
- LLM: Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text)
|
||||
- [View documentation](project/merge_requests/ai_in_merge_requests.md#generate-a-description-from-a-template).
|
||||
|
||||
|
|
@ -120,7 +119,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Helps you remediate vulnerabilities more efficiently, boost your skills, and write more secure code.
|
||||
- Helps you understand vulnerabilities, how they can be exploited, and how to fix them.
|
||||
- LLM: Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text). If degraded performance, then Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison).
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://youtu.be/ctD_qcVpIJY)
|
||||
- [View documentation](application_security/vulnerabilities/index.md#explaining-a-vulnerability).
|
||||
|
|
@ -143,7 +142,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Assists with quickly getting everyone up to speed on lengthy conversations to help ensure you are all on the same page.
|
||||
- Helps everyone get up to speed by summarizing lengthy conversations.
|
||||
- LLM: Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison)
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=IcdxLfTIUgc)
|
||||
- [View documentation](ai_experiments.md#summarize-issue-discussions-with-discussion-summary).
|
||||
|
|
@ -154,7 +153,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Generates issue descriptions.
|
||||
- Helps populate an issue more quickly by generating a more in-depth description, based on a short summary you provide.
|
||||
- LLM: Anthropic [`Claude-2.1`](https://docs.anthropic.com/claude/docs/models-overview#model-comparison)
|
||||
- [View documentation](ai_experiments.md#summarize-an-issue-with-issue-description-generation).
|
||||
|
||||
|
|
@ -164,7 +163,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Helps ease merge request handoff between authors and reviewers and help reviewers efficiently understand suggestions.
|
||||
- Helps make merge request handover to reviewers easier by summarizing all the comments in a merge request review.
|
||||
- LLM: Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text)
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=Bx6Zajyuy9k&list=PLFGfElNsQthYDx0A_FaNNfUm9NHsK6zED)
|
||||
- [View documentation](project/merge_requests/ai_in_merge_requests.md#summarize-a-code-review).
|
||||
|
|
@ -175,7 +174,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Generates a merge request containing the changes required to mitigate a vulnerability.
|
||||
- Help resolve a vulnerability by generating a merge request that addresses it.
|
||||
- LLM: Vertex AI Codey [`code-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/code-generation)
|
||||
- [View documentation](application_security/vulnerabilities/index.md#vulnerability-resolution).
|
||||
|
||||
|
|
@ -185,7 +184,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Premium and Ultimate. In the future, [GitLab Duo Pro or Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Helps you understand code by explaining it in English language.
|
||||
- Helps you understand the selected code by explaining it more clearly.
|
||||
- LLM: Anthropic: [`claude-3-haiku-20240307`](https://docs.anthropic.com/en/docs/models-overview#claude-3-a-new-generation-of-ai)
|
||||
- View documentation for explaining code in:
|
||||
- [A file](../user/project/repository/code_explain.md).
|
||||
|
|
@ -197,7 +196,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Assists you in determining the root cause for a CI/CD job failure by analyzing the logs.
|
||||
- Helps you determine the root cause for a CI/CD job failure by analyzing the logs.
|
||||
- LLM: Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text)
|
||||
- [View documentation](ai_experiments.md#root-cause-analysis).
|
||||
|
||||
|
|
@ -207,7 +206,7 @@ DETAILS:
|
|||
**Tier:** GitLab.com and Self-managed: For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md). <br>GitLab Dedicated: GitLab Duo Enterprise.
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Assists you with predicting productivity metrics and identifying anomalies across your software development lifecycle.
|
||||
- Helps you improve planning and decision-making by predicting productivity metrics and identifying anomalies across your software development lifecycle.
|
||||
- LLM: Statistical forecasting
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=6u8_8QQ5pEQ&list=PLFGfElNsQthYDx0A_FaNNfUm9NHsK6zED)
|
||||
- [View documentation](ai_experiments.md#forecast-deployment-frequency-with-value-stream-forecasting).
|
||||
|
|
@ -228,7 +227,7 @@ DETAILS:
|
|||
**Tier:** For a limited time, Ultimate. In the future, [GitLab Duo Enterprise](../subscriptions/subscription-add-ons.md).
|
||||
**Offering:** GitLab.com
|
||||
|
||||
- Helps users generate meaningful commit messages for merge and squash commits.
|
||||
- Helps you merge more quickly by generating meaningful commit messages.
|
||||
- LLM: Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/text).
|
||||
- [View documentation](project/merge_requests/ai_in_merge_requests.md#generate-a-merge-or-squash-commit-message).
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,10 @@ To ensure GitLab maps users and their contributions correctly:
|
|||
1. If users already exist on the destination instance and you use [SAML SSO for GitLab.com groups](../../group/saml_sso/index.md), all users must
|
||||
[link their SAML identity to their GitLab.com account](../../group/saml_sso/index.md#link-saml-to-your-existing-gitlabcom-account).
|
||||
|
||||
There is no way in the GitLab UI or API to automatically set public email addresses for users. If you need to set
|
||||
a lot of user accounts to have public email addresses, see
|
||||
[issue 284495](https://gitlab.com/gitlab-org/gitlab/-/issues/284495#note_1910159855) for a potential workaround.
|
||||
|
||||
## Connect the source GitLab instance
|
||||
|
||||
Create the group you want to import to and connect the source GitLab instance:
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ The scope determines the actions you can perform when you authenticate with a gr
|
|||
| `read_repository` | Grants read access (pull) to all repositories within a group. |
|
||||
| `write_repository` | Grants read and write access (pull and push) to all repositories within a group. |
|
||||
| `create_runner` | Grants permission to create runners in a group. |
|
||||
| `manage_runner` | Grants permission to manage runners in a group. |
|
||||
| `ai_features` | Grants permission to perform API actions for GitLab Duo. This scope is designed to work with the GitLab Duo Plugin for JetBrains. For all other extensions, see scope requirements. |
|
||||
| `k8s_proxy` | Grants permission to perform Kubernetes API calls using the agent for Kubernetes in a group. |
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,22 @@ To protect a package:
|
|||
|
||||
The package protection rule is created, and appears in the settings.
|
||||
|
||||
### Protecting multiple packages
|
||||
|
||||
You can use a wildcard to protect multiple packages with the same package protection rule.
|
||||
For example, you can protect all the temporary packages built during a CI/CD pipeline.
|
||||
|
||||
The following table contains examples of package protection rules that match multiple packages:
|
||||
|
||||
| Package name pattern with wildcard | Matching packages |
|
||||
|------------------------------------|-----------------------------------------------------------------------------|
|
||||
| `@group/package-*` | `@group/package-prod`, `@group/package-prod-sha123456789` |
|
||||
| `@group/*package` | `@group/package`, `@group/prod-package`, `@group/prod-sha123456789-package` |
|
||||
| `@group/*package*` | `@group/package`, `@group/prod-sha123456789-package-v1` |
|
||||
|
||||
It's possible to apply several protection rules to the same package.
|
||||
If at least one protection rule applies to the package, the package is protected.
|
||||
|
||||
## Delete a package protection rule and unprotect a package
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/140483) in GitLab 16.10.
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ A personal access token can perform actions based on the assigned scopes.
|
|||
| `sudo` | Grants permission to perform API actions as any user in the system, when authenticated as an administrator. |
|
||||
| `admin_mode` | Grants permission to perform API actions as an administrator, when Admin Mode is enabled. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107875) in GitLab 15.8.) |
|
||||
| `create_runner` | Grants permission to create runners. |
|
||||
| `manage_runner` | Grants permission to manage runners. |
|
||||
| `ai_features` | Grants permission to perform API actions for GitLab Duo. This scope is designed to work with the GitLab Duo Plugin for JetBrains. For all other extensions, see scope requirements. |
|
||||
| `k8s_proxy` | Grants permission to perform Kubernetes API calls using the agent for Kubernetes. |
|
||||
| `read_service_ping`| Grant access to download Service Ping payload through the API when authenticated as an admin use. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107875) in GitLab 16.8. |
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ See the warning in [create a project access token](#create-a-project-access-toke
|
|||
| `read_repository` | Grants read access (pull) to the repository. |
|
||||
| `write_repository` | Grants read and write access (pull and push) to the repository. |
|
||||
| `create_runner` | Grants permission to create runners in the project. |
|
||||
| `manage_runner` | Grants permission to manage runners in the project. |
|
||||
| `ai_features` | Grants permission to perform API actions for GitLab Duo. This scope is designed to work with the GitLab Duo Plugin for JetBrains. For all other extensions, see scope requirements. |
|
||||
| `k8s_proxy` | Grants permission to perform Kubernetes API calls using the agent for Kubernetes in the project. |
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
module ClickHouse
|
||||
module Client
|
||||
class Query < QueryLike
|
||||
SUBQUERY_PLACEHOLDER_REGEX = /{\w+:Subquery}/ # exmaple: {var:Subquery}, special "internal" type for subqueries
|
||||
PLACEHOLDER_REGEX = /{\w+:\w+}/ # exmaple: {var:UInt8}
|
||||
PLACEHOLDER_NAME_REGEX = /{(\w+):/ # exmaple: {var:UInt8} => var
|
||||
SUBQUERY_PLACEHOLDER_REGEX = /{\w+:Subquery}/ # example: {var:Subquery}, special "internal" type for subqueries
|
||||
PLACEHOLDER_REGEX = /{\w+:\w+}/ # example: {var:UInt8}
|
||||
PLACEHOLDER_NAME_REGEX = /{(\w+):/ # example: {var:UInt8} => var
|
||||
|
||||
def initialize(raw_query:, placeholders: {})
|
||||
raise QueryError, 'Empty query string given' if raw_query.blank?
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
module API
|
||||
module Ci
|
||||
class Runners < ::API::Base
|
||||
include APIGuard
|
||||
include PaginationParams
|
||||
|
||||
before { authenticate! }
|
||||
|
|
@ -104,6 +105,10 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
allow_access_with_scope :manage_runner, if: ->(request) do
|
||||
request.params.key?(:id) && request.path.match?(%r{\A/api/v[34]/runners/})
|
||||
end
|
||||
|
||||
resource :runners do
|
||||
desc 'Get runners available for user' do
|
||||
summary 'List owned runners'
|
||||
|
|
@ -274,7 +279,7 @@ module API
|
|||
desc: 'The ID or URL-encoded path of the project owned by the authenticated user'
|
||||
end
|
||||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
before { authorize_admin_project }
|
||||
before { authorize! :read_project_runners, user_project }
|
||||
|
||||
desc 'Get runners available for project' do
|
||||
summary "List project's runners"
|
||||
|
|
@ -310,6 +315,8 @@ module API
|
|||
requires :runner_id, type: Integer, desc: 'The ID of a runner'
|
||||
end
|
||||
post ':id/runners' do
|
||||
authorize! :create_runner, user_project # Ensure the user is allowed to create a runner on the target project
|
||||
|
||||
runner = get_runner(params[:runner_id])
|
||||
authenticate_enable_runner!(runner)
|
||||
|
||||
|
|
@ -335,6 +342,8 @@ module API
|
|||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
delete ':id/runners/:runner_id' do
|
||||
authorize! :admin_project_runners, user_project
|
||||
|
||||
runner_project = user_project.runner_projects.find_by(runner_id: params[:runner_id])
|
||||
not_found!('Runner') unless runner_project
|
||||
|
||||
|
|
@ -350,7 +359,7 @@ module API
|
|||
requires :id, type: String, desc: 'The ID of a group'
|
||||
end
|
||||
resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
before { authorize_admin_group }
|
||||
before { authorize! :read_group_runners, user_group }
|
||||
|
||||
desc 'Get runners available for group' do
|
||||
summary "List group's runners"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,13 @@ module Gitlab
|
|||
READ_API_SCOPE = :read_api
|
||||
READ_USER_SCOPE = :read_user
|
||||
CREATE_RUNNER_SCOPE = :create_runner
|
||||
API_SCOPES = [API_SCOPE, READ_API_SCOPE, READ_USER_SCOPE, CREATE_RUNNER_SCOPE, K8S_PROXY_SCOPE].freeze
|
||||
MANAGE_RUNNER_SCOPE = :manage_runner
|
||||
API_SCOPES = [
|
||||
API_SCOPE, READ_API_SCOPE,
|
||||
READ_USER_SCOPE,
|
||||
CREATE_RUNNER_SCOPE, MANAGE_RUNNER_SCOPE,
|
||||
K8S_PROXY_SCOPE
|
||||
].freeze
|
||||
|
||||
# Scopes for Duo
|
||||
AI_FEATURES = :ai_features
|
||||
|
|
@ -272,11 +278,12 @@ module Gitlab
|
|||
abilities_by_scope = {
|
||||
api: full_authentication_abilities,
|
||||
read_api: read_only_authentication_abilities,
|
||||
read_registry: [:read_container_image],
|
||||
write_registry: [:create_container_image],
|
||||
read_repository: [:download_code],
|
||||
write_repository: [:download_code, :push_code],
|
||||
create_runner: [:create_instance_runner, :create_runner]
|
||||
read_registry: %i[read_container_image],
|
||||
write_registry: %i[create_container_image],
|
||||
read_repository: %i[download_code],
|
||||
write_repository: %i[download_code push_code],
|
||||
create_runner: %i[create_instance_runner create_runner],
|
||||
manage_runner: %i[assign_runner update_runner delete_runner]
|
||||
}
|
||||
|
||||
scopes.flat_map do |scope|
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ module Gitlab
|
|||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
attr_reader :errors, :warnings,
|
||||
:root_variables, :root_variables_with_prefill_data,
|
||||
:stages, :jobs,
|
||||
:workflow_rules, :workflow_name, :workflow_auto_cancel
|
||||
:root_variables, :root_variables_with_prefill_data,
|
||||
:stages, :jobs,
|
||||
:workflow_rules, :workflow_name, :workflow_auto_cancel
|
||||
|
||||
def initialize(ci_config: nil, errors: [], warnings: [])
|
||||
@ci_config = ci_config
|
||||
|
|
|
|||
|
|
@ -139,9 +139,9 @@ module Gitlab
|
|||
|
||||
if project && user
|
||||
Gitlab::AppJsonLogger.info(event: 'ci_used_deprecated_keyword',
|
||||
entry: entry.key.to_s,
|
||||
user_id: user.id,
|
||||
project_id: project.id)
|
||||
entry: entry.key.to_s,
|
||||
user_id: user.id,
|
||||
project_id: project.id)
|
||||
end
|
||||
|
||||
deprecation = entry.deprecation
|
||||
|
|
|
|||
|
|
@ -222,9 +222,9 @@ module Gitlab
|
|||
|
||||
def content_path
|
||||
conflict_for_path_project_merge_request_path(merge_request.project,
|
||||
merge_request,
|
||||
old_path: their_path,
|
||||
new_path: our_path)
|
||||
merge_request,
|
||||
old_path: their_path,
|
||||
new_path: our_path)
|
||||
end
|
||||
|
||||
def conflict_type(when_renamed: false)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module Gitlab
|
|||
class CrossProjectAccess
|
||||
class << self
|
||||
delegate :add_check, :find_check, :checks,
|
||||
to: :instance
|
||||
to: :instance
|
||||
end
|
||||
|
||||
def self.instance
|
||||
|
|
@ -25,10 +25,10 @@ module Gitlab
|
|||
skip: false)
|
||||
|
||||
new_check = CheckInfo.new(actions,
|
||||
positive_condition,
|
||||
negative_condition,
|
||||
skip
|
||||
)
|
||||
positive_condition,
|
||||
negative_condition,
|
||||
skip
|
||||
)
|
||||
|
||||
@checks[klass] ||= Gitlab::CrossProjectAccess::CheckCollection.new
|
||||
@checks[klass].add_check(new_check)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ module Gitlab
|
|||
push_options: push_options,
|
||||
# DEPRECATED
|
||||
repository: project.hook_attrs.slice(:name, :url, :description, :homepage,
|
||||
:git_http_url, :git_ssh_url, :visibility_level)
|
||||
:git_http_url, :git_ssh_url, :visibility_level)
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -169,11 +169,11 @@ module Gitlab
|
|||
commits = project.repository.commits(project.default_branch.to_s, limit: 3)
|
||||
|
||||
build(project: project,
|
||||
user: user,
|
||||
oldrev: commits.last&.id,
|
||||
newrev: commits.first&.id,
|
||||
ref: ref,
|
||||
commits: commits)
|
||||
user: user,
|
||||
oldrev: commits.last&.id,
|
||||
newrev: commits.first&.id,
|
||||
ref: ref,
|
||||
commits: commits)
|
||||
end
|
||||
|
||||
def sample_data(is_tag = false)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ module Gitlab
|
|||
private
|
||||
|
||||
attr_reader :source_model, :target_model, :source_columns, :target_columns,
|
||||
:source_sort_column, :target_sort_column, :start_time, :result
|
||||
:source_sort_column, :target_sort_column, :start_time, :result
|
||||
|
||||
def build_result(next_start_id:)
|
||||
{ next_start_id: next_start_id }.merge(result)
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ module Gitlab
|
|||
|
||||
if check_statistics
|
||||
query = query.where('last_vacuum > ? OR last_autovacuum > ? OR last_analyze > ? OR last_autoanalyze > ?',
|
||||
time, time, time, time)
|
||||
time, time, time, time)
|
||||
end
|
||||
|
||||
query
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ module Gitlab
|
|||
# Configuration settings for a single LoadBalancer instance.
|
||||
class Configuration
|
||||
attr_accessor :hosts, :max_replication_difference,
|
||||
:max_replication_lag_time, :replica_check_interval,
|
||||
:service_discovery
|
||||
:max_replication_lag_time, :replica_check_interval,
|
||||
:service_discovery
|
||||
|
||||
# Creates a configuration object for the given ActiveRecord model.
|
||||
def self.for_model(model)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ module Gitlab
|
|||
attr_accessor :refresh_thread, :refresh_thread_last_run, :refresh_thread_interruption_logged
|
||||
|
||||
attr_reader :interval, :record, :record_type, :disconnect_timeout,
|
||||
:load_balancer
|
||||
:load_balancer
|
||||
|
||||
MAX_SLEEP_ADJUSTMENT = 10
|
||||
MAX_DISCOVERY_RETRIES = 3
|
||||
|
|
|
|||
|
|
@ -970,9 +970,9 @@ module Gitlab
|
|||
def copy_foreign_keys(table, old, new)
|
||||
foreign_keys_for(table, old).each do |fk|
|
||||
add_concurrent_foreign_key(fk.from_table,
|
||||
fk.to_table,
|
||||
column: new,
|
||||
on_delete: fk.on_delete)
|
||||
fk.to_table,
|
||||
column: new,
|
||||
on_delete: fk.on_delete)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1316,9 +1316,9 @@ into similar problems in the future (e.g. when new tables are created).
|
|||
new_limit = limit || old_col.limit
|
||||
|
||||
add_column(table, new, new_type,
|
||||
limit: new_limit,
|
||||
precision: old_col.precision,
|
||||
scale: old_col.scale)
|
||||
limit: new_limit,
|
||||
precision: old_col.precision,
|
||||
scale: old_col.scale)
|
||||
|
||||
# We set the default value _after_ adding the column so we don't end up
|
||||
# updating any existing data with the default value. This isn't
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ module Gitlab
|
|||
per_background_migration_result_dir = File.join(@result_dir, migration_name)
|
||||
|
||||
instrumentation = Instrumentation.new(result_dir: per_background_migration_result_dir,
|
||||
observer_classes: observers)
|
||||
observer_classes: observers)
|
||||
|
||||
batch_names = (1..).each.lazy.map { |i| "batch_#{i}" }
|
||||
|
||||
|
|
@ -49,9 +49,9 @@ module Gitlab
|
|||
meta = { job_meta: job_meta(j) }
|
||||
|
||||
instrumentation.observe(version: nil,
|
||||
name: batch_names.next,
|
||||
connection: connection,
|
||||
meta: meta) do
|
||||
name: batch_names.next,
|
||||
connection: connection,
|
||||
meta: meta) do
|
||||
run_job(j)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ module Gitlab
|
|||
end
|
||||
rescue StandardError => e
|
||||
Gitlab::AppLogger.error(message: "Failed to drop previously detached partition",
|
||||
partition_name: detached_partition.table_name,
|
||||
exception_class: e.class,
|
||||
exception_message: e.message)
|
||||
partition_name: detached_partition.table_name,
|
||||
exception_class: e.class,
|
||||
exception_message: e.message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -76,9 +76,9 @@ module Gitlab
|
|||
connection.execute("ALTER TABLE #{connection.quote_table_name(partition_identifier)} DROP CONSTRAINT #{connection.quote_table_name(foreign_key.name)}")
|
||||
|
||||
Gitlab::AppLogger.info(message: "Dropped foreign key for previously detached partition",
|
||||
partition_name: detached_partition.table_name,
|
||||
referenced_table_name: foreign_key.referenced_table_identifier,
|
||||
foreign_key_name: foreign_key.name)
|
||||
partition_name: detached_partition.table_name,
|
||||
referenced_table_name: foreign_key.referenced_table_identifier,
|
||||
foreign_key_name: foreign_key.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ module Gitlab
|
|||
gon.recaptcha_api_server_url = ::Recaptcha.configuration.api_server_url
|
||||
gon.recaptcha_sitekey = Gitlab::CurrentSettings.recaptcha_site_key
|
||||
gon.gitlab_url = Gitlab.config.gitlab.url
|
||||
gon.promo_url = ApplicationHelper.promo_url
|
||||
gon.forum_url = Gitlab::Saas.community_forum_url
|
||||
gon.docs_url = Gitlab::Saas.doc_url
|
||||
gon.organization_http_header_name = ::Organizations::ORGANIZATION_HTTP_HEADER
|
||||
gon.revision = Gitlab.revision
|
||||
gon.feature_category = Gitlab::ApplicationContext.current_context_attribute(:feature_category).presence
|
||||
|
|
|
|||
|
|
@ -36712,6 +36712,9 @@ msgstr ""
|
|||
msgid "PackageRegistry|%{count} packages were not published to the registry. Remove these packages and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|%{linkStart}Wildcards%{linkEnd} such as `@my-scope/my-package-*` are supported."
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|%{name} version %{version} was first created %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ RSpec.describe Admin::GroupsController, feature_category: :groups_and_projects d
|
|||
get :index
|
||||
|
||||
html_rendered = Nokogiri::HTML(response.body)
|
||||
sort_options = Gitlab::Json.parse(html_rendered.css('div.dropdown')[0]['data-items'])
|
||||
sort_options = Gitlab::Json.parse(html_rendered.css('[data-items]')[0]['data-items'])
|
||||
|
||||
expect(response).to render_template('shared/groups/_dropdown')
|
||||
|
||||
|
|
|
|||
|
|
@ -136,8 +136,6 @@ RSpec.describe 'Database schema', feature_category: :database do
|
|||
subscriptions: %w[user_id subscribable_id],
|
||||
suggestions: %w[commit_id],
|
||||
taggings: %w[tag_id taggable_id tagger_id],
|
||||
# temp_notes_backup is a temporary table created to store orphaned records from the notes table to insure against data loss.
|
||||
temp_notes_backup: %w[author_id project_id commit_id noteable_id updated_by_id resolved_by_id discussion_id review_id namespace_id],
|
||||
timelogs: %w[user_id],
|
||||
todos: %w[target_id commit_id],
|
||||
uploads: %w[model_id],
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ RSpec.describe 'User creates a merge request', :js, feature_category: :code_revi
|
|||
project.repository.create_branch("<img/src='x'/onerror=alert('oops')>", 'master')
|
||||
end
|
||||
|
||||
it 'does not execute the suspicious branch name' do
|
||||
it 'does not execute the suspicious branch name', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/447484' do
|
||||
visit(project_new_merge_request_path(project))
|
||||
|
||||
compare_source_and_target("<img/src='x'/onerror=alert('oops')>", 'feature')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { GlBadge } from '@gitlab/ui';
|
||||
import { GlBadge, GlSprintf } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import HeaderBadges from '~/ci/pipeline_details/header/components/header_badges.vue';
|
||||
|
||||
|
|
@ -8,6 +8,11 @@ describe('Header badges', () => {
|
|||
let wrapper;
|
||||
|
||||
const findAllBadges = () => wrapper.findAllComponents(GlBadge);
|
||||
const findChildPipelineBadge = () =>
|
||||
findAllBadges().filter((badge) => {
|
||||
const sprintf = badge.findComponent(GlSprintf);
|
||||
return sprintf.exists() && sprintf.attributes('message').includes('Child pipeline');
|
||||
});
|
||||
|
||||
const createComponent = (mockPipeline = pipelineHeaderSuccess.data.project.pipeline) => {
|
||||
wrapper = shallowMountExtended(HeaderBadges, {
|
||||
|
|
@ -45,4 +50,19 @@ describe('Header badges', () => {
|
|||
expect(wrapper.findByText('Scheduled').exists()).toBe(true);
|
||||
expect(wrapper.findByText('trigger token').exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('in a child pipeline', () => {
|
||||
const triggeredByPath = 'https://example.com';
|
||||
|
||||
it('displays the link to the parent', () => {
|
||||
createComponent({
|
||||
...pipelineHeaderTrigger.data.project.pipeline,
|
||||
child: true,
|
||||
triggeredByPath,
|
||||
});
|
||||
|
||||
expect(findAllBadges()).toHaveLength(4);
|
||||
expect(findChildPipelineBadge().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Vue from 'vue';
|
|||
import Vuex from 'vuex';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import ApproveAccessRequestButton from '~/members/components/action_buttons/approve_access_request_button.vue';
|
||||
import { MEMBER_TYPES } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
|
||||
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ describe('ApproveAccessRequestButton', () => {
|
|||
const createStore = (state = {}) => {
|
||||
return new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.accessRequest]: {
|
||||
[MEMBERS_TAB_TYPES.accessRequest]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
memberPath: '/groups/foo-bar/-/group_members/:id',
|
||||
|
|
@ -32,7 +32,7 @@ describe('ApproveAccessRequestButton', () => {
|
|||
wrapper = shallowMount(ApproveAccessRequestButton, {
|
||||
store: createStore(state),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.accessRequest,
|
||||
namespace: MEMBERS_TAB_TYPES.accessRequest,
|
||||
},
|
||||
propsData: {
|
||||
memberId: 1,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Vue from 'vue';
|
|||
import Vuex from 'vuex';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import RemoveGroupLinkButton from '~/members/components/action_buttons/remove_group_link_button.vue';
|
||||
import { MEMBER_TYPES } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
import { group } from '../../mock_data';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
|
@ -20,7 +20,7 @@ describe('RemoveGroupLinkButton', () => {
|
|||
const createStore = () => {
|
||||
return new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.group]: {
|
||||
[MEMBERS_TAB_TYPES.group]: {
|
||||
namespaced: true,
|
||||
actions,
|
||||
},
|
||||
|
|
@ -32,7 +32,7 @@ describe('RemoveGroupLinkButton', () => {
|
|||
wrapper = mount(RemoveGroupLinkButton, {
|
||||
store: createStore(),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.group,
|
||||
namespace: MEMBERS_TAB_TYPES.group,
|
||||
},
|
||||
propsData: {
|
||||
groupLink: group,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import Vuex from 'vuex';
|
|||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import { modalData } from 'jest/members/mock_data';
|
||||
import RemoveMemberButton from '~/members/components/action_buttons/remove_member_button.vue';
|
||||
import { MEMBER_TYPES } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ describe('RemoveMemberButton', () => {
|
|||
const createStore = (state = {}) => {
|
||||
return new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
memberPath: '/groups/foo-bar/-/group_members/:id',
|
||||
|
|
@ -36,7 +36,7 @@ describe('RemoveMemberButton', () => {
|
|||
wrapper = shallowMount(RemoveMemberButton, {
|
||||
store: createStore(state),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
},
|
||||
propsData: {
|
||||
memberId: 1,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Vue from 'vue';
|
|||
import Vuex from 'vuex';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import ResendInviteButton from '~/members/components/action_buttons/resend_invite_button.vue';
|
||||
import { MEMBER_TYPES } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
|
||||
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ describe('ResendInviteButton', () => {
|
|||
const createStore = (state = {}) => {
|
||||
return new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.invite]: {
|
||||
[MEMBERS_TAB_TYPES.invite]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
memberPath: '/groups/foo-bar/-/group_members/:id',
|
||||
|
|
@ -32,7 +32,7 @@ describe('ResendInviteButton', () => {
|
|||
wrapper = shallowMount(ResendInviteButton, {
|
||||
store: createStore(state),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.invite,
|
||||
namespace: MEMBERS_TAB_TYPES.invite,
|
||||
},
|
||||
propsData: {
|
||||
memberId: 1,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Vue from 'vue';
|
|||
import Vuex from 'vuex';
|
||||
import { modalData } from 'jest/members/mock_data';
|
||||
import RemoveMemberDropdownItem from '~/members/components/action_dropdowns/remove_member_dropdown_item.vue';
|
||||
import { MEMBER_TYPES, MEMBER_MODEL_TYPE_GROUP_MEMBER } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES, MEMBER_MODEL_TYPE_GROUP_MEMBER } from '~/members/constants';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ describe('RemoveMemberDropdownItem', () => {
|
|||
const createStore = (state = {}) => {
|
||||
return new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
memberPath: '/groups/foo-bar/-/group_members/:id',
|
||||
|
|
@ -36,7 +36,7 @@ describe('RemoveMemberDropdownItem', () => {
|
|||
wrapper = shallowMount(RemoveMemberDropdownItem, {
|
||||
store: createStore(state),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
},
|
||||
propsData: {
|
||||
memberId: 1,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import * as commonUtils from '~/lib/utils/common_utils';
|
|||
import MembersApp from '~/members/components/app.vue';
|
||||
import FilterSortContainer from '~/members/components/filter_sort/filter_sort_container.vue';
|
||||
import MembersTable from '~/members/components/table/members_table.vue';
|
||||
import { MEMBER_TYPES, TAB_QUERY_PARAM_VALUES } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES, TAB_QUERY_PARAM_VALUES } from '~/members/constants';
|
||||
import { RECEIVE_MEMBER_ROLE_ERROR, HIDE_ERROR } from '~/members/store/mutation_types';
|
||||
import mutations from '~/members/store/mutations';
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ describe('MembersApp', () => {
|
|||
const createComponent = (state = {}, options = {}) => {
|
||||
store = new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.group]: {
|
||||
[MEMBERS_TAB_TYPES.group]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
showError: true,
|
||||
|
|
@ -34,7 +34,7 @@ describe('MembersApp', () => {
|
|||
|
||||
wrapper = shallowMount(MembersApp, {
|
||||
propsData: {
|
||||
namespace: MEMBER_TYPES.group,
|
||||
namespace: MEMBERS_TAB_TYPES.group,
|
||||
tabQueryParamValue: TAB_QUERY_PARAM_VALUES.group,
|
||||
},
|
||||
store,
|
||||
|
|
@ -57,7 +57,7 @@ describe('MembersApp', () => {
|
|||
it('renders and scrolls to error alert', async () => {
|
||||
createComponent({ showError: false, errorMessage: '' });
|
||||
|
||||
store.commit(`${MEMBER_TYPES.group}/${RECEIVE_MEMBER_ROLE_ERROR}`, {
|
||||
store.commit(`${MEMBERS_TAB_TYPES.group}/${RECEIVE_MEMBER_ROLE_ERROR}`, {
|
||||
error: new Error('Network Error'),
|
||||
});
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ describe('MembersApp', () => {
|
|||
it('does not render and scroll to error alert', async () => {
|
||||
createComponent();
|
||||
|
||||
store.commit(`${MEMBER_TYPES.group}/${HIDE_ERROR}`);
|
||||
store.commit(`${MEMBERS_TAB_TYPES.group}/${HIDE_ERROR}`);
|
||||
|
||||
await nextTick();
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Vuex from 'vuex';
|
|||
import FilterSortContainer from '~/members/components/filter_sort/filter_sort_container.vue';
|
||||
import MembersFilteredSearchBar from '~/members/components/filter_sort/members_filtered_search_bar.vue';
|
||||
import SortDropdown from '~/members/components/filter_sort/sort_dropdown.vue';
|
||||
import { MEMBER_TYPES } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ describe('FilterSortContainer', () => {
|
|||
const createComponent = (state) => {
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
filteredSearchBar: {
|
||||
|
|
@ -35,7 +35,7 @@ describe('FilterSortContainer', () => {
|
|||
wrapper = shallowMount(FilterSortContainer, {
|
||||
store,
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import setWindowLocation from 'helpers/set_window_location_helper';
|
|||
import { visitUrl } from '~/lib/utils/url_utility';
|
||||
import MembersFilteredSearchBar from '~/members/components/filter_sort/members_filtered_search_bar.vue';
|
||||
import {
|
||||
MEMBER_TYPES,
|
||||
MEMBERS_TAB_TYPES,
|
||||
FILTERED_SEARCH_TOKEN_TWO_FACTOR,
|
||||
FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS,
|
||||
} from '~/members/constants';
|
||||
|
|
@ -31,7 +31,7 @@ describe('MembersFilteredSearchBar', () => {
|
|||
const createComponent = ({ state = {}, provide = {} } = {}) => {
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
filteredSearchBar: {
|
||||
|
|
@ -51,7 +51,7 @@ describe('MembersFilteredSearchBar', () => {
|
|||
provide: {
|
||||
sourceId: 1,
|
||||
canManageMembers: true,
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
...provide,
|
||||
},
|
||||
store,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import Vuex from 'vuex';
|
|||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import * as urlUtilities from '~/lib/utils/url_utility';
|
||||
import SortDropdown from '~/members/components/filter_sort/sort_dropdown.vue';
|
||||
import { MEMBER_TYPES, FIELD_KEY_MAX_ROLE } from '~/members/constants';
|
||||
import { MEMBERS_TAB_TYPES, FIELD_KEY_MAX_ROLE } from '~/members/constants';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ describe('SortDropdown', () => {
|
|||
const createComponent = (state) => {
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
tableSortableFields: ['account', 'granted', 'expires', 'maxRole', 'lastSignIn'],
|
||||
|
|
@ -38,7 +38,7 @@ describe('SortDropdown', () => {
|
|||
wrapper = mount(SortDropdown, {
|
||||
provide: {
|
||||
sourceId: 1,
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
},
|
||||
store,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { mountExtended } from 'helpers/vue_test_utils_helper';
|
|||
import MembersApp from '~/members/components/app.vue';
|
||||
import MembersTabs from '~/members/components/members_tabs.vue';
|
||||
import {
|
||||
MEMBER_TYPES,
|
||||
MEMBERS_TAB_TYPES,
|
||||
TAB_QUERY_PARAM_VALUES,
|
||||
ACTIVE_TAB_QUERY_PARAM_NAME,
|
||||
FILTERED_SEARCH_TOKEN_GROUPS_WITH_INHERITED_PERMISSIONS,
|
||||
|
|
@ -23,7 +23,7 @@ describe('MembersTabs', () => {
|
|||
const createComponent = ({ totalItems = 10, provide = {} } = {}) => {
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
pagination: {
|
||||
|
|
@ -35,7 +35,7 @@ describe('MembersTabs', () => {
|
|||
},
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.group]: {
|
||||
[MEMBERS_TAB_TYPES.group]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
pagination: {
|
||||
|
|
@ -49,7 +49,7 @@ describe('MembersTabs', () => {
|
|||
},
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.invite]: {
|
||||
[MEMBERS_TAB_TYPES.invite]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
pagination: {
|
||||
|
|
@ -62,7 +62,7 @@ describe('MembersTabs', () => {
|
|||
},
|
||||
},
|
||||
},
|
||||
[MEMBER_TYPES.accessRequest]: {
|
||||
[MEMBERS_TAB_TYPES.accessRequest]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
pagination: {
|
||||
|
|
@ -132,10 +132,10 @@ describe('MembersTabs', () => {
|
|||
|
||||
const membersApps = wrapper.findAllComponents(MembersApp).wrappers;
|
||||
|
||||
expect(membersApps[0].props('namespace')).toBe(MEMBER_TYPES.user);
|
||||
expect(membersApps[1].props('namespace')).toBe(MEMBER_TYPES.group);
|
||||
expect(membersApps[2].props('namespace')).toBe(MEMBER_TYPES.invite);
|
||||
expect(membersApps[3].props('namespace')).toBe(MEMBER_TYPES.accessRequest);
|
||||
expect(membersApps[0].props('namespace')).toBe(MEMBERS_TAB_TYPES.user);
|
||||
expect(membersApps[1].props('namespace')).toBe(MEMBERS_TAB_TYPES.group);
|
||||
expect(membersApps[2].props('namespace')).toBe(MEMBERS_TAB_TYPES.invite);
|
||||
expect(membersApps[3].props('namespace')).toBe(MEMBERS_TAB_TYPES.accessRequest);
|
||||
|
||||
expect(membersApps[1].props('tabQueryParamValue')).toBe(TAB_QUERY_PARAM_VALUES.group);
|
||||
expect(membersApps[2].props('tabQueryParamValue')).toBe(TAB_QUERY_PARAM_VALUES.invite);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
|
|||
import LeaveModal from '~/members/components/modals/leave_modal.vue';
|
||||
import {
|
||||
LEAVE_MODAL_ID,
|
||||
MEMBER_TYPES,
|
||||
MEMBERS_TAB_TYPES,
|
||||
MEMBER_MODEL_TYPE_PROJECT_MEMBER,
|
||||
} from '~/members/constants';
|
||||
import UserDeletionObstaclesList from '~/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue';
|
||||
|
|
@ -24,7 +24,7 @@ describe('LeaveModal', () => {
|
|||
const createStore = (state = {}) => {
|
||||
return new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
memberPath: '/groups/foo-bar/-/group_members/:id',
|
||||
|
|
@ -39,7 +39,7 @@ describe('LeaveModal', () => {
|
|||
wrapper = mountExtended(LeaveModal, {
|
||||
store: createStore(state),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
},
|
||||
propsData: {
|
||||
member,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Vue, { nextTick } from 'vue';
|
|||
// eslint-disable-next-line no-restricted-imports
|
||||
import Vuex from 'vuex';
|
||||
import RemoveGroupLinkModal from '~/members/components/modals/remove_group_link_modal.vue';
|
||||
import { REMOVE_GROUP_LINK_MODAL_ID, MEMBER_TYPES } from '~/members/constants';
|
||||
import { REMOVE_GROUP_LINK_MODAL_ID, MEMBERS_TAB_TYPES } from '~/members/constants';
|
||||
import { group } from '../../mock_data';
|
||||
|
||||
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
|
||||
|
|
@ -22,7 +22,7 @@ describe('RemoveGroupLinkModal', () => {
|
|||
const createStore = (state = {}) => {
|
||||
return new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.group]: {
|
||||
[MEMBERS_TAB_TYPES.group]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
memberPath: '/groups/foo-bar/-/group_links/:id',
|
||||
|
|
@ -40,7 +40,7 @@ describe('RemoveGroupLinkModal', () => {
|
|||
wrapper = mount(RemoveGroupLinkModal, {
|
||||
store: createStore(state),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.group,
|
||||
namespace: MEMBERS_TAB_TYPES.group,
|
||||
},
|
||||
attrs: {
|
||||
static: true,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Vue from 'vue';
|
|||
import Vuex from 'vuex';
|
||||
import RemoveMemberModal from '~/members/components/modals/remove_member_modal.vue';
|
||||
import {
|
||||
MEMBER_TYPES,
|
||||
MEMBERS_TAB_TYPES,
|
||||
MEMBER_MODEL_TYPE_GROUP_MEMBER,
|
||||
MEMBER_MODEL_TYPE_PROJECT_MEMBER,
|
||||
} from '~/members/constants';
|
||||
|
|
@ -32,7 +32,7 @@ describe('RemoveMemberModal', () => {
|
|||
const createStore = (removeMemberModalData) =>
|
||||
new Vuex.Store({
|
||||
modules: {
|
||||
[MEMBER_TYPES.user]: {
|
||||
[MEMBERS_TAB_TYPES.user]: {
|
||||
namespaced: true,
|
||||
state: {
|
||||
removeMemberModalData,
|
||||
|
|
@ -46,7 +46,7 @@ describe('RemoveMemberModal', () => {
|
|||
wrapper = shallowMount(RemoveMemberModal, {
|
||||
store: createStore(state),
|
||||
provide: {
|
||||
namespace: MEMBER_TYPES.user,
|
||||
namespace: MEMBERS_TAB_TYPES.user,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue