Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-01-11 09:10:26 +00:00
parent 93d2428116
commit e6b6fb6028
37 changed files with 580 additions and 799 deletions

View File

@ -301,7 +301,6 @@ Gitlab/StrongMemoizeAttr:
- 'ee/app/controllers/ee/admin/health_check_controller.rb'
- 'ee/app/controllers/ee/groups/settings/repository_controller.rb'
- 'ee/app/controllers/ee/groups_controller.rb'
- 'ee/app/controllers/ee/registrations/welcome_controller.rb'
- 'ee/app/controllers/ee/repositories/git_http_controller.rb'
- 'ee/app/controllers/groups/audit_events_controller.rb'
- 'ee/app/controllers/groups/epic_boards_controller.rb'

View File

@ -1724,7 +1724,6 @@ Layout/LineLength:
- 'ee/spec/controllers/projects/subscriptions_controller_spec.rb'
- 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb'
- 'ee/spec/controllers/projects_controller_spec.rb'
- 'ee/spec/controllers/registrations/welcome_controller_spec.rb'
- 'ee/spec/controllers/subscriptions/groups_controller_spec.rb'
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
- 'ee/spec/elastic/migrate/migration_shared_examples.rb'

View File

@ -59,7 +59,6 @@ RSpec/ContextWording:
- 'ee/spec/controllers/projects/settings/repository_controller_spec.rb'
- 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb'
- 'ee/spec/controllers/projects_controller_spec.rb'
- 'ee/spec/controllers/registrations/welcome_controller_spec.rb'
- 'ee/spec/controllers/repositories/git_http_controller_spec.rb'
- 'ee/spec/controllers/security/dashboard_controller_spec.rb'
- 'ee/spec/controllers/security/vulnerabilities_controller_spec.rb'
@ -1121,7 +1120,6 @@ RSpec/ContextWording:
- 'spec/controllers/projects/tree_controller_spec.rb'
- 'spec/controllers/projects/web_ide_terminals_controller_spec.rb'
- 'spec/controllers/projects_controller_spec.rb'
- 'spec/controllers/registrations/welcome_controller_spec.rb'
- 'spec/controllers/registrations_controller_spec.rb'
- 'spec/controllers/root_controller_spec.rb'
- 'spec/controllers/search_controller_spec.rb'

View File

@ -49,7 +49,6 @@ Style/EmptyMethod:
- 'app/controllers/projects/terraform_controller.rb'
- 'app/controllers/projects/triggers_controller.rb'
- 'app/controllers/pwa_controller.rb'
- 'app/controllers/registrations/welcome_controller.rb'
- 'app/controllers/search_controller.rb'
- 'app/experiments/security_actions_continuous_onboarding_experiment.rb'
- 'app/graphql/resolvers/concerns/caching_array_resolver.rb'

View File

@ -627,7 +627,6 @@ Style/PercentLiteralDelimiters:
- 'spec/controllers/projects/pipelines_controller_spec.rb'
- 'spec/controllers/projects/settings/ci_cd_controller_spec.rb'
- 'spec/controllers/projects_controller_spec.rb'
- 'spec/controllers/registrations/welcome_controller_spec.rb'
- 'spec/controllers/search_controller_spec.rb'
- 'spec/controllers/snippets_controller_spec.rb'
- 'spec/db/docs_spec.rb'

View File

@ -7,13 +7,21 @@ import { STATUSES } from '../constants';
const STATISTIC_ITEMS = {
diff_note: __('Diff notes'),
issue: __('Issues'),
issue_attachment: s__('GithubImporter|Issue attachments'),
issue_event: __('Issue events'),
label: __('Labels'),
lfs_object: __('LFS objects'),
merge_request_attachment: s__('GithubImporter|Merge request attachments'),
milestone: __('Milestones'),
note: __('Notes'),
note_attachment: s__('GithubImporter|Note attachments'),
protected_branch: __('Protected branches'),
pull_request: s__('GithubImporter|Pull requests'),
pull_request_merged_by: s__('GithubImporter|PR mergers'),
pull_request_review: s__('GithubImporter|PR reviews'),
pull_request_review_request: s__('GithubImporter|PR reviews'),
release: __('Releases'),
release_attachment: s__('GithubImporter|Release attachments'),
};
// support both camel case and snake case versions

View File

