Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
ab756700d5
commit
d134089c5e
|
|
@ -667,6 +667,7 @@
|
|||
.audit-events-patterns: &audit-events-patterns
|
||||
- "{,ee/}config/audit_events/types/*.yml"
|
||||
- "doc/administration/audit_event_types.md"
|
||||
- "doc/user/compliance/audit_event_types.md"
|
||||
- "tooling/audit_events/docs/templates/audit_event_types.md.erb"
|
||||
- "lib/tasks/gitlab/audit_event_types/audit_event_types.rake"
|
||||
- "lib/tasks/gitlab/audit_event_types/check_docs_task.rb"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
5.0.0
|
||||
5.1.0
|
||||
|
|
|
|||
|
|
@ -77,32 +77,46 @@ async function loadEmojiWithNames() {
|
|||
}
|
||||
|
||||
export async function loadCustomEmojiWithNames() {
|
||||
const emojiData = { emojis: {}, names: [] };
|
||||
return new Promise((resolve) => {
|
||||
const emojiData = { emojis: {}, names: [] };
|
||||
|
||||
if (document.body?.dataset?.groupFullPath) {
|
||||
const client = createApolloClient();
|
||||
const { data } = await client.query({
|
||||
query: customEmojiQuery,
|
||||
variables: {
|
||||
groupPath: document.body.dataset.groupFullPath,
|
||||
},
|
||||
});
|
||||
if (document.body?.dataset?.groupFullPath) {
|
||||
const client = createApolloClient();
|
||||
const fetchEmojis = async (after = '') => {
|
||||
const { data } = await client.query({
|
||||
query: customEmojiQuery,
|
||||
variables: {
|
||||
groupPath: document.body.dataset.groupFullPath,
|
||||
after,
|
||||
},
|
||||
});
|
||||
const { pageInfo } = data?.group?.customEmoji || {};
|
||||
|
||||
data?.group?.customEmoji?.nodes?.forEach((e) => {
|
||||
// Map the custom emoji into the format of the normal emojis
|
||||
emojiData.emojis[e.name] = {
|
||||
c: 'custom',
|
||||
d: e.name,
|
||||
e: undefined,
|
||||
name: e.name,
|
||||
src: e.url,
|
||||
u: 'custom',
|
||||
data?.group?.customEmoji?.nodes?.forEach((e) => {
|
||||
// Map the custom emoji into the format of the normal emojis
|
||||
emojiData.emojis[e.name] = {
|
||||
c: 'custom',
|
||||
d: e.name,
|
||||
e: undefined,
|
||||
name: e.name,
|
||||
src: e.url,
|
||||
u: 'custom',
|
||||
};
|
||||
emojiData.names.push(e.name);
|
||||
});
|
||||
|
||||
if (pageInfo?.hasNextPage) {
|
||||
return fetchEmojis(pageInfo.endCursor);
|
||||
}
|
||||
|
||||
return resolve(emojiData);
|
||||
};
|
||||
emojiData.names.push(e.name);
|
||||
});
|
||||
}
|
||||
|
||||
return emojiData;
|
||||
fetchEmojis();
|
||||
} else {
|
||||
resolve(emojiData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function prepareEmojiMap() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
query getCustomEmoji($groupPath: ID!) {
|
||||
query getCustomEmoji($groupPath: ID!, $after: String) {
|
||||
group(fullPath: $groupPath) {
|
||||
id
|
||||
customEmoji(includeAncestorGroups: true) {
|
||||
customEmoji(after: $after, includeAncestorGroups: true) {
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
endCursor
|
||||
}
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ export default {
|
|||
projectKey: {
|
||||
default: '',
|
||||
},
|
||||
areTicketsConfidentialByDefault: {
|
||||
default: false,
|
||||
},
|
||||
reopenIssueOnExternalParticipantNote: {
|
||||
default: false,
|
||||
},
|
||||
|
|
@ -118,6 +121,7 @@ export default {
|
|||
fileTemplateProjectId,
|
||||
outgoingName,
|
||||
projectKey,
|
||||
areTicketsConfidentialByDefault,
|
||||
reopenIssueOnExternalParticipantNote,
|
||||
addExternalParticipantsFromCc,
|
||||
}) {
|
||||
|
|
@ -127,6 +131,7 @@ export default {
|
|||
issue_template_key: selectedTemplate,
|
||||
outgoing_name: outgoingName,
|
||||
project_key: projectKey,
|
||||
tickets_confidential_by_default: areTicketsConfidentialByDefault,
|
||||
reopen_issue_on_external_participant_note: reopenIssueOnExternalParticipantNote,
|
||||
add_external_participants_from_cc: addExternalParticipantsFromCc,
|
||||
service_desk_enabled: this.isEnabled,
|
||||
|
|
@ -200,8 +205,10 @@ export default {
|
|||
:initial-selected-file-template-project-id="selectedFileTemplateProjectId"
|
||||
:initial-outgoing-name="outgoingName"
|
||||
:initial-project-key="projectKey"
|
||||
:initial-are-tickets-confidential-by-default="areTicketsConfidentialByDefault"
|
||||
:initial-reopen-issue-on-external-participant-note="reopenIssueOnExternalParticipantNote"
|
||||
:initial-add-external-participants-from-cc="addExternalParticipantsFromCc"
|
||||
:public-project="publicProject"
|
||||
:templates="templates"
|
||||
:is-template-saving="isTemplateSaving"
|
||||
@save="onSaveTemplate"
|
||||
|
|
|
|||
|
|
@ -20,9 +20,25 @@ import ServiceDeskTemplateDropdown from './service_desk_template_dropdown.vue';
|
|||
export default {
|
||||
i18n: {
|
||||
toggleLabel: __('Activate Service Desk'),
|
||||
headlines: {
|
||||
ticketVisibility: s__('ServiceDesk|Ticket visibility'),
|
||||
externalParticipants: s__('ServiceDesk|External participants'),
|
||||
},
|
||||
issueTrackerEnableMessage: __(
|
||||
'To use Service Desk in this project, you must %{linkStart}activate the issue tracker%{linkEnd}.',
|
||||
),
|
||||
areTicketsConfidentialByDefault: {
|
||||
label: s__('ServiceDesk|New tickets are confidential by default'),
|
||||
help: {
|
||||
publicProject: s__(
|
||||
'ServiceDesk|On public projects, tickets are always confidential by default.',
|
||||
),
|
||||
confidential: s__(
|
||||
'ServiceDesk|Only project members with at least the Reporter role can view new tickets.',
|
||||
),
|
||||
nonConfidential: s__('ServiceDesk|Any project member can view new tickets.'),
|
||||
},
|
||||
},
|
||||
reopenIssueOnExternalParticipantNote: {
|
||||
label: s__('ServiceDesk|Reopen issues when an external participant comments'),
|
||||
help: s__(
|
||||
|
|
@ -97,6 +113,11 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
initialAreTicketsConfidentialByDefault: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
initialReopenIssueOnExternalParticipantNote: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
|
|
@ -107,6 +128,11 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
publicProject: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
templates: {
|
||||
type: Array,
|
||||
required: false,
|
||||
|
|
@ -124,6 +150,12 @@ export default {
|
|||
selectedFileTemplateProjectId: this.initialSelectedFileTemplateProjectId,
|
||||
outgoingName: this.initialOutgoingName || __('GitLab Support Bot'),
|
||||
projectKey: this.initialProjectKey,
|
||||
// Tickets will always be confidential for public projects by default. Reflect that also in the frontend
|
||||
// although the backend setting might be `false`. The value will be persisted on save.
|
||||
// Refactoring issue: https://gitlab.com/gitlab-org/gitlab/-/issues/467547
|
||||
areTicketsConfidentialByDefault: this.publicProject
|
||||
? true
|
||||
: this.initialAreTicketsConfidentialByDefault,
|
||||
reopenIssueOnExternalParticipantNote: this.initialReopenIssueOnExternalParticipantNote,
|
||||
addExternalParticipantsFromCc: this.initialAddExternalParticipantsFromCc,
|
||||
searchTerm: '',
|
||||
|
|
@ -131,6 +163,9 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
showAreTicketsConfidentialByDefault() {
|
||||
return this.glFeatures.serviceDeskTicketsConfidentiality;
|
||||
},
|
||||
showAddExternalParticipantsFromCC() {
|
||||
return this.glFeatures.issueEmailParticipants;
|
||||
},
|
||||
|
|
@ -158,6 +193,17 @@ export default {
|
|||
anchor: 'configure-project-visibility-features-and-permissions',
|
||||
});
|
||||
},
|
||||
areTicketsConfidentialByDefaultHelp() {
|
||||
if (this.publicProject) {
|
||||
return this.$options.i18n.areTicketsConfidentialByDefault.help.publicProject;
|
||||
}
|
||||
|
||||
if (this.areTicketsConfidentialByDefault) {
|
||||
return this.$options.i18n.areTicketsConfidentialByDefault.help.confidential;
|
||||
}
|
||||
|
||||
return this.$options.i18n.areTicketsConfidentialByDefault.help.nonConfidential;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onCheckboxToggle(isChecked) {
|
||||
|
|
@ -168,6 +214,7 @@ export default {
|
|||
selectedTemplate: this.selectedTemplate,
|
||||
outgoingName: this.outgoingName,
|
||||
projectKey: this.projectKey,
|
||||
areTicketsConfidentialByDefault: this.areTicketsConfidentialByDefault,
|
||||
reopenIssueOnExternalParticipantNote: this.reopenIssueOnExternalParticipantNote,
|
||||
addExternalParticipantsFromCc: this.addExternalParticipantsFromCc,
|
||||
fileTemplateProjectId: this.selectedFileTemplateProjectId,
|
||||
|
|
@ -335,10 +382,32 @@ export default {
|
|||
</template>
|
||||
</gl-form-group>
|
||||
|
||||
<div
|
||||
v-if="showAreTicketsConfidentialByDefault"
|
||||
data-testid="service-desk-are-tickets-confidential-by-default-wrapper"
|
||||
>
|
||||
<h5>{{ $options.i18n.headlines.ticketVisibility }}</h5>
|
||||
|
||||
<gl-form-checkbox
|
||||
v-model="areTicketsConfidentialByDefault"
|
||||
:disabled="!isIssueTrackerEnabled || publicProject"
|
||||
data-testid="service-desk-are-tickets-confidential-by-default"
|
||||
>
|
||||
{{ $options.i18n.areTicketsConfidentialByDefault.label }}
|
||||
|
||||
<template #help>
|
||||
{{ areTicketsConfidentialByDefaultHelp }}
|
||||
</template>
|
||||
</gl-form-checkbox>
|
||||
</div>
|
||||
|
||||
<h5>{{ $options.i18n.headlines.externalParticipants }}</h5>
|
||||
|
||||
<gl-form-checkbox
|
||||
v-model="reopenIssueOnExternalParticipantNote"
|
||||
:disabled="!isIssueTrackerEnabled"
|
||||
data-testid="reopen-issue-on-external-participant-note"
|
||||
class="gl-mb-3"
|
||||
>
|
||||
{{ $options.i18n.reopenIssueOnExternalParticipantNote.label }}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ export default () => {
|
|||
incomingEmail,
|
||||
outgoingName,
|
||||
projectKey,
|
||||
ticketsConfidentialByDefault,
|
||||
reopenIssueOnExternalParticipantNote,
|
||||
addExternalParticipantsFromCc,
|
||||
selectedTemplate,
|
||||
|
|
@ -41,6 +42,7 @@ export default () => {
|
|||
isIssueTrackerEnabled: parseBoolean(issueTrackerEnabled),
|
||||
outgoingName,
|
||||
projectKey,
|
||||
areTicketsConfidentialByDefault: parseBoolean(ticketsConfidentialByDefault),
|
||||
reopenIssueOnExternalParticipantNote: parseBoolean(reopenIssueOnExternalParticipantNote),
|
||||
addExternalParticipantsFromCc: parseBoolean(addExternalParticipantsFromCc),
|
||||
selectedTemplate,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import DesignNavigation from './design_navigation.vue';
|
|||
|
||||
export default {
|
||||
i18n: {
|
||||
downloadButtonLabel: s__('DesignManagement|Download design'),
|
||||
hideCommentsButtonLabel: s__('DesignManagement|Hide comments'),
|
||||
showCommentsButtonLabel: s__('DesignManagement|Show comments'),
|
||||
},
|
||||
|
|
@ -84,6 +85,15 @@ export default {
|
|||
<close-button class="md:gl-hidden gl-ml-auto" />
|
||||
</div>
|
||||
<div class="gl-flex md:gl-flex-row gl-flex-shrink-0 gl-md-ml-auto gl-mr-5">
|
||||
<gl-button
|
||||
v-gl-tooltip.bottom
|
||||
category="tertiary"
|
||||
class="gl-ml-2"
|
||||
:href="design.image"
|
||||
icon="download"
|
||||
:title="$options.i18n.downloadButtonLabel"
|
||||
:aria-label="$options.i18n.downloadButtonLabel"
|
||||
/>
|
||||
<gl-button
|
||||
v-gl-tooltip.bottom
|
||||
category="tertiary"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import {
|
|||
WIDGET_TYPE_DESIGNS,
|
||||
LINKED_ITEMS_ANCHOR,
|
||||
WORK_ITEM_REFERENCE_CHAR,
|
||||
WORK_ITEM_TYPE_VALUE_TASK,
|
||||
} from '../constants';
|
||||
|
||||
import workItemUpdatedSubscription from '../graphql/work_item_updated.subscription.graphql';
|
||||
|
|
@ -206,6 +207,13 @@ export default {
|
|||
parentWorkItem() {
|
||||
return this.isWidgetPresent(WIDGET_TYPE_HIERARCHY)?.parent;
|
||||
},
|
||||
showAncestors() {
|
||||
// TODO: This is a temporary check till the issue work item migration is completed
|
||||
// Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/468114
|
||||
return this.workItemType === WORK_ITEM_TYPE_VALUE_TASK
|
||||
? this.glFeatures.namespaceLevelWorkItems && this.parentWorkItem
|
||||
: this.parentWorkItem;
|
||||
},
|
||||
parentWorkItemConfidentiality() {
|
||||
return this.parentWorkItem?.confidential;
|
||||
},
|
||||
|
|
@ -269,16 +277,16 @@ export default {
|
|||
},
|
||||
titleClassHeader() {
|
||||
return {
|
||||
'sm:!gl-hidden gl-mt-3': this.parentWorkItem,
|
||||
'sm:!gl-block': !this.parentWorkItem,
|
||||
'gl-w-full': !this.parentWorkItem && !this.editMode,
|
||||
'editable-wi-title': this.editMode && !this.parentWorkItem,
|
||||
'sm:!gl-hidden gl-mt-3': this.showAncestors,
|
||||
'sm:!gl-block': !this.showAncestors,
|
||||
'gl-w-full': !this.showAncestors && !this.editMode,
|
||||
'editable-wi-title': this.editMode && !this.showAncestors,
|
||||
};
|
||||
},
|
||||
titleClassComponent() {
|
||||
return {
|
||||
'sm:!gl-block': !this.parentWorkItem,
|
||||
'gl-hidden sm:!gl-block gl-mt-3': this.parentWorkItem,
|
||||
'sm:!gl-block': !this.showAncestors,
|
||||
'gl-hidden sm:!gl-block gl-mt-3': this.showAncestors,
|
||||
'editable-wi-title': this.workItemsAlphaEnabled,
|
||||
};
|
||||
},
|
||||
|
|
@ -494,7 +502,7 @@ export default {
|
|||
/>
|
||||
<div v-else data-testid="detail-wrapper">
|
||||
<div class="gl-block sm:!gl-flex gl-items-start gl-flex-row gl-gap-3">
|
||||
<work-item-ancestors v-if="parentWorkItem" :work-item="workItem" class="gl-mb-1" />
|
||||
<work-item-ancestors v-if="showAncestors" :work-item="workItem" class="gl-mb-1" />
|
||||
<div v-if="!error" :class="titleClassHeader" data-testid="work-item-type">
|
||||
<work-item-title
|
||||
v-if="workItem.title"
|
||||
|
|
@ -568,7 +576,7 @@ export default {
|
|||
</div>
|
||||
<div :class="{ 'gl-mt-3': !editMode }">
|
||||
<work-item-title
|
||||
v-if="workItem.title && parentWorkItem"
|
||||
v-if="workItem.title && showAncestors"
|
||||
ref="title"
|
||||
:is-editing="editMode"
|
||||
:class="titleClassComponent"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ module Groups
|
|||
push_force_frontend_feature_flag(:work_items, group&.work_items_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_beta, group&.work_items_beta_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_alpha, group&.work_items_alpha_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:namespace_level_work_items, group)
|
||||
end
|
||||
|
||||
def index
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class GroupsController < Groups::ApplicationController
|
|||
push_force_frontend_feature_flag(:work_items_alpha, group.work_items_alpha_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:issues_grid_view)
|
||||
push_frontend_feature_flag(:group_multi_select_tokens, group)
|
||||
push_frontend_feature_flag(:namespace_level_work_items, group)
|
||||
end
|
||||
|
||||
before_action only: :merge_requests do
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
push_force_frontend_feature_flag(:work_items_alpha, project&.work_items_alpha_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:epic_widget_edit_confirmation, project)
|
||||
push_frontend_feature_flag(:display_work_item_epic_issue_sidebar, project)
|
||||
push_frontend_feature_flag(:namespace_level_work_items, project&.group)
|
||||
end
|
||||
|
||||
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class Projects::WorkItemsController < Projects::ApplicationController
|
|||
push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_beta, project&.work_items_beta_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_alpha, project&.work_items_alpha_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:namespace_level_work_items, project&.group)
|
||||
end
|
||||
|
||||
feature_category :team_planning
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ class ProjectsController < Projects::ApplicationController
|
|||
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_beta, @project&.work_items_beta_feature_flag_enabled?)
|
||||
push_force_frontend_feature_flag(:work_items_alpha, @project&.work_items_alpha_feature_flag_enabled?)
|
||||
push_frontend_feature_flag(:namespace_level_work_items, @project&.group)
|
||||
end
|
||||
|
||||
layout :determine_layout
|
||||
|
|
|
|||
|
|
@ -106,9 +106,13 @@ class SearchController < ApplicationController
|
|||
|
||||
count = 0
|
||||
@global_search_duration_s = Benchmark.realtime do
|
||||
ApplicationRecord.with_fast_read_statement_timeout do
|
||||
count = search_service.search_results.formatted_count(scope)
|
||||
end
|
||||
count = if @search_type == 'basic'
|
||||
ApplicationRecord.with_fast_read_statement_timeout do
|
||||
search_service.search_results.formatted_count(scope)
|
||||
end
|
||||
else
|
||||
search_service.search_results.formatted_count(scope)
|
||||
end
|
||||
|
||||
# Users switching tabs will keep fetching the same tab counts so it's a
|
||||
# good idea to cache in their browser just for a short time. They can still
|
||||
|
|
|
|||
|
|
@ -237,6 +237,10 @@ class Notify < ApplicationMailer
|
|||
end
|
||||
|
||||
headers['List-Unsubscribe'] = list_unsubscribe_methods.map { |e| "<#{e}>" }.join(',')
|
||||
# Based on RFC 8058 one-click unsubscribe functionality should
|
||||
# be signalled with using the List-Unsubscribe-Post header
|
||||
# See https://datatracker.ietf.org/doc/html/rfc8058
|
||||
headers['List-Unsubscribe-Post'] = 'List-Unsubscribe=One-Click'
|
||||
@unsubscribe_url = unsubscribe_sent_notification_url(@sent_notification)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
module Ci
|
||||
class PipelineMessage < Ci::ApplicationRecord
|
||||
include Ci::Partitionable
|
||||
include SafelyChangeColumnDefault
|
||||
|
||||
columns_changing_default :partition_id
|
||||
|
||||
MAX_CONTENT_LENGTH = 10_000
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
%p.gl-text-secondary= _('Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
|
||||
.settings-content
|
||||
- if ::Gitlab::ServiceDesk.supported?
|
||||
-# Data attributes refactoring issue: https://gitlab.com/gitlab-org/gitlab/-/issues/467547
|
||||
.js-service-desk-setting-root{ data: { endpoint: project_service_desk_path(@project),
|
||||
enabled: "#{@project.service_desk_enabled}",
|
||||
issue_tracker_enabled: "#{@project.project_feature.issues_enabled?}",
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
selected_file_template_project_id: "#{@project.service_desk_setting&.file_template_project_id}",
|
||||
outgoing_name: "#{@project.service_desk_setting&.outgoing_name}",
|
||||
project_key: "#{@project.service_desk_setting&.project_key}",
|
||||
tickets_confidential_by_default: "#{@project.service_desk_setting.nil? ? true : @project.service_desk_setting&.tickets_confidential_by_default}",
|
||||
reopen_issue_on_external_participant_note: "#{@project.service_desk_setting&.reopen_issue_on_external_participant_note}",
|
||||
add_external_participants_from_cc: "#{@project.service_desk_setting&.add_external_participants_from_cc}",
|
||||
templates: available_service_desk_templates_for(@project),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: epic_and_work_item_associations_unification
|
||||
feature_issue_url:
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156691
|
||||
rollout_issue_url:
|
||||
milestone: '17.1'
|
||||
group: group::product planning
|
||||
type: wip
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
migration_job_name: BackfillVulnerabilityFindingsRemediationsProjectId
|
||||
description: Backfills sharding key `vulnerability_findings_remediations.project_id` from `vulnerability_occurrences`.
|
||||
feature_category: vulnerability_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156634
|
||||
milestone: '17.2'
|
||||
queued_migration_version: 20240618121521
|
||||
finalize_after: '2024-08-22'
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
|
|
@ -17,3 +17,4 @@ desired_sharding_key:
|
|||
table: vulnerability_occurrences
|
||||
sharding_key: project_id
|
||||
belongs_to: finding
|
||||
desired_sharding_key_migration_job_name: BackfillVulnerabilityFindingsRemediationsProjectId
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddProjectIdToVulnerabilityFindingsRemediations < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def change
|
||||
add_column :vulnerability_findings_remediations, :project_id, :bigint
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemovePartitionIdDefaultValueForCiPipelineMessage < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
TABLE_NAME = :ci_pipeline_messages
|
||||
COLUM_NAME = :partition_id
|
||||
|
||||
def change
|
||||
change_column_default(TABLE_NAME, COLUM_NAME, from: 100, to: nil)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class IndexVulnerabilityFindingsRemediationsOnProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_vulnerability_findings_remediations_on_project_id'
|
||||
|
||||
def up
|
||||
add_concurrent_index :vulnerability_findings_remediations, :project_id, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :vulnerability_findings_remediations, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddVulnerabilityFindingsRemediationsProjectIdFk < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :vulnerability_findings_remediations, :projects, column: :project_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :vulnerability_findings_remediations, column: :project_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddVulnerabilityFindingsRemediationsProjectIdTrigger < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
install_sharding_key_assignment_trigger(
|
||||
table: :vulnerability_findings_remediations,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :vulnerability_occurrences,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :vulnerability_occurrence_id
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_sharding_key_assignment_trigger(
|
||||
table: :vulnerability_findings_remediations,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :vulnerability_occurrences,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :vulnerability_occurrence_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class QueueBackfillVulnerabilityFindingsRemediationsProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
MIGRATION = "BackfillVulnerabilityFindingsRemediationsProjectId"
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 1000
|
||||
SUB_BATCH_SIZE = 100
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:vulnerability_findings_remediations,
|
||||
:id,
|
||||
:project_id,
|
||||
:vulnerability_occurrences,
|
||||
:project_id,
|
||||
:vulnerability_occurrence_id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(
|
||||
MIGRATION,
|
||||
:vulnerability_findings_remediations,
|
||||
:id,
|
||||
[
|
||||
:project_id,
|
||||
:vulnerability_occurrences,
|
||||
:project_id,
|
||||
:vulnerability_occurrence_id
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
27c7b399872c197d8238e688fe42c09f8df86964812ea7a4ae59f38bfa018400
|
||||
|
|
@ -0,0 +1 @@
|
|||
98d2934a8067678b201fb45a9361f78f45263c3800600e580f7e34ead39ea052
|
||||
|
|
@ -0,0 +1 @@
|
|||
808154ef3dde0e14e82d86702e7e4e807e9b1f9858feef6efdef66f0f47fb3a9
|
||||
|
|
@ -0,0 +1 @@
|
|||
8e6fc4e2d1477908ca7995f5f98127d202ed21ae3cbfcb8d7de86c4500fc4797
|
||||
|
|
@ -0,0 +1 @@
|
|||
0a9dce38fe804d84fa7ac6c1d65bdff5ac6c88e3df57a0812ccd291dfd2c147a
|
||||
|
|
@ -0,0 +1 @@
|
|||
47c824811fde371acee3547b45cceb29157c1a5a9339df22348935d89c457933
|
||||
|
|
@ -1313,6 +1313,22 @@ RETURN NEW;
|
|||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_9e137c16de79() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."project_id" IS NULL THEN
|
||||
SELECT "project_id"
|
||||
INTO NEW."project_id"
|
||||
FROM "vulnerability_occurrences"
|
||||
WHERE "vulnerability_occurrences"."id" = NEW."vulnerability_occurrence_id";
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_a1bc7c70cbdf() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -7601,7 +7617,7 @@ CREATE TABLE ci_pipeline_messages (
|
|||
severity smallint DEFAULT 0 NOT NULL,
|
||||
content text NOT NULL,
|
||||
pipeline_id bigint NOT NULL,
|
||||
partition_id bigint DEFAULT 100 NOT NULL,
|
||||
partition_id bigint NOT NULL,
|
||||
CONSTRAINT check_58ca2981b2 CHECK ((char_length(content) <= 10000))
|
||||
);
|
||||
|
||||
|
|
@ -18661,7 +18677,8 @@ CREATE TABLE vulnerability_findings_remediations (
|
|||
vulnerability_occurrence_id bigint,
|
||||
vulnerability_remediation_id bigint,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
project_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE vulnerability_findings_remediations_id_seq
|
||||
|
|
@ -29060,6 +29077,8 @@ CREATE INDEX index_vulnerability_finding_signatures_on_finding_id ON vulnerabili
|
|||
|
||||
CREATE INDEX index_vulnerability_finding_signatures_on_signature_sha ON vulnerability_finding_signatures USING btree (signature_sha);
|
||||
|
||||
CREATE INDEX index_vulnerability_findings_remediations_on_project_id ON vulnerability_findings_remediations USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_vulnerability_findings_remediations_on_remediation_id ON vulnerability_findings_remediations USING btree (vulnerability_remediation_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_vulnerability_findings_remediations_on_unique_keys ON vulnerability_findings_remediations USING btree (vulnerability_occurrence_id, vulnerability_remediation_id);
|
||||
|
|
@ -31194,6 +31213,8 @@ CREATE TRIGGER trigger_96a76ee9f147 BEFORE INSERT OR UPDATE ON design_management
|
|||
|
||||
CREATE TRIGGER trigger_98ad3a4c1d35 BEFORE INSERT OR UPDATE ON merge_request_review_llm_summaries FOR EACH ROW EXECUTE FUNCTION trigger_98ad3a4c1d35();
|
||||
|
||||
CREATE TRIGGER trigger_9e137c16de79 BEFORE INSERT OR UPDATE ON vulnerability_findings_remediations FOR EACH ROW EXECUTE FUNCTION trigger_9e137c16de79();
|
||||
|
||||
CREATE TRIGGER trigger_a1bc7c70cbdf BEFORE INSERT OR UPDATE ON vulnerability_user_mentions FOR EACH ROW EXECUTE FUNCTION trigger_a1bc7c70cbdf();
|
||||
|
||||
CREATE TRIGGER trigger_a253cb3cacdf BEFORE INSERT OR UPDATE ON dora_daily_metrics FOR EACH ROW EXECUTE FUNCTION trigger_a253cb3cacdf();
|
||||
|
|
@ -31984,6 +32005,9 @@ ALTER TABLE p_ci_builds
|
|||
ALTER TABLE ONLY approval_group_rules_users
|
||||
ADD CONSTRAINT fk_888a0df3b7 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY vulnerability_findings_remediations
|
||||
ADD CONSTRAINT fk_88a2923914 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY bulk_import_entities
|
||||
ADD CONSTRAINT fk_88c725229f FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -2018,6 +2018,52 @@ Input type: `AuditEventsInstanceDestinationEventsDeleteInput`
|
|||
| <a id="mutationauditeventsinstancedestinationeventsdeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationauditeventsinstancedestinationeventsdeleteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
|
||||
### `Mutation.auditEventsInstanceDestinationNamespaceFilterCreate`
|
||||
|
||||
DETAILS:
|
||||
**Introduced** in GitLab 17.2.
|
||||
**Status**: Experiment.
|
||||
|
||||
Input type: `AuditEventsInstanceDestinationNamespaceFilterCreateInput`
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefiltercreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefiltercreatedestinationid"></a>`destinationId` | [`AuditEventsInstanceExternalStreamingDestinationID!`](#auditeventsinstanceexternalstreamingdestinationid) | Destination ID. |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefiltercreatenamespacepath"></a>`namespacePath` | [`String`](#string) | Full path of the namespace. Project or group namespaces only. |
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefiltercreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefiltercreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefiltercreatenamespacefilter"></a>`namespaceFilter` | [`InstanceAuditEventNamespaceFilter`](#instanceauditeventnamespacefilter) | Namespace filter to be created. |
|
||||
|
||||
### `Mutation.auditEventsInstanceDestinationNamespaceFilterDelete`
|
||||
|
||||
DETAILS:
|
||||
**Introduced** in GitLab 17.2.
|
||||
**Status**: Experiment.
|
||||
|
||||
Input type: `AuditEventsInstanceDestinationNamespaceFilterDeleteInput`
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefilterdeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefilterdeletenamespacefilterid"></a>`namespaceFilterId` | [`AuditEventsInstanceNamespaceFilterID!`](#auditeventsinstancenamespacefilterid) | Namespace filter ID. |
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefilterdeleteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationauditeventsinstancedestinationnamespacefilterdeleteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
|
||||
### `Mutation.auditEventsStreamingDestinationEventsAdd`
|
||||
|
||||
Input type: `AuditEventsStreamingDestinationEventsAddInput`
|
||||
|
|
@ -23392,6 +23438,18 @@ Stores instance level Amazon S3 configurations for audit event streaming.
|
|||
| <a id="instanceamazons3configurationtypeid"></a>`id` | [`ID!`](#id) | ID of the configuration. |
|
||||
| <a id="instanceamazons3configurationtypename"></a>`name` | [`String!`](#string) | Name of the external destination to send audit events to. |
|
||||
|
||||
### `InstanceAuditEventNamespaceFilter`
|
||||
|
||||
Represents a subgroup or project filter that belongs to an instance level external audit event streaming destination.
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="instanceauditeventnamespacefilterexternalstreamingdestination"></a>`externalStreamingDestination` | [`InstanceAuditEventStreamingDestination!`](#instanceauditeventstreamingdestination) | Destination to which the filter belongs. |
|
||||
| <a id="instanceauditeventnamespacefilterid"></a>`id` | [`ID!`](#id) | ID of the filter. |
|
||||
| <a id="instanceauditeventnamespacefilternamespace"></a>`namespace` | [`Namespace!`](#namespace) | Group or project namespace the filter belongs to. |
|
||||
|
||||
### `InstanceAuditEventStreamingDestination`
|
||||
|
||||
Represents an external destination to stream instance level audit events.
|
||||
|
|
@ -23405,6 +23463,7 @@ Represents an external destination to stream instance level audit events.
|
|||
| <a id="instanceauditeventstreamingdestinationeventtypefilters"></a>`eventTypeFilters` | [`[String!]!`](#string) | List of event type filters added for streaming. |
|
||||
| <a id="instanceauditeventstreamingdestinationid"></a>`id` | [`ID!`](#id) | ID of the destination. |
|
||||
| <a id="instanceauditeventstreamingdestinationname"></a>`name` | [`String!`](#string) | Name of the external destination to send audit events to. |
|
||||
| <a id="instanceauditeventstreamingdestinationnamespacefilters"></a>`namespaceFilters` | [`[InstanceAuditEventNamespaceFilter!]`](#instanceauditeventnamespacefilter) | List of subgroup or project filters for the destination. |
|
||||
|
||||
### `InstanceExternalAuditEventDestination`
|
||||
|
||||
|
|
@ -36280,6 +36339,12 @@ A `AuditEventsInstanceGoogleCloudLoggingConfigurationID` is a global ID. It is e
|
|||
|
||||
An example `AuditEventsInstanceGoogleCloudLoggingConfigurationID` is: `"gid://gitlab/AuditEvents::Instance::GoogleCloudLoggingConfiguration/1"`.
|
||||
|
||||
### `AuditEventsInstanceNamespaceFilterID`
|
||||
|
||||
A `AuditEventsInstanceNamespaceFilterID` is a global ID. It is encoded as a string.
|
||||
|
||||
An example `AuditEventsInstanceNamespaceFilterID` is: `"gid://gitlab/AuditEvents::Instance::NamespaceFilter/1"`.
|
||||
|
||||
### `AuditEventsStreamingHTTPNamespaceFilterID`
|
||||
|
||||
A `AuditEventsStreamingHTTPNamespaceFilterID` is a global ID. It is encoded as a string.
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ GET /projects/:id/pipelines
|
|||
| `scope` | string | No | The scope of pipelines, one of: `running`, `pending`, `finished`, `branches`, `tags` |
|
||||
| `sha` | string | No | The SHA of pipelines |
|
||||
| `sort` | string | No | Sort pipelines in `asc` or `desc` order (default: `desc`) |
|
||||
| `source` | string | No | Returns how the pipeline was triggered, one of: `api`, `chat`, `external`, `external_pull_request_event`, `merge_request_event`, `ondemand_dast_scan`, `ondemand_dast_validation`, `parent_pipeline`, `pipeline`, `push`, `schedule`, `security_orchestration_policy`, `trigger`, `web`, or `webide`. |
|
||||
| `source` | string | No | The [pipeline source](../ci/jobs/job_rules.md#ci_pipeline_source-predefined-variable). |
|
||||
| `status` | string | No | The status of pipelines, one of: `created`, `waiting_for_resource`, `preparing`, `pending`, `running`, `success`, `failed`, `canceled`, `skipped`, `manual`, `scheduled` |
|
||||
| `updated_after` | datetime | No | Return pipelines updated after the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
|
||||
| `updated_before` | datetime | No | Return pipelines updated before the specified date. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
|
||||
|
|
@ -115,33 +115,110 @@ Example of response
|
|||
|
||||
```json
|
||||
{
|
||||
"id": 46,
|
||||
"iid": 11,
|
||||
"project_id": 1,
|
||||
"id": 287,
|
||||
"iid": 144,
|
||||
"project_id": 21,
|
||||
"name": "Build pipeline",
|
||||
"status": "success",
|
||||
"sha": "50f0acb76a40e34a4ff304f7347dcc6587da8a14",
|
||||
"ref": "main",
|
||||
"sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
|
||||
"before_sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
|
||||
"status": "success",
|
||||
"source": "push",
|
||||
"created_at": "2022-09-21T01:05:07.200Z",
|
||||
"updated_at": "2022-09-21T01:05:50.185Z",
|
||||
"web_url": "http://127.0.0.1:3000/test-group/test-project/-/pipelines/287",
|
||||
"before_sha": "8a24fb3c5877a6d0b611ca41fc86edc174593e2b",
|
||||
"tag": false,
|
||||
"yaml_errors": null,
|
||||
"user": {
|
||||
"name": "Administrator",
|
||||
"username": "root",
|
||||
"id": 1,
|
||||
"username": "root",
|
||||
"name": "Administrator",
|
||||
"state": "active",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://localhost:3000/root"
|
||||
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://127.0.0.1:3000/root"
|
||||
},
|
||||
"created_at": "2016-08-11T11:28:34.085Z",
|
||||
"updated_at": "2016-08-11T11:32:35.169Z",
|
||||
"started_at": null,
|
||||
"finished_at": "2016-08-11T11:32:35.145Z",
|
||||
"started_at": "2022-09-21T01:05:14.197Z",
|
||||
"finished_at": "2022-09-21T01:05:50.175Z",
|
||||
"committed_at": null,
|
||||
"duration": 123.65,
|
||||
"queued_duration": 0.010,
|
||||
"coverage": "30.0",
|
||||
"web_url": "https://example.com/foo/bar/pipelines/46"
|
||||
"duration": 34,
|
||||
"queued_duration": 6,
|
||||
"coverage": null,
|
||||
"detailed_status": {
|
||||
"icon": "status_success",
|
||||
"text": "passed",
|
||||
"label": "passed",
|
||||
"group": "success",
|
||||
"tooltip": "passed",
|
||||
"has_details": false,
|
||||
"details_path": "/test-group/test-project/-/pipelines/287",
|
||||
"illustration": null,
|
||||
"favicon": "/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Get the latest pipeline
|
||||
|
||||
> - `name` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115310) in GitLab 15.11 [with a flag](../administration/feature_flags.md) named `pipeline_name_in_api`. Disabled by default.
|
||||
> - `name` in response [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/398131) in GitLab 16.3. Feature flag `pipeline_name_in_api` removed.
|
||||
|
||||
Get the latest pipeline for the most recent commit on a specific ref in a project. If no pipeline exists for the commit, a `403` status code is returned.
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/pipelines/latest
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-----------|--------|----------|-------------|
|
||||
| `ref` | string | No | The branch or tag to check for the latest pipeline. Defaults to the default branch when not specified. |
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/pipelines/latest"
|
||||
```
|
||||
|
||||
Example of response
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 287,
|
||||
"iid": 144,
|
||||
"project_id": 21,
|
||||
"name": "Build pipeline",
|
||||
"sha": "50f0acb76a40e34a4ff304f7347dcc6587da8a14",
|
||||
"ref": "main",
|
||||
"status": "success",
|
||||
"source": "push",
|
||||
"created_at": "2022-09-21T01:05:07.200Z",
|
||||
"updated_at": "2022-09-21T01:05:50.185Z",
|
||||
"web_url": "http://127.0.0.1:3000/test-group/test-project/-/pipelines/287",
|
||||
"before_sha": "8a24fb3c5877a6d0b611ca41fc86edc174593e2b",
|
||||
"tag": false,
|
||||
"yaml_errors": null,
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "root",
|
||||
"name": "Administrator",
|
||||
"state": "active",
|
||||
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://127.0.0.1:3000/root"
|
||||
},
|
||||
"started_at": "2022-09-21T01:05:14.197Z",
|
||||
"finished_at": "2022-09-21T01:05:50.175Z",
|
||||
"committed_at": null,
|
||||
"duration": 34,
|
||||
"queued_duration": 6,
|
||||
"coverage": null,
|
||||
"detailed_status": {
|
||||
"icon": "status_success",
|
||||
"text": "passed",
|
||||
"label": "passed",
|
||||
"group": "success",
|
||||
"tooltip": "passed",
|
||||
"has_details": false,
|
||||
"details_path": "/test-group/test-project/-/pipelines/287",
|
||||
"illustration": null,
|
||||
"favicon": "/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -281,71 +358,6 @@ Sample response:
|
|||
}
|
||||
```
|
||||
|
||||
## Get the latest pipeline
|
||||
|
||||
> - `name` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/115310) in GitLab 15.11 [with a flag](../administration/feature_flags.md) named `pipeline_name_in_api`. Disabled by default.
|
||||
> - `name` in response [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/398131) in GitLab 16.3. Feature flag `pipeline_name_in_api` removed.
|
||||
|
||||
Get the latest pipeline for the most recent commit on a specific ref in a project. If no pipeline exists for the commit, a `403` status code is returned.
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/pipelines/latest
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-----------|--------|----------|-------------|
|
||||
| `ref` | string | No | The branch or tag to check for the latest pipeline. Defaults to the default branch when not specified. |
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/pipelines/latest"
|
||||
```
|
||||
|
||||
Example of response
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 287,
|
||||
"iid": 144,
|
||||
"project_id": 21,
|
||||
"name": "Build pipeline",
|
||||
"sha": "50f0acb76a40e34a4ff304f7347dcc6587da8a14",
|
||||
"ref": "main",
|
||||
"status": "success",
|
||||
"source": "push",
|
||||
"created_at": "2022-09-21T01:05:07.200Z",
|
||||
"updated_at": "2022-09-21T01:05:50.185Z",
|
||||
"web_url": "http://127.0.0.1:3000/test-group/test-project/-/pipelines/287",
|
||||
"before_sha": "8a24fb3c5877a6d0b611ca41fc86edc174593e2b",
|
||||
"tag": false,
|
||||
"yaml_errors": null,
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "root",
|
||||
"name": "Administrator",
|
||||
"state": "active",
|
||||
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||
"web_url": "http://127.0.0.1:3000/root"
|
||||
},
|
||||
"started_at": "2022-09-21T01:05:14.197Z",
|
||||
"finished_at": "2022-09-21T01:05:50.175Z",
|
||||
"committed_at": null,
|
||||
"duration": 34,
|
||||
"queued_duration": 6,
|
||||
"coverage": null,
|
||||
"detailed_status": {
|
||||
"icon": "status_success",
|
||||
"text": "passed",
|
||||
"label": "passed",
|
||||
"group": "success",
|
||||
"tooltip": "passed",
|
||||
"has_details": false,
|
||||
"details_path": "/test-group/test-project/-/pipelines/287",
|
||||
"illustration": null,
|
||||
"favicon": "/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Create a new pipeline
|
||||
|
||||
> - `iid` in response [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/342223) in GitLab 14.6.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ There are two tokens to take into account when connecting a runner with GitLab.
|
|||
| Token | Description |
|
||||
| ----- | ----------- |
|
||||
| Registration token | Token used to [register the runner](https://docs.gitlab.com/runner/register/). It can be [obtained through GitLab](../ci/runners/index.md). |
|
||||
| Authentication token | Token used to authenticate the runner with the GitLab instance. It is obtained automatically when you [register a runner](https://docs.gitlab.com/runner/register/) or by the Runner API when you manually [register a runner](#create-an-instance-runner) or [reset the authentication token](#reset-runners-authentication-token-by-using-the-runner-id). You can also obtain the authentication token using [Create a runner](users.md#create-a-runner-linked-to-a-user) API method. |
|
||||
| Authentication token | Token used to authenticate the runner with the GitLab instance. The token is obtained automatically when you [register a runner](https://docs.gitlab.com/runner/register/) or by the Runners API when you manually [register a runner](#create-a-runner) or [reset the authentication token](#reset-runners-authentication-token-by-using-the-runner-id). You can also obtain the token by using the [`POST /user/runners`](users.md#create-a-runner-linked-to-a-user) endpoint. |
|
||||
|
||||
Here's an example of how the two tokens are used in runner registration:
|
||||
|
||||
|
|
@ -776,9 +776,15 @@ Example response:
|
|||
]
|
||||
```
|
||||
|
||||
## Create an instance runner
|
||||
## Create a runner
|
||||
|
||||
Create a runner for the instance.
|
||||
WARNING:
|
||||
This endpoint returns an `HTTP 410 Gone` status code if registration with runner registration tokens
|
||||
is disabled in the project or group settings. If registration with runner registration tokens
|
||||
is disabled, use the [`POST /user/runners`](users.md#create-a-runner-linked-to-a-user) endpoint
|
||||
to create and register runners instead.
|
||||
|
||||
Create a runner with a runner registration token.
|
||||
|
||||
```plaintext
|
||||
POST /runners
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ scope.
|
|||
| Component | Milestone | Changes |
|
||||
|------------------|----------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| GitLab Rails app | `%16.0` | Adapt `register_{group|project}_runner` permissions to take [application setting](https://gitlab.com/gitlab-org/gitlab/-/issues/386712) in consideration. |
|
||||
| GitLab Rails app | `%16.1` | Make [`POST /api/v4/runners` endpoint](../../../api/runners.md#create-an-instance-runner) permanently return `HTTP 410 Gone` if either `allow_runner_registration_token` setting disables registration tokens.<br/>A future v5 version of the API should return `HTTP 404 Not Found`. |
|
||||
| GitLab Rails app | `%16.1` | Make the [`POST /api/v4/runners`](../../../api/runners.md#create-a-runner) endpoint return `HTTP 410 Gone` permanently if either `allow_runner_registration_token` setting disables registration tokens. The Runners API v5 should return `HTTP 404 Not Found`. |
|
||||
| GitLab Rails app | `%16.1` | Add runner group metadata to the runner list. |
|
||||
| GitLab Rails app | `%16.11` | Add UI to allow disabling use of registration tokens in top-level group settings. |
|
||||
| GitLab Rails app | `%16.11` | Add UI to allow disabling use of registration tokens in admin panel. |
|
||||
|
|
|
|||
|
|
@ -139,7 +139,8 @@ You can use the `$` character for both variables and paths. For example, if the
|
|||
|
||||
## Common `if` clauses with predefined variables
|
||||
|
||||
`rules:if` clauses are commonly used with [predefined CI/CD variables](../variables/predefined_variables.md).
|
||||
`rules:if` clauses are commonly used with [predefined CI/CD variables](../variables/predefined_variables.md),
|
||||
especially the [`CI_PIPELINE_SOURCE` predefined variable](#ci_pipeline_source-predefined-variable).
|
||||
|
||||
The following example runs the job as a manual job in scheduled pipelines or in push
|
||||
pipelines (to branches or tags), with `when: on_success` (default). It does not
|
||||
|
|
@ -178,18 +179,13 @@ Other commonly used `if` clauses:
|
|||
- `if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_TITLE =~ /Merge branch.*/`:
|
||||
If the commit branch is the default branch and the commit message title matches a regular expression.
|
||||
For example, the default commit message for a merge commit starts with `Merge branch`.
|
||||
|
||||
- `if: $CUSTOM_VARIABLE == "value1"`: If the custom variable `CUSTOM_VARIABLE` is
|
||||
exactly `value1`.
|
||||
|
||||
### Run jobs only in specific pipeline types
|
||||
|
||||
You can use [predefined CI/CD variables](../variables/predefined_variables.md) to choose
|
||||
which pipeline types jobs run in, with:
|
||||
|
||||
- [`rules`](../yaml/index.md#rules)
|
||||
- [`only:variables`](../yaml/index.md#onlyvariables--exceptvariables)
|
||||
- [`except:variables`](../yaml/index.md#onlyvariables--exceptvariables)
|
||||
You can use [predefined CI/CD variables](../variables/predefined_variables.md) with
|
||||
[`rules`](../yaml/index.md#rules) to choose which pipeline types jobs should run for.
|
||||
|
||||
The following table lists some of the variables that you can use, and the pipeline
|
||||
types the variables can control for:
|
||||
|
|
@ -224,6 +220,31 @@ job1:
|
|||
when: never
|
||||
```
|
||||
|
||||
### `CI_PIPELINE_SOURCE` predefined variable
|
||||
|
||||
Use the `CI_PIPELINE_SOURCE` variable to control when to add jobs for these pipeline types:
|
||||
|
||||
| Value | Description |
|
||||
|---------------------------------|-------------|
|
||||
| `api` | For pipelines triggered by the [pipelines API](../../api/pipelines.md#create-a-new-pipeline). |
|
||||
| `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/index.md) command. |
|
||||
| `external` | When you use CI services other than GitLab. |
|
||||
| `external_pull_request_event` | When an [external pull request on GitHub](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests) is created or updated. |
|
||||
| `merge_request_event` | For pipelines created when a merge request is created or updated. Required to enable [merge request pipelines](../pipelines/merge_request_pipelines.md), [merged results pipelines](../pipelines/merged_results_pipelines.md), and [merge trains](../pipelines/merge_trains.md). |
|
||||
| `ondemand_dast_scan` | For [DAST on-demand scan](../../user/application_security/dast/on-demand_scan.md) pipelines. |
|
||||
| `ondemand_dast_validation` | For [DAST on-demand validation](../../user/application_security/dast/on-demand_scan.md#site-profile-validation) pipelines |
|
||||
| `parent_pipeline` | For pipelines triggered by a [parent/child pipeline](../pipelines/downstream_pipelines.md#parent-child-pipelines). Use this pipeline source in the child pipeline configuration so that it can be triggered by the parent pipeline. |
|
||||
| `pipeline` | For [multi-project pipelines](../pipelines/downstream_pipelines.md#multi-project-pipelines) created by [using the API with `CI_JOB_TOKEN`](../pipelines/downstream_pipelines.md#trigger-a-multi-project-pipeline-by-using-the-api), or the [`trigger`](../yaml/index.md#trigger) keyword. |
|
||||
| `push` | For pipelines triggered by a Git push event, including for branches and tags. |
|
||||
| `schedule` | For [scheduled pipelines](../pipelines/schedules.md). |
|
||||
| `security_orchestration_policy` | For [security orchestration policy](../../user/application_security/policies/index.md) pipelines. |
|
||||
| `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#configure-cicd-jobs-to-run-in-triggered-pipelines). |
|
||||
| `web` | For pipelines created by selecting **Run pipeline** in the GitLab UI, from the project's **Build > Pipelines** section. |
|
||||
| `webide` | For pipelines created by using the [WebIDE](../../user/project/web_ide/index.md). |
|
||||
|
||||
These values are the same as returned for the `source` parameter when using the
|
||||
[pipelines API endpoint](../../api/pipelines.md#list-project-pipelines).
|
||||
|
||||
## Complex rules
|
||||
|
||||
You can use all `rules` keywords, like `if`, `changes`, and `exists`, in the same
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ as it can cause the pipeline to behave unexpectedly.
|
|||
| `CI_ENVIRONMENT_URL` | Pipeline | 9.3 | all | The URL of the environment for this job. Available if [`environment:url`](../yaml/index.md#environmenturl) is set. |
|
||||
| `CI_ENVIRONMENT_ACTION` | Pipeline | 13.11 | all | The action annotation specified for this job's environment. Available if [`environment:action`](../yaml/index.md#environmentaction) is set. Can be `start`, `prepare`, or `stop`. |
|
||||
| `CI_ENVIRONMENT_TIER` | Pipeline | 14.0 | all | The [deployment tier of the environment](../environments/index.md#deployment-tier-of-environments) for this job. |
|
||||
| `CI_RELEASE_DESCRIPTION` | Pipeline | 15.5 | all | The description of the release. Available only on pipelines for tags. Description length is limited to first 1024 characters. |
|
||||
| `CI_GITLAB_FIPS_MODE` | Pipeline | 14.10 | all | Only available if [FIPS mode](../../development/fips_compliance.md) is enabled in the GitLab instance. `true` when available. |
|
||||
| `CI_HAS_OPEN_REQUIREMENTS` | Pipeline | 13.1 | all | Only available if the pipeline's project has an open [requirement](../../user/project/requirements/index.md). `true` when available. |
|
||||
| `CI_JOB_ID` | Jobs only | 9.0 | all | The internal ID of the job, unique across all jobs in the GitLab instance. |
|
||||
|
|
@ -96,9 +95,8 @@ as it can cause the pipeline to behave unexpectedly.
|
|||
| `CI_PAGES_URL` | Pipeline | 11.8 | all | The URL for a GitLab Pages site. Always a subdomain of `CI_PAGES_DOMAIN`. |
|
||||
| `CI_PIPELINE_ID` | Jobs only | 8.10 | all | The instance-level ID of the current pipeline. This ID is unique across all projects on the GitLab instance. |
|
||||
| `CI_PIPELINE_IID` | Pipeline | 11.0 | all | The project-level IID (internal ID) of the current pipeline. This ID is unique only within the current project. |
|
||||
| `CI_PIPELINE_SOURCE` | Pipeline | 10.0 | all | How the pipeline was triggered. Can be `push`, `web`, `schedule`, `api`, `external`, `chat`, `webide`, `merge_request_event`, `external_pull_request_event`, `parent_pipeline`, [`trigger`, or `pipeline`](../triggers/index.md#configure-cicd-jobs-to-run-in-triggered-pipelines). For a description of each value, see [Common `if` clauses for `rules`](../jobs/job_rules.md#common-if-clauses-with-predefined-variables), which uses this variable to control when jobs run. |
|
||||
| `CI_PIPELINE_SOURCE` | Pipeline | 10.0 | all | How the pipeline was triggered. The value can be one of the [pipeline sources](../jobs/job_rules.md#ci_pipeline_source-predefined-variable). |
|
||||
| `CI_PIPELINE_TRIGGERED` | Pipeline | all | all | `true` if the job was [triggered](../triggers/index.md). |
|
||||
| `CI_TRIGGER_SHORT_TOKEN` | Jobs only | 17.0 | all | First 4 characters of the [trigger token](../triggers/index.md#create-a-pipeline-trigger-token) of the current job. Only available if the pipeline was [triggered with a trigger token](../triggers/index.md). For example, for a trigger token of `glptt-dbf556605bcad4d9db3ec5fcef84f78f9b4fec28`, `CI_TRIGGER_SHORT_TOKEN` would be `dbf5`. |
|
||||
| `CI_PIPELINE_URL` | Jobs only | 11.1 | 0.5 | The URL for the pipeline details. |
|
||||
| `CI_PIPELINE_CREATED_AT` | Pipeline | 13.10 | all | The date and time when the pipeline was created, in [ISO 8601](https://www.rfc-editor.org/rfc/rfc3339#appendix-A) format. For example, `2022-01-31T16:47:55Z`. [UTC by default](../../administration/timezone.md). |
|
||||
| `CI_PIPELINE_NAME` | Pipeline | 16.3 | all | The pipeline name defined in [`workflow:name`](../yaml/index.md#workflowname) |
|
||||
|
|
@ -120,6 +118,7 @@ as it can cause the pipeline to behave unexpectedly.
|
|||
| `CI_REGISTRY_IMAGE` | Pipeline | 8.10 | 0.5 | Base address for the container registry to push, pull, or tag project's images, formatted as `<host>[:<port>]/<project_full_path>`. For example: `registry.gitlab.example.com/my_group/my_project`. Image names must follow the [container registry naming convention](../../user/packages/container_registry/index.md#naming-convention-for-your-container-images). Only available if the container registry is enabled for the project. |
|
||||
| `CI_REGISTRY_PASSWORD` | Jobs only | 9.0 | all | The password to push containers to the GitLab project's container registry. Only available if the container registry is enabled for the project. This password value is the same as the `CI_JOB_TOKEN` and is valid only as long as the job is running. Use the `CI_DEPLOY_PASSWORD` for long-lived access to the registry |
|
||||
| `CI_REGISTRY_USER` | Jobs only | 9.0 | all | The username to push containers to the project's GitLab container registry. Only available if the container registry is enabled for the project. |
|
||||
| `CI_RELEASE_DESCRIPTION` | Pipeline | 15.5 | all | The description of the release. Available only on pipelines for tags. Description length is limited to first 1024 characters. |
|
||||
| `CI_REPOSITORY_URL` | Jobs only | 9.0 | all | The full path to Git clone (HTTP) the repository with a [CI/CD job token](../jobs/ci_job_token.md), in the format `https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.example.com/my-group/my-project.git`. |
|
||||
| `CI_RUNNER_DESCRIPTION` | Jobs only | 8.10 | 0.5 | The description of the runner. |
|
||||
| `CI_RUNNER_EXECUTABLE_ARCH` | Jobs only | all | 10.6 | The OS/architecture of the GitLab Runner executable. Might not be the same as the environment of the executor. |
|
||||
|
|
@ -147,6 +146,7 @@ as it can cause the pipeline to behave unexpectedly.
|
|||
| `CI_SERVER` | Jobs only | all | all | Available for all jobs executed in CI/CD. `yes` when available. |
|
||||
| `CI_SHARED_ENVIRONMENT` | Pipeline | all | 10.1 | Only available if the job is executed in a shared environment (something that is persisted across CI/CD invocations, like the `shell` or `ssh` executor). `true` when available. |
|
||||
| `CI_TEMPLATE_REGISTRY_HOST` | Pipeline | 15.3 | all | The host of the registry used by CI/CD templates. Defaults to `registry.gitlab.com`. |
|
||||
| `CI_TRIGGER_SHORT_TOKEN` | Jobs only | 17.0 | all | First 4 characters of the [trigger token](../triggers/index.md#create-a-pipeline-trigger-token) of the current job. Only available if the pipeline was [triggered with a trigger token](../triggers/index.md). For example, for a trigger token of `glptt-dbf556605bcad4d9db3ec5fcef84f78f9b4fec28`, `CI_TRIGGER_SHORT_TOKEN` would be `dbf5`. |
|
||||
| `GITLAB_CI` | Pipeline | all | all | Available for all jobs executed in CI/CD. `true` when available. |
|
||||
| `GITLAB_FEATURES` | Pipeline | 10.6 | all | The comma-separated list of licensed features available for the GitLab instance and license. |
|
||||
| `GITLAB_USER_EMAIL` | Pipeline | 8.12 | all | The email of the user who started the pipeline, unless the job is a manual job. In manual jobs, the value is the email of the user who started the job. |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
---
|
||||
stage: Data Stores
|
||||
group: Global Search
|
||||
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
|
||||
---
|
||||
|
||||
# Embeddings
|
||||
|
||||
Embeddings are a way of representing data in a vectorised format, making it easy and efficient to find similar documents.
|
||||
|
||||
Currently embeddings are only generated for issues which allows for features such as
|
||||
|
||||
- [Issue search](https://gitlab.com/gitlab-org/gitlab/-/issues/440424)
|
||||
- [Find similar issues](https://gitlab.com/gitlab-org/gitlab/-/issues/407385)
|
||||
- [Find duplicate issues](https://gitlab.com/gitlab-org/gitlab/-/issues/407385)
|
||||
- [Find similar/related issues for Zendesk tickets](https://gitlab.com/gitlab-org/gitlab/-/issues/411847)
|
||||
- [Auto-Categorize Service Desk issues](https://gitlab.com/gitlab-org/gitlab/-/issues/409646)
|
||||
|
||||
## Architecture
|
||||
|
||||
Embeddings are stored in Elasticsearch which is also used for [Advanced Search](../advanced_search.md).
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[database record] --> B[ActiveRecord callback]
|
||||
B --> C[build embedding reference]
|
||||
C -->|add to queue| N[queue]
|
||||
E[cron worker every minute] <-->|pull from queue| N
|
||||
E --> G[deserialize reference]
|
||||
G --> H[generate embedding]
|
||||
H <--> I[AI Gateway]
|
||||
I <--> J[Vertex API]
|
||||
H --> K[upsert document with embedding]
|
||||
K --> L[Elasticsearch]
|
||||
```
|
||||
|
||||
The process is driven by `Search::Elastic::ProcessEmbeddingBookkeepingService` which adds and pulls from a Redis queue.
|
||||
|
||||
### Adding to the embedding queue
|
||||
|
||||
The following process description uses issues as an example.
|
||||
|
||||
An issue embedding is generated from the content `"issue with title '#{issue.title}' and description '#{issue.description}'"`.
|
||||
|
||||
Using ActiveRecord callbacks defined in [`Search::Elastic::IssuesSearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/models/concerns/search/elastic/issues_search.rb), an [embedding reference](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/search/elastic/references/embedding.rb) is added to the embedding queue if it is created or if the title or description is updated and if [embedding generation is available](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/models/concerns/search/elastic/issues_search.rb#L38-47) for the issue.
|
||||
|
||||
### Pulling from the embedding queue
|
||||
|
||||
A `Search::ElasticIndexEmbeddingBulkCronWorker` cron worker runs every minute and does the following:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[cron] --> B{endpoint throttled?}
|
||||
B -->|no| C[schedule 16 workers]
|
||||
C ..->|each worker| D{endpoint throttled?}
|
||||
D -->|no| E[fetch 19 references from queue]
|
||||
E ..->|each reference| F[increment endpoint]
|
||||
F --> G{endpoint throttled?}
|
||||
G -->|no| H[call AI Gateway to generate embedding]
|
||||
```
|
||||
|
||||
Therefore we always make sure that we don't exceed the rate limit setting of 450 embeddings per minute even with 16 concurrent processes generating embeddings at the same time.
|
||||
|
||||
### Backfilling
|
||||
|
||||
An [Advanced Search migration](../search/advanced_search_migration_styleguide.md) is used to perform the backfill. It essentially adds references to the queue in batches which are then processed by the cron worker as described above.
|
||||
|
||||
## Adding a new embedding type
|
||||
|
||||
The following process outlines the steps to get embeddings generated and stored in Elasticsearch.
|
||||
|
||||
1. Do a cost and resource calculation to see if the Elasticsearch cluster can handle embedding generation or if it needs additional resources.
|
||||
1. Decide where to store embeddings. Look at the [existing indices in Elasticsearch](../../integration/advanced_search/elasticsearch.md#advanced-search-index-scopes) and if there isn't a suitable existing index, [create a new index](../advanced_search.md#add-a-new-document-type-to-elasticsearch).
|
||||
1. Add embedding fields to the index: [example](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/149209).
|
||||
1. Update the way [content](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/search/elastic/references/embedding.rb#L75-77) is generated to accommodate the new type.
|
||||
1. Add a new unit primitive: [here](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/merge_requests/918) and [here](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155835).
|
||||
1. Use `Elastic::ApplicationVersionedSearch` to access callbacks and add the necessary checks for when to generate embeddings. See [`Search::Elastic::IssuesSearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/models/concerns/search/elastic/issues_search.rb) for an example.
|
||||
1. Backfill embeddings: [example](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154940).
|
||||
|
|
@ -210,5 +210,36 @@ For instance, for `container_scanning` type the location is defined by Docker im
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Dismissed vulnerabilities are sometimes still visible
|
||||
|
||||
In some instances of GitLab 16.8 and earlier [dismissed vulnerabilities are sometimes still visible](https://gitlab.com/gitlab-org/gitlab/-/issues/367298).
|
||||
This can be resolved by upgrading to GitLab 16.9 and later.
|
||||
|
||||
### Report parsing and scan ingestion errors
|
||||
|
||||
NOTE:
|
||||
These steps are to be used by GitLab Support to reproduce such errors.
|
||||
|
||||
Some security scans may result in errors in the **Security** tab of the pipeline related to report parsing or scan ingestion. If it is not possible to get a copy of the project from the user, you can reproduce the error using the report generated from the scan.
|
||||
|
||||
To recreate the error:
|
||||
|
||||
1. Obtain a copy of the report from the user. In this example, `gl-sast-report.json`.
|
||||
1. Create a project.
|
||||
1. Commit the report to the repository.
|
||||
1. Add your `.gitlab-ci.yml` file and have the report as an artifact in a job.
|
||||
|
||||
For example, to reproduce an error caused by a SAST job:
|
||||
|
||||
```yaml
|
||||
sample-job:
|
||||
script:
|
||||
- echo "Testing report"
|
||||
artifacts:
|
||||
reports:
|
||||
sast: gl-sast-report.json
|
||||
```
|
||||
|
||||
1. After the pipeline completes, check the content of the pipeline's **Security** tab for errors.
|
||||
|
||||
You can replace `sast: gl-sast-report.json` with the respective [`artifacts:reports`](../../../ci/yaml/index.md#artifactsreports) type and the correct JSON report filename depending on the scan that generated the report.
|
||||
|
|
|
|||
|
|
@ -68,10 +68,12 @@ Audit event types belong to the following product categories.
|
|||
| [`created_group_audit_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147888) | Event triggered when an external audit event destination for a top-level group is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.11](https://gitlab.com/gitlab-org/gitlab/-/issues/436610) | Group |
|
||||
| [`created_group_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150712) | Event triggered when a namespace filter for an external audit event destination for a top-level group is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.0](https://gitlab.com/gitlab-org/gitlab/-/issues/436612) | Group |
|
||||
| [`created_instance_audit_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/148383) | Event triggered when an external audit event destination for a GitLab instance is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.11](https://gitlab.com/gitlab-org/gitlab/-/issues/436615) | Instance |
|
||||
| [`created_instance_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153156) | Event triggered when a namespace filter for an external audit event destination for an instance is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/436613) | Instance |
|
||||
| [`delete_http_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136302) | Event triggered when a namespace filter for an external audit event destination for a top-level group is deleted.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.7](https://gitlab.com/gitlab-org/gitlab/-/issues/424177) | Group |
|
||||
| [`deleted_group_audit_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/148738) | Event triggered when an external audit event destination for a top-level group is deleted.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.11](https://gitlab.com/gitlab-org/gitlab/-/issues/436610) | Group |
|
||||
| [`deleted_group_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150712) | Event triggered when a namespace filter for an external audit event destination for a top-level group is deleted.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.0](https://gitlab.com/gitlab-org/gitlab/-/issues/436612) | Group |
|
||||
| [`deleted_instance_audit_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/14910) | Event triggered when an external audit event destination for a GitLab instance is deleted.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.11](https://gitlab.com/gitlab-org/gitlab/-/issues/436615) | Instance |
|
||||
| [`deleted_instance_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153156) | Event triggered when a namespace filter for an external audit event destination for an instance is deleted.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/436613) | Instance |
|
||||
| [`destroy_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74632) | Event triggered when an external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) | Group |
|
||||
| [`destroy_instance_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125846) | Event triggered when an instance level external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/gitlab/-/issues/404730) | Instance |
|
||||
| [`event_type_filters_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113081) | Event triggered when a new audit events streaming event type filter is created| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.10](https://gitlab.com/gitlab-org/gitlab/-/issues/344848) | Group |
|
||||
|
|
|
|||
|
|
@ -186,6 +186,33 @@ To edit the custom email display name:
|
|||
1. Below **Email display name**, enter a new name.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Default ticket visibility
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33091) in GitLab 17.2 [with a flag](../../../administration/feature_flags.md) named `service_desk_ticket_confidentiality`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
The availability of this feature is controlled by a feature flag.
|
||||
For more information, see the history.
|
||||
|
||||
New tickets are confidential by default, so only project members with at least the Reporter role
|
||||
can view them.
|
||||
|
||||
In private and internal projects, you can configure GitLab so that new tickets are not confidential by default, and any project member can view them.
|
||||
|
||||
In public projects, this setting is not available because new tickets are always confidential by default.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have at least the Maintainer role for the project.
|
||||
|
||||
To disable this setting:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Service Desk**.
|
||||
1. Clear the **New tickets are confidential by default** checkbox.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Reopen issues when an external participant comments
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8549) in GitLab 16.7
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ These shortcuts are available in most areas of GitLab:
|
|||
| <kbd>Shift</kbd> + <kbd>t</kbd> | Go to your To-Do List page. |
|
||||
| <kbd>p</kbd>, then <kbd>b</kbd> | Show or hide the Performance Bar. |
|
||||
| <kbd>Escape</kbd> | Hide tooltips or popovers. |
|
||||
| <kbd>Escape</kbd> | Hide tooltips or popovers. |
|
||||
| <kbd>g</kbd>, then <kbd>x</kbd> | Toggle between [GitLab](https://gitlab.com/) and [GitLab Next](https://next.gitlab.com/) (GitLab SaaS only). |
|
||||
| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
|
||||
|
||||
|
|
@ -105,7 +104,6 @@ These shortcuts are available when viewing issues:
|
|||
| <kbd>l</kbd> | Change label. |
|
||||
| <kbd>c</kbd> + <kbd>r</kbd> | Copy issue reference. |
|
||||
| <kbd>r</kbd> | Start writing a comment. Pre-selected text is quoted in the comment. Can't be used to reply in a thread. |
|
||||
| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
|
||||
| <kbd>→</kbd> | Go to the next design. |
|
||||
| <kbd>←</kbd> | Go to the previous design. |
|
||||
| <kbd>Escape</kbd> | Close the design. |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
class BackfillVulnerabilityFindingsRemediationsProjectId < BackfillDesiredShardingKeyJob
|
||||
operation_name :backfill_vulnerability_findings_remediations_project_id
|
||||
feature_category :vulnerability_management
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -129,7 +129,7 @@ module Users
|
|||
|
||||
uniquify = Gitlab::Utils::Uniquify.new
|
||||
|
||||
username = uniquify.string(username) { |s| User.find_by_username(s) }
|
||||
username = uniquify.string(username) { |s| Namespace.by_path(s) }
|
||||
|
||||
email = uniquify.string(->(n) { Kernel.sprintf(email_pattern, n) }) do |s|
|
||||
User.find_by_email(s)
|
||||
|
|
|
|||
|
|
@ -49130,6 +49130,9 @@ msgstr ""
|
|||
msgid "ServiceDesk|Add external participants from the %{codeStart}Cc%{codeEnd} header"
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|Any project member can view new tickets."
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|CRAM-MD5"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -49205,6 +49208,9 @@ msgstr ""
|
|||
msgid "ServiceDesk|Enable custom email address"
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|External participants"
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|Forward all emails to the custom email address to %{incomingEmail}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -49238,6 +49244,15 @@ msgstr ""
|
|||
msgid "ServiceDesk|Minimum 8 characters long."
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|New tickets are confidential by default"
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|On public projects, tickets are always confidential by default."
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|Only project members with at least the Reporter role can view new tickets."
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|Or reset and connect a new custom email address to this Service Desk."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -49334,6 +49349,9 @@ msgstr ""
|
|||
msgid "ServiceDesk|This issue has been reopened because it received a new comment from an external participant."
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|Ticket visibility"
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|To use a custom email address for this Service Desk, you'll need to configure and verify an email address again."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -55876,7 +55894,7 @@ msgstr ""
|
|||
msgid "Trials|Your trial ends on %{boldStart}%{trialEndDate}%{boldEnd}. We hope you’re enjoying the features of GitLab %{planName}. To keep those features after your trial ends, you’ll need to buy a subscription. (You can also choose GitLab Premium if it meets your needs.)"
|
||||
msgstr ""
|
||||
|
||||
msgid "Trial| By clicking Continue or registering through a third party, you accept the %{gitlabSubscriptionAgreement} and acknowledge the %{privacyStatement} and %{cookiePolicy}."
|
||||
msgid "Trial| By selecting Continue or registering through a third party, you accept the %{gitlabSubscriptionAgreement} and acknowledge the %{privacyStatement} and %{cookiePolicy}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Trial|Allowed characters: +, 0-9, -, and spaces."
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@
|
|||
"swagger-cli": "^4.0.4",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"timezone-mock": "^1.0.8",
|
||||
"vite": "^5.2.13",
|
||||
"vite": "^5.3.1",
|
||||
"vite-plugin-ruby": "^5.0.0",
|
||||
"vue-loader-vue3": "npm:vue-loader@17.4.2",
|
||||
"vue-test-utils-compat": "0.0.14",
|
||||
|
|
|
|||
|
|
@ -511,6 +511,36 @@ RSpec.describe SearchController, feature_category: :global_search do
|
|||
expect(json_response).to eq({ 'count' => '0' })
|
||||
end
|
||||
|
||||
describe 'database transaction' do
|
||||
before do
|
||||
allow_next_instance_of(SearchService) do |search_service|
|
||||
allow(search_service).to receive(:search_type).and_return(search_type)
|
||||
end
|
||||
end
|
||||
|
||||
subject(:count) { get :count, params: { search: 'hello', scope: 'projects' } }
|
||||
|
||||
context 'for basic search' do
|
||||
let(:search_type) { 'basic' }
|
||||
|
||||
it 'executes within transaction with short timeout' do
|
||||
expect(ApplicationRecord).to receive(:with_fast_read_statement_timeout)
|
||||
|
||||
count
|
||||
end
|
||||
end
|
||||
|
||||
context 'for advacned search' do
|
||||
let(:search_type) { 'advanced' }
|
||||
|
||||
it 'does not execute within transaction' do
|
||||
expect(ApplicationRecord).not_to receive(:with_fast_read_statement_timeout)
|
||||
|
||||
count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
|
||||
let(:current_user) { user }
|
||||
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@ describe('gl_emoji', () => {
|
|||
group: {
|
||||
id: 1,
|
||||
customEmoji: {
|
||||
pageInfo: {
|
||||
hasNextPage: false,
|
||||
endCursor: 'test',
|
||||
},
|
||||
nodes: [{ id: 1, name: 'parrot', url: 'parrot.gif' }],
|
||||
},
|
||||
},
|
||||
|
|
@ -163,7 +167,6 @@ describe('gl_emoji', () => {
|
|||
],
|
||||
]);
|
||||
|
||||
window.gon = { features: { customEmoji: true } };
|
||||
document.body.dataset.groupFullPath = 'test-group';
|
||||
|
||||
await initEmojiMock(emojiData);
|
||||
|
|
|
|||
|
|
@ -59,24 +59,42 @@ const emptySupportMap = {
|
|||
1.1: false,
|
||||
};
|
||||
|
||||
function createMockEmojiClient() {
|
||||
mockClient = createMockClient([
|
||||
function createMockEmojiClient(hasNextPage = false) {
|
||||
mockClient = createMockClient(
|
||||
[
|
||||
customEmojiQuery,
|
||||
jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
group: {
|
||||
id: 1,
|
||||
customEmoji: {
|
||||
nodes: [{ id: 1, name: 'parrot', url: 'parrot.gif' }],
|
||||
[
|
||||
customEmojiQuery,
|
||||
({ after }) =>
|
||||
Promise.resolve({
|
||||
data: {
|
||||
group: {
|
||||
id: 1,
|
||||
customEmoji: {
|
||||
pageInfo: {
|
||||
hasNextPage: after ? false : hasNextPage,
|
||||
endCursor: 'test',
|
||||
},
|
||||
nodes: [{ id: 1, name: `parrot${after ? `-${after}` : ''}`, url: 'parrot.gif' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
],
|
||||
{},
|
||||
{
|
||||
typePolicies: {
|
||||
Query: {
|
||||
fields: {
|
||||
group: {
|
||||
merge: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
]);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
window.gon = { features: { customEmoji: true } };
|
||||
document.body.dataset.groupFullPath = 'test-group';
|
||||
}
|
||||
|
||||
|
|
@ -916,12 +934,9 @@ describe('emoji', () => {
|
|||
});
|
||||
|
||||
describe('loadCustomEmojiWithNames', () => {
|
||||
beforeEach(() => {
|
||||
createMockEmojiClient();
|
||||
});
|
||||
|
||||
describe('when not in a group', () => {
|
||||
beforeEach(() => {
|
||||
createMockEmojiClient();
|
||||
delete document.body.dataset.groupFullPath;
|
||||
});
|
||||
|
||||
|
|
@ -953,8 +968,10 @@ describe('emoji', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when in a group with flag enabled', () => {
|
||||
describe('when in a group', () => {
|
||||
it('returns emoji data', async () => {
|
||||
createMockEmojiClient();
|
||||
|
||||
const result = await loadCustomEmojiWithNames();
|
||||
|
||||
expect(result).toEqual({
|
||||
|
|
@ -971,6 +988,34 @@ describe('emoji', () => {
|
|||
names: ['parrot'],
|
||||
});
|
||||
});
|
||||
|
||||
it('paginates custom emoji emoji', async () => {
|
||||
createMockEmojiClient(true);
|
||||
|
||||
const result = await loadCustomEmojiWithNames();
|
||||
|
||||
expect(result).toEqual({
|
||||
emojis: {
|
||||
parrot: {
|
||||
c: 'custom',
|
||||
d: 'parrot',
|
||||
e: undefined,
|
||||
name: 'parrot',
|
||||
src: 'parrot.gif',
|
||||
u: 'custom',
|
||||
},
|
||||
'parrot-test': {
|
||||
c: 'custom',
|
||||
d: 'parrot-test',
|
||||
e: undefined,
|
||||
name: 'parrot-test',
|
||||
src: 'parrot.gif',
|
||||
u: 'custom',
|
||||
},
|
||||
},
|
||||
names: ['parrot', 'parrot-test'],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ describe('ServiceDeskRoot', () => {
|
|||
isIssueTrackerEnabled: true,
|
||||
outgoingName: 'GitLab Support Bot',
|
||||
projectKey: 'key',
|
||||
areTicketsConfidentialByDefault: false,
|
||||
reopenIssueOnExternalParticipantNote: true,
|
||||
addExternalParticipantsFromCc: true,
|
||||
selectedTemplate: 'Bug',
|
||||
|
|
@ -61,6 +62,7 @@ describe('ServiceDeskRoot', () => {
|
|||
incomingEmail: provideData.initialIncomingEmail,
|
||||
initialOutgoingName: provideData.outgoingName,
|
||||
initialProjectKey: provideData.projectKey,
|
||||
initialAreTicketsConfidentialByDefault: provideData.areTicketsConfidentialByDefault,
|
||||
initialReopenIssueOnExternalParticipantNote:
|
||||
provideData.reopenIssueOnExternalParticipantNote,
|
||||
initialAddExternalParticipantsFromCc: provideData.addExternalParticipantsFromCc,
|
||||
|
|
@ -69,6 +71,7 @@ describe('ServiceDeskRoot', () => {
|
|||
isEnabled: provideData.initialIsEnabled,
|
||||
isIssueTrackerEnabled: provideData.isIssueTrackerEnabled,
|
||||
isTemplateSaving: false,
|
||||
publicProject: provideData.publicProject,
|
||||
templates: provideData.templates,
|
||||
});
|
||||
});
|
||||
|
|
@ -149,6 +152,7 @@ describe('ServiceDeskRoot', () => {
|
|||
selectedTemplate: 'Bug',
|
||||
outgoingName: 'GitLab Support Bot',
|
||||
projectKey: 'key',
|
||||
areTicketsConfidentialByDefault: false,
|
||||
reopenIssueOnExternalParticipantNote: true,
|
||||
addExternalParticipantsFromCc: true,
|
||||
};
|
||||
|
|
@ -164,6 +168,7 @@ describe('ServiceDeskRoot', () => {
|
|||
outgoing_name: 'GitLab Support Bot',
|
||||
project_key: 'key',
|
||||
service_desk_enabled: true,
|
||||
tickets_confidential_by_default: false,
|
||||
reopen_issue_on_external_participant_note: true,
|
||||
add_external_participants_from_cc: true,
|
||||
});
|
||||
|
|
@ -184,6 +189,7 @@ describe('ServiceDeskRoot', () => {
|
|||
selectedTemplate: 'Bug',
|
||||
outgoingName: 'GitLab Support Bot',
|
||||
projectKey: 'key',
|
||||
tickets_confidential_by_default: false,
|
||||
reopen_issue_on_external_participant_note: true,
|
||||
addExternalParticipantsFromCc: true,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ describe('ServiceDeskSetting', () => {
|
|||
const findSuffixFormGroup = () => wrapper.findByTestId('suffix-form-group');
|
||||
const findIssueTrackerInfo = () => wrapper.findComponent(GlAlert);
|
||||
const findIssueHelpLink = () => wrapper.findByTestId('issue-help-page');
|
||||
const findAreTicketsConfidentialByDefaultWrapper = () =>
|
||||
wrapper.findByTestId('service-desk-are-tickets-confidential-by-default-wrapper');
|
||||
const findAreTicketsConfidentialByDefaultCheckbox = () =>
|
||||
wrapper.findByTestId('service-desk-are-tickets-confidential-by-default');
|
||||
const findReopenIssueOnExternalParticipantNoteCheckbox = () =>
|
||||
wrapper.findByTestId('reopen-issue-on-external-participant-note');
|
||||
const findAddExternalParticipantsFromCcCheckbox = () =>
|
||||
|
|
@ -35,6 +39,7 @@ describe('ServiceDeskSetting', () => {
|
|||
provide: {
|
||||
glFeatures: {
|
||||
issueEmailParticipants: true,
|
||||
serviceDeskTicketsConfidentiality: true,
|
||||
},
|
||||
...provide,
|
||||
},
|
||||
|
|
@ -215,6 +220,83 @@ describe('ServiceDeskSetting', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('are tickets confidential by default checkbox', () => {
|
||||
it('is rendered', () => {
|
||||
wrapper = createComponent();
|
||||
|
||||
expect(findAreTicketsConfidentialByDefaultCheckbox().exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('when project is public', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createComponent({
|
||||
props: { publicProject: true, initialAreTicketsConfidentialByDefault: false },
|
||||
});
|
||||
});
|
||||
|
||||
it('displays correct help text', () => {
|
||||
expect(findAreTicketsConfidentialByDefaultWrapper().text()).toContain(
|
||||
ServiceDeskSetting.i18n.areTicketsConfidentialByDefault.help.publicProject,
|
||||
);
|
||||
});
|
||||
|
||||
it('checks and disables the checkbox', () => {
|
||||
const { element } = findAreTicketsConfidentialByDefaultCheckbox().find('input');
|
||||
|
||||
expect(element.checked).toBe(true);
|
||||
expect(element.disabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when project is not public', () => {
|
||||
describe('when tickets are confidential by default', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createComponent({ props: { initialAreTicketsConfidentialByDefault: true } });
|
||||
});
|
||||
|
||||
it('forwards true as initial value to the checkbox', () => {
|
||||
expect(findAreTicketsConfidentialByDefaultCheckbox().find('input').element.checked).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('displays correct help text', () => {
|
||||
expect(findAreTicketsConfidentialByDefaultWrapper().text()).toContain(
|
||||
ServiceDeskSetting.i18n.areTicketsConfidentialByDefault.help.confidential,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when tickets are not confidential by default', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createComponent({ props: { initialAreTicketsConfidentialByDefault: false } });
|
||||
});
|
||||
|
||||
it('forwards false as initial value to the checkbox', () => {
|
||||
expect(findAreTicketsConfidentialByDefaultCheckbox().find('input').element.checked).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('displays correct help text', () => {
|
||||
expect(findAreTicketsConfidentialByDefaultWrapper().text()).toContain(
|
||||
ServiceDeskSetting.i18n.areTicketsConfidentialByDefault.help.nonConfidential,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when feature flag service_desk_tickets_confidentiality is disabled', () => {
|
||||
it('is not rendered', () => {
|
||||
wrapper = createComponent({
|
||||
provide: { glFeatures: { serviceDeskTicketsConfidentiality: false } },
|
||||
});
|
||||
|
||||
expect(findAreTicketsConfidentialByDefaultCheckbox().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('reopen issue on external participant note checkbox', () => {
|
||||
it('is rendered', () => {
|
||||
wrapper = createComponent();
|
||||
|
|
@ -273,6 +355,7 @@ describe('ServiceDeskSetting', () => {
|
|||
initialSelectedFileTemplateProjectId: 42,
|
||||
initialOutgoingName: 'GitLab Support Bot',
|
||||
initialProjectKey: 'key',
|
||||
initialAreTicketsConfidentialByDefault: false,
|
||||
initialReopenIssueOnExternalParticipantNote: true,
|
||||
initialAddExternalParticipantsFromCc: true,
|
||||
},
|
||||
|
|
@ -287,6 +370,7 @@ describe('ServiceDeskSetting', () => {
|
|||
fileTemplateProjectId: 42,
|
||||
outgoingName: 'GitLab Support Bot',
|
||||
projectKey: 'key',
|
||||
areTicketsConfidentialByDefault: false,
|
||||
reopenIssueOnExternalParticipantNote: true,
|
||||
addExternalParticipantsFromCc: true,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { GlSkeletonLoader } from '@gitlab/ui';
|
||||
import { GlSkeletonLoader, GlButton } from '@gitlab/ui';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import DesignToolbar from '~/work_items/components/design_management/design_preview/design_toolbar.vue';
|
||||
import CloseButton from '~/work_items/components/design_management/design_preview/close_button.vue';
|
||||
|
|
@ -41,6 +41,12 @@ describe('DesignToolbar', () => {
|
|||
expect(wrapper.find('h2').text()).toContain(mockDesign.filename);
|
||||
});
|
||||
|
||||
it('renders download button with correct link', () => {
|
||||
createComponent();
|
||||
|
||||
expect(wrapper.findComponent(GlButton).attributes('href')).toBe(mockDesign.image);
|
||||
});
|
||||
|
||||
it('renders close button', () => {
|
||||
createComponent();
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ describe('WorkItemDetail component', () => {
|
|||
error = undefined,
|
||||
workItemsAlphaEnabled = false,
|
||||
workItemsBeta = false,
|
||||
namespaceLevelWorkItems = true,
|
||||
} = {}) => {
|
||||
wrapper = shallowMountExtended(WorkItemDetail, {
|
||||
apolloProvider: createMockApollo([
|
||||
|
|
@ -130,6 +131,7 @@ describe('WorkItemDetail component', () => {
|
|||
glFeatures: {
|
||||
workItemsAlpha: workItemsAlphaEnabled,
|
||||
workItemsBeta,
|
||||
namespaceLevelWorkItems,
|
||||
},
|
||||
hasIssueWeightsFeature: true,
|
||||
hasIterationsFeature: true,
|
||||
|
|
@ -315,7 +317,7 @@ describe('WorkItemDetail component', () => {
|
|||
expect(findAncestors().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('does not show ancestors widget if there is not a parent', async () => {
|
||||
it('does not show ancestors widget if there is no parent', async () => {
|
||||
createComponent({ handler: jest.fn().mockResolvedValue(workItemQueryResponseWithoutParent) });
|
||||
|
||||
await waitForPromises();
|
||||
|
|
@ -330,6 +332,17 @@ describe('WorkItemDetail component', () => {
|
|||
expect(findWorkItemType().classes()).toEqual(['sm:!gl-block', 'gl-w-full']);
|
||||
});
|
||||
|
||||
describe('`namespace_level_work_items` is disabled', () => {
|
||||
it('does not show ancestors widget and shows title in the header', async () => {
|
||||
createComponent({ namespaceLevelWorkItems: false });
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
expect(findAncestors().exists()).toBe(false);
|
||||
expect(findWorkItemType().classes()).toEqual(['sm:!gl-block', 'gl-w-full']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with parent', () => {
|
||||
beforeEach(() => {
|
||||
const parentResponse = workItemByIidResponseFactory(mockParent);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityFindingsRemediationsProjectId,
|
||||
feature_category: :vulnerability_management,
|
||||
schema: 20240618121517 do
|
||||
include_examples 'desired sharding key backfill job' do
|
||||
let(:batch_table) { :vulnerability_findings_remediations }
|
||||
let(:backfill_column) { :project_id }
|
||||
let(:backfill_via_table) { :vulnerability_occurrences }
|
||||
let(:backfill_via_column) { :project_id }
|
||||
let(:backfill_via_foreign_key) { :vulnerability_occurrence_id }
|
||||
end
|
||||
end
|
||||
|
|
@ -27,7 +27,7 @@ RSpec.describe Users::Internal, feature_category: :user_profile do
|
|||
end.not_to change { User.count }
|
||||
end
|
||||
|
||||
context 'when a regular user exists with the bot usernane' do
|
||||
context 'when a regular user exists with the bot username' do
|
||||
it 'creates a user with a non-conflicting username' do
|
||||
create(:user, username: username)
|
||||
|
||||
|
|
@ -47,6 +47,16 @@ RSpec.describe Users::Internal, feature_category: :user_profile do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when a group namespace exists with path that is equal to the bot username' do
|
||||
it 'creates a user with a non-conflicting username' do
|
||||
create(:group, path: username)
|
||||
|
||||
expect do
|
||||
described_class.public_send(bot_type)
|
||||
end.to change { User.where(user_type: bot_type).count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a domain allowlist is in place' do
|
||||
before do
|
||||
stub_application_setting(domain_allowlist: ['gitlab.com'])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe QueueBackfillVulnerabilityFindingsRemediationsProjectId, feature_category: :vulnerability_management do
|
||||
let!(:batched_migration) { described_class::MIGRATION }
|
||||
|
||||
it 'schedules a new batched migration' do
|
||||
reversible_migration do |migration|
|
||||
migration.before -> {
|
||||
expect(batched_migration).not_to have_scheduled_batched_migration
|
||||
}
|
||||
|
||||
migration.after -> {
|
||||
expect(batched_migration).to have_scheduled_batched_migration(
|
||||
table_name: :vulnerability_findings_remediations,
|
||||
column_name: :id,
|
||||
interval: described_class::DELAY_INTERVAL,
|
||||
batch_size: described_class::BATCH_SIZE,
|
||||
sub_batch_size: described_class::SUB_BATCH_SIZE,
|
||||
gitlab_schema: :gitlab_main_cell,
|
||||
job_arguments: [
|
||||
:project_id,
|
||||
:vulnerability_occurrences,
|
||||
:project_id,
|
||||
:vulnerability_occurrence_id
|
||||
]
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -196,11 +196,12 @@ end
|
|||
RSpec.shared_examples 'an unsubscribeable thread' do
|
||||
it_behaves_like 'an unsubscribeable thread with incoming address without %{key}'
|
||||
|
||||
it 'has a List-Unsubscribe header in the correct format, and a body link' do
|
||||
it 'has a List-Unsubscribe header in the correct format, List-Unsubscribe-Post header, and a body link' do
|
||||
aggregate_failures do
|
||||
is_expected.to have_header('List-Unsubscribe', /unsubscribe/)
|
||||
is_expected.to have_header('List-Unsubscribe', /mailto/)
|
||||
is_expected.to have_header('List-Unsubscribe', /^<.+,.+>$/)
|
||||
is_expected.to have_header('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click')
|
||||
is_expected.to have_body_text('unsubscribe')
|
||||
end
|
||||
end
|
||||
|
|
@ -209,20 +210,22 @@ end
|
|||
RSpec.shared_examples 'an unsubscribeable thread with incoming address without %{key}' do
|
||||
include_context 'reply-by-email is enabled with incoming address without %{key}'
|
||||
|
||||
it 'has a List-Unsubscribe header in the correct format, and a body link' do
|
||||
it 'has a List-Unsubscribe header in the correct format, List-Unsubscribe-Post header, and a body link' do
|
||||
aggregate_failures do
|
||||
is_expected.to have_header('List-Unsubscribe', /unsubscribe/)
|
||||
is_expected.not_to have_header('List-Unsubscribe', /mailto/)
|
||||
is_expected.to have_header('List-Unsubscribe', /^<[^,]+>$/)
|
||||
is_expected.to have_header('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click')
|
||||
is_expected.to have_body_text('unsubscribe')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'a user cannot unsubscribe through footer link' do
|
||||
it 'does not have a List-Unsubscribe header or a body link' do
|
||||
it 'does not have a List-Unsubscribe header, List-Unsubscribe-Post header or a body link' do
|
||||
aggregate_failures do
|
||||
is_expected.not_to have_header('List-Unsubscribe', /unsubscribe/)
|
||||
is_expected.not_to have_header('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click')
|
||||
is_expected.not_to have_body_text('unsubscribe')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
248
yarn.lock
248
yarn.lock
|
|
@ -1092,125 +1092,125 @@
|
|||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||
|
||||
"@esbuild/aix-ppc64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537"
|
||||
integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==
|
||||
"@esbuild/aix-ppc64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
|
||||
integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==
|
||||
|
||||
"@esbuild/android-arm64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9"
|
||||
integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==
|
||||
"@esbuild/android-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052"
|
||||
integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==
|
||||
|
||||
"@esbuild/android-arm@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995"
|
||||
integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==
|
||||
"@esbuild/android-arm@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28"
|
||||
integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==
|
||||
|
||||
"@esbuild/android-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98"
|
||||
integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==
|
||||
"@esbuild/android-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e"
|
||||
integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==
|
||||
|
||||
"@esbuild/darwin-arm64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb"
|
||||
integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==
|
||||
"@esbuild/darwin-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a"
|
||||
integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==
|
||||
|
||||
"@esbuild/darwin-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0"
|
||||
integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==
|
||||
"@esbuild/darwin-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22"
|
||||
integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911"
|
||||
integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==
|
||||
"@esbuild/freebsd-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e"
|
||||
integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==
|
||||
|
||||
"@esbuild/freebsd-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c"
|
||||
integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==
|
||||
"@esbuild/freebsd-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261"
|
||||
integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==
|
||||
|
||||
"@esbuild/linux-arm64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5"
|
||||
integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==
|
||||
"@esbuild/linux-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b"
|
||||
integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==
|
||||
|
||||
"@esbuild/linux-arm@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c"
|
||||
integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==
|
||||
"@esbuild/linux-arm@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9"
|
||||
integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==
|
||||
|
||||
"@esbuild/linux-ia32@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa"
|
||||
integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==
|
||||
"@esbuild/linux-ia32@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2"
|
||||
integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==
|
||||
|
||||
"@esbuild/linux-loong64@0.14.54":
|
||||
version "0.14.54"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028"
|
||||
integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==
|
||||
|
||||
"@esbuild/linux-loong64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5"
|
||||
integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==
|
||||
"@esbuild/linux-loong64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df"
|
||||
integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==
|
||||
|
||||
"@esbuild/linux-mips64el@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa"
|
||||
integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==
|
||||
"@esbuild/linux-mips64el@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe"
|
||||
integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==
|
||||
|
||||
"@esbuild/linux-ppc64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20"
|
||||
integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==
|
||||
"@esbuild/linux-ppc64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4"
|
||||
integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==
|
||||
|
||||
"@esbuild/linux-riscv64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300"
|
||||
integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==
|
||||
"@esbuild/linux-riscv64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc"
|
||||
integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==
|
||||
|
||||
"@esbuild/linux-s390x@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685"
|
||||
integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==
|
||||
"@esbuild/linux-s390x@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de"
|
||||
integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==
|
||||
|
||||
"@esbuild/linux-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff"
|
||||
integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==
|
||||
"@esbuild/linux-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0"
|
||||
integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==
|
||||
|
||||
"@esbuild/netbsd-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6"
|
||||
integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==
|
||||
"@esbuild/netbsd-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047"
|
||||
integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==
|
||||
|
||||
"@esbuild/openbsd-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf"
|
||||
integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==
|
||||
"@esbuild/openbsd-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70"
|
||||
integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==
|
||||
|
||||
"@esbuild/sunos-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f"
|
||||
integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==
|
||||
"@esbuild/sunos-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b"
|
||||
integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==
|
||||
|
||||
"@esbuild/win32-arm64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90"
|
||||
integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==
|
||||
"@esbuild/win32-arm64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d"
|
||||
integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==
|
||||
|
||||
"@esbuild/win32-ia32@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23"
|
||||
integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==
|
||||
"@esbuild/win32-ia32@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b"
|
||||
integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==
|
||||
|
||||
"@esbuild/win32-x64@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc"
|
||||
integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==
|
||||
"@esbuild/win32-x64@0.21.5":
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c"
|
||||
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
|
||||
|
||||
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
|
||||
version "4.4.0"
|
||||
|
|
@ -6494,34 +6494,34 @@ esbuild@^0.14.14:
|
|||
esbuild-windows-64 "0.14.54"
|
||||
esbuild-windows-arm64 "0.14.54"
|
||||
|
||||
esbuild@^0.20.1:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1"
|
||||
integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==
|
||||
esbuild@^0.21.3:
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"
|
||||
integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==
|
||||
optionalDependencies:
|
||||
"@esbuild/aix-ppc64" "0.20.2"
|
||||
"@esbuild/android-arm" "0.20.2"
|
||||
"@esbuild/android-arm64" "0.20.2"
|
||||
"@esbuild/android-x64" "0.20.2"
|
||||
"@esbuild/darwin-arm64" "0.20.2"
|
||||
"@esbuild/darwin-x64" "0.20.2"
|
||||
"@esbuild/freebsd-arm64" "0.20.2"
|
||||
"@esbuild/freebsd-x64" "0.20.2"
|
||||
"@esbuild/linux-arm" "0.20.2"
|
||||
"@esbuild/linux-arm64" "0.20.2"
|
||||
"@esbuild/linux-ia32" "0.20.2"
|
||||
"@esbuild/linux-loong64" "0.20.2"
|
||||
"@esbuild/linux-mips64el" "0.20.2"
|
||||
"@esbuild/linux-ppc64" "0.20.2"
|
||||
"@esbuild/linux-riscv64" "0.20.2"
|
||||
"@esbuild/linux-s390x" "0.20.2"
|
||||
"@esbuild/linux-x64" "0.20.2"
|
||||
"@esbuild/netbsd-x64" "0.20.2"
|
||||
"@esbuild/openbsd-x64" "0.20.2"
|
||||
"@esbuild/sunos-x64" "0.20.2"
|
||||
"@esbuild/win32-arm64" "0.20.2"
|
||||
"@esbuild/win32-ia32" "0.20.2"
|
||||
"@esbuild/win32-x64" "0.20.2"
|
||||
"@esbuild/aix-ppc64" "0.21.5"
|
||||
"@esbuild/android-arm" "0.21.5"
|
||||
"@esbuild/android-arm64" "0.21.5"
|
||||
"@esbuild/android-x64" "0.21.5"
|
||||
"@esbuild/darwin-arm64" "0.21.5"
|
||||
"@esbuild/darwin-x64" "0.21.5"
|
||||
"@esbuild/freebsd-arm64" "0.21.5"
|
||||
"@esbuild/freebsd-x64" "0.21.5"
|
||||
"@esbuild/linux-arm" "0.21.5"
|
||||
"@esbuild/linux-arm64" "0.21.5"
|
||||
"@esbuild/linux-ia32" "0.21.5"
|
||||
"@esbuild/linux-loong64" "0.21.5"
|
||||
"@esbuild/linux-mips64el" "0.21.5"
|
||||
"@esbuild/linux-ppc64" "0.21.5"
|
||||
"@esbuild/linux-riscv64" "0.21.5"
|
||||
"@esbuild/linux-s390x" "0.21.5"
|
||||
"@esbuild/linux-x64" "0.21.5"
|
||||
"@esbuild/netbsd-x64" "0.21.5"
|
||||
"@esbuild/openbsd-x64" "0.21.5"
|
||||
"@esbuild/sunos-x64" "0.21.5"
|
||||
"@esbuild/win32-arm64" "0.21.5"
|
||||
"@esbuild/win32-ia32" "0.21.5"
|
||||
"@esbuild/win32-x64" "0.21.5"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
|
|
@ -14131,12 +14131,12 @@ vite-plugin-ruby@^5.0.0:
|
|||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
|
||||
vite@^5.2.13:
|
||||
version "5.2.13"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.13.tgz#945ababcbe3d837ae2479c29f661cd20bc5e1a80"
|
||||
integrity sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==
|
||||
vite@^5.3.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.3.1.tgz#bb2ca6b5fd7483249d3e86b25026e27ba8a663e6"
|
||||
integrity sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==
|
||||
dependencies:
|
||||
esbuild "^0.20.1"
|
||||
esbuild "^0.21.3"
|
||||
postcss "^8.4.38"
|
||||
rollup "^4.13.0"
|
||||
optionalDependencies:
|
||||
|
|
|
|||
Loading…
Reference in New Issue