Add latest changes from gitlab-org/gitlab@master
|
|
@ -11,7 +11,6 @@ Layout/SpaceInsideParens:
|
|||
- 'spec/lib/error_tracking/sentry_client/projects_spec.rb'
|
||||
- 'spec/lib/error_tracking/sentry_client/repo_spec.rb'
|
||||
- 'spec/lib/feature/gitaly_spec.rb'
|
||||
- 'spec/lib/gitlab/app_text_logger_spec.rb'
|
||||
- 'spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/config/entry/reports_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/config/entry/trigger_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1087,7 +1087,6 @@ RSpec/FeatureCategory:
|
|||
- 'ee/spec/services/boards/lists/update_service_spec.rb'
|
||||
- 'ee/spec/services/boards/update_service_spec.rb'
|
||||
- 'ee/spec/services/boards/user_preferences/update_service_spec.rb'
|
||||
- 'ee/spec/services/branches/delete_service_spec.rb'
|
||||
- 'ee/spec/services/external_status_checks/create_service_spec.rb'
|
||||
- 'ee/spec/services/projects/alerting/notify_service_spec.rb'
|
||||
- 'ee/spec/services/projects/cleanup_service_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1843,7 +1843,6 @@ Style/InlineDisableAnnotation:
|
|||
- 'ee/spec/serializers/vulnerabilities/issue_link_entity_spec.rb'
|
||||
- 'ee/spec/serializers/vulnerabilities/merge_request_link_entity_spec.rb'
|
||||
- 'ee/spec/services/app_sec/fuzzing/api/ci_configuration_create_service_spec.rb'
|
||||
- 'ee/spec/services/branches/delete_service_spec.rb'
|
||||
- 'ee/spec/services/ee/branches/delete_service_spec.rb'
|
||||
- 'ee/spec/services/ee/resource_events/change_iteration_service_spec.rb'
|
||||
- 'ee/spec/services/geo/file_registry_removal_service_spec.rb'
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
{"name":"apollo_upload_server","version":"2.1.6","platform":"ruby","checksum":"dcec4072258e6518b0b82e03b485efbddde946813543c14184fc81952d6bcdb2"},
|
||||
{"name":"app_store_connect","version":"0.29.0","platform":"ruby","checksum":"01d7a923825a4221892099acb5a72f86f6ee7d8aa95815d3c459ba6816ea430f"},
|
||||
{"name":"arr-pm","version":"0.0.12","platform":"ruby","checksum":"fdff482f75239239201f4d667d93424412639aad0b3b0ad4d827e7c637e0ad39"},
|
||||
{"name":"asciidoctor","version":"2.0.18","platform":"ruby","checksum":"bbd1e1d16deed8db94bf9624b9f4474fac32d9ca7225d377f076c08d9adde387"},
|
||||
{"name":"asciidoctor","version":"2.0.23","platform":"ruby","checksum":"52208807f237dfa0ca29882f8b13d60b820496116ad191cf197ca56f2b7fddf3"},
|
||||
{"name":"asciidoctor-include-ext","version":"0.4.0","platform":"ruby","checksum":"406adb9d2fbfc25536609ca13b787ed704dc06a4e49d6709b83f3bad578f7878"},
|
||||
{"name":"asciidoctor-kroki","version":"0.10.0","platform":"ruby","checksum":"8e4225d88f120e2e7b5d3f5ddb67c5e69496d7344a16c57db5036ac900123062"},
|
||||
{"name":"asciidoctor-plantuml","version":"0.0.16","platform":"ruby","checksum":"407e47cd1186ded5ccc75f0c812e5524c26c571d542247c5132abb8f47bd1793"},
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ GEM
|
|||
activesupport (>= 6.0.0)
|
||||
jwt (>= 1.4, <= 2.5.0)
|
||||
arr-pm (0.0.12)
|
||||
asciidoctor (2.0.18)
|
||||
asciidoctor (2.0.23)
|
||||
asciidoctor-include-ext (0.4.0)
|
||||
asciidoctor (>= 1.5.6, < 3.0.0)
|
||||
asciidoctor-kroki (0.10.0)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
{"name":"apollo_upload_server","version":"2.1.6","platform":"ruby","checksum":"dcec4072258e6518b0b82e03b485efbddde946813543c14184fc81952d6bcdb2"},
|
||||
{"name":"app_store_connect","version":"0.29.0","platform":"ruby","checksum":"01d7a923825a4221892099acb5a72f86f6ee7d8aa95815d3c459ba6816ea430f"},
|
||||
{"name":"arr-pm","version":"0.0.12","platform":"ruby","checksum":"fdff482f75239239201f4d667d93424412639aad0b3b0ad4d827e7c637e0ad39"},
|
||||
{"name":"asciidoctor","version":"2.0.18","platform":"ruby","checksum":"bbd1e1d16deed8db94bf9624b9f4474fac32d9ca7225d377f076c08d9adde387"},
|
||||
{"name":"asciidoctor","version":"2.0.23","platform":"ruby","checksum":"52208807f237dfa0ca29882f8b13d60b820496116ad191cf197ca56f2b7fddf3"},
|
||||
{"name":"asciidoctor-include-ext","version":"0.4.0","platform":"ruby","checksum":"406adb9d2fbfc25536609ca13b787ed704dc06a4e49d6709b83f3bad578f7878"},
|
||||
{"name":"asciidoctor-kroki","version":"0.10.0","platform":"ruby","checksum":"8e4225d88f120e2e7b5d3f5ddb67c5e69496d7344a16c57db5036ac900123062"},
|
||||
{"name":"asciidoctor-plantuml","version":"0.0.16","platform":"ruby","checksum":"407e47cd1186ded5ccc75f0c812e5524c26c571d542247c5132abb8f47bd1793"},
|
||||
|
|
@ -342,7 +342,7 @@
|
|||
{"name":"io-event","version":"1.6.5","platform":"ruby","checksum":"5da4c044ac5f411563da1a4743d28c8d30d7802e29370db42139a52b807b4ce2"},
|
||||
{"name":"ipaddr","version":"1.2.5","platform":"ruby","checksum":"4e679c71d6d8ed99f925487082f70f9a958de155591caa0e7f6cef9aa160f17a"},
|
||||
{"name":"ipaddress","version":"0.8.3","platform":"ruby","checksum":"85640c4f9194c26937afc8c78e3074a8e7c97d5d1210358d1440f01034d006f5"},
|
||||
{"name":"irb","version":"1.14.0","platform":"ruby","checksum":"53d805013bbd194874b8c13a56aca6aebcd11dd79166d88724f8a434fedde615"},
|
||||
{"name":"irb","version":"1.14.1","platform":"ruby","checksum":"5975003b58d36efaf492380baa982ceedf5aed36967a4d5b40996bc5c66e80f8"},
|
||||
{"name":"jaeger-client","version":"1.1.0","platform":"ruby","checksum":"cb5e9b9bbee6ee8d6a82d03d947a5b04543d8c0a949c22e484254f18d8a458a8"},
|
||||
{"name":"jaro_winkler","version":"1.5.6","platform":"java","checksum":"3262aea433861fec3179184e9adc1933cca8bc15665957a143b56816f1a22f74"},
|
||||
{"name":"jaro_winkler","version":"1.5.6","platform":"ruby","checksum":"007db7805527ada1cc12f2547676181d63b0a504ec4dd7a9a2eb2424521ccd81"},
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ GEM
|
|||
activesupport (>= 6.0.0)
|
||||
jwt (>= 1.4, <= 2.5.0)
|
||||
arr-pm (0.0.12)
|
||||
asciidoctor (2.0.18)
|
||||
asciidoctor (2.0.23)
|
||||
asciidoctor-include-ext (0.4.0)
|
||||
asciidoctor (>= 1.5.6, < 3.0.0)
|
||||
asciidoctor-kroki (0.10.0)
|
||||
|
|
@ -1022,7 +1022,7 @@ GEM
|
|||
io-event (1.6.5)
|
||||
ipaddr (1.2.5)
|
||||
ipaddress (0.8.3)
|
||||
irb (1.14.0)
|
||||
irb (1.14.1)
|
||||
rdoc (>= 4.0.0)
|
||||
reline (>= 0.4.2)
|
||||
jaeger-client (1.1.0)
|
||||
|
|
|
|||
|
|
@ -91,6 +91,11 @@ export default {
|
|||
// Don't do anything if this happened on a no trigger element
|
||||
if (e.target.closest('.js-no-trigger')) return;
|
||||
|
||||
if (e.target.closest('.js-no-trigger-title') && (e.ctrlKey || e.metaKey || e.button === 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
const isMultiSelect = e.ctrlKey || e.metaKey;
|
||||
if (isMultiSelect && gon?.features?.boardMultiSelect) {
|
||||
this.toggleBoardItemMultiSelection(this.item);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { GlLabel, GlTooltipDirective, GlIcon, GlLoadingIcon } from '@gitlab/ui';
|
|||
import { sortBy } from 'lodash';
|
||||
import boardCardInner from 'ee_else_ce/boards/mixins/board_card_inner';
|
||||
import { isScopedLabel, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { updateHistory, queryToObject } from '~/lib/utils/url_utility';
|
||||
import { sprintf, __, n__ } from '~/locale';
|
||||
import isShowingLabelsQuery from '~/graphql_shared/client/is_showing_labels.query.graphql';
|
||||
|
|
@ -36,7 +37,7 @@ export default {
|
|||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
mixins: [boardCardInner],
|
||||
mixins: [boardCardInner, glFeatureFlagsMixin()],
|
||||
inject: [
|
||||
'allowSubEpics',
|
||||
'rootPath',
|
||||
|
|
@ -260,8 +261,13 @@ export default {
|
|||
<a
|
||||
:href="item.path || item.webUrl || ''"
|
||||
:title="item.title"
|
||||
:class="{ '!gl-text-gray-400': isLoading }"
|
||||
class="js-no-trigger gl-text-primary hover:gl-text-gray-900"
|
||||
:class="{
|
||||
'!gl-text-gray-400': isLoading,
|
||||
'js-no-trigger': !glFeatures.issuesListDrawer,
|
||||
'js-no-trigger-title': glFeatures.issuesListDrawer,
|
||||
}"
|
||||
class="gl-text-primary hover:gl-text-gray-900"
|
||||
data-testid="board-card-title-link"
|
||||
@mousemove.stop
|
||||
>{{ item.title }}</a
|
||||
>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import produce from 'immer';
|
|||
import Draggable from 'vuedraggable';
|
||||
import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue';
|
||||
import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import WorkItemDrawer from '~/work_items/components/work_item_drawer.vue';
|
||||
import { s__ } from '~/locale';
|
||||
import { defaultSortableOptions, DRAG_DELAY } from '~/sortable/constants';
|
||||
|
|
@ -39,7 +38,6 @@ export default {
|
|||
GlAlert,
|
||||
WorkItemDrawer,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
inject: [
|
||||
'boardType',
|
||||
'canAdminList',
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { GlDrawer } from '@gitlab/ui';
|
|||
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
|
||||
import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
|
||||
import getMergeRequestReviewers from '~/sidebar/queries/get_merge_request_reviewers.query.graphql';
|
||||
import ReviewersContainer from './reviewers_container.vue';
|
||||
|
||||
export default {
|
||||
apollo: {
|
||||
|
|
@ -23,7 +22,6 @@ export default {
|
|||
},
|
||||
components: {
|
||||
GlDrawer,
|
||||
ReviewersContainer,
|
||||
ApprovalSummary: () =>
|
||||
import('ee_component/merge_requests/components/reviewers/approval_summary.vue'),
|
||||
ApprovalRulesWrapper: () =>
|
||||
|
|
@ -65,14 +63,12 @@ export default {
|
|||
<h4 class="gl-my-0">{{ __('Assign reviewers') }}</h4>
|
||||
</template>
|
||||
<template #header>
|
||||
<approval-summary />
|
||||
<approval-summary class="gl-mt-3" />
|
||||
</template>
|
||||
<reviewers-container
|
||||
<approval-rules-wrapper
|
||||
:reviewers="reviewers"
|
||||
:loading-reviewers="loadingReviewers"
|
||||
@request-review="(params) => $emit('request-review', params)"
|
||||
@remove-reviewer="(params) => $emit('remove-reviewer', params)"
|
||||
@request-review="(data) => $emit('request-review', data)"
|
||||
@remove-reviewer="(data) => $emit('remove-reviewer', data)"
|
||||
/>
|
||||
<approval-rules-wrapper :reviewers="reviewers" />
|
||||
</gl-drawer>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import userPermissionsQuery from './queries/user_permissions.query.graphql';
|
|||
|
||||
export default {
|
||||
apollo: {
|
||||
// eslint-disable-next-line @gitlab/vue-no-undef-apollo-properties
|
||||
userPermissions: {
|
||||
query: userPermissionsQuery,
|
||||
variables() {
|
||||
|
|
@ -50,6 +49,7 @@ export default {
|
|||
searching: false,
|
||||
fetchedUsers: [],
|
||||
currentSelectedReviewers: this.selectedReviewers.map((r) => r.username),
|
||||
userPermissions: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -141,18 +141,16 @@ export default {
|
|||
|
||||
<template>
|
||||
<update-reviewers
|
||||
v-if="userPermissions && userPermissions.adminMergeRequest"
|
||||
v-if="userPermissions.adminMergeRequest"
|
||||
:selected-reviewers="currentSelectedReviewers"
|
||||
>
|
||||
<template #default="{ loading, updateReviewers }">
|
||||
<gl-collapsible-listbox
|
||||
v-model="currentSelectedReviewers"
|
||||
icon="plus"
|
||||
:toggle-text="$options.i18n.selectReviewer"
|
||||
:toggle-text="__('Edit')"
|
||||
toggle-class="!gl-text-primary"
|
||||
:header-text="$options.i18n.selectReviewer"
|
||||
:reset-button-label="$options.i18n.unassign"
|
||||
text-sr-only
|
||||
category="tertiary"
|
||||
no-caret
|
||||
size="small"
|
||||
|
|
|
|||
|
|
@ -1,115 +0,0 @@
|
|||
<script>
|
||||
import { GlEmptyState, GlButton } from '@gitlab/ui';
|
||||
import noReviewersAssignedSvg from '@gitlab/svgs/dist/illustrations/add-user-sm.svg?url';
|
||||
import UncollapsedReviewerList from '~/sidebar/components/reviewers/uncollapsed_reviewer_list.vue';
|
||||
import { sprintf, __, n__ } from '~/locale';
|
||||
import ReviewerDropdown from '~/merge_requests/components/reviewers/reviewer_dropdown.vue';
|
||||
import UpdateReviewers from './update_reviewers.vue';
|
||||
import userPermissionsQuery from './queries/user_permissions.query.graphql';
|
||||
|
||||
export default {
|
||||
apollo: {
|
||||
userPermissions: {
|
||||
query: userPermissionsQuery,
|
||||
variables() {
|
||||
return {
|
||||
fullPath: this.projectPath,
|
||||
iid: this.issuableIid,
|
||||
};
|
||||
},
|
||||
update: (data) => data.project?.mergeRequest?.userPermissions || {},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
GlEmptyState,
|
||||
GlButton,
|
||||
UncollapsedReviewerList,
|
||||
UpdateReviewers,
|
||||
ReviewerDropdown,
|
||||
},
|
||||
inject: ['projectPath', 'issuableIid'],
|
||||
props: {
|
||||
reviewers: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
loadingReviewers: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
userPermissions: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentUser() {
|
||||
return [gon.current_username];
|
||||
},
|
||||
relativeUrlRoot() {
|
||||
return gon.relative_url_root ?? '';
|
||||
},
|
||||
reviewersTitle() {
|
||||
if (this.reviewers.length === 0) {
|
||||
return sprintf(__('%{count} Reviewers'), { count: this.reviewers.length });
|
||||
}
|
||||
|
||||
return sprintf(n__('%{count} Reviewer', '%{count} Reviewers', this.reviewers.length), {
|
||||
count: this.reviewers.length,
|
||||
});
|
||||
},
|
||||
},
|
||||
noReviewersAssignedSvg,
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="gl-mb-3 gl-flex gl-w-full gl-items-center gl-font-bold gl-leading-20">
|
||||
<template v-if="loadingReviewers">
|
||||
<div class="gl-animate-skeleton-loader gl-h-4 gl-w-20 gl-rounded-base"></div>
|
||||
<div class="gl-animate-skeleton-loader gl-ml-auto gl-h-4 gl-w-4 gl-rounded-base"></div>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ reviewersTitle }}
|
||||
<reviewer-dropdown :selected-reviewers="reviewers" class="gl-ml-auto" />
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="loadingReviewers">
|
||||
<div class="gl-animate-skeleton-loader gl-mb-3 gl-h-4 !gl-max-w-20 gl-rounded-base"></div>
|
||||
<div class="gl-animate-skeleton-loader gl-mb-3 gl-h-4 !gl-max-w-20 gl-rounded-base"></div>
|
||||
<div class="gl-animate-skeleton-loader gl-h-4 !gl-max-w-20 gl-rounded-base"></div>
|
||||
</div>
|
||||
<uncollapsed-reviewer-list
|
||||
v-else-if="reviewers.length"
|
||||
:is-editable="userPermissions.adminMergeRequest"
|
||||
:root-path="relativeUrlRoot"
|
||||
:users="reviewers"
|
||||
issuable-type="merge_request"
|
||||
@request-review="(params) => $emit('request-review', params)"
|
||||
@remove-reviewer="(params) => $emit('remove-reviewer', params)"
|
||||
/>
|
||||
<gl-empty-state v-else :svg-path="$options.noReviewersAssignedSvg" :svg-height="70">
|
||||
<template #description>
|
||||
<p class="gl-mb-3 gl-font-normal">{{ __('No reviewers assigned') }}</p>
|
||||
<update-reviewers
|
||||
v-if="userPermissions.adminMergeRequest"
|
||||
:selected-reviewers="currentUser"
|
||||
>
|
||||
<template #default="{ loading, updateReviewers }">
|
||||
<gl-button
|
||||
category="tertiary"
|
||||
size="small"
|
||||
:loading="loading"
|
||||
data-testid="assign-yourself-button"
|
||||
@click="updateReviewers"
|
||||
>
|
||||
{{ __('Assign yourself') }}
|
||||
</gl-button>
|
||||
</template>
|
||||
</update-reviewers>
|
||||
</template>
|
||||
</gl-empty-state>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -1,19 +1,17 @@
|
|||
<script>
|
||||
// NOTE! For the first iteration, we are simply copying the implementation of Assignees
|
||||
// It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736
|
||||
import { MountingPortal } from 'portal-vue';
|
||||
import { GlLoadingIcon, GlButton, GlTooltipDirective } from '@gitlab/ui';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { n__, s__ } from '~/locale';
|
||||
import ReviewerDrawer from '~/merge_requests/components/reviewers/reviewer_drawer.vue';
|
||||
import ReviewerDropdown from '~/merge_requests/components/reviewers/reviewer_dropdown.vue';
|
||||
|
||||
export default {
|
||||
name: 'ReviewerTitle',
|
||||
components: {
|
||||
MountingPortal,
|
||||
GlLoadingIcon,
|
||||
GlButton,
|
||||
ReviewerDrawer,
|
||||
ReviewerDropdown,
|
||||
},
|
||||
directives: {
|
||||
Tooltip: GlTooltipDirective,
|
||||
|
|
@ -33,11 +31,11 @@ export default {
|
|||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
reviewers: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
drawerOpen: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
reviewerTitle() {
|
||||
|
|
@ -45,17 +43,8 @@ export default {
|
|||
return n__('Reviewer', `%d Reviewers`, reviewers);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleDrawerOpen(drawerOpen = !this.drawerOpen) {
|
||||
if (!this.glFeatures.reviewerAssignDrawer) return;
|
||||
|
||||
this.drawerOpen = drawerOpen;
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
addEditReviewers: s__('MergeRequest|Add or edit reviewers'),
|
||||
changeReviewer: s__('MergeRequest|Change reviewer'),
|
||||
quickAdd: s__('MergeRequest|Quick add reviewers'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -66,33 +55,25 @@ export default {
|
|||
{{ reviewerTitle }}
|
||||
<gl-loading-icon v-if="loading" size="sm" inline class="align-bottom" />
|
||||
<template v-if="editable">
|
||||
<reviewer-dropdown
|
||||
v-if="glFeatures.reviewerAssignDrawer"
|
||||
class="gl-ml-auto"
|
||||
:selected-reviewers="reviewers"
|
||||
/>
|
||||
<gl-button
|
||||
v-else
|
||||
v-tooltip.hover
|
||||
:title="
|
||||
glFeatures.reviewerAssignDrawer
|
||||
? $options.i18n.addEditReviewers
|
||||
: $options.i18n.changeReviewer
|
||||
"
|
||||
class="hide-collapsed gl-float-right gl-ml-auto"
|
||||
:class="{ 'js-sidebar-dropdown-toggle edit-link': !glFeatures.reviewerAssignDrawer }"
|
||||
:title="$options.i18n.changeReviewer"
|
||||
class="hide-collapsed js-sidebar-dropdown-toggle edit-link gl-float-right gl-ml-auto"
|
||||
data-track-action="click_edit_button"
|
||||
data-track-label="right_sidebar"
|
||||
data-track-property="reviewer"
|
||||
:data-testid="glFeatures.reviewerAssignDrawer ? 'drawer-toggle' : 'reviewers-edit-button'"
|
||||
data-testid="reviewers-edit-button"
|
||||
category="tertiary"
|
||||
size="small"
|
||||
@click="toggleDrawerOpen(!drawerOpen)"
|
||||
>
|
||||
{{ __('Edit') }}
|
||||
</gl-button>
|
||||
</template>
|
||||
<mounting-portal v-if="glFeatures.reviewerAssignDrawer" mount-to="#js-reviewer-drawer-portal">
|
||||
<reviewer-drawer
|
||||
:open="drawerOpen"
|
||||
@request-review="(params) => $emit('request-review', params)"
|
||||
@remove-reviewer="(data) => $emit('remove-reviewer', data)"
|
||||
@close="toggleDrawerOpen(false)"
|
||||
/>
|
||||
</mounting-portal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@
|
|||
// NOTE! For the first iteration, we are simply copying the implementation of Assignees
|
||||
// It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736
|
||||
import Vue from 'vue';
|
||||
import { MountingPortal } from 'portal-vue';
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import { createAlert } from '~/alert';
|
||||
import { TYPE_ISSUE } from '~/issues/constants';
|
||||
import { __ } from '~/locale';
|
||||
import { isGid, getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { fetchUserCounts } from '~/super_sidebar/user_counts_fetch';
|
||||
import ReviewerDrawer from '~/merge_requests/components/reviewers/reviewer_drawer.vue';
|
||||
import eventHub from '../../event_hub';
|
||||
import getMergeRequestReviewersQuery from '../../queries/get_merge_request_reviewers.query.graphql';
|
||||
import mergeRequestReviewersUpdatedSubscription from '../../queries/merge_request_reviewers.subscription.graphql';
|
||||
|
|
@ -18,14 +22,21 @@ export const state = Vue.observable({
|
|||
issuable: {},
|
||||
loading: false,
|
||||
initialLoading: true,
|
||||
drawerOpen: false,
|
||||
});
|
||||
|
||||
export default {
|
||||
name: 'SidebarReviewers',
|
||||
components: {
|
||||
MountingPortal,
|
||||
GlButton,
|
||||
ReviewerTitle,
|
||||
Reviewers,
|
||||
ReviewerDrawer,
|
||||
ApprovalSummary: () =>
|
||||
import('ee_component/merge_requests/components/reviewers/approval_summary.vue'),
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
props: {
|
||||
mediator: {
|
||||
type: Object,
|
||||
|
|
@ -132,12 +143,14 @@ export default {
|
|||
eventHub.$on('sidebar.addReviewer', this.addReviewer);
|
||||
eventHub.$on('sidebar.removeAllReviewers', this.removeAllReviewers);
|
||||
eventHub.$on('sidebar.saveReviewers', this.saveReviewers);
|
||||
eventHub.$on('sidebar.toggleReviewerDrawer', this.toggleDrawerOpen);
|
||||
},
|
||||
beforeDestroy() {
|
||||
eventHub.$off('sidebar.removeReviewer', this.removeReviewer);
|
||||
eventHub.$off('sidebar.addReviewer', this.addReviewer);
|
||||
eventHub.$off('sidebar.removeAllReviewers', this.removeAllReviewers);
|
||||
eventHub.$off('sidebar.saveReviewers', this.saveReviewers);
|
||||
eventHub.$off('sidebar.toggleReviewerDrawer', this.toggleDrawerOpen);
|
||||
},
|
||||
methods: {
|
||||
reviewBySelf() {
|
||||
|
|
@ -178,6 +191,11 @@ export default {
|
|||
event.done();
|
||||
}
|
||||
},
|
||||
toggleDrawerOpen(drawerOpen = !this.drawerOpen) {
|
||||
if (!this.glFeatures.reviewerAssignDrawer) return;
|
||||
|
||||
this.drawerOpen = drawerOpen;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -185,12 +203,24 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<reviewer-title
|
||||
:reviewers="reviewers"
|
||||
:number-of-reviewers="reviewers.length"
|
||||
:loading="isLoading"
|
||||
:editable="canUpdate"
|
||||
@request-review="requestReview"
|
||||
@remove-reviewer="removeReviewerById"
|
||||
/>
|
||||
<approval-summary v-if="glFeatures.reviewerAssignDrawer" short-text class="gl-mb-2">
|
||||
<gl-button
|
||||
size="small"
|
||||
category="tertiary"
|
||||
variant="confirm"
|
||||
class="gl-ml-3"
|
||||
@click="toggleDrawerOpen()"
|
||||
>
|
||||
{{ __('Assign') }}
|
||||
</gl-button>
|
||||
</approval-summary>
|
||||
<reviewers
|
||||
v-if="!initialLoading"
|
||||
:root-path="relativeUrlRoot"
|
||||
|
|
@ -202,5 +232,13 @@ export default {
|
|||
@assign-self="reviewBySelf"
|
||||
@remove-reviewer="removeReviewerById"
|
||||
/>
|
||||
<mounting-portal v-if="glFeatures.reviewerAssignDrawer" mount-to="#js-reviewer-drawer-portal">
|
||||
<reviewer-drawer
|
||||
:open="drawerOpen"
|
||||
@request-review="requestReview"
|
||||
@remove-reviewer="removeReviewerById"
|
||||
@close="toggleDrawerOpen(false)"
|
||||
/>
|
||||
</mounting-portal>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ export default {
|
|||
this.loadingStates[userId] = LOADING_STATE;
|
||||
this.$emit('remove-reviewer', {
|
||||
userId,
|
||||
callback: () => this.requestRemovalComplete(userId),
|
||||
done: () => this.requestRemovalComplete(userId),
|
||||
});
|
||||
},
|
||||
requestReviewComplete(userId, success) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#import "~/graphql_shared/fragments/user.fragment.graphql"
|
||||
#import "~/graphql_shared/fragments/user_availability.fragment.graphql"
|
||||
#import "ee_else_ce/sidebar/queries/reviewer_applicable_approval_rules.fragment.graphql"
|
||||
|
||||
query mergeRequestReviewers($fullPath: ID!, $iid: String!) {
|
||||
workspace: project(fullPath: $fullPath) {
|
||||
|
|
@ -15,6 +16,8 @@ query mergeRequestReviewers($fullPath: ID!, $iid: String!) {
|
|||
canUpdate
|
||||
approved
|
||||
reviewState
|
||||
|
||||
...ReviewersApplicableApprovalRules
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#import "~/graphql_shared/fragments/user.fragment.graphql"
|
||||
#import "~/graphql_shared/fragments/user_availability.fragment.graphql"
|
||||
#import "ee_else_ce/sidebar/queries/reviewer_applicable_approval_rules.fragment.graphql"
|
||||
|
||||
subscription mergeRequestReviewersUpdated($issuableId: IssuableID!) {
|
||||
mergeRequestReviewersUpdated(issuableId: $issuableId) {
|
||||
|
|
@ -14,6 +15,8 @@ subscription mergeRequestReviewersUpdated($issuableId: IssuableID!) {
|
|||
canUpdate
|
||||
approved
|
||||
reviewState
|
||||
|
||||
...ReviewersApplicableApprovalRules
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
fragment ReviewersApplicableApprovalRules on UserMergeRequestInteraction {
|
||||
# Overriden in EE
|
||||
approved
|
||||
}
|
||||
|
|
@ -66,11 +66,17 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
actionButtons: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasApprovalAuthError: false,
|
||||
isApproving: false,
|
||||
userPermissions: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -276,6 +282,7 @@ export default {
|
|||
:collapsed="collapsed"
|
||||
:expand-details-tooltip="__('Expand eligible approvers')"
|
||||
:collapse-details-tooltip="__('Collapse eligible approvers')"
|
||||
:actions="actionButtons"
|
||||
@toggle="() => $emit('toggle')"
|
||||
>
|
||||
<template v-if="isLoading">{{ $options.FETCH_LOADING }}</template>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ export const COMPONENTS = {
|
|||
import('ee_component/vue_merge_request_widget/components/checks/locked_paths.vue'),
|
||||
locked_lfs_files: () =>
|
||||
import('ee_component/vue_merge_request_widget/components/checks/locked_paths.vue'),
|
||||
not_approved: () =>
|
||||
import('ee_component/vue_merge_request_widget/components/checks/not_approved.vue'),
|
||||
};
|
||||
|
||||
export const FAILURE_REASONS = {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ export default {
|
|||
class="media-body gl-leading-normal"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div
|
||||
:class="{
|
||||
'state-container-action-buttons gl-flex-wrap lg:gl-justify-end': !actions.length,
|
||||
|
|
@ -114,7 +115,6 @@ export default {
|
|||
<actions v-if="actions.length" :tertiary-buttons="actions" />
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="isCollapsible"
|
||||
:class="{ 'md:gl-hidden': !collapseOnDesktop }"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ module Import
|
|||
class SourceUsersController < ApplicationController
|
||||
prepend_before_action :check_feature_flag!
|
||||
|
||||
before_action :source_user
|
||||
before_action :check_source_user_valid!
|
||||
|
||||
respond_to :html
|
||||
|
|
@ -53,7 +52,7 @@ module Import
|
|||
strong_memoize_attr :source_user
|
||||
|
||||
def check_feature_flag!
|
||||
not_found unless Feature.enabled?(:importer_user_mapping, current_user)
|
||||
not_found unless Feature.enabled?(:importer_user_mapping, source_user.reassigned_by_user)
|
||||
end
|
||||
|
||||
def banner(partial)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ module ViteHelper
|
|||
options[:host] = URI::HTTP.build(host: ViteRuby.config.host, port: ViteRuby.config.port).to_s
|
||||
end
|
||||
|
||||
options[:extname] = false
|
||||
|
||||
stylesheet_link_tag(
|
||||
ViteRuby.instance.manifest.path_for("stylesheets/styles.#{path}.scss", type: :stylesheet),
|
||||
**options
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@ module Import
|
|||
def perform(import_source_user_id, _params = {})
|
||||
@import_source_user = Import::SourceUser.find_by_id(import_source_user_id)
|
||||
|
||||
return unless Feature.enabled?(
|
||||
:importer_user_mapping,
|
||||
User.actor_from_id(import_source_user&.reassigned_by_user_id)
|
||||
)
|
||||
|
||||
return unless import_source_user_valid?
|
||||
|
||||
Import::ReassignPlaceholderUserRecordsService.new(import_source_user).execute
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
migration_job_name: BackfillApprovalGroupRulesProtectedBranchesGroupId
|
||||
description: Backfills sharding key `approval_group_rules_protected_branches.group_id` from `approval_group_rules`.
|
||||
description: Backfills sharding key `approval_group_rules_protected_branches.group_id`
|
||||
from `approval_group_rules`.
|
||||
feature_category: source_code_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159584
|
||||
milestone: '17.2'
|
||||
queued_migration_version: 20240716135032
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
finalized_by: '20240926232010'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FinalizeBackfillApprovalGroupRulesProtectedBranchesGroupId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.5'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
def up
|
||||
ensure_batched_background_migration_is_finished(
|
||||
job_class_name: 'BackfillApprovalGroupRulesProtectedBranchesGroupId',
|
||||
table_name: :approval_group_rules_protected_branches,
|
||||
column_name: :id,
|
||||
job_arguments: [:group_id, :approval_group_rules, :group_id, :approval_group_rule_id],
|
||||
finalize: true
|
||||
)
|
||||
end
|
||||
|
||||
def down; end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
33eb34ed1ba55339802c399e74aec4318a5e83fdbdd744e32632adbf6a452b93
|
||||
|
|
@ -19,8 +19,11 @@ These options are in lowercase.
|
|||
|
||||
### Target Types
|
||||
|
||||
> - Support for epics [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13056) in GitLab 17.3.
|
||||
|
||||
Available target types for the `target_type` parameter are:
|
||||
|
||||
- `epic`
|
||||
- `issue`
|
||||
- `milestone`
|
||||
- `merge_request`
|
||||
|
|
@ -31,7 +34,7 @@ Available target types for the `target_type` parameter are:
|
|||
- `user`
|
||||
|
||||
These options are in lowercase.
|
||||
Events associated with epics are not available using the API.
|
||||
Some epic features like child items, linked items, start dates, due dates, and health statuses are not available using the API.
|
||||
Some discussions on merge requests may be of type `DiscussionNote`. These are not available using the API.
|
||||
|
||||
### Date formatting
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
|
@ -22,7 +22,7 @@ environment, reducing the effort to assess the impact of changes. Thus, when we
|
|||
and it will immediately be clear that the application can still be properly built and deployed. After all, you can _see_ it
|
||||
running!
|
||||
|
||||

|
||||

|
||||
|
||||
However, looking at the freshly deployed code to check whether it still looks and behaves as
|
||||
expected is repetitive manual work, which means it is a prime candidate for automation. This is
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -127,7 +127,7 @@ They can be added per project by navigating to the project's **Settings** > **CI
|
|||
To the field **KEY**, add the name `SSH_PRIVATE_KEY`, and to the **VALUE** field, paste the private key you've copied earlier.
|
||||
We'll use this variable in the `.gitlab-ci.yml` later, to easily connect to our remote server as the deployer user without entering its password.
|
||||
|
||||

|
||||

|
||||
|
||||
We also need to add the public key to **Project** > **Settings** > **Repository** as a [deploy key](../../../user/project/deploy_keys/index.md), which gives us the ability to access our repository from the server through the SSH protocol.
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ cat ~/.ssh/id_rsa.pub
|
|||
|
||||
To the field **Title**, add any name you want, and paste the public key into the **Key** field.
|
||||
|
||||

|
||||

|
||||
|
||||
Now, let's clone our repository on the server just to make sure the `deployer` user has access to the repository.
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ Now that we have our `Dockerfile` let's build and push it to our [GitLab contain
|
|||
|
||||
In your GitLab project repository, go to the **Registry** tab.
|
||||
|
||||

|
||||

|
||||
|
||||
You may need to enable the container registry for your project to see this tab. You'll find it under your project's **Settings > General > Visibility, project features, permissions**.
|
||||
|
||||
|
|
@ -464,7 +464,7 @@ docker push registry.gitlab.com/<USERNAME>/laravel-sample
|
|||
|
||||
Congratulations! You just pushed the first Docker image to the GitLab Registry, and if you refresh the page you should be able to see it:
|
||||
|
||||

|
||||

|
||||
|
||||
You can also [use GitLab CI/CD](https://about.gitlab.com/blog/2016/05/23/gitlab-container-registry/#use-with-gitlab-ci) to build and push your Docker images, rather than doing that on your machine.
|
||||
|
||||
|
|
@ -624,41 +624,41 @@ You may also want to add another job for [staging environment](https://about.git
|
|||
We have prepared everything we need to test and deploy our app with GitLab CI/CD.
|
||||
To do that, commit and push `.gitlab-ci.yml` to the `main` branch. It will trigger a pipeline, which you can watch live under your project's **Pipelines**.
|
||||
|
||||

|
||||

|
||||
|
||||
Here we see our **Test** and **Deploy** stages.
|
||||
The **Test** stage has the `unit_test` build running.
|
||||
Select it to see the runner's output.
|
||||
|
||||

|
||||

|
||||
|
||||
After our code passed through the pipeline successfully, we can deploy to our production server by selecting **Run** (**{play}**) on the right side.
|
||||
|
||||

|
||||

|
||||
|
||||
After the deploy pipeline passes successfully, go to **Pipelines > Environments**.
|
||||
|
||||

|
||||

|
||||
|
||||
If something doesn't work as expected, you can roll back to the latest working version of your app.
|
||||
|
||||

|
||||

|
||||
|
||||
By selecting the external link icon specified on the right side, GitLab opens the production website.
|
||||
Our deployment successfully was done and we can see the application is live.
|
||||
|
||||

|
||||

|
||||
|
||||
In the case that you're interested to know how is the application directory structure on the production server after deployment, here are three directories named `current`, `releases` and `storage`.
|
||||
As you know, the `current` directory is a symbolic link that points to the latest release.
|
||||
The `.env` file consists of our Laravel environment variables.
|
||||
|
||||

|
||||

|
||||
|
||||
If you go to the `current` directory, you should see the application's content.
|
||||
As you see, the `.env` is pointing to the `/var/www/app/.env` file and also `storage` is pointing to the `/var/www/app/storage/` directory.
|
||||
|
||||

|
||||

|
||||
|
||||
## Conclusion
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ To enable the plugin:
|
|||
1. In your IDE, on the top bar, select your IDE's name, then select **Settings**.
|
||||
1. On the left sidebar, select **Plugins**.
|
||||
1. Select the **GitLab Duo** plugin, and select **Install**.
|
||||
1. Select **OK**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
||||
To configure the plugin in your IDE after you enable it:
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ To configure the plugin in your IDE after you enable it:
|
|||
1. For **GitLab Personal Access Token**, paste in the personal access token you created. The token is not displayed,
|
||||
nor is it accessible to others.
|
||||
1. Select **Verify setup**.
|
||||
1. Select **OK**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
||||
### Enable experimental or beta features
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ To use a custom SSL certificate with GitLab Duo:
|
|||
1. On the left sidebar, expand **Tools**, then select **GitLab Duo**.
|
||||
1. Under **Connection**, enter the **URL to GitLab instance**.
|
||||
1. To verify your connection, select **Verify setup**.
|
||||
1. Select **OK**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
||||
If your IDE detects a non-trusted SSL certificate:
|
||||
|
||||
|
|
@ -161,18 +161,7 @@ From the IDE:
|
|||
1. Select **Integrate with 1Password CLI**.
|
||||
1. Optional. For **Secret reference**, paste the secret reference you copied from 1Password.
|
||||
1. Optional. To verify your credentials, select **Verify setup**.
|
||||
1. Select **OK**.
|
||||
|
||||
## Toggle sending open tabs as context
|
||||
|
||||
By default, the Code Suggestions use the files open in your IDE for context.
|
||||
To enable or disable this feature in your IDE:
|
||||
|
||||
1. Go to your IDE's top menu bar and select **Settings**.
|
||||
1. On the left sidebar, expand **Tools**, then select **GitLab Duo**.
|
||||
1. Expand **GitLab Language Server**.
|
||||
1. Under **Code Completion**, select or clear **Send open tabs as context**.
|
||||
1. Select **OK**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
||||
## Report issues with the plugin
|
||||
|
||||
|
|
@ -195,6 +184,7 @@ built-in error reporting tool:
|
|||
|
||||
## Related topics
|
||||
|
||||
- [Code Suggestions](../../user/project/repository/code_suggestions/index.md)
|
||||
- [About the Create:Editor Extensions Group](https://handbook.gitlab.com/handbook/engineering/development/dev/create/editor-extensions/)
|
||||
- [Open issues for this plugin](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin/-/issues/)
|
||||
- [Plugin documentation](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin/-/blob/main/README.md)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ To enable debug logs in JetBrains:
|
|||
1. On the top bar, go to **Help > Diagnostic Tools > Debug Log Settings**, or
|
||||
search for the action by going to **Help > Find Action > Debug log settings**.
|
||||
1. Add this line: `com.gitlab.plugin`
|
||||
1. Select **OK**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
||||
The debug logs are available in the `idea.log` log file.
|
||||
|
||||
|
|
@ -66,8 +66,7 @@ To do this:
|
|||
1. Confirm your default browser trusts the **URL to GitLab instance** you're using.
|
||||
1. Enable the **Ignore certificate errors** option.
|
||||
1. Select **Verify setup**.
|
||||
1. Select **Apply**.
|
||||
1. Select **OK**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
||||
## Error: `Failed to check token`
|
||||
|
||||
|
|
@ -79,4 +78,4 @@ GitLab Language Server process are invalid. To re-enable Code Suggestions:
|
|||
1. Under **Connection**, select **Verify setup**.
|
||||
1. Update your **Connection** details as needed.
|
||||
1. Select **Verify setup**, and confirm that authentication succeeds.
|
||||
1. Select **OK**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 3.7 KiB |
|
|
@ -114,15 +114,6 @@ This extension brings the GitLab features you use every day directly into your V
|
|||
|
||||
For detailed information on these features, refer to the [GitLab Workflow extension documentation](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/README.md).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you encounter any issues or have feature requests:
|
||||
|
||||
1. Check the [extension documentation](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/README.md)
|
||||
for known issues and solutions.
|
||||
1. Report bugs or request features in the
|
||||
[`gitlab-vscode-extension` issue queue](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues).
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Download the GitLab Workflow extension](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor Extensions
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Using the VS Code extension with self-signed certificates
|
||||
|
||||
You can still use the GitLab Workflow extension for VS Code even if your GitLab instance uses a self-signed SSL certificate.
|
||||
|
||||
If you also use a proxy to connect to your GitLab instance, let us know in
|
||||
[issue 314](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/314). If you still have connection problems
|
||||
after completing these steps, review [epic 6244](https://gitlab.com/groups/gitlab-org/-/epics/6244), which links to
|
||||
all existing SSL issues for the GitLab Workflow extension.
|
||||
|
||||
## Use the extension with a self-signed CA
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Your GitLab instance uses a certificate signed with a self-signed certificate authority (CA).
|
||||
|
||||
1. Ensure your CA certificate is correctly added to your system for the extension to work. VS Code reads
|
||||
the system certificate store, and changes all node `http` requests to trust the certificates:
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
A[Self-signed CA] -- signed --> B[Your GitLab instance certificate]
|
||||
```
|
||||
|
||||
For more information, see [Self-signed certificate error when installing Python support in WSL](https://github.com/microsoft/vscode/issues/131836#issuecomment-909983815) in the Visual Studio Code issue queue.
|
||||
|
||||
1. In your VS Code `settings.json`, set `"http.systemCertificates": true`. The default value is `true`, so you might not need to change this value.
|
||||
1. Follow the instructions for your operating system:
|
||||
|
||||
### Windows
|
||||
|
||||
NOTE:
|
||||
These instructions were tested on Windows 10 and VS Code 1.60.0.
|
||||
|
||||
Make sure you can see your self-signed CA in your certificate store:
|
||||
|
||||
1. Open the command prompt.
|
||||
1. Run `certmgr`.
|
||||
1. Make sure you see your certificate in **Trusted Root Certification Authorities > Certificates**.
|
||||
|
||||
### Linux
|
||||
|
||||
NOTE:
|
||||
These instructions were tested on Arch Linux `5.14.3-arch1-1` and VS Code 1.60.0.
|
||||
|
||||
1. Use your operating system's tools to confirm you can add our self-signed CA to your system:
|
||||
- `update-ca-trust` (Fedora, RHEL, CentOS)
|
||||
- `update-ca-certificates` (Ubuntu, Debian, OpenSUSE, SLES)
|
||||
- `trust` (Arch)
|
||||
1. Confirm the CA certificate is in `/etc/ssl/certs/ca-certificates.crt` or `/etc/ssl/certs/ca-bundle.crt`.
|
||||
VS Code [checks this location](https://github.com/microsoft/vscode/issues/131836#issuecomment-909983815).
|
||||
|
||||
### MacOS
|
||||
|
||||
NOTE:
|
||||
These instructions are untested, but likely work as intended. If you can confirm this setup,
|
||||
create a documentation issue with more information.
|
||||
|
||||
Make sure you see the self-signed CA in your keychain:
|
||||
|
||||
1. Go to **Finder > Applications > Utilities > Keychain Access**.
|
||||
1. In the left-hand column, select **System**.
|
||||
1. Your self-signed CA certificate should be on the list.
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor Extensions
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Troubleshooting the GitLab Workflow extension for VS Code
|
||||
|
||||
If you encounter any issues with the GitLab Workflow extension for VS Code, or have feature requests for it:
|
||||
|
||||
1. Check the [extension documentation](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/README.md)
|
||||
for known issues and solutions.
|
||||
1. Report bugs or request features in the
|
||||
[`gitlab-vscode-extension` issue queue](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues).
|
||||
|
||||
## Enable debug logs
|
||||
|
||||
Both the VS Code Extension and the GitLab Language Server provide logs that can help you troubleshoot. To enable debug logging:
|
||||
|
||||
1. In VS Code, on the top bar, go to **Code > Preferences > Settings**.
|
||||
1. On the top right corner, select **Open Settings (JSON)** to edit your `settings.json` file.
|
||||
1. Add this line, or edit it if it already exists:
|
||||
|
||||
```json
|
||||
"gitlab.debug": true,
|
||||
```
|
||||
|
||||
1. Save your changes.
|
||||
|
||||
### View log files
|
||||
|
||||
To view debug logs from either the VS Code Extension or the GitLab Language Server:
|
||||
|
||||
1. Use the command `GitLab: Show Extension Logs` to view the output panel.
|
||||
1. In the upper right corner of the output panel, select either **GitLab Workflow** or
|
||||
**GitLab Language Server** from the dropdown list.
|
||||
|
||||
## Error: `407 Access Denied` failure with a proxy
|
||||
|
||||
If you use an authenticated proxy, you might encounter an error like `407 Access Denied (authentication_failed)`:
|
||||
|
||||
```plaintext
|
||||
Request failed: Can't add GitLab account for https://gitlab.com. Check your instance URL and network connection.
|
||||
Fetching resource from https://gitlab.com/api/v4/personal_access_tokens/self failed
|
||||
```
|
||||
|
||||
GitLab Duo Code Suggestions does not support authenticated proxies. For the proposed feature,
|
||||
see [issue 1234](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/1234) in the extension's project.
|
||||
|
||||
## Configure self-signed certificates
|
||||
|
||||
To use self-signed certificates to connect to your GitLab instance, configure them using these settings.
|
||||
These settings are community contributions, because the GitLab team uses a public CA. None of the fields are required.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You're not using the [`http.proxy` setting](https://code.visualstudio.com/docs/setup/network#_legacy-proxy-server-support)
|
||||
in VS Code. For more information, see [issue 314](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/314).
|
||||
|
||||
| Setting name | Default | Information |
|
||||
| ------------ | :-----: | ----------- |
|
||||
| `gitlab.ca` | null | Deprecated. See [the SSL setup guide](ssl.md) for more information on how to set up your self-signed CA. |
|
||||
| `gitlab.cert`| null | Unsupported. See [epic 6244](https://gitlab.com/groups/gitlab-org/-/epics/6244). If your self-managed GitLab instance requires a custom certificate or key pair, set this option to point to your certificate file. See `gitlab.certKey`. |
|
||||
| `gitlab.certKey`| null | Unsupported. See [epic 6244](https://gitlab.com/groups/gitlab-org/-/epics/6244). If your self-managed GitLab instance requires a custom certificate or key pair, set this option to point to your certificate key file. See `gitlab.cert`. |
|
||||
| `gitlab.ignoreCertificateErrors` | false | Unsupported. See [epic 6244](https://gitlab.com/groups/gitlab-org/-/epics/6244). If you use a self-managed GitLab instance with no SSL certificate, or have certificate issues that prevent you from using the extension, set this option to `true` to ignore certificate errors. |
|
||||
|
||||
## Disable code suggestions
|
||||
|
||||
Code completion is enabled by default. To disable it:
|
||||
|
||||
1. In VS Code, on the left sidebar, select **Extensions > GitLab Workflow**.
|
||||
1. Select **Manage** (**{settings}**) **> Extension Settings**.
|
||||
1. In **GitLab > Duo Code Suggestions**, clear **Enable GitLab Duo Code Suggestions**.
|
||||
|
||||
## Disable streaming of code generation results
|
||||
|
||||
By default, code generation streams AI-generated code. Streaming sends generated code
|
||||
to your editor incrementally, rather than waiting for the full code snippet to generate.
|
||||
This allows for a more interactive and responsive experience.
|
||||
|
||||
If you prefer to see code generation results only when they are complete, you can turn off streaming.
|
||||
Disabling streaming means that code generation requests might be perceived
|
||||
as taking longer to resolve. To disable streaming:
|
||||
|
||||
1. In VS Code, on the top bar, go to **Code > Settings > Settings**.
|
||||
1. On the top right corner, select **Open Settings (JSON)** to edit your `settings.json` file:
|
||||
|
||||

|
||||
1. In your `settings.json` file, add this line, or set it to `false` it already exists:
|
||||
|
||||
```json
|
||||
"gitlab.featureFlags.streamCodeGenerations": false,
|
||||
```
|
||||
|
||||
1. Save your changes.
|
||||
|
||||
## Error: Direct connection fails
|
||||
|
||||
> - Direct connection [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13252) in GitLab 17.2.
|
||||
|
||||
To reduce latency, the Workflow extension tries to send suggestion completion requests directly to GitLab Cloud Connector,
|
||||
bypassing the GitLab instance. This network connection does not use the proxy and certificate settings of the VS Code extension.
|
||||
|
||||
If your GitLab instance doesn't support direct connections, or your network prevents the extension from connecting to
|
||||
GitLab Cloud Connector, you might see these warnings in your logs:
|
||||
|
||||
```plaintext
|
||||
Failed to fetch direct connection details from GitLab instance.
|
||||
Code suggestion requests will be sent to GitLab instance.
|
||||
```
|
||||
|
||||
This error means your instance either doesn't support direct connections, or is misconfigured.
|
||||
To fix the problem, see the [troubleshooting guide for Code Suggestions](../../user/project/repository/code_suggestions/troubleshooting.md).
|
||||
|
||||
If you see this error, the extension can't connect to GitLab Cloud Connector, and is reverting to use your GitLab instance:
|
||||
|
||||
```plaintext
|
||||
Direct connection for code suggestions failed.
|
||||
Code suggestion requests will be sent to your GitLab instance.
|
||||
```
|
||||
|
||||
The indirect connection through your GitLab instance is about 100 ms slower, but otherwise works the same.
|
||||
This issue is often caused by network connection problems, like with your LAN firewall or proxy settings.
|
||||
|
|
@ -108,11 +108,9 @@ you might write something like:
|
|||
AI is non-deterministic, so you may not get the same suggestion every time with the same input.
|
||||
To generate quality code, write clear, descriptive, specific tasks.
|
||||
|
||||
### Best practice examples
|
||||
|
||||
For use cases and best practices, follow the [GitLab Duo examples documentation](../../../gitlab_duo_examples.md).
|
||||
|
||||
#### Use open tabs as context
|
||||
## Open tabs as context
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/464767) in GitLab 17.2 [with a flag](../../../../administration/feature_flags.md) named `advanced_context_resolver`. Disabled by default.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/462750) in GitLab 17.2 [with a flag](../../../../administration/feature_flags.md) named `code_suggestions_context`. Disabled by default.
|
||||
|
|
@ -125,49 +123,80 @@ FLAG:
|
|||
The availability of this feature is controlled by a feature flag.
|
||||
For more information, see the history.
|
||||
|
||||
For better results from GitLab Duo Code Suggestions, ensure that Open Tabs Context is enabled in your IDE settings.
|
||||
This feature uses the contents of the files currently open in your IDE to get more
|
||||
accurate and relevant results from Code Suggestions. Like prompt engineering, these files
|
||||
To get more accurate and relevant results from Code Suggestions and code generation, you can use
|
||||
the contents of the files open in tabs in your IDE. Similar to prompt engineering, these files
|
||||
give GitLab Duo more information about the standards and practices in your code project.
|
||||
|
||||
To get the most benefit from using your open tabs as context, open the files relevant to the code
|
||||
you want to create, including configuration files. When you start work in a new file,
|
||||
Code Suggestions offers you suggestions in the new file.
|
||||
### Enable open tabs as context
|
||||
|
||||
By default, Code Suggestions uses the open files in your IDE for context when making suggestions.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Requires GitLab 17.2 and later. Earlier GitLab versions that support Code Suggestions
|
||||
cannot weight the content of open tabs more heavily than other files in your project.
|
||||
- Requires a [supported code language](#advanced-context-supported-languages).
|
||||
- You must have GitLab 17.2 or later. Earlier GitLab versions that support Code Suggestions
|
||||
cannot weigh the content of open tabs more heavily than other files in your project.
|
||||
- GitLab Duo Code Suggestions must be enabled for your project.
|
||||
- Use a [supported code language](#advanced-context-supported-languages):
|
||||
- Code completion: All configured languages.
|
||||
- Code generation: Go, Java, JavaScript, Kotlin, Python, Ruby, Rust, TypeScript (`.ts` and `.tsx` files),
|
||||
Vue, and YAML.
|
||||
- For Visual Studio Code, you must have GitLab Workflow extension version 4.14.2 or later.
|
||||
|
||||
1. Open the files you want to provide for context. Advanced Context uses the most recently
|
||||
opened or changed files for context. If you don’t want a file sent as additional context, close it.
|
||||
1. To fine-tune your Code Generation results, add code comments to your file that explain
|
||||
what you want to build. Code Generation treats your code comments like chat. Your code comments
|
||||
update the `user_instruction`, and then improve the next results you receive.
|
||||
To confirm that open tabs are used as context:
|
||||
|
||||
As you work, GitLab Duo provides Code Suggestions that use your other open files
|
||||
(within [truncation limits](#truncation-of-file-content))
|
||||
as extra context.
|
||||
::Tabs
|
||||
|
||||
:::TabTitle Visual Studio Code
|
||||
|
||||
1. On the top bar, go to **Code > Settings > Extensions**.
|
||||
1. Search for GitLab Workflow in the list, and select the gear icon.
|
||||
1. Select **Extension Settings**.
|
||||
1. In your **User** settings, under **GitLab › Duo Code Suggestions: Open Tabs Context**,
|
||||
select **Enable Open Tabs Context to improve Code Suggestions by sharing context across open tabs**.
|
||||
|
||||
:::TabTitle JetBrains IDEs
|
||||
|
||||
1. Go to your IDE's top menu bar and select **Settings**.
|
||||
1. On the left sidebar, expand **Tools**, then select **GitLab Duo**.
|
||||
1. Expand **GitLab Language Server**.
|
||||
1. Under **Code Completion**, select **Send open tabs as context**.
|
||||
1. Select **OK** or **Save**.
|
||||
|
||||
::EndTabs
|
||||
|
||||
### Use open tabs as context
|
||||
|
||||
Open the files you want to provide for context:
|
||||
|
||||
- Open tabs uses the most recently opened or changed files.
|
||||
- If you do not want a file used as additional context, close that file.
|
||||
|
||||
When you start working in a file, GitLab Duo uses your open files
|
||||
as extra context, within [truncation limits](#truncation-of-file-content).
|
||||
|
||||
You can adjust your code generation results by adding code comments to your file
|
||||
that explain what you want to build. Code generation treats your code comments
|
||||
like chat. Your code comments update the `user_instruction`, and then improve
|
||||
the next results you receive.
|
||||
|
||||
To learn about the code that builds the prompt, see these files:
|
||||
|
||||
- **Code Generation**:
|
||||
- **Code generation**:
|
||||
[`ee/lib/api/code_suggestions.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/api/code_suggestions.rb#L76)
|
||||
in the `gitlab` repository.
|
||||
- **Code Completion**:
|
||||
- **Code completion**:
|
||||
[`ai_gateway/code_suggestions/processing/completions.py`](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/fcb3f485a8f047a86a8166aad81f93b6d82106a7/ai_gateway/code_suggestions/processing/completions.py#L273)
|
||||
in the `modelops` repository.
|
||||
|
||||
We'd love your feedback about the Advanced Context feature in
|
||||
Provide feedback about this feature in
|
||||
[issue 258](https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/issues/258).
|
||||
|
||||
### Advanced Context supported languages
|
||||
## Advanced Context supported languages
|
||||
|
||||
The Advanced Context feature supports these languages:
|
||||
|
||||
- Code Completion: all configured languages.
|
||||
- Code Generation: Go, Java, JavaScript, Kotlin, Python, Ruby, Rust, TypeScript (`.ts` and `.tsx` files), Vue, and YAML.
|
||||
- Code completion: all configured languages.
|
||||
- Code generation: Go, Java, JavaScript, Kotlin, Python, Ruby, Rust, TypeScript (`.ts` and `.tsx` files), Vue, and YAML.
|
||||
|
||||
## Response time
|
||||
|
||||
|
|
|
|||
|
|
@ -145,57 +145,6 @@ To do this:
|
|||
|
||||
::EndTabs
|
||||
|
||||
## Use open tabs as context
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/issues/206) in GitLab 17.2.
|
||||
|
||||
To enhance the accuracy and relevance of GitLab Duo Code Suggestions, enable the use of
|
||||
open tabs as context in your IDE settings. This feature uses the contents of files most recently
|
||||
opened or changed in your IDE to provide more tailored code suggestions, within certain truncation limits.
|
||||
This extra context gives you:
|
||||
|
||||
- More accurate and relevant code suggestions
|
||||
- Better alignment with your project's standards and practices
|
||||
- Improved context for new file creation
|
||||
|
||||
Open tabs as context supports these languages:
|
||||
|
||||
- Code Completion: All configured languages.
|
||||
- Code Generation: Go, Java, JavaScript, Kotlin, Python, Ruby, Rust, TypeScript (`.ts` and `.tsx` files),
|
||||
Vue, and YAML.
|
||||
|
||||
## Enable open tabs as context
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Requires GitLab 17.1 or later.
|
||||
- For GitLab self-managed instances, enable the `code_suggestions_context`and the
|
||||
`advanced_context_resolver` [feature flags](../../../feature_flags.md).
|
||||
- GitLab Duo Code Suggestions enabled for your project
|
||||
- For Visual Studio Code, requires the GitLab Workflow extension, version 4.14.2 or later.
|
||||
|
||||
::Tabs
|
||||
|
||||
:::TabTitle Visual Studio Code
|
||||
|
||||
1. Install the [GitLab Workflow extension](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow)
|
||||
from the Visual Studio Marketplace.
|
||||
1. Configure the extension following the
|
||||
[setup instructions](https://gitlab.com/gitlab-org/gitlab-vscode-extension#extension-settings).
|
||||
1. Enable the feature by toggling the `gitlab.duoCodeSuggestions.enabledSupportedLanguages` setting.
|
||||
|
||||
:::TabTitle JetBrains IDEs
|
||||
|
||||
For installation instructions for JetBrains IDEs, see the
|
||||
[GitLab JetBrains Plugin documentation](https://gitlab.com/gitlab-org/editor-extensions/gitlab-jetbrains-plugin#toggle-sending-open-tabs-as-context).
|
||||
|
||||
::EndTabs
|
||||
|
||||
When you're ready to start coding:
|
||||
|
||||
1. Open relevant files, including configuration files, to provide better context.
|
||||
1. Close any files you don't want to be used as context.
|
||||
|
||||
## View multiple code suggestions
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/1325) in GitLab 17.1.
|
||||
|
|
|
|||
|
|
@ -685,14 +685,6 @@ msgid_plural "%{count} Participants"
|
|||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "%{count} Reviewer"
|
||||
msgid_plural "%{count} Reviewers"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "%{count} Reviewers"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{count} approval required from %{name}"
|
||||
msgid_plural "%{count} approvals required from %{name}"
|
||||
msgstr[0] ""
|
||||
|
|
@ -754,9 +746,6 @@ msgstr ""
|
|||
msgid "%{count} of %{total}"
|
||||
msgstr ""
|
||||
|
||||
msgid "%{count} optional %{label}."
|
||||
msgstr ""
|
||||
|
||||
msgid "%{count} project"
|
||||
msgid_plural "%{count} projects"
|
||||
msgstr[0] ""
|
||||
|
|
@ -7592,9 +7581,6 @@ msgstr ""
|
|||
msgid "Assign to me"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assign yourself"
|
||||
msgstr ""
|
||||
|
||||
msgid "Assigned"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -33890,6 +33876,9 @@ msgstr ""
|
|||
msgid "MergeChecks|All threads must be resolved"
|
||||
msgstr ""
|
||||
|
||||
msgid "MergeChecks|Assign reviewers"
|
||||
msgstr ""
|
||||
|
||||
msgid "MergeChecks|Enable \"Pipelines must succeed\" first."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -34052,9 +34041,6 @@ msgstr ""
|
|||
msgid "MergeRequests|started a thread on commit %{linkStart}%{commitDisplay}%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "MergeRequest|Add or edit reviewers"
|
||||
msgstr ""
|
||||
|
||||
msgid "MergeRequest|Awaiting review"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -34094,9 +34080,6 @@ msgstr ""
|
|||
msgid "MergeRequest|No files found"
|
||||
msgstr ""
|
||||
|
||||
msgid "MergeRequest|Quick add reviewers"
|
||||
msgstr ""
|
||||
|
||||
msgid "MergeRequest|Remove reviewer"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -36290,9 +36273,6 @@ msgstr ""
|
|||
msgid "No results found."
|
||||
msgstr ""
|
||||
|
||||
msgid "No reviewers assigned"
|
||||
msgstr ""
|
||||
|
||||
msgid "No runner executable"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -38094,6 +38074,9 @@ msgstr ""
|
|||
msgid "Optional"
|
||||
msgstr ""
|
||||
|
||||
msgid "Optional approvals"
|
||||
msgstr ""
|
||||
|
||||
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46165,6 +46148,11 @@ msgstr ""
|
|||
msgid "Requirement|Requirements have become work items and the legacy requirement IDs are being deprecated. Update your links to reference this item's new ID %{id}. %{linkStart}Learn more%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Requires %d approval"
|
||||
msgid_plural "Requires %d approvals"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Requires %d approval from eligible users."
|
||||
msgid_plural "Requires %d approvals from eligible users."
|
||||
msgstr[0] ""
|
||||
|
|
|
|||
|
|
@ -96,15 +96,27 @@ describe('Board card', () => {
|
|||
});
|
||||
|
||||
describe('when GlLabel is clicked in BoardCardInner', () => {
|
||||
it("doesn't call setSelectedBoardItemsMutation", () => {
|
||||
it("doesn't call setSelectedBoardItemsMutation", async () => {
|
||||
mountComponent();
|
||||
|
||||
wrapper.findComponent(GlLabel).trigger('mouseup');
|
||||
await wrapper.findComponent(GlLabel).trigger('mouseup');
|
||||
|
||||
expect(mockSetSelectedBoardItemsResolver).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when issuable title is clicked in BoardCardInner and issuesListDrawer feature is enabled', () => {
|
||||
it('calls mockSetSelectedBoardItemsResolver', async () => {
|
||||
mountComponent({ provide: { glFeatures: { issuesListDrawer: true } } });
|
||||
|
||||
await wrapper.findByTestId('board-card-title-link').trigger('click');
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(mockSetActiveBoardItemResolver).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not highlight the card by default', () => {
|
||||
mountComponent();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,134 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import { GlEmptyState, GlButton } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import UpdateReviewers from '~/merge_requests/components/reviewers/update_reviewers.vue';
|
||||
import ReviewersContainer from '~/merge_requests/components/reviewers/reviewers_container.vue';
|
||||
import UncollapsedReviewerList from '~/sidebar/components/reviewers/uncollapsed_reviewer_list.vue';
|
||||
import userPermissionsQuery from '~/merge_requests/components/reviewers/queries/user_permissions.query.graphql';
|
||||
import setReviewersMutation from '~/merge_requests/components/reviewers/queries/set_reviewers.mutation.graphql';
|
||||
|
||||
let wrapper;
|
||||
let setReviewersMutationHandler;
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
function createComponent(propsData = {}, adminMergeRequest = true) {
|
||||
setReviewersMutationHandler = jest.fn().mockResolvedValue({
|
||||
data: { mergeRequestSetReviewers: { errors: null } },
|
||||
});
|
||||
|
||||
const apolloProvider = createMockApollo([
|
||||
[
|
||||
userPermissionsQuery,
|
||||
jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
project: { id: 1, mergeRequest: { id: 1, userPermissions: { adminMergeRequest } } },
|
||||
},
|
||||
}),
|
||||
],
|
||||
[setReviewersMutation, setReviewersMutationHandler],
|
||||
]);
|
||||
|
||||
wrapper = shallowMountExtended(ReviewersContainer, {
|
||||
apolloProvider,
|
||||
propsData: {
|
||||
reviewers: [],
|
||||
loadingReviewers: false,
|
||||
...propsData,
|
||||
},
|
||||
provide: {
|
||||
projectPath: 'gitlab-org/gitlab',
|
||||
issuableIid: '1',
|
||||
},
|
||||
stubs: {
|
||||
GlEmptyState,
|
||||
UpdateReviewers,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
|
||||
const findAssignButton = () => wrapper.findComponent(GlButton);
|
||||
const findReviewersList = () => wrapper.findComponent(UncollapsedReviewerList);
|
||||
const findUpdateReviewers = () => wrapper.findComponent(UpdateReviewers);
|
||||
|
||||
describe('Reviewers container component', () => {
|
||||
beforeEach(() => {
|
||||
window.gon = { current_username: 'root' };
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
window.gon = {};
|
||||
});
|
||||
|
||||
describe('when no reviewers exist', () => {
|
||||
it('renders empty state', () => {
|
||||
createComponent();
|
||||
|
||||
expect(findEmptyState().exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('when user has permission to add reviewers', () => {
|
||||
it('renders empty state with add reviewers button', async () => {
|
||||
createComponent();
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(findAssignButton().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('sets current user as update-reviewers component prop', async () => {
|
||||
createComponent();
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(findUpdateReviewers().props('selectedReviewers')).toEqual(
|
||||
expect.arrayContaining(['root']),
|
||||
);
|
||||
});
|
||||
|
||||
it('adds current user as reviewer', async () => {
|
||||
createComponent();
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
findAssignButton().vm.$emit('click');
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(setReviewersMutationHandler).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
reviewerUsernames: ['root'],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when user does not have permission to add reviewers', () => {
|
||||
it('renders empty state with add reviewers button', async () => {
|
||||
createComponent({}, false);
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(findAssignButton().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('renders reviewers list component', async () => {
|
||||
createComponent({ reviewers: ['test-reviewer'] });
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(findReviewersList().exists()).toBe(true);
|
||||
expect(findReviewersList().props()).toEqual(
|
||||
expect.objectContaining({
|
||||
users: ['test-reviewer'],
|
||||
issuableType: 'merge_request',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -2,9 +2,7 @@ import Vue from 'vue';
|
|||
import VueApollo from 'vue-apollo';
|
||||
import { GlLoadingIcon } from '@gitlab/ui';
|
||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
|
||||
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import Component from '~/sidebar/components/reviewers/reviewer_title.vue';
|
||||
import getMergeRequestReviewers from '~/sidebar/queries/get_merge_request_reviewers.query.graphql';
|
||||
|
|
@ -16,7 +14,6 @@ describe('ReviewerTitle component', () => {
|
|||
let wrapper;
|
||||
|
||||
const findEditButton = () => wrapper.findByTestId('reviewers-edit-button');
|
||||
const findDrawerToggle = () => wrapper.findByTestId('drawer-toggle');
|
||||
|
||||
const createComponent = (props, { reviewerAssignDrawer = false } = {}) => {
|
||||
const apolloProvider = createMockApollo([
|
||||
|
|
@ -126,44 +123,4 @@ describe('ReviewerTitle component', () => {
|
|||
|
||||
expect(findEditButton().attributes('title')).toBe('Change reviewer');
|
||||
});
|
||||
|
||||
describe('when reviewerAssignDrawer is enabled', () => {
|
||||
beforeEach(() => {
|
||||
setHTMLFixture('<div id="js-reviewer-drawer-portal"></div>');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
resetHTMLFixture();
|
||||
});
|
||||
|
||||
it('sets title for drawer toggle as `Add or edit reviewers`', async () => {
|
||||
wrapper = createComponent(
|
||||
{
|
||||
editable: true,
|
||||
},
|
||||
{ reviewerAssignDrawer: true },
|
||||
);
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(findDrawerToggle().attributes('title')).toBe('Add or edit reviewers');
|
||||
});
|
||||
|
||||
it('clicking toggle opens reviewer drawer', async () => {
|
||||
wrapper = createComponent(
|
||||
{
|
||||
editable: true,
|
||||
},
|
||||
{ reviewerAssignDrawer: true },
|
||||
);
|
||||
|
||||
expect(document.querySelector('.gl-drawer')).toBe(null);
|
||||
|
||||
findDrawerToggle().vm.$emit('click');
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(document.querySelector('.gl-drawer')).not.toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@ describe('sidebar reviewers', () => {
|
|||
changing: false,
|
||||
...props,
|
||||
},
|
||||
provide: {
|
||||
projectPath: 'projectPath',
|
||||
issuableId: 1,
|
||||
issuableIid: 1,
|
||||
multipleApprovalRulesAvailable: false,
|
||||
},
|
||||
// Attaching to document is required because this component emits something from the parent element :/
|
||||
attachTo: document.body,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -938,17 +938,19 @@ RSpec.describe Group, feature_category: :groups_and_projects do
|
|||
group.destroy!
|
||||
end
|
||||
|
||||
let!(:group_1) { create(:group, name: 'Y group') }
|
||||
let!(:group_2) { create(:group, name: 'J group', created_at: 2.days.ago, updated_at: 1.day.ago) }
|
||||
let!(:group_3) { create(:group, name: 'A group') }
|
||||
let!(:group_4) { create(:group, name: 'F group', created_at: 1.day.ago, updated_at: 1.day.ago) }
|
||||
let!(:group_1) { create(:group, id: 10, name: 'Y group') }
|
||||
let!(:group_2) { create(:group, id: 11, name: 'J group', created_at: 2.days.ago, updated_at: 1.day.ago) }
|
||||
let!(:group_3) { create(:group, id: 12, name: 'A group') }
|
||||
let!(:group_4) { create(:group, id: 13, name: 'F group', created_at: 1.day.ago, updated_at: 1.day.ago) }
|
||||
|
||||
subject { described_class.with_statistics.with_route.sort_by_attribute(sort) }
|
||||
|
||||
context 'when sort by is not provided (id desc by default)' do
|
||||
context 'when sort by is not provided' do
|
||||
let(:sort) { nil }
|
||||
|
||||
it { is_expected.to eq([group_1, group_2, group_3, group_4]) }
|
||||
it 'results are not ordered' do
|
||||
is_expected.to contain_exactly(group_1, group_2, group_3, group_4)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when sort by name_asc' do
|
||||
|
|
@ -975,30 +977,18 @@ RSpec.describe Group, feature_category: :groups_and_projects do
|
|||
it { is_expected.to eq([group_1, group_2, group_3, group_4].sort_by(&:path).reverse) }
|
||||
end
|
||||
|
||||
context 'when sort by recently_created' do
|
||||
context 'when sort by created_desc' do
|
||||
let(:sort) { 'created_desc' }
|
||||
|
||||
it { is_expected.to eq([group_3, group_1, group_4, group_2]) }
|
||||
end
|
||||
|
||||
context 'when sort by oldest_created' do
|
||||
context 'when sort by created_asc' do
|
||||
let(:sort) { 'created_asc' }
|
||||
|
||||
it { is_expected.to eq([group_2, group_4, group_1, group_3]) }
|
||||
end
|
||||
|
||||
context 'when sort by latest_activity' do
|
||||
let(:sort) { 'latest_activity_desc' }
|
||||
|
||||
it { is_expected.to eq([group_1, group_2, group_3, group_4]) }
|
||||
end
|
||||
|
||||
context 'when sort by oldest_activity' do
|
||||
let(:sort) { 'latest_activity_asc' }
|
||||
|
||||
it { is_expected.to eq([group_1, group_2, group_3, group_4]) }
|
||||
end
|
||||
|
||||
context 'when sort by storage_size_desc' do
|
||||
let!(:project_1) do
|
||||
create(:project,
|
||||
|
|
|
|||
|
|
@ -2072,7 +2072,6 @@
|
|||
- './ee/spec/services/boards/lists/update_service_spec.rb'
|
||||
- './ee/spec/services/boards/update_service_spec.rb'
|
||||
- './ee/spec/services/boards/user_preferences/update_service_spec.rb'
|
||||
- './ee/spec/services/branches/delete_service_spec.rb'
|
||||
- './ee/spec/services/ci/audit_variable_change_service_spec.rb'
|
||||
- './ee/spec/services/ci_cd/github_integration_setup_service_spec.rb'
|
||||
- './ee/spec/services/ci_cd/github_setup_service_spec.rb'
|
||||
|
|
|
|||
|
|
@ -51,18 +51,6 @@ RSpec.describe Import::ReassignPlaceholderUserRecordsWorker, feature_category: :
|
|||
it_behaves_like 'an invalid source user'
|
||||
end
|
||||
|
||||
context 'when the feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(importer_user_mapping: false)
|
||||
end
|
||||
|
||||
it 'does not enqueue service to map records to real users' do
|
||||
expect(Import::ReassignPlaceholderUserRecordsService).not_to receive(:new)
|
||||
|
||||
perform_multiple(job_args)
|
||||
end
|
||||
end
|
||||
|
||||
it 'queues a DeletePlaceholderUserWorker with the source user ID' do
|
||||
expect(Import::DeletePlaceholderUserWorker)
|
||||
.to receive(:perform_async).with(import_source_user.id)
|
||||
|
|
|
|||