Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-08-29 12:12:01 +00:00
parent 1cc5b352a3
commit 9d2ebf5c7a
83 changed files with 9375 additions and 223 deletions

View File

@ -6,7 +6,7 @@ workflow:
include:
- local: .gitlab/ci/version.yml
- component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.21.0"
- component: "gitlab.com/gitlab-org/quality/pipeline-common/allure-report@8.22.0"
inputs:
job_name: "e2e-test-report"
job_stage: "report"
@ -16,7 +16,7 @@ include:
gitlab_auth_token_variable_name: "PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE"
allure_job_name: "${QA_RUN_TYPE}"
- project: gitlab-org/quality/pipeline-common
ref: 8.21.0
ref: 8.22.0
file:
- /ci/base.gitlab-ci.yml
- /ci/knapsack-report.yml

View File

@ -18,4 +18,4 @@ variables:
# Retry failed specs in separate process
QA_RETRY_FAILED_SPECS: "true"
# helm chart ref used by test-on-cng pipeline
GITLAB_HELM_CHART_REF: "e7f459ab671d8fdaecddd34c739e3d53c498bae2"
GITLAB_HELM_CHART_REF: "3466c297acf5efa6de6bdfaa3c12b696041faa02"

View File

@ -71,6 +71,7 @@ export default {
:reviewers="reviewers"
:loading-reviewers="loadingReviewers"
@request-review="(params) => $emit('request-review', params)"
@remove-reviewer="(params) => $emit('remove-reviewer', params)"
/>
<approval-rules-wrapper :reviewers="reviewers" />
</gl-drawer>

View File

@ -83,10 +83,12 @@ export default {
</div>
<uncollapsed-reviewer-list
v-else-if="reviewers.length"
:is-editable="userPermissions.adminMergeRequest"
:root-path="relativeUrlRoot"
:users="reviewers"
issuable-type="merge_request"
@request-review="(params) => $emit('request-review', params)"
@remove-reviewer="(params) => $emit('remove-reviewer', params)"
/>
<gl-empty-state v-else :svg-path="$options.noReviewersAssignedSvg" :svg-height="70">
<template #description>

View File

@ -83,6 +83,7 @@ export default {
<reviewer-drawer
:open="drawerOpen"
@request-review="(params) => $emit('request-review', params)"
@remove-reviewer="(data) => $emit('remove-reviewer', data)"
@close="toggleDrawerOpen(false)"
/>
</mounting-portal>

View File

@ -51,6 +51,9 @@ export default {
requestReview(data) {
this.$emit('request-review', data);
},
removeReviewer(data) {
this.$emit('remove-reviewer', data);
},
},
};
</script>
@ -84,6 +87,7 @@ export default {
:root-path="rootPath"
:issuable-type="issuableType"
@request-review="requestReview"
@remove-reviewer="removeReviewer"
/>
</div>
</div>

View File

@ -5,7 +5,7 @@ import Vue from 'vue';
import { createAlert } from '~/alert';
import { TYPE_ISSUE } from '~/issues/constants';
import { __ } from '~/locale';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { isGid, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { fetchUserCounts } from '~/super_sidebar/user_counts_fetch';
import eventHub from '../../event_hub';
import getMergeRequestReviewersQuery from '../../queries/get_merge_request_reviewers.query.graphql';
@ -166,6 +166,17 @@ export default {
requestReview(data) {
this.mediator.requestReview(data);
},
async removeReviewerById(event) {
const userId = isGid(event.userId) ? getIdFromGraphQLId(event.userId) : event.userId;
this.store.reviewers = this.store.reviewers.filter((user) => user.id !== userId);
try {
await this.saveReviewers();
} catch (error) {
createAlert(__('Unable to remove a reviewer at the moment, try again later'), { error });
} finally {
event.done();
}
},
},
};
</script>
@ -177,6 +188,7 @@ export default {
:loading="isLoading"
:editable="canUpdate"
@request-review="requestReview"
@remove-reviewer="removeReviewerById"
/>
<reviewers
v-if="!initialLoading"
@ -187,6 +199,7 @@ export default {
class="gl-pt-2"
@request-review="requestReview"
@assign-self="reviewBySelf"
@remove-reviewer="removeReviewerById"
/>
</div>
</template>

View File

@ -38,6 +38,7 @@ const REVIEW_STATE_ICONS = {
export default {
i18n: {
reRequestReview: __('Re-request review'),
removeReviewer: s__('MergeRequest|Remove reviewer'),
},
components: {
GlButton,
@ -61,6 +62,11 @@ export default {
required: false,
default: TYPE_ISSUE,
},
isEditable: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
@ -112,7 +118,13 @@ export default {
this.loadingStates[userId] = LOADING_STATE;
this.$emit('request-review', { userId, callback: this.requestReviewComplete });
},
removeReviewer(userId) {
this.loadingStates[userId] = LOADING_STATE;
this.$emit('remove-reviewer', {
userId,
callback: () => this.requestRemovalComplete(userId),
});
},
requestReviewComplete(userId, success) {
if (success) {
this.loadingStates[userId] = SUCCESS_STATE;
@ -124,6 +136,9 @@ export default {
this.loadingStates[userId] = null;
}
},
requestRemovalComplete(userId) {
delete this.loadingStates[userId];
},
reviewStateIcon(user) {
if (user.mergeRequestInteraction.approved) {
return {
@ -201,6 +216,20 @@ export default {
data-testid="reviewer-state-icon"
/>
</span>
<span v-if="isEditable" class="gl-inline-flex gl-h-6 gl-w-6">
<gl-button
v-gl-tooltip.top.viewport
:title="$options.i18n.removeReviewer"
:aria-label="$options.i18n.removeReviewer"
:loading="loadingStates[user.id] === $options.LOADING_STATE"
class="gl-float-right gl-ml-2 !gl-text-subtle"
size="small"
icon="close"
variant="link"
data-testid="remove-request-button"
@click="removeReviewer(user.id)"
/>
</span>
</div>
</div>
</template>

View File

@ -510,6 +510,7 @@ export default {
class="js-assignee gl-mb-5"
:can-update="canUpdate"
:full-path="fullPath"
:is-group="isGroup"
:work-item-id="workItemId"
:assignees="workItemAssignees.assignees.nodes"
:participants="workItemParticipantNodes"
@ -525,6 +526,7 @@ export default {
class="js-labels gl-mb-5"
:can-update="canUpdate"
:full-path="fullPath"
:is-group="isGroup"
:work-item-id="workItemId"
:work-item-iid="workItemIid"
:work-item-type="selectedWorkItemTypeName"

View File

@ -27,7 +27,6 @@ export default {
GlAlert,
},
directives: { SafeHtml },
inject: ['isGroup'],
props: {
value: {
type: Array,
@ -38,6 +37,11 @@ export default {
type: String,
required: true,
},
isGroup: {
type: Boolean,
required: false,
default: false,
},
childrenType: {
type: String,
required: false,

View File

@ -23,7 +23,6 @@ export default {
UncollapsedAssigneeList,
},
mixins: [Tracking.mixin()],
inject: ['isGroup'],
props: {
fullPath: {
type: String,
@ -55,6 +54,11 @@ export default {
required: false,
default: false,
},
isGroup: {
type: Boolean,
required: false,
default: false,
},
participants: {
type: Array,
required: false,

View File

@ -60,6 +60,11 @@ export default {
type: String,
required: true,
},
isGroup: {
type: Boolean,
required: false,
default: false,
},
workItem: {
type: Object,
required: true,
@ -185,6 +190,7 @@ export default {
class="js-assignee gl-mb-5"
:can-update="canUpdate"
:full-path="fullPath"
:is-group="isGroup"
:work-item-id="workItem.id"
:assignees="workItemAssignees.assignees.nodes"
:participants="workItemParticipants"
@ -203,6 +209,7 @@ export default {
class="js-labels gl-mb-5"
:can-update="canUpdate"
:full-path="fullPath"
:is-group="isGroup"
:work-item-id="workItem.id"
:work-item-iid="workItem.iid"
:work-item-type="workItemType"
@ -314,6 +321,7 @@ export default {
:parent="workItemParent"
:has-parent="hasParent"
:group-path="groupPath"
:is-group="isGroup"
@error="$emit('error', $event)"
/>
</template>

View File

@ -7,7 +7,7 @@ import { s__ } from '~/locale';
import { getParameterByName, updateHistory, setUrlParams } from '~/lib/utils/url_utility';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_WORK_ITEM } from '~/graphql_shared/constants';
import { TYPENAME_GROUP, TYPENAME_WORK_ITEM } from '~/graphql_shared/constants';
import { isLoggedIn } from '~/lib/utils/common_utils';
import { WORKSPACE_PROJECT } from '~/issues/constants';
import {
@ -252,6 +252,9 @@ export default {
isDiscussionLocked() {
return this.workItemNotes?.discussionLocked;
},
isGroupWorkItem() {
return this.workItem.namespace?.id.includes(TYPENAME_GROUP);
},
workItemsAlphaEnabled() {
return this.glFeatures.workItemsAlpha;
},
@ -701,6 +704,7 @@ export default {
<work-item-attributes-wrapper
:class="{ 'gl-top-3': isDrawer }"
:full-path="workItemFullPath"
:is-group="isGroupWorkItem"
:work-item="workItem"
:group-path="groupPath"
@error="updateError = $event"
@ -718,6 +722,7 @@ export default {
<work-item-tree
v-if="showWorkItemTree"
:full-path="workItemFullPath"
:is-group="isGroupWorkItem"
:work-item-type="workItemType"
:parent-work-item-type="workItem.workItemType.name"
:work-item-id="workItem.id"
@ -734,6 +739,7 @@ export default {
/>
<work-item-relationships
v-if="workItemLinkedItems"
:is-group="isGroupWorkItem"
:work-item-id="workItem.id"
:work-item-iid="workItemIid"
:work-item-full-path="workItemFullPath"

View File

@ -33,12 +33,17 @@ export default {
WorkItemSidebarDropdownWidget,
},
mixins: [Tracking.mixin()],
inject: ['canAdminLabel', 'isGroup', 'issuesListPath', 'labelsManagePath'],
inject: ['canAdminLabel', 'issuesListPath', 'labelsManagePath'],
props: {
fullPath: {
type: String,
required: true,
},
isGroup: {
type: Boolean,
required: false,
default: false,
},
workItemId: {
type: String,
required: true,

View File

@ -314,6 +314,7 @@ export default {
data-testid="add-links-form"
:full-path="fullPath"
:full-name="workItem.namespace.fullName"
:is-group="false"
:issuable-gid="issuableGid"
:work-item-iid="iid"
:children-ids="childrenIds"

View File

@ -36,12 +36,17 @@ export default {
WorkItemProjectsListbox,
},
mixins: [glFeatureFlagsMixin()],
inject: ['hasIterationsFeature', 'isGroup'],
inject: ['hasIterationsFeature'],
props: {
fullPath: {
type: String,
required: true,
},
isGroup: {
type: Boolean,
required: false,
default: false,
},
issuableGid: {
type: String,
required: false,
@ -450,6 +455,7 @@ export default {
<work-item-token-input
v-model="workItemsToAdd"
:is-create-form="isCreateForm"
:is-group="isGroup"
:parent-work-item-id="issuableGid"
:children-type="childrenType"
:children-ids="childrenIds"

View File

@ -44,6 +44,11 @@ export default {
type: String,
required: true,
},
isGroup: {
type: Boolean,
required: false,
default: false,
},
workItemType: {
type: String,
required: true,
@ -292,6 +297,7 @@ export default {
data-testid="add-tree-form"
:full-path="fullPath"
:full-name="workItemNamespaceName"
:is-group="isGroup"
:issuable-gid="workItemId"
:work-item-iid="workItemIid"
:form-type="formType"

View File

@ -38,7 +38,7 @@ export default {
GlPopover,
WorkItemSidebarDropdownWidget,
},
inject: ['fullPath', 'isGroup'],
inject: ['fullPath'],
props: {
workItemId: {
type: String,
@ -69,6 +69,11 @@ export default {
required: false,
default: false,
},
isGroup: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {

View File

@ -24,6 +24,11 @@ export default {
WorkItemTokenInput,
},
props: {
isGroup: {
type: Boolean,
required: false,
default: false,
},
workItemId: {
type: String,
required: false,
@ -205,6 +210,7 @@ export default {
:children-ids="childrenIds"
:are-work-items-to-add-valid="areWorkItemsToAddValid"
:full-path="workItemFullPath"
:is-group="isGroup"
:max-selection-limit="maxWorkItems"
@searching="searchInProgress = $event"
/>

View File

@ -27,6 +27,11 @@ export default {
WorkItemMoreActions,
},
props: {
isGroup: {
type: Boolean,
required: false,
default: false,
},
workItemId: {
type: String,
required: false,
@ -227,6 +232,7 @@ export default {
<template #form>
<work-item-add-relationship-form
:is-group="isGroup"
:work-item-id="workItemId"
:work-item-iid="workItemIid"
:work-item-full-path="workItemFullPath"

View File

@ -235,7 +235,7 @@
z-index: 1;
position: relative;
padding: $gl-padding-4 0;
&.opened {
color: $green-500;
}
@ -243,7 +243,7 @@
&.closed {
color: $blue-500;
}
svg {
vertical-align: baseline;
}
@ -270,17 +270,17 @@
}
.assignee-grid {
grid-template-areas: ' attention user';
grid-template-areas: 'attention user';
grid-template-columns: min-content 1fr;
}
.reviewer-grid {
grid-template-areas: ' user approval rerequest';
grid-template-columns: 1fr min-content min-content;
grid-template-areas: 'user approval rerequest remove';
grid-template-columns: 1fr;
&.attention-requests {
grid-template-areas: ' attention user approval';
grid-template-columns: min-content 1fr min-content;
grid-template-areas: 'attention user approval remove';
grid-template-columns: auto 1fr;
}
}

View File

@ -8,11 +8,17 @@ module Packages
end
def execute!(package_name, package_version)
project
.packages
.generic
.installable
.by_name_and_version!(package_name, package_version)
if Feature.enabled?(:generic_extract_generic_package_model, Feature.current_request)
Packages::Generic::Package.for_projects(project)
.installable
.by_name_and_version!(package_name, package_version)
else
project
.packages
.generic
.installable
.by_name_and_version!(package_name, package_version)
end
end
private

View File

@ -12,7 +12,16 @@ class ApplicationSetting < ApplicationRecord
ignore_columns %i[repository_storages], remove_with: '16.8', remove_after: '2023-12-21'
ignore_column :required_instance_ci_template, remove_with: '17.1', remove_after: '2024-05-10'
ignore_column :sign_in_text_html, remove_with: '17.5', remove_after: '2024-10-17'
ignore_columns %i[openai_api_key anthropic_api_key vertex_ai_credentials vertex_ai_access_token], remove_with: '17.3', remove_after: '2024-08-15'
ignore_columns %i[
encrypted_openai_api_key
encrypted_openai_api_key_iv
encrypted_anthropic_api_key
encrypted_anthropic_api_key_iv
encrypted_vertex_ai_credentials
encrypted_vertex_ai_credentials_iv
encrypted_vertex_ai_access_token
encrypted_vertex_ai_access_token_iv
], remove_with: '17.5', remove_after: '2024-09-19'
ignore_columns %i[toggle_security_policy_custom_ci lock_toggle_security_policy_custom_ci], remove_with: '17.6', remove_after: '2024-10-17'
INSTANCE_REVIEW_MIN_USERS = 50

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
module Packages
module Generic
class Package < Packages::Package
self.allow_legacy_sti_class = true
after_create_commit :publish_creation_event
validates :name, format: { with: Gitlab::Regex.generic_package_name_regex }
validates :version, presence: true, format: { with: Gitlab::Regex.generic_package_version_regex }
end
end
end

View File

@ -35,7 +35,9 @@ class Packages::Package < ApplicationRecord
belongs_to :project
belongs_to :creator, class_name: 'User'
after_create_commit :publish_creation_event, if: :generic?
# TODO: Remove with the rollout of the FF generic_extract_generic_package_model
# https://gitlab.com/gitlab-org/gitlab/-/issues/479933
after_create_commit :publish_creation_event, if: -> { generic? && Feature.disabled?(:generic_extract_generic_package_model, Feature.current_request) }
# package_files must be destroyed by ruby code in order to properly remove carrierwave uploads and update project statistics
has_many :package_files, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
@ -71,7 +73,10 @@ class Packages::Package < ApplicationRecord
validate :npm_package_already_taken, if: :npm?
# TODO: Remove with the rollout of the FF generic_extract_generic_package_model
# https://gitlab.com/gitlab-org/gitlab/-/issues/479933
validates :name, format: { with: Gitlab::Regex.generic_package_name_regex }, if: :generic?
validates :name, format: { with: Gitlab::Regex.npm_package_name_regex, message: Gitlab::Regex.npm_package_name_regex_message }, if: :npm?
validates :name, format: { with: Gitlab::Regex.nuget_package_name_regex }, if: :nuget?
validates :name, format: { with: Gitlab::Regex.terraform_module_package_name_regex }, if: :terraform_module?
@ -81,6 +86,8 @@ class Packages::Package < ApplicationRecord
validates :version, format: { with: Gitlab::Regex.semver_regex, message: Gitlab::Regex.semver_regex_message },
if: -> { npm? || terraform_module? }
# TODO: Remove with the rollout of the FF generic_extract_generic_package_model
# https://gitlab.com/gitlab-org/gitlab/-/issues/479933
validates :version,
presence: true,
format: { with: Gitlab::Regex.generic_package_version_regex },
@ -183,16 +190,24 @@ class Packages::Package < ApplicationRecord
def self.inheritance_column = 'package_type'
def self.inheritance_column_to_class_map = {
ml_model: 'Packages::MlModel::Package',
golang: 'Packages::Go::Package',
rubygems: 'Packages::Rubygems::Package',
conan: 'Packages::Conan::Package',
rpm: 'Packages::Rpm::Package',
debian: 'Packages::Debian::Package',
composer: 'Packages::Composer::Package',
helm: 'Packages::Helm::Package'
}.freeze
def self.inheritance_column_to_class_map
hash = {
ml_model: 'Packages::MlModel::Package',
golang: 'Packages::Go::Package',
rubygems: 'Packages::Rubygems::Package',
conan: 'Packages::Conan::Package',
rpm: 'Packages::Rpm::Package',
debian: 'Packages::Debian::Package',
composer: 'Packages::Composer::Package',
helm: 'Packages::Helm::Package'
}
if Feature.enabled?(:generic_extract_generic_package_model, Feature.current_request)
hash[:generic] = 'Packages::Generic::Package'
end
hash
end
def self.only_maven_packages_with_path(path, use_cte: false)
if use_cte

View File

@ -54,6 +54,11 @@ class ProjectSetting < ApplicationRecord
Feature.enabled?(:legacy_open_source_license_available, type: :ops)
end
# Checks if a given domain is already assigned to any existing project
def self.unique_domain_exists?(domain)
where(pages_unique_domain: domain).exists?
end
def squash_enabled_by_default?
%w[always default_on].include?(squash_option)
end

View File

@ -39,10 +39,10 @@ module Projects
else
update_failed!
end
rescue ValidationError => e
error(e.message)
rescue ApiError => e
error(e.message, status: :api_error)
rescue ValidationError, Gitlab::Pages::UniqueDomainGenerationFailure => e
error(e.message)
end
def run_auto_devops_pipeline?

View File

@ -0,0 +1,9 @@
---
name: prompt_migration_explain_vulnerability
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/475046
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164210
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/480824
milestone: '17.4'
group: group::custom models
type: experiment
default_enabled: false

View File

@ -0,0 +1,9 @@
---
name: generic_extract_generic_package_model
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/435829
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163477
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/479933
milestone: '17.4'
group: group::package registry
type: gitlab_com_derisk
default_enabled: false

View File

@ -4,6 +4,7 @@ classes:
- Packages::Composer::Package
- Packages::Conan::Package
- Packages::Debian::Package
- Packages::Generic::Package
- Packages::Go::Package
- Packages::Helm::Package
- Packages::MlModel::Package

View File

@ -0,0 +1,12 @@
---
table_name: security_policy_requirements
classes:
- ComplianceManagement::ComplianceFramework::SecurityPolicyRequirement
feature_categories:
- compliance_management
description: Stores the mapping of compliance framework security policies and compliance requirements
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163535
milestone: '17.4'
gitlab_schema: gitlab_main_cell
sharding_key:
namespace_id: namespaces

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class CreateSecurityPolicyRequirements < Gitlab::Database::Migration[2.2]
milestone '17.4'
def change
create_table :security_policy_requirements do |t| # rubocop:disable Migration/EnsureFactoryForTable -- https://gitlab.com/gitlab-org/gitlab/-/issues/468630
t.bigint :compliance_framework_security_policy_id, null: false
t.bigint :compliance_requirement_id, null: false
t.bigint :namespace_id, null: false
t.index :namespace_id
t.index :compliance_requirement_id
t.index [:compliance_framework_security_policy_id, :compliance_requirement_id], unique: true,
name: :uniq_idx_security_policy_requirements_on_requirement_and_policy
end
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddFkToSecurityPolicyRequirementsOnNamespaceId < Gitlab::Database::Migration[2.2]
milestone '17.4'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :security_policy_requirements, :namespaces, column: :namespace_id, on_delete: :cascade,
reverse_lock_order: true
end
def down
with_lock_retries do
remove_foreign_key_if_exists :security_policy_requirements, column: :namespace_id, reverse_lock_order: true
end
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddFkToSecurityPolicyRequirementsOnPolicyId < Gitlab::Database::Migration[2.2]
milestone '17.4'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :security_policy_requirements, :compliance_framework_security_policies,
column: :compliance_framework_security_policy_id, on_delete: :cascade, reverse_lock_order: true
end
def down
with_lock_retries do
remove_foreign_key_if_exists :security_policy_requirements, column: :compliance_framework_security_policy_id,
reverse_lock_order: true
end
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddFkToSecurityPolicyRequirementsOnRequirementId < Gitlab::Database::Migration[2.2]
milestone '17.4'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :security_policy_requirements, :compliance_requirements,
column: :compliance_requirement_id, on_delete: :cascade, reverse_lock_order: true
end
def down
with_lock_retries do
remove_foreign_key_if_exists :security_policy_requirements, column: :compliance_requirement_id,
reverse_lock_order: true
end
end
end

View File

@ -0,0 +1 @@
d4eb4ba8c8e1aff092c54710456eefc6aef515eada1241577c3ff9dbfe2ecc44

View File

@ -0,0 +1 @@
e829816829772abaf14b6a66ebeebd1abd1420da3e56da80152f288e0d4eb160

View File

@ -0,0 +1 @@
9963ffaf6bb629a07340bc4ebf09af6f034be4e408b904dfe889dab340ac9f86

View File

@ -0,0 +1 @@
7e0c29fe5575e2dcc5e24bff41657ea3243f958566187a46d7c51207a1a8265d

View File

@ -17952,6 +17952,22 @@ CREATE SEQUENCE security_policy_project_links_id_seq
ALTER SEQUENCE security_policy_project_links_id_seq OWNED BY security_policy_project_links.id;
CREATE TABLE security_policy_requirements (
id bigint NOT NULL,
compliance_framework_security_policy_id bigint NOT NULL,
compliance_requirement_id bigint NOT NULL,
namespace_id bigint NOT NULL
);
CREATE SEQUENCE security_policy_requirements_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE security_policy_requirements_id_seq OWNED BY security_policy_requirements.id;
CREATE TABLE security_scans (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@ -22158,6 +22174,8 @@ ALTER TABLE ONLY security_policies ALTER COLUMN id SET DEFAULT nextval('security
ALTER TABLE ONLY security_policy_project_links ALTER COLUMN id SET DEFAULT nextval('security_policy_project_links_id_seq'::regclass);
ALTER TABLE ONLY security_policy_requirements ALTER COLUMN id SET DEFAULT nextval('security_policy_requirements_id_seq'::regclass);
ALTER TABLE ONLY security_scans ALTER COLUMN id SET DEFAULT nextval('security_scans_id_seq'::regclass);
ALTER TABLE ONLY security_training_providers ALTER COLUMN id SET DEFAULT nextval('security_training_providers_id_seq'::regclass);
@ -24801,6 +24819,9 @@ ALTER TABLE ONLY security_policies
ALTER TABLE ONLY security_policy_project_links
ADD CONSTRAINT security_policy_project_links_pkey PRIMARY KEY (id);
ALTER TABLE ONLY security_policy_requirements
ADD CONSTRAINT security_policy_requirements_pkey PRIMARY KEY (id);
ALTER TABLE ONLY security_scans
ADD CONSTRAINT security_scans_pkey PRIMARY KEY (id);
@ -30023,6 +30044,10 @@ CREATE UNIQUE INDEX index_security_policy_project_links_on_project_and_policy ON
CREATE INDEX index_security_policy_project_links_on_project_id ON security_policy_project_links USING btree (project_id);
CREATE INDEX index_security_policy_requirements_on_compliance_requirement_id ON security_policy_requirements USING btree (compliance_requirement_id);
CREATE INDEX index_security_policy_requirements_on_namespace_id ON security_policy_requirements USING btree (namespace_id);
CREATE INDEX index_security_scans_for_non_purged_records ON security_scans USING btree (created_at, id) WHERE (status <> 6);
CREATE INDEX index_security_scans_on_created_at ON security_scans USING btree (created_at);
@ -30945,6 +30970,8 @@ CREATE UNIQUE INDEX uniq_idx_packages_packages_on_project_id_name_version_ml_mod
CREATE UNIQUE INDEX uniq_idx_project_compliance_framework_on_project_framework ON project_compliance_framework_settings USING btree (project_id, framework_id);
CREATE UNIQUE INDEX uniq_idx_security_policy_requirements_on_requirement_and_policy ON security_policy_requirements USING btree (compliance_framework_security_policy_id, compliance_requirement_id);
CREATE UNIQUE INDEX uniq_idx_streaming_destination_id_and_namespace_id ON audit_events_streaming_instance_namespace_filters USING btree (external_streaming_destination_id, namespace_id);
CREATE UNIQUE INDEX uniq_idx_streaming_group_destination_id_and_namespace_id ON audit_events_streaming_group_namespace_filters USING btree (external_streaming_destination_id, namespace_id);
@ -33357,6 +33384,9 @@ ALTER TABLE ONLY incident_management_timeline_events
ALTER TABLE ONLY todos
ADD CONSTRAINT fk_45054f9c45 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY security_policy_requirements
ADD CONSTRAINT fk_458f7f5ad5 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY releases
ADD CONSTRAINT fk_47fe2a0596 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@ -33453,6 +33483,9 @@ ALTER TABLE ONLY project_export_jobs
ALTER TABLE ONLY dependency_list_exports
ADD CONSTRAINT fk_5b3d11e1ef FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY security_policy_requirements
ADD CONSTRAINT fk_5b4fae9635 FOREIGN KEY (compliance_requirement_id) REFERENCES compliance_requirements(id) ON DELETE CASCADE;
ALTER TABLE ONLY user_broadcast_message_dismissals
ADD CONSTRAINT fk_5c0cfb74ce FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
@ -33990,6 +34023,9 @@ ALTER TABLE ONLY catalog_resource_versions
ALTER TABLE ONLY bulk_import_entities
ADD CONSTRAINT fk_b69fa2b2df FOREIGN KEY (bulk_import_id) REFERENCES bulk_imports(id) ON DELETE CASCADE;
ALTER TABLE ONLY security_policy_requirements
ADD CONSTRAINT fk_b6e48e3428 FOREIGN KEY (compliance_framework_security_policy_id) REFERENCES compliance_framework_security_policies(id) ON DELETE CASCADE;
ALTER TABLE ONLY compliance_management_frameworks
ADD CONSTRAINT fk_b74c45b71f FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;

View File

@ -17,6 +17,24 @@ LDAP synchronization updates user and group information for existing GitLab user
You can change when synchronization occurs.
## LDAP servers with rate limits
Some LDAP servers have rate limits configured.
GitLab queries the LDAP server once for every:
- User during the scheduled [user sync](#user-sync) process.
- Group during the scheduled [group sync](#group-sync) process.
In some cases, more queries to the LDAP server may be triggered. For example, when a [group sync query returns a `memberuid` attribute](#queries).
If the LDAP server has a rate limit configured and that limit is reached during the:
- User sync process, the LDAP server responds with an error code and GitLab blocks that user.
- Group sync process, the LDAP server responds with an error code and GitLab removes that user's group memberships.
You must consider your LDAP server's rate limits when configuring LDAP synchronization to prevent unwanted user blocks and group membership removals.
## User sync
> - Preventing LDAP user's profile name synchronization [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11336) in GitLab 15.11.
@ -49,6 +67,9 @@ The process also updates the following user information:
- SSH public keys if `sync_ssh_keys` is set.
- Kerberos identity if Kerberos is enabled.
NOTE:
If your LDAP server has a rate limit, that limit might be reached during the user sync process. Check the [rate limit documentation](#ldap-servers-with-rate-limits) for more information.
### Synchronize LDAP user's profile name
By default, GitLab synchronizes the LDAP user's profile name field.
@ -184,6 +205,9 @@ be available to GitLab. For example, `group_base` could be
`ou=groups,dc=example,dc=com`. In the configuration file, it looks like the
following.
NOTE:
If your LDAP server has a rate limit, that limit might be reached during the group sync process. Check the [rate limit documentation](#ldap-servers-with-rate-limits) for more information.
::Tabs
:::TabTitle Linux package (Omnibus)

View File

@ -65,7 +65,7 @@ DETAILS:
**Status:** Beta
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/11180) as an [experiment](../../policy/experiment-beta-support.md#experiment) in GitLab 16.7 with [flags](../../administration/feature_flags.md) named `ci_data_ingestion_to_click_house` and `clickhouse_ci_analytics`. Disabled by default.
> - [Enabled on GitLab.com, self-managed, and GitLab Dedicated](https://gitlab.com/gitlab-org/gitlab/-/issues/424866) in GitLab 16.10. Feature flags `ci_data_ingestion_to_click_house` and `clickhouse_ci_analytics` removed.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/424866) in GitLab 16.10. Feature flags `ci_data_ingestion_to_click_house` and `clickhouse_ci_analytics` removed.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/424789) to [beta](../../policy/experiment-beta-support.md#beta) in GitLab 17.1.
WARNING:

View File

@ -11,8 +11,7 @@ DETAILS:
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
**Status:** Beta
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227345) in
> GitLab 17.3 [with a flag](../../../administration/feature_flags.md) named `jacoco_coverage_reports`. Disabled by default.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227345) in GitLab 17.3 [with a flag](../../../administration/feature_flags.md) named `jacoco_coverage_reports`. Disabled by default.
For JaCoCo coverage reports to work, you must generate a properly formatted [JaCoCo XML file](https://www.jacoco.org/jacoco/trunk/coverage/jacoco.xml)
that provides [line coverage](https://www.eclemma.org/jacoco/trunk/doc/counters.html).

View File

@ -155,6 +155,13 @@ Instead of **agnostic**, use **platform-independent** or **vendor-neutral**.
Use **AI**. Do not spell out **artificial intelligence**.
## AI Impact Dashboard
Use title case for **AI Impact Dashboard**.
On first mention on a page, use **GitLab Duo AI Impact Dashboard**.
Thereafter, use **AI Impact Dashboard** by itself.
## AI-powered DevSecOps platform
If preceded by GitLab, capitalize **Platform**. For example, the GitLab AI-powered DevSecOps Platform.
@ -428,12 +435,12 @@ Example:
- Use code completion to populate the file.
## Code explanation
## Code Explanation
Use sentence case for **Code explanation**.
Use title case for **Code Explanation**.
On first mention on a page, use **GitLab Duo Code explanation**.
Thereafter, use **Code explanation** by itself.
On first mention on a page, use **GitLab Duo Code Explanation**.
Thereafter, use **Code Explanation** by itself.
## code generation
@ -452,12 +459,12 @@ Examples:
- Use code generation to create code based on your comments.
- Adjust your code generation results by adding code comments to your file.
## Code review summary
## Code Review Summary
Use sentence case for **Code review summary**.
Use title case for **Code Review Summary**.
On first mention on a page, use **GitLab Duo Code review summary**.
Thereafter, use **Code review summary** by itself.
On first mention on a page, use **GitLab Duo Code Review Summary**.
Thereafter, use **Code Review Summary** by itself.
## Code Suggestions
@ -672,12 +679,12 @@ Use **inactive** or **off** instead.
Use **prevent** instead of **disallow**. ([Vale](../testing/vale.md) rule: [`Substitutions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab_base/Substitutions.yml))
## Discussion summary
## Discussion Summary
Use sentence case for **Discussion summary**.
Use title case for **Discussion Summary**.
On first mention on a page, use **GitLab Duo Discussion summary**.
Thereafter, use **Discussion summary** by itself.
On first mention on a page, use **GitLab Duo Discussion Summary**.
Thereafter, use **Discussion Summary** by itself.
## Docker-in-Docker, `dind`
@ -967,25 +974,34 @@ Do not use **Dedicated** by itself. Always use **GitLab Dedicated**.
Do not use **Duo** by itself. Always use **GitLab Duo**.
On first use on a page, use **GitLab Duo `<featurename>`**. As of Dec, 2023,
On first use on a page, use **GitLab Duo `<featurename>`**. As of Aug, 2024,
the following are the names of GitLab Duo features:
- GitLab Duo AI Impact Dashboard
- GitLab Duo Chat
- GitLab Duo Code Explanation
- GitLab Duo Code Review Summary
- GitLab Duo Code Suggestions
- GitLab Duo Value stream forecasting
- GitLab Duo Discussion summary
- GitLab Duo Merge request summary
- GitLab Duo Code review summary
- GitLab Duo Code explanation
- GitLab Duo Vulnerability explanation
- GitLab Duo Vulnerability resolution
- GitLab Duo Test generation
- GitLab Duo for the CLI
- GitLab Duo Root cause analysis
- GitLab Duo Issue description generation
- GitLab Duo Issue Description Generation
- GitLab Duo Issue Discussion Summary
- GitLab Duo Merge Commit Message Generation
- GitLab Duo Merge Request Summary
- GitLab Duo Product Analytics
- GitLab Duo Root Cause Analysis
- GitLab Duo Test Generation
- GitLab Duo Vulnerability Explanation
- GitLab Duo Vulnerability Resolution
After the first use, use the feature name without **GitLab Duo**.
## GitLab Duo Enterprise
Always use **GitLab Duo Enterprise** for the add-on. Do not use **Duo Enterprise** unless approved by legal.
You can use **the GitLab Duo Enterprise add-on** (with this capitalization) but you do not need to use **add-on**
and should leave it off when you can.
## GitLab Duo Pro
Always use **GitLab Duo Pro** for the add-on. Do not use **Duo Pro** unless approved by legal.
@ -1171,12 +1187,19 @@ Use lowercase for **issue**.
Use lowercase for **issue board**.
## Issue description generation
## Issue Description Generation
Use sentence case for **Issue description generation**.
Use title case for **Issue Description Generation**.
On first mention on a page, use **GitLab Duo Issue description generation**.
Thereafter, use **Issue description generation** by itself.
On first mention on a page, use **GitLab Duo Issue Description Generation**.
Thereafter, use **Issue Description Generation** by itself.
## Issue Discussion Summary
Use title case for **Issue Discussion Summary**.
On first mention on a page, use **GitLab Duo Issue Discussion Summary**.
Thereafter, use **Issue Discussion Summary** by itself.
## issue weights
@ -1387,6 +1410,13 @@ For **MB** and **GB**, follow the [Microsoft guidance](https://learn.microsoft.c
When you add a [user account](#user-account) to a group or project,
the user account becomes a **member**.
## Merge Commit Message Generation
Use title case for **Merge Commit Message Generation**.
On first mention on a page, use **GitLab Duo Merge Commit Message Generation**.
Thereafter, use **Merge Commit Message Generation** by itself.
## merge request branch
Do not use **merge request branch**. See [branch](#branch).
@ -1395,12 +1425,12 @@ Do not use **merge request branch**. See [branch](#branch).
Use lowercase for **merge requests**. If you use **MR** as the acronym, spell it out on first use.
## Merge request summary
## Merge Request Summary
Use sentence case for **Merge request summary**.
Use title case for **Merge Request Summary**.
On first mention on a page, use **GitLab Duo Merge request summary**.
Thereafter, use **Merge request summary** by itself.
On first mention on a page, use **GitLab Duo Merge Request Summary**.
Thereafter, use **Merge Request Summary** by itself.
## milestones
@ -1829,12 +1859,12 @@ There are two types of roles: [custom](#custom-role) and [default](#default-role
Roles are not the same as [**access levels**](#access-level).
## Root cause analysis
## Root Cause Analysis
Use sentence case for **Root cause analysis**.
Use title case for **Root Cause Analysis**.
On first mention on a page, use **GitLab Duo Root cause analysis**.
Thereafter, use **Root cause analysis** by itself.
On first mention on a page, use **GitLab Duo Root Cause Analysis**.
Thereafter, use **Root Cause Analysis** by itself.
## roll back
@ -2110,12 +2140,12 @@ talking about non-specific modules. For example:
- You can publish a Terraform module to your project's Terraform Module Registry.
## Test generation
## Test Generation
Use sentence case for **Test generation**.
Use title case for **Test Generation**.
On first mention on a page, use **GitLab Duo Test generation**.
Thereafter, use **Test generation** by itself.
On first mention on a page, use **GitLab Duo Test Generation**.
Thereafter, use **Test Generation** by itself.
## text box
@ -2272,12 +2302,6 @@ For example:
Do not use **utilize**. Use **use** instead. It's more succinct and easier for non-native English speakers to understand.
([Vale](../testing/vale.md) rule: [`SubstitutionWarning.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab_base/SubstitutionWarning.yml))
## Value stream forecasting
Use sentence case for **Value stream forecasting**. On first mention on a page, use **GitLab Duo Value stream forecasting**.
Thereafter, use **Value stream forecasting** by itself.
## version, v
To describe versions of GitLab, use **GitLab `<version number>`**. For example:
@ -2297,19 +2321,19 @@ Pay attention to spacing by the letter **v**. In semantic versioning, no space e
Do not use Latin abbreviations. Use **with**, **through**, or **by using** instead. ([Vale](../testing/vale.md) rule: [`LatinTerms.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab_base/LatinTerms.yml))
## Vulnerability resolution
## Vulnerability Explanation
Use sentence case for **Vulnerability resolution**.
Use title case for **Vulnerability Explanation**.
On first mention on a page, use **GitLab Duo Vulnerability resolution**.
Thereafter, use **Vulnerability resolution** by itself.
On first mention on a page, use **GitLab Duo Vulnerability Explanation**.
Thereafter, use **Vulnerability Explanation** by itself.
## Vulnerability explanation
## Vulnerability Resolution
Use sentence case for **Vulnerability explanation**.
Use title case for **Vulnerability Resolution**.
On first mention on a page, use **GitLab Duo Vulnerability explanation**.
Thereafter, use **Vulnerability explanation** by itself.
On first mention on a page, use **GitLab Duo Vulnerability Resolution**.
Thereafter, use **Vulnerability Resolution** by itself.
## we

View File

@ -92,7 +92,7 @@ To add more languages to Code Suggestions:
1. On the top bar, go to **Code > Settings > Extensions**.
1. Search for **GitLab Workflow** in the list, then select **Manage** (**{settings}**) **> Extension Settings**.
1. In your **User** settings, find
**GitLab Ai Assisted Code Suggestions: Additional Languages** and select **Add Item**.
**GitLab Duo Code Suggestions: Additional Languages** and select **Add Item**.
1. In **Item**, add the language identifier, and select **OK**.
## Integrate with GitLab

View File

@ -85,3 +85,23 @@ To request a limit increase to 1,048,576 bytes per minute, contact GitLab suppor
## Data retention
GitLab has a retention limit of 30 days for all traces.
## Create an issue for a trace
You can create an issue to track any action taken to resolve or investigate a trace. To create an issue for a trace:
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Monitor > Traces**.
1. From the list of traces, select a trace.
1. Select **Create issue**.
The issue is created in the selected project and pre-filled with information from the trace.
You can edit the issue title and description.
## View issues related to a trace
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Monitor > Traces**.
1. From the list of traces, select a trace.
1. Scroll to **Related issues**.
1. Optional. To view the issue details, select an issue.

View File

@ -78,7 +78,7 @@ You are automatically enrolled in quarterly reconciliation if:
You are excluded from quarterly reconciliation if you:
- Purchased your subscription from a reseller or another channel partner.
- Purchased a multi-year subscription.
- Purchased a subscription that is not a 12-month term (includes multi-year and non-standard length subscriptions).
- Purchased your subscription with a purchasing order.
- Are a public sector customer.
- Have an offline environment and used a license file to activate your subscription.
@ -91,12 +91,9 @@ If you are excluded from quarterly reconciliation and not on a free tier, your t
### Failed payment
If your credit card is declined during the reconciliation process, you receive an email with the subject `Your GitLab subscription failed to reconcile`.
To resolve this issue, you must [update your payment information](customers_portal.md#set-a-default-payment-method).
If your credit card is declined during the reconciliation process, you receive an email with the subject `Action required: Your GitLab subscription failed to reconcile`. To resolve this issue, you must:
1. Sign in to your account at `https://customers.gitlab.com`.
1. On the left sidebar, select **Billing account settings**.
1. Under **Payment methods**, select **Add new payment method**.
1. To mark the new payment method as default, select **Edit** > **Default**.
1. [Update your payment information](customers_portal.md#change-your-payment-method).
1. [Set your chosen payment method as default](customers_portal.md#set-a-default-payment-method).
When the payment method is updated, reconciliation is retried automatically.

View File

@ -574,28 +574,28 @@ To add another contact for your subscription, see [Add a secondary contact](../c
## Subscription expiry
When your license expires, GitLab locks down features, like Git pushes
and issue creation. Then, your instance becomes read-only and
an expiration message is displayed to all administrators.
Licenses expire at the start of the expiration date, 00:00 server time.
For GitLab self-managed instances, you have a 14-day grace period
before this occurs.
When your license expires, after a 14 day grace period:
For example, if a license has a start date of January 1, 2024 and an end date of January 1, 2025:
- Your instance becomes read-only.
- GitLab locks features, such as Git pushes and issue creation.
- An expiration message is displayed to all administrators.
For example, if a license has an expiry date of January 1, 2025:
- It expires at 11:59:59 PM server time December 31, 2024.
- It is considered expired from 12:00:00 AM server time January 1, 2025.
- The grace period of 14 days starts at 12:00:00 AM server time January 1, 2025 and ends at 11:59:59 PM server time January 14, 2025.
- The grace period of 14 days starts at 12:00:00 AM server time January 1, 2025
and ends at 11:59:59 PM server time January 14, 2025.
- Your instance becomes read-only at 12:00:00 AM server time January 15, 2025.
- To resume functionality, activate a new license.
- To fall back to Free features, delete the expired license.
After your license has expired:
## Activate a license file or key
If you have a license file or key, you can activate it [in the **Admin** area](../../administration/license_file.md#activate-gitlab-ee-with-a-license-file-or-key).
- To resume functionality,
[activate a new license](../../administration/license_file.md#activate-gitlab-ee-with-a-license-file-or-key).
- To keep using Free tier features only,
[delete the expired license](../../administration/license_file.md#remove-a-license).
## Storage

View File

@ -297,9 +297,8 @@ DETAILS:
**Tier:** Ultimate
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211387) in GitLab 13.5.
> Expanded to include additional passthrough types of `file` and `raw` in GitLab 14.6.
> - [Enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/235359) support for overriding rules in
> GitLab 14.8.
> - Expanded to include additional passthrough types of `file` and `raw` in GitLab 14.6.
> - [Enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/235359) support for overriding rules in GitLab 14.8.
> - [Enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/336395) support for passthrough chains and included additional passthrough types of `git` and `url` in GitLab 17.2.
You can customize the behavior of pipeline secret detection by [creating a ruleset configuration file](#create-a-ruleset-configuration-file),

View File

@ -11,8 +11,7 @@ DETAILS:
**Offering:** GitLab.com
**Status:** Beta
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141127) in GitLab 16.10 [with a flag](../../../administration/feature_flags.md) named
`google_cloud_support_feature_flag`. This feature is in [beta](../../../policy/experiment-beta-support.md).
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141127) in GitLab 16.10 [with a flag](../../../administration/feature_flags.md) named `google_cloud_support_feature_flag`. This feature is in [beta](../../../policy/experiment-beta-support.md).
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150472) in GitLab 17.1. Feature flag `google_cloud_support_feature_flag` removed.
This feature is in [beta](../../../policy/experiment-beta-support.md).
@ -127,7 +126,7 @@ list-images:
```yaml
list-images:
image:
image:
name: gcr.io/go-containerregistry/crane:debug
entrypoint: [""]
identity: google_cloud
@ -209,7 +208,7 @@ copy-image:
```yaml
copy-image:
image:
image:
name: gcr.io/go-containerregistry/crane:debug
entrypoint: [""]
identity: google_cloud

View File

@ -182,7 +182,7 @@ Prerequisites:
from the Visual Studio Marketplace.
1. Configure the extension following the
[setup instructions](https://gitlab.com/gitlab-org/gitlab-vscode-extension#extension-settings).
1. Enable the feature by toggling the `gitlab.aiAssistedCodeSuggestions.enabledSupportedLanguages` setting.
1. Enable the feature by toggling the `gitlab.duoCodeSuggestions.enabledSupportedLanguages` setting.
:::TabTitle JetBrains IDEs

View File

@ -41,7 +41,7 @@ If you are a self-managed user, ensure that Code Suggestions for the [GitLab Web
1. On the left sidebar, select **Extensions > GitLab Workflow**.
1. Select **Settings** (**{settings}**), and then select **Extension Settings**.
1. In **GitLab > AI Assisted Code Suggestions**, select the **GitLab Duo Code Suggestions**
1. In **GitLab > Duo Code Suggestions**, select the **GitLab Duo Code Suggestions**
checkbox.
### View Code Suggestions logs

View File

@ -43,7 +43,7 @@ module Gitlab
override :validate_regex
def validate_regex(value, default)
return unless spec.key?(:regex)
return unless spec.key?(:regex) && value.is_a?(String)
safe_regex = ::Gitlab::UntrustedRegexp.new(spec[:regex])

View File

@ -7,14 +7,14 @@ module Gitlab
module Validators
class SchemaValidator
SUPPORTED_VERSIONS = {
cluster_image_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
container_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
coverage_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
dast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
api_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
dependency_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
sast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0],
secret_detection: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0]
cluster_image_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1],
container_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1],
coverage_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1],
dast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1],
api_fuzzing: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1],
dependency_scanning: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1],
sast: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1],
secret_detection: %w[15.0.0 15.0.1 15.0.2 15.0.4 15.0.5 15.0.6 15.0.7 15.1.0 15.1.1 15.1.2 15.1.3 15.1.4 15.2.0 15.2.1]
}.freeze
VERSIONS_TO_REMOVE_IN_18_0 = %w[].freeze

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,12 @@ module Gitlab
include JwtAuthenticatable
class UniqueDomainGenerationFailure < StandardError
def initialize(msg = "Can't generate unique domain for GitLab Pages")
super(msg)
end
end
class << self
def verify_api_request(request_headers)
decode_jwt(request_headers[INTERNAL_API_REQUEST_HEADER], issuer: 'gitlab-pages')
@ -35,9 +41,7 @@ module Gitlab
return if project.project_setting.pages_unique_domain_in_database.present?
project.project_setting.pages_unique_domain_enabled = true
project.project_setting.pages_unique_domain = Gitlab::Pages::RandomDomain.generate(
project_path: project.path,
namespace_path: project.parent.full_path)
project.project_setting.pages_unique_domain = generate_unique_domain(project)
end
def multiple_versions_enabled_for?(project)
@ -47,6 +51,17 @@ module Gitlab
project.licensed_feature_available?(:pages_multiple_versions) &&
project.project_setting.pages_multiple_versions_enabled
end
private
def generate_unique_domain(project)
10.times do
pages_unique_domain = Gitlab::Pages::RandomDomain.generate(project_path: project.path)
return pages_unique_domain unless ProjectSetting.unique_domain_exists?(pages_unique_domain)
end
raise UniqueDomainGenerationFailure
end
end
end
end

View File

@ -3,41 +3,27 @@
module Gitlab
module Pages
class RandomDomain
PROJECT_PATH_LIMIT = 48
SUBDOMAIN_LABEL_LIMIT = 63
PROJECT_PATH_LIMIT = 56
def self.generate(project_path:, namespace_path:)
new(project_path: project_path, namespace_path: namespace_path).generate
def self.generate(project_path:)
new(project_path: project_path).generate
end
def initialize(project_path:, namespace_path:)
def initialize(project_path:)
@project_path = project_path
@namespace_path = namespace_path
end
# Subdomains have a limit of 63 bytes (https://www.freesoft.org/CIE/RFC/1035/9.htm)
# For this reason we're limiting each part of the unique subdomain
#
# The domain is made up of 3 parts, like: projectpath-namespacepath-randomstring
# - project path: between 1 and 48 chars
# - namespace path: when the project path has less than 48 chars,
# the namespace full path will be used to fill the value up to 48 chars
# - random hexadecimal: to ensure a random value, the domain is then filled
# with a random hexadecimal value to complete 63 chars
# The domain is made up of 2 parts, like: projectpath-randomstring
# - project path: between 1 and 56 chars
# - random hexadecimal: to ensure a random value of length 6
def generate
domain = project_path.byteslice(0, PROJECT_PATH_LIMIT)
# if the project_path has less than PROJECT_PATH_LIMIT chars,
# fill the domain with the parent full_path up to 48 chars like:
# projectpath-namespacepath
if domain.length < PROJECT_PATH_LIMIT
namespace_size = PROJECT_PATH_LIMIT - domain.length - 1
domain.concat('-', namespace_path.byteslice(0, namespace_size))
end
# Complete the domain with random hexadecimal values util it is 63 chars long
# PS.: SecureRandom.hex return an string twice the size passed as argument.
domain.concat('-', SecureRandom.hex(SUBDOMAIN_LABEL_LIMIT - domain.length - 1))
domain.concat('-', SecureRandom.hex(3))
# Slugify ensures the format and size (63 chars) of the given string
Gitlab::Utils.slugify(domain)
@ -45,7 +31,7 @@ module Gitlab
private
attr_reader :project_path, :namespace_path
attr_reader :project_path
end
end
end

View File

@ -33730,6 +33730,9 @@ msgstr ""
msgid "MergeRequest|No files found"
msgstr ""
msgid "MergeRequest|Remove reviewer"
msgstr ""
msgid "MergeRequest|Reviewed by @%{username} but not yet approved"
msgstr ""
@ -56711,7 +56714,10 @@ msgstr ""
msgid "Tracing|Tracing"
msgstr ""
msgid "Tracing|View Logs"
msgid "Tracing|View logs"
msgstr ""
msgid "Tracing|View metrics"
msgstr ""
msgid "Tracing|You must select a Service and Operation first."
@ -57334,6 +57340,9 @@ msgstr ""
msgid "Unable to parse the vulnerability report's options."
msgstr ""
msgid "Unable to remove a reviewer at the moment, try again later"
msgstr ""
msgid "Unable to save iteration. Please try again"
msgstr ""

View File

@ -3,7 +3,7 @@
source 'https://rubygems.org'
gem 'gitlab-qa', '~> 14', '>= 14.13.0', require: 'gitlab/qa'
gem 'gitlab_quality-test_tooling', '~> 1.34.0', require: false
gem 'gitlab_quality-test_tooling', '~> 1.35.0', require: false
gem 'gitlab-utils', path: '../gems/gitlab-utils'
gem 'activesupport', '~> 7.0.8.4' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.25.0'

View File

@ -131,7 +131,7 @@ GEM
rainbow (>= 3, < 4)
table_print (= 1.5.7)
zeitwerk (>= 2, < 3)
gitlab_quality-test_tooling (1.34.0)
gitlab_quality-test_tooling (1.35.0)
activesupport (>= 7.0, < 7.2)
amatch (~> 0.4.1)
gitlab (~> 4.19)
@ -377,7 +377,7 @@ DEPENDENCIES
gitlab-cng!
gitlab-qa (~> 14, >= 14.13.0)
gitlab-utils!
gitlab_quality-test_tooling (~> 1.34.0)
gitlab_quality-test_tooling (~> 1.35.0)
googleauth (~> 1.9.0)
influxdb-client (~> 3.1)
junit_merge (~> 0.1.2)

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
FactoryBot.define do
factory :generic_package, class: 'Packages::Generic::Package', parent: :package do
sequence(:name) { |n| "generic-package-#{n}" }
version { '1.0.0' }
package_type { :generic }
trait(:with_zip_file) do
package_files do
[association(:package_file, :generic_zip, package: instance)]
end
end
end
end

View File

@ -139,7 +139,9 @@ FactoryBot.define do
end
end
factory :generic_package do
# TODO: Remove with the rollout of the FF generic_extract_generic_package_model
# https://gitlab.com/gitlab-org/gitlab/-/issues/479933
factory :generic_package_legacy do
sequence(:name) { |n| "generic-package-#{n}" }
version { '1.0.0' }
package_type { :generic }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Packages::Generic::PackageFinder do
RSpec.describe ::Packages::Generic::PackageFinder, feature_category: :package_registry do
let_it_be(:project) { create(:project) }
let_it_be(:package) { create(:generic_package, project: project) }
@ -34,5 +34,27 @@ RSpec.describe ::Packages::Generic::PackageFinder do
expect { finder.execute!(package.name, '3.1.4') }
.to raise_error(ActiveRecord::RecordNotFound)
end
context 'when generic_extract_generic_package_model is disabled' do
let_it_be(:package) { create(:generic_package_legacy, project: project, name: FFaker::Lorem.word) }
before do
stub_feature_flags(generic_extract_generic_package_model: false)
end
it 'finds package by name and version' do
found_package = finder.execute!(package.name, package.version)
expect(found_package).to eq(package)
end
it 'ignores packages with same name but different version' do
create(:generic_package_legacy, project: project, name: package.name, version: '3.1.4')
found_package = finder.execute!(package.name, package.version)
expect(found_package).to eq(package)
end
end
end
end

View File

@ -65,7 +65,6 @@ describe('Create work item component', () => {
const createComponent = ({
props = {},
isGroup = false,
mutationHandler = createWorkItemSuccessHandler,
singleWorkItemType = false,
workItemTypeName = WORK_ITEM_TYPE_ENUM_EPIC,
@ -97,7 +96,6 @@ describe('Create work item component', () => {
},
provide: {
fullPath: 'full-path',
isGroup,
hasIssuableHealthStatusFeature: false,
},
});

View File

@ -80,14 +80,12 @@ describe('WorkItemTokenInput', () => {
[groupWorkItemsQuery, groupSearchedWorkItemResolver],
[workItemsByReferencesQuery, workItemReferencesQueryResolver],
]),
provide: {
isGroup,
},
propsData: {
value: workItemsToAdd,
childrenType,
childrenIds: [],
fullPath: 'test-project-path',
isGroup,
parentWorkItemId: 'gid://gitlab/WorkItem/1',
parentConfidential,
areWorkItemsToAddValid,

View File

@ -78,9 +78,6 @@ describe('WorkItemAssignees component', () => {
]);
wrapper = mountFn(WorkItemAssignees, {
provide: {
isGroup: false,
},
propsData: {
assignees,
fullPath: 'test-project-path',

View File

@ -70,11 +70,6 @@ describe('WorkItemAttributesWrapper component', () => {
groupPath,
},
provide: {
hasIssueWeightsFeature: true,
hasIterationsFeature: true,
hasOkrsFeature: true,
hasIssuableHealthStatusFeature: true,
projectNamespace: 'namespace',
hasSubepicsFeature: true,
glFeatures: {
workItemsBeta,

View File

@ -99,7 +99,6 @@ describe('WorkItemDetail component', () => {
const findDetailWrapper = () => wrapper.findByTestId('detail-wrapper');
const createComponent = ({
isGroup = false,
isModal = false,
isDrawer = false,
updateInProgress = false,
@ -142,15 +141,9 @@ describe('WorkItemDetail component', () => {
workItemsBeta,
namespaceLevelWorkItems,
},
hasIssueWeightsFeature: true,
hasIterationsFeature: true,
hasOkrsFeature: true,
hasSubepicsFeature,
hasIssuableHealthStatusFeature: true,
projectNamespace: 'namespace',
fullPath: 'group/project',
groupPath: 'group',
isGroup,
reportAbusePath: '/report/abuse/path',
},
stubs: {

View File

@ -82,7 +82,6 @@ describe('WorkItemLabels component', () => {
]),
provide: {
canAdminLabel: true,
isGroup,
issuesListPath: 'test-project-path/issues',
labelsManagePath: 'test-project-path/labels',
},
@ -91,6 +90,7 @@ describe('WorkItemLabels component', () => {
workItemIid,
canUpdate,
fullPath: 'test-project-path',
isGroup,
workItemType: 'Task',
},
});

View File

@ -93,6 +93,7 @@ describe('WorkItemLinksForm', () => {
]),
propsData: {
fullPath: 'group-a',
isGroup,
issuableGid: 'gid://gitlab/WorkItem/1',
parentConfidential,
parentIteration,
@ -105,7 +106,6 @@ describe('WorkItemLinksForm', () => {
},
provide: {
hasIterationsFeature,
isGroup,
},
stubs: {
GlFormGroup: stubComponent(GlFormGroup, {

View File

@ -62,7 +62,6 @@ describe('WorkItemParent component', () => {
parent = null,
searchQueryHandler = availableWorkItemsSuccessHandler,
mutationHandler = successUpdateWorkItemMutationHandler,
isGroup = false,
hasParent = true,
} = {}) => {
wrapper = mountExtended(WorkItemParent, {
@ -74,7 +73,6 @@ describe('WorkItemParent component', () => {
]),
provide: {
fullPath: mockFullPath,
isGroup,
},
propsData: {
canUpdate,

View File

@ -34,9 +34,6 @@ describe('WorkItemAddRelationshipForm', () => {
wrapper = shallowMountExtended(WorkItemAddRelationshipForm, {
apolloProvider: mockApolloProvider,
provide: {
isGroup: false,
},
propsData: {
workItemId,
workItemIid,

View File

@ -421,6 +421,18 @@ RSpec.describe Gitlab::Ci::Config::Interpolation::Inputs, feature_category: :pip
end
end
context 'when given a value that is not a string' do
let(:specs) { { test_input: { regex: '^input_value$' } } }
let(:args) { { test_input: 999 } }
it 'is invalid' do
expect(inputs).not_to be_valid
expect(inputs.errors).to contain_exactly(
'`test_input` input: provided value is not a string'
)
end
end
context 'when the pattern is unsafe' do
let(:specs) { { test_input: { regex: 'a++' } } }
let(:args) { { test_input: 'aaaaaaaaaaaaaaaaaaaaa' } }

View File

@ -3,10 +3,8 @@
require 'spec_helper'
RSpec.describe Gitlab::Pages::RandomDomain, feature_category: :pages do
let(:namespace_path) { 'namespace' }
subject(:generator) do
described_class.new(project_path: project_path, namespace_path: namespace_path)
described_class.new(project_path: project_path)
end
RSpec.shared_examples 'random domain' do |domain|
@ -14,31 +12,30 @@ RSpec.describe Gitlab::Pages::RandomDomain, feature_category: :pages do
expect(SecureRandom)
.to receive(:hex)
.and_wrap_original do |_, size, _|
('h' * size)
('h' * size * 2)
end
generated = generator.generate
expect(generated).to eq(domain)
expect(generated.length).to eq(63)
end
end
context 'when project path is less than 48 chars' do
let(:project_path) { 'p' }
it_behaves_like 'random domain', 'p-namespace-hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh'
it_behaves_like 'random domain', 'p-hhhhhh'
end
context 'when project path is close to 48 chars' do
let(:project_path) { 'p' * 45 }
let(:project_path) { 'p' * 56 }
it_behaves_like 'random domain', 'ppppppppppppppppppppppppppppppppppppppppppppp-na-hhhhhhhhhhhhhh'
it_behaves_like 'random domain', 'pppppppppppppppppppppppppppppppppppppppppppppppppppppppp-hhhhhh'
end
context 'when project path is larger than 48 chars' do
let(:project_path) { 'p' * 49 }
let(:project_path) { 'p' * 57 }
it_behaves_like 'random domain', 'pppppppppppppppppppppppppppppppppppppppppppppppp-hhhhhhhhhhhhhh'
it_behaves_like 'random domain', 'pppppppppppppppppppppppppppppppppppppppppppppppppppppppp-hhhhhh'
end
end

View File

@ -131,6 +131,36 @@ RSpec.describe Gitlab::Pages, feature_category: :pages do
expect(project.project_setting.pages_unique_domain).to eq('unique-domain')
end
end
context 'when a unique domain is already in use and needs to generate a new one' do
it 'generates a different unique domain if the original is already taken' do
allow(Gitlab::Pages::RandomDomain).to receive(:generate).and_return('existing-domain', 'new-unique-domain')
# Simulate the existing domain being in use
create(:project_setting, pages_unique_domain: 'existing-domain')
described_class.add_unique_domain_to(project)
expect(project.project_setting.pages_unique_domain_enabled).to eq(true)
expect(project.project_setting.pages_unique_domain).to eq('new-unique-domain')
end
end
context 'when generated 10 unique domains are already in use' do
it 'raises an error' do
allow(Gitlab::Pages::RandomDomain).to receive(:generate).and_return('existing-domain')
# Simulate the existing domain being in use
create(:project_setting, pages_unique_domain: 'existing-domain')
expect { described_class.add_unique_domain_to(project) }.to raise_error(
described_class::UniqueDomainGenerationFailure,
"Can't generate unique domain for GitLab Pages"
)
expect(project.project_setting.pages_unique_domain).to be_nil
end
end
end
end
end

View File

@ -0,0 +1,63 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Packages::Generic::Package, type: :model, feature_category: :package_registry do
describe 'validations' do
describe '#name' do
it { is_expected.to allow_value('123').for(:name) }
it { is_expected.to allow_value('foo').for(:name) }
it { is_expected.to allow_value('foo.bar.baz-2.0-20190901.47283-1').for(:name) }
it { is_expected.not_to allow_value('../../foo').for(:name) }
it { is_expected.not_to allow_value('..\..\foo').for(:name) }
it { is_expected.not_to allow_value('%2f%2e%2e%2f%2essh%2fauthorized_keys').for(:name) }
it { is_expected.not_to allow_value('$foo/bar').for(:name) }
it { is_expected.not_to allow_value('my file name').for(:name) }
it { is_expected.not_to allow_value('!!().for(:name)().for(:name)').for(:name) }
end
describe '#version' do
it { is_expected.to validate_presence_of(:version) }
it { is_expected.to allow_value('1.2.3').for(:version) }
it { is_expected.to allow_value('1.3.350').for(:version) }
it { is_expected.to allow_value('1.3.350-20201230123456').for(:version) }
it { is_expected.to allow_value('1.2.3-rc1').for(:version) }
it { is_expected.to allow_value('1.2.3g').for(:version) }
it { is_expected.to allow_value('1.2').for(:version) }
it { is_expected.to allow_value('1.2.bananas').for(:version) }
it { is_expected.to allow_value('v1.2.4-build').for(:version) }
it { is_expected.to allow_value('d50d836eb3de6177ce6c7a5482f27f9c2c84b672').for(:version) }
it { is_expected.to allow_value('this_is_a_string_only').for(:version) }
it { is_expected.not_to allow_value('..1.2.3').for(:version) }
it { is_expected.not_to allow_value(' 1.2.3').for(:version) }
it { is_expected.not_to allow_value("1.2.3 \r\t").for(:version) }
it { is_expected.not_to allow_value("\r\t 1.2.3").for(:version) }
it { is_expected.not_to allow_value('1.2.3-4/../../').for(:version) }
it { is_expected.not_to allow_value('1.2.3-4%2e%2e%').for(:version) }
it { is_expected.not_to allow_value('../../../../../1.2.3').for(:version) }
it { is_expected.not_to allow_value('%2e%2e%2f1.2.3').for(:version) }
it { is_expected.not_to allow_value('').for(:version) }
it { is_expected.not_to allow_value(nil).for(:version) }
end
end
describe '#publish_creation_event' do
let_it_be(:project) { create(:project) }
let(:version) { '-' }
subject(:create_package) { described_class.create!(project: project, name: 'incoming', version: version) }
it 'publishes an event' do
expect { create_package }
.to publish_event(::Packages::PackageCreatedEvent)
.with({
project_id: project.id,
id: kind_of(Numeric),
name: 'incoming',
version: '-',
package_type: 'generic'
})
end
end
end

View File

@ -111,6 +111,8 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
it { is_expected.to allow_value("my.app-11.07.2018").for(:name) }
it { is_expected.not_to allow_value("my(dom$$$ain)com.my-app").for(:name) }
# TODO: Remove with the rollout of the FF generic_extract_generic_package_model
# https://gitlab.com/gitlab-org/gitlab/-/issues/479933
context 'generic package' do
subject { build_stubbed(:generic_package) }
@ -262,6 +264,8 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
it { is_expected.not_to allow_value('%2e%2e%2f1.2.3').for(:version) }
end
# TODO: Remove with the rollout of the FF generic_extract_generic_package_model
# https://gitlab.com/gitlab-org/gitlab/-/issues/479933
context 'generic package' do
subject { build_stubbed(:generic_package) }
@ -1173,34 +1177,65 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
it { is_expected.to eq(normalized_version) }
end
describe "#publish_creation_event" do
describe '#publish_creation_event' do
let_it_be(:project) { create(:project) }
let(:version) { '-' }
let(:package_type) { :generic }
let(:package) { build_stubbed(:generic_package) }
subject { described_class.create!(project: project, name: 'incoming', version: version, package_type: package_type) }
context 'when package is generic' do
it 'publishes an event' do
expect { subject }
.to publish_event(::Packages::PackageCreatedEvent)
.with({
project_id: project.id,
id: kind_of(Numeric),
name: "incoming",
version: "-",
package_type: 'generic'
})
end
it 'publishes an event' do
expect { package.publish_creation_event }
.to publish_event(::Packages::PackageCreatedEvent)
.with({
project_id: package.project_id,
id: package.id,
name: package.name,
version: package.version,
package_type: package.package_type
})
end
context 'when package is not generic' do
let(:package_type) { :debian }
let(:version) { 1 }
# TODO: Remove with the rollout of the FF generic_extract_generic_package_model
# https://gitlab.com/gitlab-org/gitlab/-/issues/479933
context 'with after_create_commit callback' do
let(:name) { FFaker::Lorem.word }
let(:version) { '1.0.0' }
it 'does not create event' do
expect { subject }.not_to publish_event(::Packages::PackageCreatedEvent)
subject(:create_package) do
described_class.create!(project: project, name: name, version: version, package_type: package_type)
end
context 'when package is generic' do
let(:package_type) { 'generic' }
it 'does not create event' do
expect { create_package }.not_to publish_event(::Packages::PackageCreatedEvent)
end
context 'when generic_extract_generic_package_model is disabled' do
before do
stub_feature_flags(generic_extract_generic_package_model: false)
end
it 'publishes an event' do
expect { create_package }
.to publish_event(::Packages::PackageCreatedEvent)
.with({
project_id: project.id,
id: kind_of(Numeric),
name: name,
version: version,
package_type: package_type
})
end
end
end
context 'when package is not generic' do
let(:package_type) { 'debian' }
it 'does not create event' do
expect { create_package }.not_to publish_event(::Packages::PackageCreatedEvent)
end
end
end
end
@ -1237,5 +1272,19 @@ RSpec.describe Packages::Package, type: :model, feature_category: :package_regis
end
end
end
context 'when generic_extract_generic_package_model is disabled' do
before do
stub_feature_flags(generic_extract_generic_package_model: false)
end
context 'for package format generic' do
let(:format) { :generic }
it 'maps to Packages::Package' do
is_expected.to eq(described_class)
end
end
end
end
end