@ -18,8 +18,6 @@ import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
import { getParameterValues } from '~/lib/utils/url_utility';
import { n__, sprintf } from '~/locale';
import {
CLOSE_TO_LIMIT_VARIANT,
REACHED_LIMIT_VARIANT,
USERS_FILTER_ALL,
INVITE_MEMBERS_FOR_TASK,
MEMBER_MODAL_LABELS,
@ -189,10 +187,10 @@ export default {
return this.source === LEARN_GITLAB;
},
showUserLimitNotification() {
return this.usersLimitDataset.reachedLimit || this.usersLimitDataset.closeToDashboardLimit;
return !isEmpty(this.usersLimitDataset.alertVariant);
},
limitVariant() {
return this.usersLimitDataset.reachedLimit ? REACHED_LIMIT_VARIANT : CLOSE_TO_LIMIT_VARIANT;
return this.usersLimitDataset.alertVariant;
},
errorList() {
return Object.entries(this.invalidMembers).map(([member, error]) => {
@ -479,6 +477,7 @@ export default {
</gl-alert>
<user-limit-notification
v-else-if="showUserLimitNotification"
class="gl-mb-5"
:limit-variant="limitVariant"
:users-limit-dataset="usersLimitDataset"
/>

View File

@ -1,14 +1,18 @@
<script>
import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
import { n__, sprintf } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import {
INFO_ALERT_TITLE,
WARNING_ALERT_TITLE,
DANGER_ALERT_TITLE,
REACHED_LIMIT_UPGRADE_SUGGESTION_MESSAGE,
REACHED_LIMIT_VARIANT,
CLOSE_TO_LIMIT_MESSAGE,
CLOSE_TO_LIMIT_VARIANT,
NOTIFICATION_LIMIT_MESSAGE,
NOTIFICATION_LIMIT_VARIANT,
} from '../constants';
export default {
@ -28,6 +32,15 @@ export default {
computed: {
limitAttributes() {
return {
[NOTIFICATION_LIMIT_VARIANT]: {
variant: 'info',
title: this.notificationTitle(
INFO_ALERT_TITLE,
this.name,
this.usersLimitDataset.freeUsersLimit,
),
message: this.message(NOTIFICATION_LIMIT_MESSAGE, this.usersLimitDataset.freeUsersLimit),
},
[CLOSE_TO_LIMIT_VARIANT]: {
variant: 'warning',
title: this.title(WARNING_ALERT_TITLE, this.usersLimitDataset.remainingSeats),
@ -42,6 +55,13 @@ export default {
},
},
methods: {
notificationTitle(titleTemplate, namespaceName, dashboardLimit) {
return sprintf(titleTemplate, {
namespaceName,
dashboardLimit,
});
},
title(titleTemplate, count) {
return sprintf(titleTemplate, {
count,
@ -49,7 +69,14 @@ export default {
name: this.name,
});
},
message(messageTemplate, dashboardLimit) {
return sprintf(messageTemplate, {
dashboardLimit,
});
},
},
freeUserLimitHelpPath: helpPagePath('user/free_user_limit'),
};
</script>
@ -60,6 +87,11 @@ export default {
:title="limitAttributes[limitVariant].title"
>
<gl-sprintf :message="limitAttributes[limitVariant].message">
<template #freeUserLimitLink="{ content }">
<gl-link :href="$options.freeUserLimitHelpPath" class="gl-label-link">{{
content
}}</gl-link>
</template>
<template #trialLink="{ content }">
<gl-link
:href="usersLimitDataset.newTrialRegistrationPath"

View File

@ -139,6 +139,9 @@ export const GROUP_MODAL_LABELS = {
export const LEARN_GITLAB = 'learn_gitlab';
export const ON_SHOW_TRACK_LABEL = 'over_limit_modal_viewed';
export const INFO_ALERT_TITLE = s__(
'InviteMembersModal|Your namespace %{namespaceName} is over the %{dashboardLimit} user limit.',
);
export const WARNING_ALERT_TITLE = s__(
'InviteMembersModal|You only have space for %{count} more %{members} in %{name}',
);
@ -148,6 +151,7 @@ export const DANGER_ALERT_TITLE = s__(
export const REACHED_LIMIT_VARIANT = 'reached';
export const CLOSE_TO_LIMIT_VARIANT = 'close';
export const NOTIFICATION_LIMIT_VARIANT = 'notification';
export const REACHED_LIMIT_MESSAGE = s__(
'InviteMembersModal|To invite new users to this namespace, you must remove existing users. You can still add existing namespace users.',
@ -162,3 +166,7 @@ export const REACHED_LIMIT_UPGRADE_SUGGESTION_MESSAGE = REACHED_LIMIT_MESSAGE.co
export const CLOSE_TO_LIMIT_MESSAGE = s__(
'InviteMembersModal|To get more members an owner of the group can %{trialLinkStart}start a trial%{trialLinkEnd} or %{upgradeLinkStart}upgrade%{upgradeLinkEnd} to a paid tier.',
);
export const NOTIFICATION_LIMIT_MESSAGE = s__(
'InviteMembersModal|GitLab will enforce this limit in the future. If you are over %{dashboardLimit} users when enforcement begins, your namespace will be placed in a %{freeUserLimitLinkStart}read-only state%{freeUserLimitLinkEnd}. To avoid being placed in a read-only state, reduce your namespace to %{dashboardLimit} users or less, or purchase a paid tier.',
);

View File

@ -30,6 +30,11 @@ export default {
required: true,
default: () => [],
},
additionalClass: {
type: Array,
required: false,
default: () => [],
},
},
data() {
return {
@ -96,7 +101,14 @@ export default {
:value="timezoneIdentifier || value"
type="hidden"
/>
<gl-dropdown :text="selectedTimezoneLabel" block lazy menu-class="gl-w-full!" v-bind="$attrs">
<gl-dropdown
:text="selectedTimezoneLabel"
:class="additionalClass"
block
lazy
menu-class="gl-w-full!"
v-bind="$attrs"
>
<gl-search-box-by-type v-model.trim="searchTerm" v-autofocusonshow autofocus />
<gl-dropdown-item
v-for="timezone in filteredResults"

View File

@ -5,14 +5,14 @@
}
.timezone-dropdown {
.dropdown-menu {
@include gl-w-full;
}
.gl-dropdown-item-text-primary {
@include gl-overflow-hidden;
@include gl-text-overflow-ellipsis;
}
.btn-block {
margin-bottom: 0;
}
}
.modal-footer {
@ -20,7 +20,7 @@
}
.invalid-dropdown {
.gl-dropdown-toggle {
.gl-button.gl-dropdown-toggle {
@include inset-border-1-red-500;
&:hover {

View File

@ -21,21 +21,10 @@ module Registrations
def update
result = ::Users::SignupService.new(current_user, update_params).execute
if result[:status] == :success
if result.success?
track_event('successfully_submitted_form')
return redirect_to issues_dashboard_path(assignee_username: current_user.username) if show_tasks_to_be_done?
return redirect_to update_success_path if redirect_to_signup_onboarding?
members = current_user.members
if registering_from_invite?(members)
redirect_to members_activity_path(members), notice: helpers.invite_accepted_notice(members.last)
else
# subscription registrations goes through here as well
redirect_to path_for_signed_in_user(current_user)
end
redirect_to update_success_path
else
render :show
end
@ -84,17 +73,31 @@ module Registrations
false
end
def show_tasks_to_be_done?
def redirect_for_tasks_to_be_done?
MemberTask.for_members(current_user.members).exists?
end
# overridden in EE
def update_success_path
return issues_dashboard_path(assignee_username: current_user.username) if redirect_for_tasks_to_be_done?
return signup_onboarding_path if redirect_to_signup_onboarding?
members = current_user.members
if registering_from_invite?(members)
flash[:notice] = helpers.invite_accepted_notice(members.last)
members_activity_path(members)
else
# subscription registrations goes through here as well
path_for_signed_in_user(current_user)
end
end
# overridden in EE
def track_event(action)
end
def signup_onboarding_path; end
# overridden in EE
def track_event(action); end
end
end

View File

@ -27,7 +27,7 @@ class Integration < ApplicationRecord
# TODO Shimo is temporary disabled on group and instance-levels.
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/345677
PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[
jenkins shimo
apple_app_store jenkins shimo
].freeze
# Fake integrations to help with local development.
@ -282,13 +282,10 @@ class Integration < ApplicationRecord
# Returns a list of available integration names.
# Example: ["asana", ...]
# @deprecated
# @param [Boolean] include_feature_flagged used only in specs
# TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/386731
def self.available_integration_names(include_project_specific: true, include_dev: true, include_feature_flagged: false)
def self.available_integration_names(include_project_specific: true, include_dev: true)
names = integration_names
names += project_specific_integration_names if include_project_specific
names += dev_integration_names if include_dev
names << 'apple_app_store' if Feature.enabled?(:apple_app_store_integration) || include_feature_flagged
names.sort_by(&:downcase)
end

View File

@ -1615,7 +1615,9 @@ class Project < ApplicationRecord
end
def disabled_integrations
[]
disabled_integrations = []
disabled_integrations << 'apple_app_store' unless Feature.enabled?(:apple_app_store_integration, self)
disabled_integrations
end
def find_or_initialize_integration(name)

View File

@ -12,9 +12,9 @@ module Users
inject_validators
if @user.save
success
ServiceResponse.success
else
error(@user.errors.full_messages.join('. '))
ServiceResponse.error(message: @user.errors.full_messages.join('. '))
end
end

View File

@ -7,6 +7,14 @@
%h5.gl-display-flex
= _("Import project from")
= link_to _('History'), import_history_index_path, class: 'gl-link gl-ml-auto gl-font-weight-normal'
%div
= render Pajamas::AlertComponent.new(variant: :tip,
alert_options: { class: 'gl-my-3' },
dismissible: false) do |c|
= c.body do
- docs_link_url = help_page_path('user/group/import/index') + '#migrate-groups-by-direct-transfer-recommended'
- docs_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
= html_escape(_("Importing GitLab projects? Migrating GitLab projects when migrating groups by direct transfer is in Beta. %{link_start}Learn more.%{link_end}")) % { link_start: docs_link, link_end: '</a>'.html_safe }
.import-buttons
- if gitlab_project_import_enabled?
.import_gitlab_project.has-tooltip{ data: { container: 'body', qa_selector: 'gitlab_import_button' } }

View File

@ -2,9 +2,9 @@
= form_tag path do
%input{ :name => "_method", :type => "hidden", :value => "delete" }
- if defined? small
= button_tag type: "submit", class: "gl-button btn btn-danger btn-icon", data: { confirm: _("Are you sure?"), confirm_btn_variant: "danger" } do
= render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, icon: 'remove', button_options: { data: { confirm: _("Are you sure?"), confirm_btn_variant: "danger" } }) do
%span.sr-only
= _('Destroy')
= sprite_icon('remove')
- else
= submit_tag _('Destroy'), data: { confirm: _("Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Destroy') }, class: submit_btn_css
= render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, button_options: { aria: { label: _('Destroy') }, class: submit_btn_css, data: { confirm: _("Are you sure?"), confirm_btn_variant: "danger" } }) do
= _('Destroy')

View File

@ -1,137 +0,0 @@
# frozen_string_literal: true
class PartitionPmPackageMetadataTables < Gitlab::Database::Migration[2.1]
PURL_TYPES = (1..8).freeze
def up
drop_table(:pm_package_version_licenses) # rubocop:disable Migration/DropTable
drop_table(:pm_package_versions) # rubocop:disable Migration/DropTable
drop_table(:pm_packages) # rubocop:disable Migration/DropTable
create_partitions_for_pm_packages
create_partitions_for_pm_package_versions
create_partitions_for_pm_package_version_licenses
end
def down
drop_table(:pm_package_version_licenses, force: :cascade) # rubocop:disable Migration/DropTable
drop_table(:pm_package_versions, force: :cascade) # rubocop:disable Migration/DropTable
drop_table(:pm_packages, force: :cascade) # rubocop:disable Migration/DropTable
create_table :pm_packages do |t|
t.integer :purl_type, limit: 2, null: false
t.text :name, null: false, limit: 255
t.index [:purl_type, :name], name: 'i_pm_packages_purl_type_and_name', unique: true
end
create_table :pm_package_versions do |t|
t.references :pm_package,
index: false,
foreign_key: {
to_table: :pm_packages,
column: :pm_package_id,
name: 'fk_rails_cf94c3e601',
on_delete: :cascade
}
t.text :version, null: false, limit: 255
t.index [:pm_package_id, :version], name: 'i_pm_package_versions_on_package_id_and_version', unique: true
t.index :pm_package_id, name: 'index_pm_package_versions_on_pm_package_id'
end
create_table :pm_package_version_licenses, primary_key: [:pm_package_version_id, :pm_license_id] do |t|
t.references :pm_package_version,
index: false,
null: false,
foreign_key: {
to_table: :pm_package_versions,
column: :pm_package_version_id,
name: 'fk_rails_30ddb7f837',
on_delete: :cascade
}
t.references :pm_license,
index: false,
null: false,
foreign_key: { name: 'fk_rails_7520ea026d', on_delete: :cascade }
t.index :pm_license_id, name: 'index_pm_package_version_licenses_on_pm_license_id'
t.index :pm_package_version_id, name: 'index_pm_package_version_licenses_on_pm_package_version_id'
end
end
private
def create_partitions_for_pm_packages
execute(<<~SQL)
CREATE TABLE pm_packages (
id BIGSERIAL NOT NULL,
purl_type SMALLINT NOT NULL,
name TEXT NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255)),
PRIMARY KEY (id, purl_type)
) PARTITION BY LIST (purl_type);
SQL
execute(<<~SQL)
CREATE UNIQUE INDEX i_pm_packages_for_inserts ON pm_packages USING btree(purl_type, name);
SQL
PURL_TYPES.each do |i|
execute(<<~SQL)
CREATE TABLE gitlab_partitions_static.pm_packages_#{i}
PARTITION OF pm_packages
FOR VALUES IN (#{i})
SQL
end
end
def create_partitions_for_pm_package_versions
execute(<<~SQL)
CREATE TABLE pm_package_versions (
id BIGSERIAL NOT NULL,
pm_package_id BIGINT NOT NULL,
purl_type SMALLINT NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255)),
PRIMARY KEY (id, purl_type),
CONSTRAINT fkey_fb6234c446 FOREIGN KEY (pm_package_id, purl_type) REFERENCES pm_packages(id, purl_type) ON DELETE CASCADE
) PARTITION BY LIST (purl_type);
SQL
execute(<<~SQL)
CREATE UNIQUE INDEX i_pm_package_versions_for_inserts ON pm_package_versions USING btree (pm_package_id, version, purl_type);
SQL
PURL_TYPES.each do |i|
execute(<<~SQL)
CREATE TABLE gitlab_partitions_static.pm_package_versions_#{i}
PARTITION OF pm_package_versions
FOR VALUES IN (#{i})
SQL
end
end
def create_partitions_for_pm_package_version_licenses
execute(<<~SQL)
CREATE TABLE pm_package_version_licenses (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL,
PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type),
CONSTRAINT pm_package_versions_fkey FOREIGN KEY (pm_package_version_id, purl_type) REFERENCES pm_package_versions (id, purl_type) ON DELETE CASCADE,
CONSTRAINT pm_package_licenses_fkey FOREIGN KEY (pm_license_id) REFERENCES pm_licenses (id) ON DELETE CASCADE
) PARTITION BY LIST (purl_type);
SQL
execute(<<~SQL)
CREATE INDEX i_pm_package_version_licenses_for_inserts ON pm_package_version_licenses USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX i_pm_package_version_licenses_for_selects_on_licenses ON pm_package_version_licenses USING btree (pm_license_id);
SQL
PURL_TYPES.each do |i|
execute(<<~SQL)
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_#{i}
PARTITION OF pm_package_version_licenses
FOR VALUES IN (#{i})
SQL
end
end
end

View File

@ -1 +0,0 @@
37df82f093bb81ff1bc36ea9ba29f4e70bcb96274e2dcc70438ce0710dd7e9d9

View File

@ -1940,240 +1940,6 @@ CREATE TABLE gitlab_partitions_static.issue_search_data_63 (
);
ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_63 FOR VALUES WITH (modulus 64, remainder 63);
CREATE TABLE pm_package_version_licenses (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
)
PARTITION BY LIST (purl_type);
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_1 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_1 FOR VALUES IN ('1');
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_2 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_2 FOR VALUES IN ('2');
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_3 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_3 FOR VALUES IN ('3');
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_4 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_4 FOR VALUES IN ('4');
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_5 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_5 FOR VALUES IN ('5');
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_6 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_6 FOR VALUES IN ('6');
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_7 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_7 FOR VALUES IN ('7');
CREATE TABLE gitlab_partitions_static.pm_package_version_licenses_8 (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL,
purl_type smallint NOT NULL
);
ALTER TABLE ONLY pm_package_version_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_8 FOR VALUES IN ('8');
CREATE TABLE pm_package_versions (
id bigint NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
)
PARTITION BY LIST (purl_type);
CREATE SEQUENCE pm_package_versions_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE pm_package_versions_id_seq OWNED BY pm_package_versions.id;
CREATE TABLE gitlab_partitions_static.pm_package_versions_1 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_1 FOR VALUES IN ('1');
CREATE TABLE gitlab_partitions_static.pm_package_versions_2 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_2 FOR VALUES IN ('2');
CREATE TABLE gitlab_partitions_static.pm_package_versions_3 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_3 FOR VALUES IN ('3');
CREATE TABLE gitlab_partitions_static.pm_package_versions_4 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_4 FOR VALUES IN ('4');
CREATE TABLE gitlab_partitions_static.pm_package_versions_5 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_5 FOR VALUES IN ('5');
CREATE TABLE gitlab_partitions_static.pm_package_versions_6 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_6 FOR VALUES IN ('6');
CREATE TABLE gitlab_partitions_static.pm_package_versions_7 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_7 FOR VALUES IN ('7');
CREATE TABLE gitlab_partitions_static.pm_package_versions_8 (
id bigint DEFAULT nextval('pm_package_versions_id_seq'::regclass) NOT NULL,
pm_package_id bigint NOT NULL,
purl_type smallint NOT NULL,
version text NOT NULL,
CONSTRAINT check_7ed2cc733f CHECK ((char_length(version) <= 255))
);
ALTER TABLE ONLY pm_package_versions ATTACH PARTITION gitlab_partitions_static.pm_package_versions_8 FOR VALUES IN ('8');
CREATE TABLE pm_packages (
id bigint NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
)
PARTITION BY LIST (purl_type);
CREATE SEQUENCE pm_packages_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE pm_packages_id_seq OWNED BY pm_packages.id;
CREATE TABLE gitlab_partitions_static.pm_packages_1 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_1 FOR VALUES IN ('1');
CREATE TABLE gitlab_partitions_static.pm_packages_2 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_2 FOR VALUES IN ('2');
CREATE TABLE gitlab_partitions_static.pm_packages_3 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_3 FOR VALUES IN ('3');
CREATE TABLE gitlab_partitions_static.pm_packages_4 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_4 FOR VALUES IN ('4');
CREATE TABLE gitlab_partitions_static.pm_packages_5 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_5 FOR VALUES IN ('5');
CREATE TABLE gitlab_partitions_static.pm_packages_6 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_6 FOR VALUES IN ('6');
CREATE TABLE gitlab_partitions_static.pm_packages_7 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_7 FOR VALUES IN ('7');
CREATE TABLE gitlab_partitions_static.pm_packages_8 (
id bigint DEFAULT nextval('pm_packages_id_seq'::regclass) NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_9df27a82fe CHECK ((char_length(name) <= 255))
);
ALTER TABLE ONLY pm_packages ATTACH PARTITION gitlab_partitions_static.pm_packages_8 FOR VALUES IN ('8');
CREATE TABLE product_analytics_events_experimental (
id bigint NOT NULL,
project_id integer NOT NULL,
@ -19883,6 +19649,43 @@ CREATE SEQUENCE pm_licenses_id_seq
ALTER SEQUENCE pm_licenses_id_seq OWNED BY pm_licenses.id;
CREATE TABLE pm_package_version_licenses (
pm_package_version_id bigint NOT NULL,
pm_license_id bigint NOT NULL
);
CREATE TABLE pm_package_versions (
id bigint NOT NULL,
pm_package_id bigint,
version text NOT NULL,
CONSTRAINT check_2d8a88cfcc CHECK ((char_length(version) <= 255))
);
CREATE SEQUENCE pm_package_versions_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE pm_package_versions_id_seq OWNED BY pm_package_versions.id;
CREATE TABLE pm_packages (
id bigint NOT NULL,
purl_type smallint NOT NULL,
name text NOT NULL,
CONSTRAINT check_3a3aedb8ba CHECK ((char_length(name) <= 255))
);
CREATE SEQUENCE pm_packages_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE pm_packages_id_seq OWNED BY pm_packages.id;
CREATE TABLE pool_repositories (
id bigint NOT NULL,
shard_id integer NOT NULL,
@ -25419,87 +25222,6 @@ ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_62
ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_63
ADD CONSTRAINT issue_search_data_63_pkey PRIMARY KEY (project_id, issue_id);
ALTER TABLE ONLY pm_package_version_licenses
ADD CONSTRAINT pm_package_version_licenses_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_1
ADD CONSTRAINT pm_package_version_licenses_1_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_2
ADD CONSTRAINT pm_package_version_licenses_2_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_3
ADD CONSTRAINT pm_package_version_licenses_3_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_4
ADD CONSTRAINT pm_package_version_licenses_4_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_5
ADD CONSTRAINT pm_package_version_licenses_5_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_6
ADD CONSTRAINT pm_package_version_licenses_6_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_7
ADD CONSTRAINT pm_package_version_licenses_7_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_version_licenses_8
ADD CONSTRAINT pm_package_version_licenses_8_pkey PRIMARY KEY (pm_package_version_id, pm_license_id, purl_type);
ALTER TABLE ONLY pm_package_versions
ADD CONSTRAINT pm_package_versions_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_1
ADD CONSTRAINT pm_package_versions_1_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_2
ADD CONSTRAINT pm_package_versions_2_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_3
ADD CONSTRAINT pm_package_versions_3_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_4
ADD CONSTRAINT pm_package_versions_4_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_5
ADD CONSTRAINT pm_package_versions_5_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_6
ADD CONSTRAINT pm_package_versions_6_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_7
ADD CONSTRAINT pm_package_versions_7_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_package_versions_8
ADD CONSTRAINT pm_package_versions_8_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY pm_packages
ADD CONSTRAINT pm_packages_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_1
ADD CONSTRAINT pm_packages_1_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_2
ADD CONSTRAINT pm_packages_2_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_3
ADD CONSTRAINT pm_packages_3_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_4
ADD CONSTRAINT pm_packages_4_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_5
ADD CONSTRAINT pm_packages_5_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_6
ADD CONSTRAINT pm_packages_6_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_7
ADD CONSTRAINT pm_packages_7_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY gitlab_partitions_static.pm_packages_8
ADD CONSTRAINT pm_packages_8_pkey PRIMARY KEY (id, purl_type);
ALTER TABLE ONLY product_analytics_events_experimental
ADD CONSTRAINT product_analytics_events_experimental_pkey PRIMARY KEY (id, project_id);
@ -26970,6 +26692,15 @@ ALTER TABLE ONLY plans
ALTER TABLE ONLY pm_licenses
ADD CONSTRAINT pm_licenses_pkey PRIMARY KEY (id);
ALTER TABLE ONLY pm_package_version_licenses
ADD CONSTRAINT pm_package_version_licenses_pkey PRIMARY KEY (pm_package_version_id, pm_license_id);
ALTER TABLE ONLY pm_package_versions
ADD CONSTRAINT pm_package_versions_pkey PRIMARY KEY (id);
ALTER TABLE ONLY pm_packages
ADD CONSTRAINT pm_packages_pkey PRIMARY KEY (id);
ALTER TABLE ONLY pool_repositories
ADD CONSTRAINT pool_repositories_pkey PRIMARY KEY (id);
@ -28334,78 +28065,6 @@ CREATE INDEX issue_search_data_63_issue_id_idx ON gitlab_partitions_static.issue
CREATE INDEX issue_search_data_63_search_vector_idx ON gitlab_partitions_static.issue_search_data_63 USING gin (search_vector);
CREATE INDEX i_pm_package_version_licenses_for_selects_on_licenses ON ONLY pm_package_version_licenses USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_1_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_1 USING btree (pm_license_id);
CREATE INDEX i_pm_package_version_licenses_for_inserts ON ONLY pm_package_version_licenses USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_1_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_1 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_2_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_2 USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_2_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_2 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_3_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_3 USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_3_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_3 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_4_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_4 USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_4_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_4 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_5_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_5 USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_5_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_5 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_6_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_6 USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_6_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_6 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_7_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_7 USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_7_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_7 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE INDEX pm_package_version_licenses_8_pm_license_id_idx ON gitlab_partitions_static.pm_package_version_licenses_8 USING btree (pm_license_id);
CREATE INDEX pm_package_version_licenses_8_purl_type_pm_package_version__idx ON gitlab_partitions_static.pm_package_version_licenses_8 USING btree (purl_type, pm_package_version_id, pm_license_id);
CREATE UNIQUE INDEX i_pm_package_versions_for_inserts ON ONLY pm_package_versions USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_1_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_1 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_2_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_2 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_3_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_3 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_4_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_4 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_5_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_5 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_6_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_6 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_7_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_7 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX pm_package_versions_8_pm_package_id_version_purl_type_idx ON gitlab_partitions_static.pm_package_versions_8 USING btree (pm_package_id, version, purl_type);
CREATE UNIQUE INDEX i_pm_packages_for_inserts ON ONLY pm_packages USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_1_purl_type_name_idx ON gitlab_partitions_static.pm_packages_1 USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_2_purl_type_name_idx ON gitlab_partitions_static.pm_packages_2 USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_3_purl_type_name_idx ON gitlab_partitions_static.pm_packages_3 USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_4_purl_type_name_idx ON gitlab_partitions_static.pm_packages_4 USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_5_purl_type_name_idx ON gitlab_partitions_static.pm_packages_5 USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_6_purl_type_name_idx ON gitlab_partitions_static.pm_packages_6 USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_7_purl_type_name_idx ON gitlab_partitions_static.pm_packages_7 USING btree (purl_type, name);
CREATE UNIQUE INDEX pm_packages_8_purl_type_name_idx ON gitlab_partitions_static.pm_packages_8 USING btree (purl_type, name);
CREATE INDEX index_product_analytics_events_experimental_project_and_time ON ONLY product_analytics_events_experimental USING btree (project_id, collector_tstamp);
CREATE INDEX product_analytics_events_expe_project_id_collector_tstamp_idx10 ON gitlab_partitions_static.product_analytics_events_experimental_10 USING btree (project_id, collector_tstamp);
@ -28598,6 +28257,10 @@ CREATE INDEX i_dast_scanner_profiles_tags_on_scanner_profiles_id ON dast_scanner
CREATE UNIQUE INDEX i_pm_licenses_on_spdx_identifier ON pm_licenses USING btree (spdx_identifier);
CREATE UNIQUE INDEX i_pm_package_versions_on_package_id_and_version ON pm_package_versions USING btree (pm_package_id, version);
CREATE UNIQUE INDEX i_pm_packages_purl_type_and_name ON pm_packages USING btree (purl_type, name);
CREATE INDEX idx_analytics_devops_adoption_segments_on_namespace_id ON analytics_devops_adoption_segments USING btree (namespace_id);
CREATE INDEX idx_analytics_devops_adoption_snapshots_finalized ON analytics_devops_adoption_snapshots USING btree (namespace_id, end_time) WHERE (recorded_at >= end_time);
@ -30912,6 +30575,12 @@ CREATE UNIQUE INDEX index_plan_limits_on_plan_id ON plan_limits USING btree (pla
CREATE UNIQUE INDEX index_plans_on_name ON plans USING btree (name);
CREATE INDEX index_pm_package_version_licenses_on_pm_license_id ON pm_package_version_licenses USING btree (pm_license_id);
CREATE INDEX index_pm_package_version_licenses_on_pm_package_version_id ON pm_package_version_licenses USING btree (pm_package_version_id);
CREATE INDEX index_pm_package_versions_on_pm_package_id ON pm_package_versions USING btree (pm_package_id);
CREATE UNIQUE INDEX index_pool_repositories_on_disk_path ON pool_repositories USING btree (disk_path);
CREATE INDEX index_pool_repositories_on_shard_id ON pool_repositories USING btree (shard_id);
@ -33170,118 +32839,6 @@ ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.iss
ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_63_search_vector_idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_1_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_1_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_1_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_2_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_2_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_2_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_3_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_3_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_3_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_4_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_4_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_4_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_5_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_5_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_5_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_6_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_6_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_6_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_7_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_7_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_7_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_version_licenses_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_8_pkey;
ALTER INDEX i_pm_package_version_licenses_for_selects_on_licenses ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_8_pm_license_id_idx;
ALTER INDEX i_pm_package_version_licenses_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_version_licenses_8_purl_type_pm_package_version__idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_1_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_1_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_2_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_2_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_3_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_3_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_4_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_4_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_5_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_5_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_6_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_6_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_7_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_7_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_package_versions_pkey ATTACH PARTITION gitlab_partitions_static.pm_package_versions_8_pkey;
ALTER INDEX i_pm_package_versions_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_package_versions_8_pm_package_id_version_purl_type_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_1_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_1_purl_type_name_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_2_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_2_purl_type_name_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_3_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_3_purl_type_name_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_4_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_4_purl_type_name_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_5_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_5_purl_type_name_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_6_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_6_purl_type_name_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_7_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_7_purl_type_name_idx;
ALTER INDEX pm_packages_pkey ATTACH PARTITION gitlab_partitions_static.pm_packages_8_pkey;
ALTER INDEX i_pm_packages_for_inserts ATTACH PARTITION gitlab_partitions_static.pm_packages_8_purl_type_name_idx;
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx10;
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx11;
@ -34893,6 +34450,9 @@ ALTER TABLE ONLY issuable_severities
ALTER TABLE ONLY saml_providers
ADD CONSTRAINT fk_rails_306d459be7 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY pm_package_version_licenses
ADD CONSTRAINT fk_rails_30ddb7f837 FOREIGN KEY (pm_package_version_id) REFERENCES pm_package_versions(id) ON DELETE CASCADE;
ALTER TABLE ONLY resource_state_events
ADD CONSTRAINT fk_rails_3112bba7dc FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
@ -35355,6 +34915,9 @@ ALTER TABLE ONLY merge_request_context_commit_diff_files
ALTER TABLE ONLY group_crm_settings
ADD CONSTRAINT fk_rails_74fdf2f13d FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY pm_package_version_licenses
ADD CONSTRAINT fk_rails_7520ea026d FOREIGN KEY (pm_license_id) REFERENCES pm_licenses(id) ON DELETE CASCADE;
ALTER TABLE ONLY clusters_applications_ingress
ADD CONSTRAINT fk_rails_753a7b41c1 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
@ -35937,6 +35500,9 @@ ALTER TABLE ONLY resource_iteration_events
ALTER TABLE ONLY member_roles
ADD CONSTRAINT fk_rails_cf0ee35814 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY pm_package_versions
ADD CONSTRAINT fk_rails_cf94c3e601 FOREIGN KEY (pm_package_id) REFERENCES pm_packages(id) ON DELETE CASCADE;
ALTER TABLE ONLY upload_states
ADD CONSTRAINT fk_rails_d00f153613 FOREIGN KEY (upload_id) REFERENCES uploads(id) ON DELETE CASCADE;
@ -36267,21 +35833,12 @@ ALTER TABLE ONLY timelogs
ALTER TABLE ONLY u2f_registrations
ADD CONSTRAINT fk_u2f_registrations_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE pm_package_versions
ADD CONSTRAINT fkey_fb6234c446 FOREIGN KEY (pm_package_id, purl_type) REFERENCES pm_packages(id, purl_type) ON DELETE CASCADE;
ALTER TABLE issue_search_data
ADD CONSTRAINT issue_search_data_issue_id_fkey FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
ALTER TABLE issue_search_data
ADD CONSTRAINT issue_search_data_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE pm_package_version_licenses
ADD CONSTRAINT pm_package_licenses_fkey FOREIGN KEY (pm_license_id) REFERENCES pm_licenses(id) ON DELETE CASCADE;
ALTER TABLE pm_package_version_licenses
ADD CONSTRAINT pm_package_versions_fkey FOREIGN KEY (pm_package_version_id, purl_type) REFERENCES pm_package_versions(id, purl_type) ON DELETE CASCADE;
ALTER TABLE product_analytics_events_experimental
ADD CONSTRAINT product_analytics_events_experimental_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;

View File

@ -5727,7 +5727,7 @@ Input type: `UpdateRequirementInput`
| ---- | ---- | ----------- |
| <a id="mutationupdaterequirementclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationupdaterequirementdescription"></a>`description` | [`String`](#string) | Description of the requirement. |
| <a id="mutationupdaterequirementiid"></a>`iid` | [`String`](#string) | IID of the requirement to update. |
| <a id="mutationupdaterequirementiid"></a>`iid` **{warning-solid}** | [`String`](#string) | **Deprecated:** Use work_item_iid instead. Deprecated in 15.8. |
| <a id="mutationupdaterequirementlasttestreportstate"></a>`lastTestReportState` | [`TestReportState`](#testreportstate) | Creates a test report for the requirement with the given state. |
| <a id="mutationupdaterequirementprojectpath"></a>`projectPath` | [`ID!`](#id) | Full project path the requirement is associated with. |
| <a id="mutationupdaterequirementstate"></a>`state` | [`RequirementState`](#requirementstate) | State of the requirement. |
@ -18193,8 +18193,8 @@ Returns [`Requirement`](#requirement).
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectrequirementauthorusername"></a>`authorUsername` | [`[String!]`](#string) | Filter requirements by author username. |
| <a id="projectrequirementiid"></a>`iid` | [`ID`](#id) | IID of the requirement, for example, "1". |
| <a id="projectrequirementiids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of requirements, for example, `[1, 2]`. |
| <a id="projectrequirementiid"></a>`iid` **{warning-solid}** | [`ID`](#id) | **Deprecated** in 15.8. Use work_item_iid instead. |
| <a id="projectrequirementiids"></a>`iids` **{warning-solid}** | [`[ID!]`](#id) | **Deprecated** in 15.8. Use work_item_iids instead. |
| <a id="projectrequirementlasttestreportstate"></a>`lastTestReportState` | [`RequirementStatusFilter`](#requirementstatusfilter) | State of latest requirement test report. |
| <a id="projectrequirementsearch"></a>`search` | [`String`](#string) | Search query for requirement title. |
| <a id="projectrequirementsort"></a>`sort` | [`Sort`](#sort) | List requirements by sort order. |
@ -18217,8 +18217,8 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectrequirementsauthorusername"></a>`authorUsername` | [`[String!]`](#string) | Filter requirements by author username. |
| <a id="projectrequirementsiid"></a>`iid` | [`ID`](#id) | IID of the requirement, for example, "1". |
| <a id="projectrequirementsiids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of requirements, for example, `[1, 2]`. |
| <a id="projectrequirementsiid"></a>`iid` **{warning-solid}** | [`ID`](#id) | **Deprecated** in 15.8. Use work_item_iid instead. |
| <a id="projectrequirementsiids"></a>`iids` **{warning-solid}** | [`[ID!]`](#id) | **Deprecated** in 15.8. Use work_item_iids instead. |
| <a id="projectrequirementslasttestreportstate"></a>`lastTestReportState` | [`RequirementStatusFilter`](#requirementstatusfilter) | State of latest requirement test report. |
| <a id="projectrequirementssearch"></a>`search` | [`String`](#string) | Search query for requirement title. |
| <a id="projectrequirementssort"></a>`sort` | [`Sort`](#sort) | List requirements by sort order. |
@ -18992,7 +18992,7 @@ Represents a requirement.
| <a id="requirementdescription"></a>`description` | [`String`](#string) | Description of the requirement. |
| <a id="requirementdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of `description`. |
| <a id="requirementid"></a>`id` | [`ID!`](#id) | ID of the requirement. |
| <a id="requirementiid"></a>`iid` | [`ID!`](#id) | Internal ID of the requirement. |
| <a id="requirementiid"></a>`iid` **{warning-solid}** | [`ID!`](#id) | **Deprecated** in 15.8. Use work_item_iid instead. |
| <a id="requirementlasttestreportmanuallycreated"></a>`lastTestReportManuallyCreated` | [`Boolean`](#boolean) | Indicates if latest test report was created by user. |
| <a id="requirementlasttestreportstate"></a>`lastTestReportState` | [`TestReportState`](#testreportstate) | Latest requirement test report state. |
| <a id="requirementproject"></a>`project` | [`Project!`](#project) | Project to which the requirement belongs. |

View File

@ -244,21 +244,25 @@ To trigger a child pipeline as a [merge request pipeline](merge_request_pipeline
```
1. Configure the child pipeline jobs to run in merge request pipelines with [`rules`](../yaml/index.md#rules)
or [`workflow:rules`](../yaml/index.md#workflowrules). For example, with `rules`
in a child pipeline's configuration file:
or [`workflow:rules`](../yaml/index.md#workflowrules).
For example, with `rules` in a child pipeline's configuration file:
```yaml
job1:
script: ...
script: echo "Child pipeline job 1"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_MERGE_REQUEST_ID
job2:
script: ...
script: echo "Child pipeline job 2"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_MERGE_REQUEST_ID
```
In child pipelines, `$CI_PIPELINE_SOURCE` always has a value of `parent_pipeline`
and cannot be used to identify merge request pipelines. Use `$CI_MERGE_REQUEST_ID`
instead, which is always present in merge request pipelines.
### Specify a branch for multi-project pipelines
You can specify the branch to use when triggering a multi-project pipeline. GitLab uses

View File

@ -85,7 +85,7 @@ An alternative to `File` type variables is to:
```shell
# Read certificate stored in $KUBE_CA_PEM variable and save it in a new file
cat "$KUBE_CA_PEM" > "$(pwd)/kube.ca.pem"
echo "$KUBE_CA_PEM" > "$(pwd)/kube.ca.pem"
# Pass the newly created file to kubectl
kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$(pwd)/kube.ca.pem"
```

View File

@ -17,15 +17,16 @@ If you want to bring existing projects to GitLab or copy GitLab projects to a di
For any type of source and target, you can migrate projects:
- As part of a [GitLab group migration](../../group/import/index.md). You can't migrate only chosen projects,
but you can migrate many projects at once within a group.
- When [migrating groups by direct transfer](../../group/import/index.md#migrate-groups-by-direct-transfer-recommended), which allows you to migrate all
projects in a group at once. Migrating projects by direct transfer is in [Beta](../../../policy/alpha-beta-support.md#beta-features). The feature is not ready
for production use.
- Using [file exports](../settings/import_export.md). With this method you can migrate projects one by one. No network
connection between instances is required.
If you only need to migrate Git repositories, you can [import each project by URL](repo_by_url.md). However, you can't
import issues and merge requests this way. To retain metadata like issues and merge requests, either:
- [Migrate projects with groups](../../group/import/index.md).
- [Migrate projects with groups by direct transfer](../../group/import/index.md#migrate-groups-by-direct-transfer-recommended). This feature is in [Beta](../../../policy/alpha-beta-support.md#beta-features). It is not ready for production use.
- Use [file exports](../settings/import_export.md) to import projects.
Keep in mind the limitations of [migrating using file exports](../settings/import_export.md#items-that-are-exported).

View File

@ -18,7 +18,7 @@ An Apple ID enrolled in the [Apple Developer Program](https://developer.apple.co
## Configure GitLab
GitLab supports enabling the Apple App Store integration at the group or project level. Complete these steps in GitLab:
GitLab supports enabling the Apple App Store integration at the project level. Complete these steps in GitLab:
1. In the Apple App Store Connect portal, generate a new private key for your project by following [these instructions](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api).
1. On the top bar, select **Main menu > Projects** and find your project.
@ -36,7 +36,6 @@ After the Apple App Store integration is activated:
- The global variables `$APP_STORE_CONNECT_API_KEY_ISSUER_ID`, `$APP_STORE_CONNECT_API_KEY_KEY_ID`, and `$APP_STORE_CONNECT_API_KEY_KEY` are created for CI/CD use.
- `$APP_STORE_CONNECT_API_KEY_KEY` contains the Base64 encoded Private Key.
- The project-level integration settings override the group-level integration settings.
## Security considerations

View File

@ -38,33 +38,37 @@ module Gitlab
SKIP_LOG_METHOD_MISSING_FOR_COMMANDS = %i[info].freeze
# Define valid empty responses for each read command to check for
# cache hit. The only other acceptable value is nil, in the case of errors being
# raised.
# For ENUMERATOR_CACHE_HIT_VALIDATOR and READ_CACHE_HIT_VALIDATOR,
# we define procs to validate cache hit. The only other acceptable value is nil,
# in the case of errors being raised.
#
# If a command has no empty response, set an empty array as its value.
# If a command has no empty response, set ->(val) { true }
#
# Ref: https://www.rubydoc.info/github/redis/redis-rb/Redis/Commands
#
READ_COMMANDS_EMPTY_RESPONSE_HASH = {
exists: [0],
exists?: [false],
get: [nil],
hexists: [false],
hget: [nil],
hgetall: [{}],
hlen: [0],
scard: [0],
sismember: [false],
smembers: [[]],
sscan: [['0', []]],
ttl: [0, -2],
ENUMERATOR_CACHE_HIT_VALIDATOR = {
scan_each: ->(val) { val.is_a?(Enumerator) && !val.first.nil? },
hscan_each: ->(val) { val.is_a?(Enumerator) && !val.first.nil? },
sscan_each: ->(val) { val.is_a?(Enumerator) && !val.first.nil? },
zscan_each: ->(val) { val.is_a?(Enumerator) && !val.first.nil? }
}.freeze
# response container may contain nil values
# cache-hit checker will run .compact before comparison
hmget: [[]],
mapped_hmget: [{}],
mget: [[]]
READ_CACHE_HIT_VALIDATOR = {
exists: ->(val) { val != 0 },
exists?: ->(val) { val },
get: ->(val) { !val.nil? },
hexists: ->(val) { val },
hget: ->(val) { !val.nil? },
hgetall: ->(val) { val.is_a?(Hash) && !val.empty? },
hlen: ->(val) { val != 0 },
hmget: ->(val) { val.is_a?(Array) && !val.compact.empty? },
mapped_hmget: ->(val) { val.is_a?(Hash) && !val.compact.empty? },
mget: ->(val) { val.is_a?(Array) && !val.compact.empty? },
scard: ->(val) { val != 0 },
sismember: ->(val) { val },
smembers: ->(val) { val.is_a?(Array) && !val.empty? },
sscan: ->(val) { val != ['0', []] },
ttl: ->(val) { val != 0 && val != -2 }
}.freeze
WRITE_COMMANDS = %i[
@ -110,12 +114,12 @@ module Gitlab
end
# rubocop:disable GitlabSecurity/PublicSend
READ_COMMANDS_EMPTY_RESPONSE_HASH.each_key do |name|
define_method(name) do |*args, &block|
READ_CACHE_HIT_VALIDATOR.each_key do |name|
define_method(name) do |*args, **kwargs, &block|
if use_primary_and_secondary_stores?
read_command(name, *args, &block)
read_command(name, *args, **kwargs, &block)
else
default_store.send(name, *args, &block)
default_store.send(name, *args, **kwargs, &block)
end
end
end
@ -130,6 +134,20 @@ module Gitlab
end
end
ENUMERATOR_CACHE_HIT_VALIDATOR.each_key do |name|
define_method(name) do |*args, **kwargs, &block|
enumerator = if use_primary_and_secondary_stores?
read_command(name, *args, **kwargs)
else
default_store.send(name, *args, **kwargs)
end
return enumerator if block.nil?
enumerator.each(&block)
end
end
PIPELINED_COMMANDS.each do |name|
define_method(name) do |*args, **kwargs, &block|
if use_primary_and_secondary_stores?
@ -228,11 +246,11 @@ module Gitlab
increment_method_missing_count(command_name)
end
def read_command(command_name, *args, &block)
def read_command(command_name, *args, **kwargs, &block)
if @instance
send_command(@instance, command_name, *args, &block)
send_command(@instance, command_name, *args, **kwargs, &block)
else
read_one_with_fallback(command_name, *args, &block)
read_one_with_fallback(command_name, *args, **kwargs, &block)
end
end
@ -244,9 +262,9 @@ module Gitlab
end
end
def read_one_with_fallback(command_name, *args, &block)
def read_one_with_fallback(command_name, *args, **kwargs, &block)
begin
value = send_command(primary_store, command_name, *args, &block)
value = send_command(primary_store, command_name, *args, **kwargs, &block)
rescue StandardError => e
log_error(e, command_name,
multi_store_error_message: FAILED_TO_READ_ERROR_MESSAGE)
@ -254,17 +272,18 @@ module Gitlab
return value if cache_hit?(command_name, value)
fallback_read(command_name, *args, &block)
fallback_read(command_name, *args, **kwargs, &block)
end
def cache_hit?(command, value)
empty_responses = READ_COMMANDS_EMPTY_RESPONSE_HASH[command]
compacted = value.is_a?(Array) || value.is_a?(Hash) ? value.compact : value
empty_responses.exclude?(compacted) && !value.nil?
validator = READ_CACHE_HIT_VALIDATOR[command] || ENUMERATOR_CACHE_HIT_VALIDATOR[command]
return false unless validator
!value.nil? && validator.call(value)
end
def fallback_read(command_name, *args, &block)
value = send_command(secondary_store, command_name, *args, &block)
def fallback_read(command_name, *args, **kwargs, &block)
value = send_command(secondary_store, command_name, *args, **kwargs, &block)
if value
log_error(ReadFromPrimaryError.new, command_name)

View File

@ -1292,9 +1292,6 @@ msgstr ""
msgid "(No changes)"
msgstr ""
msgid "(UTC %{offset}) %{timezone}"
msgstr ""
msgid "(Unlimited pipeline minutes)"
msgstr ""
@ -18869,6 +18866,15 @@ msgstr ""
msgid "Gitea Import"
msgstr ""
msgid "GithubImporter|Issue attachments"
msgstr ""
msgid "GithubImporter|Merge request attachments"
msgstr ""
msgid "GithubImporter|Note attachments"
msgstr ""
msgid "GithubImporter|PR mergers"
msgstr ""
@ -18878,6 +18884,9 @@ msgstr ""
msgid "GithubImporter|Pull requests"
msgstr ""
msgid "GithubImporter|Release attachments"
msgstr ""
msgid "GithubIntegration|Create a %{token_link_start}personal access token%{token_link_end} with %{status_html} access granted and paste it here."
msgstr ""
@ -21238,6 +21247,9 @@ msgid_plural "Importing %d repositories"
msgstr[0] ""
msgstr[1] ""
msgid "Importing GitLab projects? Migrating GitLab projects when migrating groups by direct transfer is in Beta. %{link_start}Learn more.%{link_end}"
msgstr ""
msgid "Importing..."
msgstr ""
@ -22857,6 +22869,9 @@ msgstr ""
msgid "InviteMembersModal|GitLab is better with colleagues!"
msgstr ""
msgid "InviteMembersModal|GitLab will enforce this limit in the future. If you are over %{dashboardLimit} users when enforcement begins, your namespace will be placed in a %{freeUserLimitLinkStart}read-only state%{freeUserLimitLinkEnd}. To avoid being placed in a read-only state, reduce your namespace to %{dashboardLimit} users or less, or purchase a paid tier."
msgstr ""
msgid "InviteMembersModal|How about inviting a colleague or two to join you?"
msgstr ""
@ -22937,6 +22952,9 @@ msgstr ""
msgid "InviteMembersModal|You've reached your %{count} %{members} limit for %{name}"
msgstr ""
msgid "InviteMembersModal|Your namespace %{namespaceName} is over the %{dashboardLimit} user limit."
msgstr ""
msgid "InviteMembers|Invite a group"
msgstr ""

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Registrations::WelcomeController do
RSpec.describe Registrations::WelcomeController, feature_category: :authentication_and_authorization do
let(:user) { create(:user) }
describe '#welcome' do
@ -47,7 +47,7 @@ RSpec.describe Registrations::WelcomeController do
it { is_expected.to render_template(:show) }
end
context '2FA is required from group' do
context 'when 2FA is required from group' do
before do
user = create(:user, require_two_factor_authentication_from_group: true)
sign_in(user)
@ -99,7 +99,7 @@ RSpec.describe Registrations::WelcomeController do
end
context 'when tasks to be done are assigned' do
let!(:member1) { create(:group_member, user: user, tasks_to_be_done: %w(ci code)) }
let!(:member1) { create(:group_member, user: user, tasks_to_be_done: %w[ci code]) }
it { is_expected.to redirect_to(issues_dashboard_path(assignee_username: user.username)) }
end

View File

@ -170,8 +170,7 @@ RSpec.describe 'Database schema' do
let(:ignored_columns) { ignored_fk_columns(table) }
it 'do have the foreign keys' do
foreign_keys_columns_with_id = foreign_keys_columns.select { |column_name| column_name.ends_with?('_id') }
expect(column_names_with_id - ignored_columns).to include(*foreign_keys_columns_with_id)
expect(column_names_with_id - ignored_columns).to match_array(foreign_keys_columns)
end
it 'and having foreign key are not in the ignore list' do

View File

@ -365,7 +365,7 @@ describe('InviteMembersModal', () => {
describe('rendering the user limit notification', () => {
it('shows the user limit notification alert when reached limit', () => {
const usersLimitDataset = { reachedLimit: true };
const usersLimitDataset = { alertVariant: 'reached' };
createInviteMembersToProjectWrapper(usersLimitDataset);
@ -373,7 +373,15 @@ describe('InviteMembersModal', () => {
});
it('shows the user limit notification alert when close to dashboard limit', () => {
const usersLimitDataset = { closeToDashboardLimit: true };
const usersLimitDataset = { alertVariant: 'close' };
createInviteMembersToProjectWrapper(usersLimitDataset);
expect(findUserLimitAlert().exists()).toBe(true);
});
it('shows the user limit notification alert when :preview_free_user_cap is enabled', () => {
const usersLimitDataset = { alertVariant: 'notification' };
createInviteMembersToProjectWrapper(usersLimitDataset);

View File

@ -1,9 +1,14 @@
import { GlAlert, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import UserLimitNotification from '~/invite_members/components/user_limit_notification.vue';
import { REACHED_LIMIT_VARIANT, CLOSE_TO_LIMIT_VARIANT } from '~/invite_members/constants';
import {
NOTIFICATION_LIMIT_VARIANT,
REACHED_LIMIT_VARIANT,
CLOSE_TO_LIMIT_VARIANT,
} from '~/invite_members/constants';
import { freeUsersLimit, remainingSeats } from '../mock_data/member_modal';
const INFO_ALERT_TITLE = 'Your namespace name is over the 5 user limit.';
const WARNING_ALERT_TITLE = 'You only have space for 2 more members in name';
describe('UserLimitNotification', () => {
@ -31,6 +36,17 @@ describe('UserLimitNotification', () => {
});
};
describe('when previewing free user cap', () => {
it("renders user's preview limit notification", () => {
createComponent(NOTIFICATION_LIMIT_VARIANT);
const alert = findAlert();
expect(alert.attributes('title')).toEqual(INFO_ALERT_TITLE);
expect(alert.text()).toContain('GitLab will enforce this limit in the future.');
});
});
describe('when close to limit within a group', () => {
it("renders user's limit notification", () => {
createComponent(CLOSE_TO_LIMIT_VARIANT);

View File

@ -42,7 +42,9 @@ describe('RelatedMergeRequests', () => {
const assignees = [{ name: 'foo' }, { name: 'bar' }];
describe('when there is assignees array', () => {
it('should return assignees array', () => {
// https://gitlab.com/gitlab-org/gitlab/-/issues/387756
// eslint-disable-next-line jest/no-disabled-tests
it.skip('should return assignees array', () => {
const mr = { assignees };
expect(wrapper.vm.getAssignees(mr)).toEqual(assignees);

View File

@ -1,4 +1,5 @@
import { GlDropdownItem, GlDropdown } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import TimezoneDropdown from '~/vue_shared/components/timezone_dropdown/timezone_dropdown.vue';
import { formatTimezone } from '~/lib/utils/datetime_utility';
@ -107,5 +108,12 @@ describe('Deploy freeze timezone dropdown', () => {
it('renders selected time zone as dropdown label', () => {
expect(wrapper.findComponent(GlDropdown).props().text).toBe('[UTC+2] Berlin');
});
it('adds a checkmark to the selected option', async () => {
const selectedTZOption = findAllDropdownItems().at(0);
selectedTZOption.vm.$emit('click');
await nextTick();
expect(selectedTZOption.attributes('ischecked')).toBe('true');
});
});
});

View File

@ -25,7 +25,9 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
let_it_be(:instance_name) { 'TestStore' }
let_it_be(:multi_store) { described_class.new(primary_store, secondary_store, instance_name) }
subject { multi_store.send(name, *args) }
subject do
multi_store.send(name, *args)
end
before do
skip_feature_flags_yaml_validation
@ -110,6 +112,10 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
# rubocop:disable RSpec/MultipleMemoizedHelpers
context 'with READ redis commands' do
subject do
multi_store.send(name, *args, **kwargs)
end
let_it_be(:key1) { "redis:{1}:key_a" }
let_it_be(:key2) { "redis:{1}:key_b" }
let_it_be(:value1) { "redis_value1" }
@ -118,7 +124,11 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
let_it_be(:skey2) { "redis:set:key2" }
let_it_be(:smemberargs) { [skey, value1] }
let_it_be(:hkey) { "redis:hash:key" }
let_it_be(:hkey2) { "redis:hash:key2" }
let_it_be(:zkey) { "redis:sortedset:key" }
let_it_be(:zkey2) { "redis:sortedset:key2" }
let_it_be(:hitem1) { "item1" }
let_it_be(:hitem2) { "item2" }
let_it_be(:keys) { [key1, key2] }
let_it_be(:values) { [value1, value2] }
let_it_be(:svalues) { [value2, value1] }
@ -128,24 +138,39 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
let_it_be(:hvalmapped) { { "item1" => value1 } }
let_it_be(:sscanargs) { [skey2, 0] }
let_it_be(:sscanval) { ["0", [value1]] }
let_it_be(:sscan_eachval) { [value1] }
let_it_be(:sscan_each_arg) { { match: '*1*' } }
let_it_be(:hscan_eachval) { [[hitem1, value1]] }
let_it_be(:zscan_eachval) { [[value1, 1.0]] }
let_it_be(:scan_each_arg) { { match: 'redis*' } }
let_it_be(:scan_each_val) { [key1, key2, skey, skey2, hkey, hkey2, zkey, zkey2] }
# rubocop:disable Layout/LineLength
where(:case_name, :name, :args, :value, :block) do
'execute :get command' | :get | ref(:key1) | ref(:value1) | nil
'execute :mget command' | :mget | ref(:keys) | ref(:values) | nil
'execute :mget with block' | :mget | ref(:keys) | ref(:values) | ->(value) { value }
'execute :smembers command' | :smembers | ref(:skey) | ref(:svalues) | nil
'execute :scard command' | :scard | ref(:skey) | 2 | nil
'execute :sismember command' | :sismember | ref(:smemberargs) | true | nil
'execute :exists command' | :exists | ref(:key1) | 1 | nil
'execute :exists? command' | :exists? | ref(:key1) | true | nil
'execute :hget command' | :hget | ref(:hgetargs) | ref(:value1) | nil
'execute :hlen command' | :hlen | ref(:hkey) | 1 | nil
'execute :hgetall command' | :hgetall | ref(:hkey) | ref(:hvalmapped) | nil
'execute :hexists command' | :hexists | ref(:hgetargs) | true | nil
'execute :hmget command' | :hmget | ref(:hgetargs) | ref(:hmgetval) | nil
'execute :mapped_hmget command' | :mapped_hmget | ref(:mhmgetargs) | ref(:hvalmapped) | nil
'execute :sscan command' | :sscan | ref(:sscanargs) | ref(:sscanval) | nil
where(:case_name, :name, :args, :value, :kwargs, :block) do
'execute :get command' | :get | ref(:key1) | ref(:value1) | {} | nil
'execute :mget command' | :mget | ref(:keys) | ref(:values) | {} | nil
'execute :mget with block' | :mget | ref(:keys) | ref(:values) | {} | ->(value) { value }
'execute :smembers command' | :smembers | ref(:skey) | ref(:svalues) | {} | nil
'execute :scard command' | :scard | ref(:skey) | 2 | {} | nil
'execute :sismember command' | :sismember | ref(:smemberargs) | true | {} | nil
'execute :exists command' | :exists | ref(:key1) | 1 | {} | nil
'execute :exists? command' | :exists? | ref(:key1) | true | {} | nil
'execute :hget command' | :hget | ref(:hgetargs) | ref(:value1) | {} | nil
'execute :hlen command' | :hlen | ref(:hkey) | 1 | {} | nil
'execute :hgetall command' | :hgetall | ref(:hkey) | ref(:hvalmapped) | {} | nil
'execute :hexists command' | :hexists | ref(:hgetargs) | true | {} | nil
'execute :hmget command' | :hmget | ref(:hgetargs) | ref(:hmgetval) | {} | nil
'execute :mapped_hmget command' | :mapped_hmget | ref(:mhmgetargs) | ref(:hvalmapped) | {} | nil
'execute :sscan command' | :sscan | ref(:sscanargs) | ref(:sscanval) | {} | nil
# we run *scan_each here as they are reads too
'execute :scan_each command' | :scan_each | nil | ref(:scan_each_val) | ref(:scan_each_arg) | nil
'execute :sscan_each command' | :sscan_each | ref(:skey2) | ref(:sscan_eachval) | {} | nil
'execute :sscan_each w block' | :sscan_each | ref(:skey) | ref(:sscan_eachval) | ref(:sscan_each_arg) | nil
'execute :hscan_each command' | :hscan_each | ref(:hkey) | ref(:hscan_eachval) | {} | nil
'execute :hscan_each w block' | :hscan_each | ref(:hkey2) | ref(:hscan_eachval) | ref(:sscan_each_arg) | nil
'execute :zscan_each command' | :zscan_each | ref(:zkey) | ref(:zscan_eachval) | {} | nil
'execute :zscan_each w block' | :zscan_each | ref(:zkey2) | ref(:zscan_eachval) | ref(:sscan_each_arg) | nil
end
# rubocop:enable Layout/LineLength
@ -155,12 +180,18 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
primary_store.sadd?(skey, [value1, value2])
primary_store.sadd?(skey2, [value1])
primary_store.hset(hkey, hitem1, value1)
primary_store.hset(hkey2, hitem1, value1, hitem2, value2)
primary_store.zadd(zkey, 1, value1)
primary_store.zadd(zkey2, [[1, value1], [2, value2]])
secondary_store.set(key1, value1)
secondary_store.set(key2, value2)
secondary_store.sadd?(skey, [value1, value2])
secondary_store.sadd?(skey2, [value1])
secondary_store.hset(hkey, hitem1, value1)
secondary_store.hset(hkey2, hitem1, value1, hitem2, value2)
secondary_store.zadd(zkey, 1, value1)
secondary_store.zadd(zkey2, [[1, value1], [2, value2]])
end
after do
@ -187,7 +218,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
it 'fallback and execute on secondary instance' do
expect(secondary_store).to receive(name).with(*args).and_call_original
expect(secondary_store).to receive(name).with(*expected_args).and_call_original
subject
end
@ -211,7 +242,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
context 'when fallback read from the secondary instance raises an exception' do
before do
allow(secondary_store).to receive(name).with(*args).and_raise(StandardError)
allow(secondary_store).to receive(name).with(*expected_args).and_raise(StandardError)
end
it 'fails with exception' do
@ -222,7 +253,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
RSpec.shared_examples_for 'secondary store' do
it 'execute on the secondary instance' do
expect(secondary_store).to receive(name).with(*args).and_call_original
expect(secondary_store).to receive(name).with(*expected_args).and_call_original
subject
end
@ -238,6 +269,8 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
with_them do
describe name.to_s do
let(:expected_args) { kwargs&.present? ? [*args, { **kwargs }] : Array(args) }
before do
allow(primary_store).to receive(name).and_call_original
allow(secondary_store).to receive(name).and_call_original
@ -245,7 +278,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
context 'when reading from the primary is successful' do
it 'returns the correct value' do
expect(primary_store).to receive(name).with(*args).and_call_original
expect(primary_store).to receive(name).with(*expected_args).and_call_original
subject
end
@ -261,7 +294,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
context 'when reading from primary instance is raising an exception' do
before do
allow(primary_store).to receive(name).with(*args).and_raise(StandardError)
allow(primary_store).to receive(name).with(*expected_args).and_raise(StandardError)
allow(Gitlab::ErrorTracking).to receive(:log_exception)
end
@ -287,7 +320,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
context 'when the command is executed within pipelined block' do
subject do
multi_store.pipelined do |pipeline|
pipeline.send(name, *args)
pipeline.send(name, *args, **kwargs)
end
end
@ -297,7 +330,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
2.times do
expect_next_instance_of(Redis::PipelinedConnection) do |pipeline|
expect(pipeline).to receive(name).with(*args).once.and_call_original
expect(pipeline).to receive(name).with(*expected_args).once.and_call_original
end
end
@ -307,7 +340,7 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
if params[:block]
subject do
multi_store.send(name, *args, &block)
multi_store.send(name, *expected_args, &block)
end
context 'when block is provided' do
@ -340,8 +373,8 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
it 'executes only on secondary redis store', :aggregate_errors do
expect(secondary_store).to receive(name).with(*args).and_call_original
expect(primary_store).not_to receive(name).with(*args).and_call_original
expect(secondary_store).to receive(name).with(*expected_args).and_call_original
expect(primary_store).not_to receive(name).with(*expected_args).and_call_original
subject
end
@ -349,8 +382,8 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
context 'when using primary store as default' do
it 'executes only on primary redis store', :aggregate_errors do
expect(primary_store).to receive(name).with(*args).and_call_original
expect(secondary_store).not_to receive(name).with(*args).and_call_original
expect(primary_store).to receive(name).with(*expected_args).and_call_original
expect(secondary_store).not_to receive(name).with(*expected_args).and_call_original
subject
end
@ -361,6 +394,86 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
# rubocop:enable RSpec/MultipleMemoizedHelpers
context 'with nested command in block' do
let(:skey) { "test_set" }
let(:values) { %w[{x}a {x}b {x}c] }
before do
primary_store.set('{x}a', 1)
primary_store.set('{x}b', 2)
primary_store.set('{x}c', 3)
secondary_store.set('{x}a', 10)
secondary_store.set('{x}b', 20)
secondary_store.set('{x}c', 30)
end
subject do
multi_store.mget(values) do |v|
multi_store.sadd(skey, v)
multi_store.scard(skey)
v # mget receiving block returns the last line of the block for cache-hit check
end
end
RSpec.shared_examples_for 'primary instance executes block' do
it 'ensures primary instance is executing the block' do
expect(primary_store).to receive(:send).with(:mget, values).and_call_original
expect(primary_store).to receive(:send).with(:sadd, skey, %w[1 2 3]).and_call_original
expect(primary_store).to receive(:send).with(:scard, skey).and_call_original
expect(secondary_store).not_to receive(:send).with(:mget, values).and_call_original
expect(secondary_store).not_to receive(:send).with(:sadd, skey, %w[1 2 3]).and_call_original
expect(secondary_store).not_to receive(:send).with(:scard, skey).and_call_original
subject
end
end
context 'when using both stores' do
context 'when primary instance is default store' do
it_behaves_like 'primary instance executes block'
end
context 'when secondary instance is default store' do
before do
stub_feature_flags(use_primary_store_as_default_for_test_store: false)
end
# multistore read still favours the primary store
it_behaves_like 'primary instance executes block'
end
end
context 'when using 1 store only' do
before do
stub_feature_flags(use_primary_and_secondary_stores_for_test_store: false)
end
context 'when primary instance is default store' do
it_behaves_like 'primary instance executes block'
end
context 'when secondary instance is default store' do
before do
stub_feature_flags(use_primary_store_as_default_for_test_store: false)
end
it 'ensures only secondary instance is executing the block' do
expect(secondary_store).to receive(:send).with(:mget, values).and_call_original
expect(secondary_store).to receive(:send).with(:sadd, skey, %w[10 20 30]).and_call_original
expect(secondary_store).to receive(:send).with(:scard, skey).and_call_original
expect(primary_store).not_to receive(:send).with(:mget, values).and_call_original
expect(primary_store).not_to receive(:send).with(:sadd, skey, %w[10 20 30]).and_call_original
expect(primary_store).not_to receive(:send).with(:scard, skey).and_call_original
subject
end
end
end
end
RSpec.shared_examples_for 'verify that store contains values' do |store|
it "#{store} redis store contains correct values", :aggregate_errors do
subject
@ -540,6 +653,120 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
# rubocop:enable RSpec/MultipleMemoizedHelpers
context 'with ENUMERATOR_COMMANDS redis commands' do
let_it_be(:hkey) { "redis:hash" }
let_it_be(:skey) { "redis:set" }
let_it_be(:zkey) { "redis:sortedset" }
let_it_be(:rvalue) { "value1" }
let_it_be(:scan_kwargs) { { match: 'redis:hash' } }
where(:case_name, :name, :args, :kwargs) do
'execute :scan_each command' | :scan_each | nil | ref(:scan_kwargs)
'execute :sscan_each command' | :sscan_each | ref(:skey) | {}
'execute :hscan_each command' | :hscan_each | ref(:hkey) | {}
'execute :zscan_each command' | :zscan_each | ref(:zkey) | {}
end
before(:all) do
primary_store.hset(hkey, rvalue, 1)
primary_store.sadd?(skey, rvalue)
primary_store.zadd(zkey, 1, rvalue)
secondary_store.hset(hkey, rvalue, 1)
secondary_store.sadd?(skey, rvalue)
secondary_store.zadd(zkey, 1, rvalue)
end
RSpec.shared_examples_for 'enumerator commands execution' do |both_stores, default_primary|
context 'without block passed in' do
subject do
multi_store.send(name, *args, **kwargs)
end
it 'returns an enumerator' do
expect(subject).to be_instance_of(Enumerator)
end
end
context 'with block passed in' do
subject do
multi_store.send(name, *args, **kwargs) { |key| multi_store.incr(rvalue) }
end
it 'returns nil' do
expect(subject).to eq(nil)
end
it 'runs block on correct Redis instance' do
if both_stores
expect(primary_store).to receive(name).with(*expected_args).and_call_original
expect(secondary_store).not_to receive(name)
expect(primary_store).to receive(:incr).with(rvalue)
expect(secondary_store).to receive(:incr).with(rvalue)
elsif default_primary
expect(primary_store).to receive(name).with(*expected_args).and_call_original
expect(primary_store).to receive(:incr).with(rvalue)
expect(secondary_store).not_to receive(name)
expect(secondary_store).not_to receive(:incr).with(rvalue)
else
expect(secondary_store).to receive(name).with(*expected_args).and_call_original
expect(secondary_store).to receive(:incr).with(rvalue)
expect(primary_store).not_to receive(name)
expect(primary_store).not_to receive(:incr).with(rvalue)
end
subject
end
end
end
with_them do
describe name.to_s do
let(:expected_args) { kwargs.present? ? [*args, { **kwargs }] : Array(args) }
before do
allow(primary_store).to receive(name).and_call_original
allow(secondary_store).to receive(name).and_call_original
end
context 'when only using 1 store' do
before do
stub_feature_flags(use_primary_and_secondary_stores_for_test_store: false)
end
context 'when using secondary store as default' do
before do
stub_feature_flags(use_primary_store_as_default_for_test_store: false)
end
it_behaves_like 'enumerator commands execution', false, false
end
context 'when using primary store as default' do
it_behaves_like 'enumerator commands execution', false, true
end
end
context 'when using both stores' do
context 'when using secondary store as default' do
before do
stub_feature_flags(use_primary_store_as_default_for_test_store: false)
end
it_behaves_like 'enumerator commands execution', true, false
end
context 'when using primary store as default' do
it_behaves_like 'enumerator commands execution', true, true
end
end
end
end
end
RSpec.shared_examples_for 'pipelined command' do |name|
let_it_be(:key1) { "redis:{1}:key_a" }
let_it_be(:value1) { "redis_value1" }

View File

@ -10,7 +10,7 @@ RSpec.describe Users::SignupService do
it 'updates the name attribute' do
result = update_user(user, name: 'New Name')
expect(result).to eq(status: :success)
expect(result.success?).to be(true)
expect(user.reload.name).to eq('New Name')
end
@ -18,8 +18,8 @@ RSpec.describe Users::SignupService do
result = update_user(user, name: '')
expect(user.reload.name).not_to be_blank
expect(result[:status]).to eq(:error)
expect(result[:message]).to include("Name can't be blank")
expect(result.success?).to be(false)
expect(result.message).to include("Name can't be blank")
end
end
@ -27,7 +27,7 @@ RSpec.describe Users::SignupService do
it 'updates the role attribute' do
result = update_user(user, role: 'development_team_lead')
expect(result).to eq(status: :success)
expect(result.success?).to be(true)
expect(user.reload.role).to eq('development_team_lead')
end
@ -35,8 +35,8 @@ RSpec.describe Users::SignupService do
result = update_user(user, role: '')
expect(user.reload.role).not_to be_blank
expect(result[:status]).to eq(:error)
expect(result[:message]).to eq("Role can't be blank")
expect(result.success?).to be(false)
expect(result.message).to eq("Role can't be blank")
end
end
@ -44,7 +44,7 @@ RSpec.describe Users::SignupService do
it 'updates the setup_for_company attribute' do
result = update_user(user, setup_for_company: 'false')
expect(result).to eq(status: :success)
expect(result.success?).to be(true)
expect(user.reload.setup_for_company).to be(false)
end
@ -57,8 +57,8 @@ RSpec.describe Users::SignupService do
result = update_user(user, setup_for_company: '')
expect(user.reload.setup_for_company).not_to be_blank
expect(result[:status]).to eq(:error)
expect(result[:message]).to eq("Setup for company can't be blank")
expect(result.success?).to be(false)
expect(result.message).to eq("Setup for company can't be blank")
end
end
@ -66,7 +66,7 @@ RSpec.describe Users::SignupService do
it 'returns success when setup_for_company is blank' do
result = update_user(user, setup_for_company: '')
expect(result).to eq(status: :success)
expect(result.success?).to be(true)
expect(user.reload.setup_for_company).to be(nil)
end
end

View File

@ -175,7 +175,6 @@
- './ee/spec/controllers/registrations/groups_projects_controller_spec.rb'
- './ee/spec/controllers/registrations/projects_controller_spec.rb'
- './ee/spec/controllers/registrations/verification_controller_spec.rb'
- './ee/spec/controllers/registrations/welcome_controller_spec.rb'
- './ee/spec/controllers/repositories/git_http_controller_spec.rb'
- './ee/spec/controllers/security/dashboard_controller_spec.rb'
- './ee/spec/controllers/security/projects_controller_spec.rb'
@ -3705,7 +3704,6 @@
- './spec/controllers/projects/web_ide_terminals_controller_spec.rb'
- './spec/controllers/projects/wikis_controller_spec.rb'
- './spec/controllers/registrations_controller_spec.rb'
- './spec/controllers/registrations/welcome_controller_spec.rb'
- './spec/controllers/repositories/git_http_controller_spec.rb'
- './spec/controllers/repositories/lfs_storage_controller_spec.rb'
- './spec/controllers/root_controller_spec.rb'

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
Integration.available_integration_names(include_feature_flagged: true).each do |integration|
Integration.available_integration_names.each do |integration|
RSpec.shared_context integration do
include JiraIntegrationHelpers if integration == 'jira'