Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-07-23 00:26:35 +00:00
parent 013d339e9a
commit 8212b8fd70
77 changed files with 619 additions and 239 deletions

View File

@ -587,11 +587,13 @@ lib/gitlab/checks/**
/doc/administration/package_information/ @axil /doc/administration/package_information/ @axil
/doc/administration/packages/ @marcel.amirault /doc/administration/packages/ @marcel.amirault
/doc/administration/packages/index.md @phillipwells /doc/administration/packages/index.md @phillipwells
/doc/administration/pages/ @msedlakjakubowski
/doc/administration/polling.md @axil /doc/administration/polling.md @axil
/doc/administration/postgresql/ @lciutacu /doc/administration/postgresql/ @lciutacu
/doc/administration/raketasks/ @axil /doc/administration/raketasks/ @axil
/doc/administration/raketasks/ldap.md @jglassman1 /doc/administration/raketasks/ldap.md @jglassman1
/doc/administration/raketasks/praefect.md @eread /doc/administration/raketasks/praefect.md @eread
/doc/administration/raketasks/tokens/ @jglassman1
/doc/administration/read_only_gitlab.md @axil /doc/administration/read_only_gitlab.md @axil
/doc/administration/redis/ @axil /doc/administration/redis/ @axil
/doc/administration/reference_architectures/ @axil /doc/administration/reference_architectures/ @axil
@ -646,6 +648,7 @@ lib/gitlab/checks/**
/doc/administration/troubleshooting/ @axil /doc/administration/troubleshooting/ @axil
/doc/administration/uploads.md @axil /doc/administration/uploads.md @axil
/doc/administration/user_settings.md @jglassman1 /doc/administration/user_settings.md @jglassman1
/doc/administration/wikis/ @msedlakjakubowski
/doc/api/access_requests.md @jglassman1 /doc/api/access_requests.md @jglassman1
/doc/api/admin_sidekiq_queues.md @axil /doc/api/admin_sidekiq_queues.md @axil
/doc/api/api_resources.md @eread /doc/api/api_resources.md @eread
@ -706,6 +709,7 @@ lib/gitlab/checks/**
/doc/api/group_releases.md @phillipwells /doc/api/group_releases.md @phillipwells
/doc/api/group_repository_storage_moves.md @ashrafkhamis /doc/api/group_repository_storage_moves.md @ashrafkhamis
/doc/api/group_ssh_certificates.md @msedlakjakubowski /doc/api/group_ssh_certificates.md @msedlakjakubowski
/doc/api/group_wikis.md @msedlakjakubowski
/doc/api/groups.md @lciutacu /doc/api/groups.md @lciutacu
/doc/api/import.md @eread /doc/api/import.md @eread
/doc/api/index.md @eread /doc/api/index.md @eread
@ -738,6 +742,8 @@ lib/gitlab/checks/**
/doc/api/openapi/ @eread /doc/api/openapi/ @eread
/doc/api/packages.md @phillipwells /doc/api/packages.md @phillipwells
/doc/api/packages/ @phillipwells /doc/api/packages/ @phillipwells
/doc/api/pages.md @msedlakjakubowski
/doc/api/pages_domains.md @msedlakjakubowski
/doc/api/personal_access_tokens.md @jglassman1 /doc/api/personal_access_tokens.md @jglassman1
/doc/api/pipeline_schedules.md @marcel.amirault @lyspin /doc/api/pipeline_schedules.md @marcel.amirault @lyspin
/doc/api/pipeline_triggers.md @marcel.amirault @lyspin /doc/api/pipeline_triggers.md @marcel.amirault @lyspin
@ -800,6 +806,7 @@ lib/gitlab/checks/**
/doc/api/vulnerabilities.md @rdickenson /doc/api/vulnerabilities.md @rdickenson
/doc/api/vulnerability_exports.md @rdickenson /doc/api/vulnerability_exports.md @rdickenson
/doc/api/vulnerability_findings.md @rdickenson /doc/api/vulnerability_findings.md @rdickenson
/doc/api/wikis.md @msedlakjakubowski
/doc/ci/ @marcel.amirault @lyspin /doc/ci/ @marcel.amirault @lyspin
/doc/ci/chatops/ @phillipwells /doc/ci/chatops/ @phillipwells
/doc/ci/cloud_deployment/ @phillipwells /doc/ci/cloud_deployment/ @phillipwells
@ -899,6 +906,7 @@ lib/gitlab/checks/**
/doc/tutorials/dependency_scanning.md @rdickenson @phillipwells /doc/tutorials/dependency_scanning.md @rdickenson @phillipwells
/doc/tutorials/export_sbom.md @rdickenson @phillipwells /doc/tutorials/export_sbom.md @rdickenson @phillipwells
/doc/tutorials/fuzz_testing/ @rdickenson @phillipwells /doc/tutorials/fuzz_testing/ @rdickenson @phillipwells
/doc/tutorials/hugo/ @msedlakjakubowski
/doc/tutorials/idea_management/ @msedlakjakubowski /doc/tutorials/idea_management/ @msedlakjakubowski
/doc/tutorials/install_gitlab_single_node/ @axil /doc/tutorials/install_gitlab_single_node/ @axil
/doc/tutorials/issue_triage/ @msedlakjakubowski /doc/tutorials/issue_triage/ @msedlakjakubowski
@ -914,6 +922,7 @@ lib/gitlab/checks/**
/doc/tutorials/update_commit_messages/ @msedlakjakubowski /doc/tutorials/update_commit_messages/ @msedlakjakubowski
/doc/tutorials/website_project_with_analytics/ @lciutacu /doc/tutorials/website_project_with_analytics/ @lciutacu
/doc/update/ @axil /doc/update/ @axil
/doc/user/ @msedlakjakubowski
/doc/user/analytics/ @lciutacu /doc/user/analytics/ @lciutacu
/doc/user/analytics/ci_cd_analytics.md @phillipwells /doc/user/analytics/ci_cd_analytics.md @phillipwells
/doc/user/application_security/ @rdickenson @phillipwells /doc/user/application_security/ @rdickenson @phillipwells
@ -923,13 +932,11 @@ lib/gitlab/checks/**
/doc/user/application_security/security_dashboard/ @rdickenson /doc/user/application_security/security_dashboard/ @rdickenson
/doc/user/application_security/vulnerabilities/ @rdickenson /doc/user/application_security/vulnerabilities/ @rdickenson
/doc/user/application_security/vulnerability_report/ @rdickenson /doc/user/application_security/vulnerability_report/ @rdickenson
/doc/user/asciidoc.md @msedlakjakubowski
/doc/user/clusters/ @phillipwells /doc/user/clusters/ @phillipwells
/doc/user/compliance/ @eread /doc/user/compliance/ @eread
/doc/user/compliance/license_approval_policies.md @rdickenson /doc/user/compliance/license_approval_policies.md @rdickenson
/doc/user/compliance/license_scanning_of_cyclonedx_files/ @rdickenson @phillipwells /doc/user/compliance/license_scanning_of_cyclonedx_files/ @rdickenson @phillipwells
/doc/user/discussions/ @aqualls /doc/user/discussions/ @aqualls
/doc/user/emoji_reactions.md @msedlakjakubowski
/doc/user/enterprise_user/ @jglassman1 /doc/user/enterprise_user/ @jglassman1
/doc/user/get_started/get_started_managing_code.md @msedlakjakubowski /doc/user/get_started/get_started_managing_code.md @msedlakjakubowski
/doc/user/get_started/get_started_managing_infrastructure.md @phillipwells /doc/user/get_started/get_started_managing_infrastructure.md @phillipwells
@ -962,9 +969,7 @@ lib/gitlab/checks/**
/doc/user/infrastructure/ @phillipwells /doc/user/infrastructure/ @phillipwells
/doc/user/infrastructure/clusters/manage/management_project_applications/ @phillipwells /doc/user/infrastructure/clusters/manage/management_project_applications/ @phillipwells
/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md @ashrafkhamis /doc/user/infrastructure/clusters/manage/management_project_applications/runner.md @ashrafkhamis
/doc/user/markdown.md @msedlakjakubowski
/doc/user/namespace/ @lciutacu /doc/user/namespace/ @lciutacu
/doc/user/okrs.md @msedlakjakubowski
/doc/user/operations_dashboard/ @phillipwells /doc/user/operations_dashboard/ @phillipwells
/doc/user/organization/ @lciutacu /doc/user/organization/ @lciutacu
/doc/user/packages/ @phillipwells /doc/user/packages/ @phillipwells
@ -976,7 +981,6 @@ lib/gitlab/checks/**
/doc/user/profile/achievements.md @lciutacu /doc/user/profile/achievements.md @lciutacu
/doc/user/profile/comment_templates.md @aqualls /doc/user/profile/comment_templates.md @aqualls
/doc/user/profile/contributions_calendar.md @lciutacu /doc/user/profile/contributions_calendar.md @lciutacu
/doc/user/project/ @msedlakjakubowski
/doc/user/project/badges.md @lciutacu /doc/user/project/badges.md @lciutacu
/doc/user/project/clusters/ @phillipwells /doc/user/project/clusters/ @phillipwells
/doc/user/project/code_intelligence.md @aqualls /doc/user/project/code_intelligence.md @aqualls
@ -1028,11 +1032,9 @@ lib/gitlab/checks/**
/doc/user/public_access.md @lciutacu /doc/user/public_access.md @lciutacu
/doc/user/reserved_names.md @lciutacu /doc/user/reserved_names.md @lciutacu
/doc/user/search/ @ashrafkhamis /doc/user/search/ @ashrafkhamis
/doc/user/snippets.md @msedlakjakubowski
/doc/user/ssh.md @jglassman1 /doc/user/ssh.md @jglassman1
/doc/user/ssh_troubleshooting.md @jglassman1 /doc/user/ssh_troubleshooting.md @jglassman1
/doc/user/storage_management_automation.md @fneill /doc/user/storage_management_automation.md @fneill
/doc/user/tasks.md @msedlakjakubowski
/doc/user/usage_quotas.md @fneill /doc/user/usage_quotas.md @fneill
/doc/user/workspace/ @ashrafkhamis /doc/user/workspace/ @ashrafkhamis
# End rake-managed-docs-block # End rake-managed-docs-block

View File

@ -407,7 +407,8 @@ gem 'webrick', '~> 1.8.1', require: false # rubocop:todo Gemfile/MissingFeatureC
gem 'prometheus-client-mmap', '~> 1.1', '>= 1.1.1', require: 'prometheus/client' # rubocop:todo Gemfile/MissingFeatureCategory gem 'prometheus-client-mmap', '~> 1.1', '>= 1.1.1', require: 'prometheus/client' # rubocop:todo Gemfile/MissingFeatureCategory
# Event-driven reactor for Ruby # Event-driven reactor for Ruby
gem 'async', '~> 2.12.1' # rubocop:disable Gemfile/MissingFeatureCategory -- This is general utility gem # Required manually in config/initializers/require_async_gem
gem 'async', '~> 2.12.1', require: false # rubocop:disable Gemfile/MissingFeatureCategory -- This is general utility gem
# OpenTelemetry # OpenTelemetry
group :opentelemetry do group :opentelemetry do

View File

@ -8,7 +8,7 @@ import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import { waitForElement } from '~/lib/utils/dom_utils'; import { waitForElement } from '~/lib/utils/dom_utils';
import findAndFollowLink from '~/lib/utils/navigation_utility'; import findAndFollowLink from '~/lib/utils/navigation_utility';
import { refreshCurrentPage } from '~/lib/utils/url_utility'; import { refreshCurrentPage } from '~/lib/utils/url_utility';
import { helpCenterState } from '~/super_sidebar/constants'; import { duoChatGlobalState } from '~/super_sidebar/constants';
import { import {
keysFor, keysFor,
TOGGLE_KEYBOARD_SHORTCUTS_DIALOG, TOGGLE_KEYBOARD_SHORTCUTS_DIALOG,
@ -225,7 +225,7 @@ export default class Shortcuts {
static onToggleDuoChat(e) { static onToggleDuoChat(e) {
e.preventDefault(); e.preventDefault();
helpCenterState.showTanukiBotChatDrawer = !helpCenterState.showTanukiBotChatDrawer; duoChatGlobalState.isShown = !duoChatGlobalState.isShown;
} }
static onTogglePerfBar(e) { static onTogglePerfBar(e) {

View File

@ -60,6 +60,7 @@ export default {
modelData: null, modelData: null,
versionData: null, versionData: null,
markdownDocPath: helpPagePath('user/markdown'), markdownDocPath: helpPagePath('user/markdown'),
markdownEditorRestrictedToolBarItems: ['full-screen'],
}; };
}, },
computed: { computed: {
@ -242,7 +243,7 @@ export default {
:title="$options.modal.title" :title="$options.modal.title"
:action-primary="actionPrimary" :action-primary="actionPrimary"
:action-secondary="$options.modal.actionSecondary" :action-secondary="$options.modal.actionSecondary"
size="sm" size="lg"
@primary="create" @primary="create"
@secondary="resetModal" @secondary="resetModal"
> >
@ -284,6 +285,7 @@ export default {
:markdown-docs-path="markdownDocPath" :markdown-docs-path="markdownDocPath"
:disable-attachments="disableAttachments" :disable-attachments="disableAttachments"
:placeholder="$options.modal.nameDescriptionPlaceholder" :placeholder="$options.modal.nameDescriptionPlaceholder"
:restricted-tool-bar-items="markdownEditorRestrictedToolBarItems"
@input="setDescription" @input="setDescription"
/> />
</gl-form-group> </gl-form-group>

View File

@ -173,7 +173,7 @@ export default {
:title="$options.modal.title" :title="$options.modal.title"
:action-primary="actionPrimary" :action-primary="actionPrimary"
:action-secondary="$options.modal.actionSecondary" :action-secondary="$options.modal.actionSecondary"
size="sm" size="lg"
@primary="create" @primary="create"
@secondary="resetModal" @secondary="resetModal"
> >

View File

@ -6,7 +6,7 @@ import { FORUM_URL, PROMO_URL } from 'jh_else_ce/lib/utils/url_utility';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { STORAGE_KEY } from '~/whats_new/utils/notification'; import { STORAGE_KEY } from '~/whats_new/utils/notification';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
import { DROPDOWN_Y_OFFSET, HELP_MENU_TRACKING_DEFAULTS, helpCenterState } from '../constants'; import { DROPDOWN_Y_OFFSET, HELP_MENU_TRACKING_DEFAULTS, duoChatGlobalState } from '../constants';
export default { export default {
components: { components: {
@ -39,7 +39,7 @@ export default {
data() { data() {
return { return {
showWhatsNewNotification: this.shouldShowWhatsNewNotification(), showWhatsNewNotification: this.shouldShowWhatsNewNotification(),
helpCenterState, duoChatGlobalState,
toggleWhatsNewDrawer: null, toggleWhatsNewDrawer: null,
}; };
}, },

View File

@ -21,8 +21,9 @@ export const sidebarState = Vue.observable({
wasHoverPeek: false, wasHoverPeek: false,
}); });
export const helpCenterState = Vue.observable({ export const duoChatGlobalState = Vue.observable({
showTanukiBotChatDrawer: false, commands: [],
isShown: false,
}); });
export const SUPER_SIDEBAR_PEEK_OPEN_DELAY = 200; export const SUPER_SIDEBAR_PEEK_OPEN_DELAY = 200;

View File

@ -119,6 +119,11 @@ export default {
required: false, required: false,
default: () => ({}), default: () => ({}),
}, },
restrictedToolBarItems: {
type: Array,
required: false,
default: () => [],
},
}, },
data() { data() {
const editingMode = const editingMode =
@ -139,7 +144,9 @@ export default {
return this.autofocus && !this.autofocused ? 'end' : false; return this.autofocus && !this.autofocused ? 'end' : false;
}, },
markdownFieldRestrictedToolBarItems() { markdownFieldRestrictedToolBarItems() {
return this.disableAttachments ? ['attach-file'] : []; const restrictAttachments = this.disableAttachments ? ['attach-file'] : [];
return [...this.restrictedToolBarItems, ...restrictAttachments];
}, },
}, },
watch: { watch: {

View File

@ -187,10 +187,15 @@ class GraphqlController < ApplicationController
def disable_query_limiting def disable_query_limiting
return unless Gitlab::QueryLimiting.enabled_for_env? return unless Gitlab::QueryLimiting.enabled_for_env?
disable_issue = request.headers[DISABLE_SQL_QUERY_LIMIT_HEADER] disable_reference = request.headers[DISABLE_SQL_QUERY_LIMIT_HEADER]
return unless disable_issue return unless disable_reference
Gitlab::QueryLimiting.disable!(disable_issue) disable_issue, new_threshold = disable_reference.split(';')
if new_threshold
Gitlab::QueryLimiting.disable!(disable_issue, new_threshold: new_threshold&.to_i)
else
Gitlab::QueryLimiting.disable!(disable_issue)
end
end end
def set_user_last_activity def set_user_last_activity

View File

@ -21,7 +21,10 @@ class Import::GitlabGroupsController < ApplicationController
) )
.with_defaults(organization_id: Current.organization_id) .with_defaults(organization_id: Current.organization_id)
response = ::Groups::CreateService.new(current_user, group_data).execute response = Namespace.with_disabled_organization_validation do
::Groups::CreateService.new(current_user, group_data).execute
end
group = response[:group] group = response[:group]
if response.success? if response.success?

View File

@ -22,7 +22,9 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController
return admin_mode_flow(Gitlab::Auth::Ldap::User) if current_user_mode.admin_mode_requested? return admin_mode_flow(Gitlab::Auth::Ldap::User) if current_user_mode.admin_mode_requested?
end end
sign_in_user_flow(Gitlab::Auth::Ldap::User) Namespace.with_disabled_organization_validation do
sign_in_user_flow(Gitlab::Auth::Ldap::User)
end
end end
define_providers! define_providers!

View File

@ -165,7 +165,9 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
redirect_identity_exists redirect_identity_exists
end end
else else
sign_in_user_flow(auth_module::User) Namespace.with_disabled_organization_validation do
sign_in_user_flow(auth_module::User)
end
end end
end end

View File

@ -38,14 +38,15 @@ class RegistrationsController < Devise::RegistrationsController
def create def create
set_resource_fields set_resource_fields
super do |new_user| Namespace.with_disabled_organization_validation do
if new_user.persisted? super do |new_user|
after_successful_create_hook(new_user) if new_user.persisted?
else after_successful_create_hook(new_user)
track_error(new_user) else
track_error(new_user)
end
end end
end end
# Devise sets a flash message on both successful & failed signups, # Devise sets a flash message on both successful & failed signups,
# but we only want to show a message if the resource is blocked by a pending approval. # but we only want to show a message if the resource is blocked by a pending approval.
flash[:notice] = nil unless allow_flash_content?(resource) flash[:notice] = nil unless allow_flash_content?(resource)

View File

@ -7,79 +7,42 @@ module Types
graphql_name 'WorkItemWidget' graphql_name 'WorkItemWidget'
field :type, ::Types::WorkItems::WidgetTypeEnum, field :type,
::Types::WorkItems::WidgetTypeEnum,
null: true, null: true,
description: 'Widget type.' description: 'Widget type.'
ORPHAN_TYPES = [
::Types::WorkItems::Widgets::DescriptionType,
::Types::WorkItems::Widgets::HierarchyType,
::Types::WorkItems::Widgets::LabelsType,
::Types::WorkItems::Widgets::AssigneesType,
::Types::WorkItems::Widgets::StartAndDueDateType,
::Types::WorkItems::Widgets::MilestoneType,
::Types::WorkItems::Widgets::NotesType,
::Types::WorkItems::Widgets::NotificationsType,
::Types::WorkItems::Widgets::CurrentUserTodosType,
::Types::WorkItems::Widgets::AwardEmojiType,
::Types::WorkItems::Widgets::LinkedItemsType,
::Types::WorkItems::Widgets::ParticipantsType,
::Types::WorkItems::Widgets::TimeTracking::TimeTrackingType,
::Types::WorkItems::Widgets::DesignsType,
::Types::WorkItems::Widgets::DevelopmentType,
::Types::WorkItems::Widgets::CrmContactsType
].freeze
def self.ce_orphan_types
ORPHAN_TYPES
end
# Whenever a new widget is added make sure to update the spec to avoid N + 1 queries in # Whenever a new widget is added make sure to update the spec to avoid N + 1 queries in
# spec/requests/api/graphql/project/work_items_spec.rb and add the necessary preloads # spec/requests/api/graphql/project/work_items_spec.rb and add the necessary preloads
# in app/graphql/resolvers/work_items_resolver.rb # in app/graphql/resolvers/work_items_resolver.rb
# TYPE_MAPPINGS = {
# rubocop:disable Metrics/CyclomaticComplexity -- we'll have a lot of widgets to handle in the WidgetInterface ::WorkItems::Widgets::Description => ::Types::WorkItems::Widgets::DescriptionType,
def self.resolve_type(object, context) ::WorkItems::Widgets::Hierarchy => ::Types::WorkItems::Widgets::HierarchyType,
case object ::WorkItems::Widgets::Labels => ::Types::WorkItems::Widgets::LabelsType,
when ::WorkItems::Widgets::Description ::WorkItems::Widgets::Assignees => ::Types::WorkItems::Widgets::AssigneesType,
::Types::WorkItems::Widgets::DescriptionType ::WorkItems::Widgets::StartAndDueDate => ::Types::WorkItems::Widgets::StartAndDueDateType,
when ::WorkItems::Widgets::Hierarchy ::WorkItems::Widgets::Milestone => ::Types::WorkItems::Widgets::MilestoneType,
::Types::WorkItems::Widgets::HierarchyType ::WorkItems::Widgets::Notes => ::Types::WorkItems::Widgets::NotesType,
when ::WorkItems::Widgets::Assignees ::WorkItems::Widgets::Notifications => ::Types::WorkItems::Widgets::NotificationsType,
::Types::WorkItems::Widgets::AssigneesType ::WorkItems::Widgets::CurrentUserTodos => ::Types::WorkItems::Widgets::CurrentUserTodosType,
when ::WorkItems::Widgets::Labels ::WorkItems::Widgets::AwardEmoji => ::Types::WorkItems::Widgets::AwardEmojiType,
::Types::WorkItems::Widgets::LabelsType ::WorkItems::Widgets::LinkedItems => ::Types::WorkItems::Widgets::LinkedItemsType,
when ::WorkItems::Widgets::StartAndDueDate ::WorkItems::Widgets::Participants => ::Types::WorkItems::Widgets::ParticipantsType,
::Types::WorkItems::Widgets::StartAndDueDateType ::WorkItems::Widgets::TimeTracking => ::Types::WorkItems::Widgets::TimeTracking::TimeTrackingType,
when ::WorkItems::Widgets::Milestone ::WorkItems::Widgets::Designs => ::Types::WorkItems::Widgets::DesignsType,
::Types::WorkItems::Widgets::MilestoneType ::WorkItems::Widgets::Development => ::Types::WorkItems::Widgets::DevelopmentType,
when ::WorkItems::Widgets::Notes ::WorkItems::Widgets::CrmContacts => ::Types::WorkItems::Widgets::CrmContactsType
::Types::WorkItems::Widgets::NotesType }.freeze
when ::WorkItems::Widgets::Notifications
::Types::WorkItems::Widgets::NotificationsType
when ::WorkItems::Widgets::CurrentUserTodos
::Types::WorkItems::Widgets::CurrentUserTodosType
when ::WorkItems::Widgets::AwardEmoji
::Types::WorkItems::Widgets::AwardEmojiType
when ::WorkItems::Widgets::LinkedItems
::Types::WorkItems::Widgets::LinkedItemsType
when ::WorkItems::Widgets::Participants
::Types::WorkItems::Widgets::ParticipantsType
when ::WorkItems::Widgets::TimeTracking
::Types::WorkItems::Widgets::TimeTracking::TimeTrackingType
when ::WorkItems::Widgets::Designs
::Types::WorkItems::Widgets::DesignsType
when ::WorkItems::Widgets::Development
::Types::WorkItems::Widgets::DevelopmentType
when ::WorkItems::Widgets::CrmContacts
::Types::WorkItems::Widgets::CrmContactsType
else
raise "Unknown GraphQL type for widget #{object}"
end
end
# rubocop:enable Metrics/CyclomaticComplexity
orphan_types(*ORPHAN_TYPES) def self.type_mappings
TYPE_MAPPINGS
end
def self.resolve_type(object, context)
type_mappings[object.class] || raise("Unknown GraphQL type for widget #{object}")
end
orphan_types(*type_mappings.values)
end end
end end
end end

View File

@ -115,6 +115,7 @@ class Namespace < ApplicationRecord
has_one :import_user, class_name: 'User', through: :namespace_import_user, foreign_key: :user_id has_one :import_user, class_name: 'User', through: :namespace_import_user, foreign_key: :user_id
validates :owner, presence: true, if: ->(n) { n.owner_required? } validates :owner, presence: true, if: ->(n) { n.owner_required? }
validates :organization, presence: true, if: :require_organization?
validates :name, validates :name,
presence: true, presence: true,
length: { maximum: 255 } length: { maximum: 255 }
@ -351,6 +352,15 @@ class Namespace < ApplicationRecord
coalesce = Arel::Nodes::NamedFunction.new('COALESCE', [sum, 0]) coalesce = Arel::Nodes::NamedFunction.new('COALESCE', [sum, 0])
coalesce.as(column.to_s) coalesce.as(column.to_s)
end end
def with_disabled_organization_validation
current_value = Gitlab::SafeRequestStore[:require_organization]
Gitlab::SafeRequestStore[:require_organization] = false
yield
ensure
Gitlab::SafeRequestStore[:require_organization] = current_value
end
end end
def to_reference_base(from = nil, full: false, absolute_path: false) def to_reference_base(from = nil, full: false, absolute_path: false)
@ -712,6 +722,12 @@ class Namespace < ApplicationRecord
:active_pages_deployments) :active_pages_deployments)
end end
def require_organization?
return false unless Feature.enabled?(:require_organization, Feature.current_request)
Gitlab::SafeRequestStore.fetch(:require_organization) { true } # rubocop:disable Style/RedundantFetchBlock -- This fetch has a different interface
end
private private
def cross_namespace_reference?(from) def cross_namespace_reference?(from)

View File

@ -27,7 +27,9 @@ module Ci
runner = ::Ci::Runner.new(params) runner = ::Ci::Runner.new(params)
return ServiceResponse.success(payload: { runner: runner }) if runner.save if Namespace.with_disabled_organization_validation { runner.save }
return ServiceResponse.success(payload: { runner: runner })
end
ServiceResponse.error(message: runner.errors.full_messages, reason: :save_error) ServiceResponse.error(message: runner.errors.full_messages, reason: :save_error)
end end

View File

@ -17,7 +17,7 @@ module Groups
@group.name ||= @group.path.dup @group.name ||= @group.path.dup
create_chat_team create_chat_team
create_group Namespace.with_disabled_organization_validation { create_group }
return error_response unless @group.persisted? return error_response unless @group.persisted?

View File

@ -39,7 +39,7 @@ module Groups
group.assign_attributes(params) group.assign_attributes(params)
begin begin
success = group.save success = Namespace.with_disabled_organization_validation { group.save }
after_update if success after_update if success

View File

@ -88,7 +88,7 @@ module MergeRequests
trigger_merge_request_reviewers_updated(merge_request) trigger_merge_request_reviewers_updated(merge_request)
capture_suggested_reviewers_accepted(merge_request) capture_suggested_reviewers_accepted(merge_request)
set_first_reviewer_assigned_at_metrics(merge_request, current_user) if new_reviewers.any? set_first_reviewer_assigned_at_metrics(merge_request) if new_reviewers.any?
end end
def cleanup_environments(merge_request) def cleanup_environments(merge_request)
@ -279,9 +279,7 @@ module MergeRequests
# Implemented in EE # Implemented in EE
end end
def set_first_reviewer_assigned_at_metrics(merge_request, user) def set_first_reviewer_assigned_at_metrics(merge_request)
return unless Feature.enabled?(:store_first_reviewer_assignment_timestamp_in_metrics, user, type: :beta)
metrics = merge_request.metrics metrics = merge_request.metrics
return unless metrics return unless metrics

View File

@ -13,7 +13,9 @@ module Users
user = build_class.new(current_user, params).execute user = build_class.new(current_user, params).execute
reset_token = user.generate_reset_token if user.recently_sent_password_reset? reset_token = user.generate_reset_token if user.recently_sent_password_reset?
after_create_hook(user, reset_token) if user.save Namespace.with_disabled_organization_validation do
after_create_hook(user, reset_token) if user.save
end
user user
end end

View File

@ -1,9 +1,9 @@
--- ---
name: store_first_reviewer_assignment_timestamp_in_metrics name: require_organization
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/466383 feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/411832
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158422 introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155732
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/470926 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/470839
milestone: '17.2' milestone: '17.3'
group: group::optimize group: group::tenant scale
type: beta type: gitlab_com_derisk
default_enabled: true default_enabled: false

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
if RUBY_VERSION >= "3.3"
# No more such warnings in Ruby 3.3+
require 'async'
else
# Silences this warning while requiring async gem:
# `warning: IO::Buffer is experimental and both the Ruby and C interface may change in the future!`
# See also https://github.com/socketry/io-event/issues/82
Kernel.silence_warnings do
require 'async'
end
end

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillEvidencesProjectId
description: Backfills sharding key `evidences.project_id` from `releases`.
feature_category: release_evidence
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159580
milestone: '17.3'
queued_migration_version: 20240716133952
finalize_after: '2024-08-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -17,3 +17,4 @@ desired_sharding_key:
table: releases table: releases
sharding_key: project_id sharding_key: project_id
belongs_to: release belongs_to: release
desired_sharding_key_migration_job_name: BackfillEvidencesProjectId

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddProjectIdToEvidences < Gitlab::Database::Migration[2.2]
milestone '17.3'
def change
add_column :evidences, :project_id, :bigint
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class IndexEvidencesOnProjectId < Gitlab::Database::Migration[2.2]
milestone '17.3'
disable_ddl_transaction!
INDEX_NAME = 'index_evidences_on_project_id'
def up
add_concurrent_index :evidences, :project_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :evidences, INDEX_NAME
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddEvidencesProjectIdFk < Gitlab::Database::Migration[2.2]
milestone '17.3'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :evidences, :projects, column: :project_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key :evidences, column: :project_id
end
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class AddEvidencesProjectIdTrigger < Gitlab::Database::Migration[2.2]
milestone '17.3'
def up
install_sharding_key_assignment_trigger(
table: :evidences,
sharding_key: :project_id,
parent_table: :releases,
parent_sharding_key: :project_id,
foreign_key: :release_id
)
end
def down
remove_sharding_key_assignment_trigger(
table: :evidences,
sharding_key: :project_id,
parent_table: :releases,
parent_sharding_key: :project_id,
foreign_key: :release_id
)
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
class QueueBackfillEvidencesProjectId < Gitlab::Database::Migration[2.2]
milestone '17.3'
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
MIGRATION = "BackfillEvidencesProjectId"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 1000
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:evidences,
:id,
:project_id,
:releases,
:project_id,
:release_id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(
MIGRATION,
:evidences,
:id,
[
:project_id,
:releases,
:project_id,
:release_id
]
)
end
end

View File

@ -0,0 +1 @@
db1a5709484f2352e0858fb1efc4191e408c361aba1d3b94a50f943c508fd941

View File

@ -0,0 +1 @@
4b6c8960d7eab5e62087b56afb1855b277eab8bd38662f7fc8c269392638ff06

View File

@ -0,0 +1 @@
8680f5ef0acbc1e9b4bebf9b8c81e7d72f72f7f2bdc68d6aab247dd9b8ad4416

View File

@ -0,0 +1 @@
1798657b951493363ac8bd42596b3ff2b6007a0e80f026a2f1890543b1d2f7bf

View File

@ -0,0 +1 @@
b88c38cc0991bda066f569bbb3e6a1519bccc19219dde3782eb7afdffbe4063c

View File

@ -1757,6 +1757,22 @@ RETURN NEW;
END END
$$; $$;
CREATE FUNCTION trigger_cac7c0698291() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW."project_id" IS NULL THEN
SELECT "project_id"
INTO NEW."project_id"
FROM "releases"
WHERE "releases"."id" = NEW."release_id";
END IF;
RETURN NEW;
END
$$;
CREATE FUNCTION trigger_d4487a75bd44() RETURNS trigger CREATE FUNCTION trigger_d4487a75bd44() RETURNS trigger
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
@ -10457,7 +10473,8 @@ CREATE TABLE evidences (
created_at timestamp with time zone NOT NULL, created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL,
summary_sha bytea, summary_sha bytea,
summary jsonb DEFAULT '{}'::jsonb NOT NULL summary jsonb DEFAULT '{}'::jsonb NOT NULL,
project_id bigint
); );
CREATE SEQUENCE evidences_id_seq CREATE SEQUENCE evidences_id_seq
@ -27366,6 +27383,8 @@ CREATE INDEX index_events_on_project_id_and_id ON events USING btree (project_id
CREATE UNIQUE INDEX index_events_on_target_type_and_target_id_and_fingerprint ON events USING btree (target_type, target_id, fingerprint); CREATE UNIQUE INDEX index_events_on_target_type_and_target_id_and_fingerprint ON events USING btree (target_type, target_id, fingerprint);
CREATE INDEX index_evidences_on_project_id ON evidences USING btree (project_id);
CREATE INDEX index_evidences_on_release_id ON evidences USING btree (release_id); CREATE INDEX index_evidences_on_release_id ON evidences USING btree (release_id);
CREATE INDEX index_expired_and_not_notified_personal_access_tokens ON personal_access_tokens USING btree (id, expires_at) WHERE ((impersonation = false) AND (revoked = false) AND (expire_notification_delivered = false)); CREATE INDEX index_expired_and_not_notified_personal_access_tokens ON personal_access_tokens USING btree (id, expires_at) WHERE ((impersonation = false) AND (revoked = false) AND (expire_notification_delivered = false));
@ -31914,6 +31933,8 @@ CREATE TRIGGER trigger_c8bc8646bce9 BEFORE INSERT OR UPDATE ON vulnerability_sta
CREATE TRIGGER trigger_c9090feed334 BEFORE INSERT OR UPDATE ON boards_epic_lists FOR EACH ROW EXECUTE FUNCTION trigger_c9090feed334(); CREATE TRIGGER trigger_c9090feed334 BEFORE INSERT OR UPDATE ON boards_epic_lists FOR EACH ROW EXECUTE FUNCTION trigger_c9090feed334();
CREATE TRIGGER trigger_cac7c0698291 BEFORE INSERT OR UPDATE ON evidences FOR EACH ROW EXECUTE FUNCTION trigger_cac7c0698291();
CREATE TRIGGER trigger_catalog_resource_sync_event_on_project_update AFTER UPDATE ON projects FOR EACH ROW WHEN ((((old.name)::text IS DISTINCT FROM (new.name)::text) OR (old.description IS DISTINCT FROM new.description) OR (old.visibility_level IS DISTINCT FROM new.visibility_level))) EXECUTE FUNCTION insert_catalog_resource_sync_event(); CREATE TRIGGER trigger_catalog_resource_sync_event_on_project_update AFTER UPDATE ON projects FOR EACH ROW WHEN ((((old.name)::text IS DISTINCT FROM (new.name)::text) OR (old.description IS DISTINCT FROM new.description) OR (old.visibility_level IS DISTINCT FROM new.visibility_level))) EXECUTE FUNCTION insert_catalog_resource_sync_event();
CREATE TRIGGER trigger_d4487a75bd44 BEFORE INSERT OR UPDATE ON terraform_state_versions FOR EACH ROW EXECUTE FUNCTION trigger_d4487a75bd44(); CREATE TRIGGER trigger_d4487a75bd44 BEFORE INSERT OR UPDATE ON terraform_state_versions FOR EACH ROW EXECUTE FUNCTION trigger_d4487a75bd44();
@ -33125,6 +33146,9 @@ ALTER TABLE ONLY personal_access_tokens
ALTER TABLE ONLY jira_tracker_data ALTER TABLE ONLY jira_tracker_data
ADD CONSTRAINT fk_c98abcd54c FOREIGN KEY (integration_id) REFERENCES integrations(id) ON DELETE CASCADE; ADD CONSTRAINT fk_c98abcd54c FOREIGN KEY (integration_id) REFERENCES integrations(id) ON DELETE CASCADE;
ALTER TABLE ONLY evidences
ADD CONSTRAINT fk_ca4bbc114d FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY subscription_add_on_purchases ALTER TABLE ONLY subscription_add_on_purchases
ADD CONSTRAINT fk_caed789645 FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE; ADD CONSTRAINT fk_caed789645 FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;

View File

@ -21,6 +21,7 @@ exceptions:
- ANSI - ANSI
- APAC - APAC
- API - API
- ARIA
- APM - APM
- ARM - ARM
- ARN - ARN

View File

@ -46,7 +46,8 @@ Instead of checking repositories manually, GitLab can be configured to run the c
1. Enable **Enable repository checks**. 1. Enable **Enable repository checks**.
When enabled, GitLab periodically runs a repository check on all project repositories and wiki When enabled, GitLab periodically runs a repository check on all project repositories and wiki
repositories to detect possible data corruption. A project is checked no more than once per month. repositories to detect possible data corruption. A project is checked no more than once per month, and new projects aren't checked for at least 24 hours.
Administrators can configure the frequency of repository checks. To edit the frequency: Administrators can configure the frequency of repository checks. To edit the frequency:
- For Linux package installations, edit `gitlab_rails['repository_check_worker_cron']` in - For Linux package installations, edit `gitlab_rails['repository_check_worker_cron']` in

View File

@ -118,45 +118,38 @@ Chat interface. The following example shows how to open the GitLab Duo Chat
drawer by using an event listener and the GitLab Duo Chat global state: drawer by using an event listener and the GitLab Duo Chat global state:
```javascript ```javascript
import { helpCenterState } from '~/super_sidebar/constants'; import { duoChatGlobalState } from '~/super_sidebar/constants';
myFancyToggleToOpenChat.addEventListener('click', () => { myFancyToggleToOpenChat.addEventListener('click', () => {
helpCenterState.showTanukiBotChatDrawer = true; duoChatGlobalState.isShown = true;
}); });
``` ```
#### Initiating GitLab Duo Chat with a pre-defined prompt #### Initiating GitLab Duo Chat with a pre-defined prompt
In some scenarios, you may want to direct users towards a specific topic or In some scenarios, you may want to direct users towards a specific topic or
query when they open GitLab Duo Chat. The following example method: query when they open GitLab Duo Chat. We have a utility function that will
open DuoChat drawer and send a command in a queue for DuoChat to execute on.
1. Opens the GitLab Duo Chat drawer. This should trigger the loading state and the streaming with the given prompt.
1. Sends a pre-defined prompt to GitLab Duo Chat.
```javascript ```javascript
import chatMutation from 'ee/ai/graphql/chat.mutation.graphql'; import { sendDuoChatCommand } from 'ee/ai/utils';
import { helpCenterState } from '~/super_sidebar/constants';
[...] [...]
methods: { methods: {
openChatWithPrompt() { openChatWithPrompt() {
const myPrompt = "What is the meaning of life?" sendDuoChatCommand(
helpCenterState.showTanukiBotChatDrawer = true; {
question: '/feedback' // This is your prompt
this.$apollo resourceId: 'gid:://gitlab/WorkItem/1', // A unique ID to identify the action for streaming
.mutate({ variables: {} // Any additional graphql variables you want to pass to ee/app/assets/javascripts/ai/graphql/chat.mutation.graphql when executing the query
mutation: chatMutation, }
variables: { )
question: myPrompt,
resourceId: this.resourceId,
},
})
.catch((error) => {
// handle potential errors here
});
} }
} }
``` ```
Note that `sendDuoChatCommand` cannot be chained, meaning that you can send one command to DuoChat and have to wait until this action is done before sending a different command or the previous command might not work as expected.
This enhancement allows for a more tailored user experience by guiding the This enhancement allows for a more tailored user experience by guiding the
conversation in GitLab Duo Chat towards predefined areas of interest or concern. conversation in GitLab Duo Chat towards predefined areas of interest or concern.

View File

@ -31,6 +31,7 @@ All tables with the following `gitlab_schema` are considered "cell-local":
- `gitlab_main_cell` - `gitlab_main_cell`
- `gitlab_ci` - `gitlab_ci`
- `gitlab_sec`
All newly created cell-local tables are required to have a `sharding_key` All newly created cell-local tables are required to have a `sharding_key`
defined in the corresponding `db/docs/` file for that table. defined in the corresponding `db/docs/` file for that table.

View File

@ -12,4 +12,15 @@ The following feature flags exist in GitLab. These flags determine the availabil
For self-managed instances, [GitLab administrators can change the state of the flag](../administration/feature_flags.md). For self-managed instances, [GitLab administrators can change the state of the flag](../administration/feature_flags.md).
<!-- markdownlint-disable MD044 -->
<!-- MD044/proper-names test disabled after this line to make page compatible with markdownlint-cli 0.29.0. -->
<!-- See https://docs.gitlab.com/ee/development/documentation/testing/markdownlint.html#disable-markdownlint-tests -->
<div class="d-none">
<strong>If you don't see the feature flag tables below, view them at <a href="https://docs.gitlab.com/ee/user/feature_flags.html">docs.gitlab.com</a>.</strong>
</div>
<!-- the div above will not display on the docs site but will display on /help -->
<!-- markdownlint-enable MD044 -->
<!-- When published, everything below this line is generated by 'layouts/feature_flags_table.md.erb' in the 'gitlab-docs' repository --> <!-- When published, everything below this line is generated by 'layouts/feature_flags_table.md.erb' in the 'gitlab-docs' repository -->

View File

@ -57,7 +57,9 @@ module Gitlab
block_after_save = needs_blocking? block_after_save = needs_blocking?
Users::UpdateService.new(gl_user, user: gl_user).execute! Namespace.with_disabled_organization_validation do
Users::UpdateService.new(gl_user, user: gl_user).execute!
end
gl_user.block_pending_approval if block_after_save gl_user.block_pending_approval if block_after_save
activate_user_if_user_cap_not_reached activate_user_if_user_cap_not_reached

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillEvidencesProjectId < BackfillDesiredShardingKeyJob
operation_name :backfill_evidences_project_id
feature_category :release_evidence
end
end
end

View File

@ -19,7 +19,9 @@ module Gitlab
) )
user.assign_personal_namespace(Organizations::Organization.default_organization) user.assign_personal_namespace(Organizations::Organization.default_organization)
user.save! Namespace.with_disabled_organization_validation do
user.save!
end
user user
end end

View File

@ -178,7 +178,7 @@ module Gitlab
modify_attributes modify_attributes
@importable.save!(touch: false) Namespace.with_disabled_organization_validation { @importable.save!(touch: false) }
end end
def filter_attributes(params) def filter_attributes(params)

View File

@ -178,7 +178,9 @@ module Gitlab
def create_group(**args) def create_group(**args)
logger.info(message: 'Creating group', **args) logger.info(message: 'Creating group', **args)
ensure_success(::Groups::CreateService.new(@user, **args).execute[:group]) Namespace.with_disabled_organization_validation do
ensure_success(::Groups::CreateService.new(@user, **args).execute[:group])
end
end end
def ensure_project(name:, namespace_id:, **args) def ensure_project(name:, namespace_id:, **args)
@ -194,7 +196,9 @@ module Gitlab
def create_project(**args) def create_project(**args)
logger.info(message: 'Creating project', **args) logger.info(message: 'Creating project', **args)
ensure_success(::Projects::CreateService.new(@user, **args).execute) Namespace.with_disabled_organization_validation do
ensure_success(::Projects::CreateService.new(@user, **args).execute)
end
end end
def register_record(record, records) def register_record(record, records)

View File

@ -18,6 +18,7 @@ namespace :tw do
end end
end end
# For groups without an assigned TW, comment out the line.
CODE_OWNER_RULES = [ CODE_OWNER_RULES = [
# CodeOwnerRule.new('Activation', ''), # CodeOwnerRule.new('Activation', ''),
# CodeOwnerRule.new('Acquisition', ''), # CodeOwnerRule.new('Acquisition', ''),
@ -56,7 +57,7 @@ namespace :tw do
CodeOwnerRule.new('Remote Development', '@ashrafkhamis'), CodeOwnerRule.new('Remote Development', '@ashrafkhamis'),
CodeOwnerRule.new('Import and Integrate', '@eread'), CodeOwnerRule.new('Import and Integrate', '@eread'),
CodeOwnerRule.new('Infrastructure', '@sselhorn'), CodeOwnerRule.new('Infrastructure', '@sselhorn'),
# CodeOwnerRule.new('Knowledge', ''), CodeOwnerRule.new('Knowledge', '@msedlakjakubowski'),
CodeOwnerRule.new('MLOps', '@sselhorn @jglassman1 @fneill'), CodeOwnerRule.new('MLOps', '@sselhorn @jglassman1 @fneill'),
# CodeOwnerRule.new('Observability', ''), # CodeOwnerRule.new('Observability', ''),
CodeOwnerRule.new('Optimize', '@lciutacu'), CodeOwnerRule.new('Optimize', '@lciutacu'),

View File

@ -37,7 +37,9 @@ namespace :gitlab do
tmp_namespace_path = "tmp-project-import-#{Time.now.to_i}" tmp_namespace_path = "tmp-project-import-#{Time.now.to_i}"
puts "Creating temporary namespace #{tmp_namespace_path}" puts "Creating temporary namespace #{tmp_namespace_path}"
tmp_namespace = Namespace.create!(owner: admin, name: tmp_namespace_path, path: tmp_namespace_path, type: Namespaces::UserNamespace.sti_name) tmp_namespace = Namespace.with_disabled_organization_validation do
Namespace.create!(owner: admin, name: tmp_namespace_path, path: tmp_namespace_path, type: Namespaces::UserNamespace.sti_name)
end
templates = if template_names.empty? templates = if template_names.empty?
Gitlab::ProjectTemplate.all Gitlab::ProjectTemplate.all
@ -54,7 +56,7 @@ namespace :gitlab do
} }
puts "Creating project for #{template.title}" puts "Creating project for #{template.title}"
project = Projects::CreateService.new(admin, params).execute project = Namespace.with_disabled_organization_validation { Projects::CreateService.new(admin, params).execute }
unless project.persisted? unless project.persisted?
raise "Failed to create project: #{project.errors.messages}" raise "Failed to create project: #{project.errors.messages}"

View File

@ -2156,12 +2156,6 @@ msgstr ""
msgid "AISummary|View summary" msgid "AISummary|View summary"
msgstr "" msgstr ""
msgid "AI|An error occurred while explaining the code."
msgstr ""
msgid "AI|An error occurred while troubleshooting the failed job."
msgstr ""
msgid "AI|Apply AI-generated description" msgid "AI|Apply AI-generated description"
msgstr "" msgstr ""

View File

@ -11,7 +11,7 @@ gem 'capybara', '~> 3.40.0'
gem 'capybara-screenshot', '~> 1.0.26' gem 'capybara-screenshot', '~> 1.0.26'
gem 'rake', '~> 13', '>= 13.2.1' gem 'rake', '~> 13', '>= 13.2.1'
gem 'rspec', '~> 3.13' gem 'rspec', '~> 3.13'
gem 'selenium-webdriver', '= 4.22.0' gem 'selenium-webdriver', '= 4.23.0'
gem 'airborne', '~> 0.3.7', require: false # airborne is messing with rspec sandboxed mode so not requiring by default gem 'airborne', '~> 0.3.7', require: false # airborne is messing with rspec sandboxed mode so not requiring by default
gem 'rest-client', '~> 2.1.0' gem 'rest-client', '~> 2.1.0'
gem 'rspec_junit_formatter', '~> 0.6.0' gem 'rspec_junit_formatter', '~> 0.6.0'

View File

@ -328,7 +328,7 @@ GEM
sawyer (0.9.2) sawyer (0.9.2)
addressable (>= 2.3.5) addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3) faraday (>= 0.17.3, < 3)
selenium-webdriver (4.22.0) selenium-webdriver (4.23.0)
base64 (~> 0.2) base64 (~> 0.2)
logger (~> 1.4) logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
@ -423,7 +423,7 @@ DEPENDENCIES
rspec-parameterized (~> 1.0.2) rspec-parameterized (~> 1.0.2)
rspec_junit_formatter (~> 0.6.0) rspec_junit_formatter (~> 0.6.0)
ruby-debug-ide (~> 0.7.3) ruby-debug-ide (~> 0.7.3)
selenium-webdriver (= 4.22.0) selenium-webdriver (= 4.23.0)
slack-notifier (~> 2.4) slack-notifier (~> 2.4)
terminal-table (~> 3.0.2) terminal-table (~> 3.0.2)
warning (~> 1.4) warning (~> 1.4)

View File

@ -11,6 +11,8 @@ FactoryBot.define do
owner { association(:user, strategy: :build, namespace: instance, username: path) } owner { association(:user, strategy: :build, namespace: instance, username: path) }
association :organization
after(:create) do |namespace, evaluator| after(:create) do |namespace, evaluator|
# simulating ::Namespaces::ProcessSyncEventsWorker because most tests don't run Sidekiq inline # simulating ::Namespaces::ProcessSyncEventsWorker because most tests don't run Sidekiq inline
# Note: we need to get refreshed `traversal_ids` it is updated via SQL query # Note: we need to get refreshed `traversal_ids` it is updated via SQL query

View File

@ -115,8 +115,6 @@ describe('ModelCreate', () => {
it('should show markdown editor', () => { it('should show markdown editor', () => {
createWrapper(); createWrapper();
expect(findMarkdownEditor().exists()).toBe(true);
expect(findMarkdownEditor().props()).toMatchObject({ expect(findMarkdownEditor().props()).toMatchObject({
enableContentEditor: true, enableContentEditor: true,
formFieldProps: { formFieldProps: {
@ -127,6 +125,7 @@ describe('ModelCreate', () => {
markdownDocsPath: '/help/user/markdown', markdownDocsPath: '/help/user/markdown',
renderMarkdownPath: '/markdown-preview', renderMarkdownPath: '/markdown-preview',
uploadsPath: '', uploadsPath: '',
restrictedToolBarItems: ['full-screen'],
}); });
}); });
}); });
@ -238,7 +237,7 @@ describe('ModelCreate', () => {
expect(findGlModal().props()).toMatchObject({ expect(findGlModal().props()).toMatchObject({
modalId: 'create-model-modal', modalId: 'create-model-modal',
title: 'Create model, version & import artifacts', title: 'Create model, version & import artifacts',
size: 'sm', size: 'lg',
}); });
}); });

View File

@ -124,7 +124,7 @@ describe('ModelVersionCreate', () => {
expect(findGlModal().props()).toMatchObject({ expect(findGlModal().props()).toMatchObject({
modalId: 'create-model-version-modal', modalId: 'create-model-version-modal',
title: 'Create model version & import artifacts', title: 'Create model version & import artifacts',
size: 'sm', size: 'lg',
}); });
}); });

View File

@ -203,6 +203,31 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
}); });
}); });
describe('when additional restricted tool bar items are given', () => {
beforeEach(() => {
buildWrapper({ propsData: { restrictedToolBarItems: ['full-screen'] } });
});
it('passes them to restrictedToolBarItems', () => {
expect(findMarkdownField().props().restrictedToolBarItems).toContain('full-screen');
});
describe('when attachments are disabled', () => {
beforeEach(() => {
buildWrapper({
propsData: { disableAttachments: true, restrictedToolBarItems: ['full-screen'] },
});
});
it('passes `attach-file` and `full-screen` restrictedToolBarItems', () => {
expect(findMarkdownField().props().restrictedToolBarItems).toEqual([
'full-screen',
'attach-file',
]);
});
});
});
describe('disabled', () => { describe('disabled', () => {
it('disables markdown field when disabled prop is true', () => { it('disables markdown field when disabled prop is true', () => {
buildWrapper({ propsData: { disabled: true } }); buildWrapper({ propsData: { disabled: true } });

View File

@ -266,13 +266,5 @@ RSpec.describe GitlabSchema.types['Group'], feature_category: :groups_and_projec
) )
end end
end end
context 'when group does not have an organization associated with it' do
let_it_be(:group) { create(:group, :public, organization: nil) }
it 'returns nil' do
expect(organization_edit_path).to be_nil
end
end
end end
end end

View File

@ -1305,13 +1305,5 @@ RSpec.describe GitlabSchema.types['Project'], feature_category: :groups_and_proj
) )
end end
end end
context 'when project does not have an organization associated with it' do
let_it_be(:project) { create(:project, :public, organization: nil) }
it 'returns nil' do
expect(organization_edit_path).to be_nil
end
end
end end
end end

View File

@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Types::WorkItems::WidgetInterface, feature_category: :team_planning do RSpec.describe Types::WorkItems::WidgetInterface, feature_category: :team_planning do
include GraphqlHelpers include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
it 'exposes the expected fields' do it 'exposes the expected fields' do
expected_fields = %i[type] expected_fields = %i[type]
@ -11,42 +12,45 @@ RSpec.describe Types::WorkItems::WidgetInterface, feature_category: :team_planni
expect(described_class).to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
end end
describe ".resolve_type" do where(:widget_class, :widget_type_name) do
using RSpec::Parameterized::TableSyntax WorkItems::Widgets::Description | Types::WorkItems::Widgets::DescriptionType
WorkItems::Widgets::Hierarchy | Types::WorkItems::Widgets::HierarchyType
WorkItems::Widgets::Assignees | Types::WorkItems::Widgets::AssigneesType
WorkItems::Widgets::Labels | Types::WorkItems::Widgets::LabelsType
WorkItems::Widgets::Notes | Types::WorkItems::Widgets::NotesType
WorkItems::Widgets::Notifications | Types::WorkItems::Widgets::NotificationsType
WorkItems::Widgets::CurrentUserTodos | Types::WorkItems::Widgets::CurrentUserTodosType
WorkItems::Widgets::AwardEmoji | Types::WorkItems::Widgets::AwardEmojiType
WorkItems::Widgets::LinkedItems | Types::WorkItems::Widgets::LinkedItemsType
WorkItems::Widgets::LinkedItems | Types::WorkItems::Widgets::LinkedItemsType
WorkItems::Widgets::StartAndDueDate | Types::WorkItems::Widgets::StartAndDueDateType
WorkItems::Widgets::Milestone | Types::WorkItems::Widgets::MilestoneType
WorkItems::Widgets::Participants | Types::WorkItems::Widgets::ParticipantsType
WorkItems::Widgets::TimeTracking | Types::WorkItems::Widgets::TimeTracking::TimeTrackingType
WorkItems::Widgets::Designs | Types::WorkItems::Widgets::DesignsType
WorkItems::Widgets::CrmContacts | Types::WorkItems::Widgets::CrmContactsType
end
where(:widget_class, :widget_type_name) do with_them do
WorkItems::Widgets::Description | Types::WorkItems::Widgets::DescriptionType describe ".resolve_type" do
WorkItems::Widgets::Hierarchy | Types::WorkItems::Widgets::HierarchyType
WorkItems::Widgets::Assignees | Types::WorkItems::Widgets::AssigneesType
WorkItems::Widgets::Labels | Types::WorkItems::Widgets::LabelsType
WorkItems::Widgets::Notes | Types::WorkItems::Widgets::NotesType
WorkItems::Widgets::Notifications | Types::WorkItems::Widgets::NotificationsType
WorkItems::Widgets::CurrentUserTodos | Types::WorkItems::Widgets::CurrentUserTodosType
WorkItems::Widgets::AwardEmoji | Types::WorkItems::Widgets::AwardEmojiType
WorkItems::Widgets::LinkedItems | Types::WorkItems::Widgets::LinkedItemsType
WorkItems::Widgets::LinkedItems | Types::WorkItems::Widgets::LinkedItemsType
WorkItems::Widgets::StartAndDueDate | Types::WorkItems::Widgets::StartAndDueDateType
WorkItems::Widgets::Milestone | Types::WorkItems::Widgets::MilestoneType
WorkItems::Widgets::Participants | Types::WorkItems::Widgets::ParticipantsType
WorkItems::Widgets::TimeTracking | Types::WorkItems::Widgets::TimeTracking::TimeTrackingType
WorkItems::Widgets::Designs | Types::WorkItems::Widgets::DesignsType
WorkItems::Widgets::Development | Types::WorkItems::Widgets::DevelopmentType
WorkItems::Widgets::CrmContacts | Types::WorkItems::Widgets::CrmContactsType
end
with_them do
it 'knows the correct type for objects' do it 'knows the correct type for objects' do
expect( expect(
described_class.resolve_type(widget_class.new(build(:work_item)), {}) described_class.resolve_type(widget_class.new(build(:work_item)), {})
).to eq(widget_type_name) ).to eq(widget_type_name)
end end
it 'raises an error for an unknown type' do
project = build(:project)
expect { described_class.resolve_type(project, {}) }
.to raise_error("Unknown GraphQL type for widget #{project}")
end
end end
it 'raises an error for an unknown type' do describe '.orphan_types' do
project = build(:project) it 'includes the type' do
expect(described_class.orphan_types).to include(widget_type_name)
expect { described_class.resolve_type(project, {}) } end
.to raise_error("Unknown GraphQL type for widget #{project}")
end end
end end
end end

View File

@ -51,7 +51,7 @@ RSpec.describe Gitlab::Auth::Ldap::User do
describe '#valid_sign_in?' do describe '#valid_sign_in?' do
before do before do
gl_user.save! Namespace.with_disabled_organization_validation { gl_user.save! }
end end
it 'returns true' do it 'returns true' do

View File

@ -30,6 +30,10 @@ RSpec.describe Gitlab::Auth::OAuth::User, feature_category: :system_access do
let(:ldap_user) { Gitlab::Auth::Ldap::Person.new(Net::LDAP::Entry.new, 'ldapmain') } let(:ldap_user) { Gitlab::Auth::Ldap::Person.new(Net::LDAP::Entry.new, 'ldapmain') }
let(:ldap_user_2) { Gitlab::Auth::Ldap::Person.new(Net::LDAP::Entry.new, 'ldapmain') } let(:ldap_user_2) { Gitlab::Auth::Ldap::Person.new(Net::LDAP::Entry.new, 'ldapmain') }
around do |example|
Namespace.with_disabled_organization_validation { example.run }
end
describe '.find_by_uid_and_provider' do describe '.find_by_uid_and_provider' do
let(:provider) { 'provider' } let(:provider) { 'provider' }
let(:uid) { 'uid' } let(:uid) { 'uid' }

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillEvidencesProjectId,
feature_category: :release_evidence,
schema: 20240716133948 do
include_examples 'desired sharding key backfill job' do
let(:batch_table) { :evidences }
let(:backfill_column) { :project_id }
let(:backfill_via_table) { :releases }
let(:backfill_via_column) { :project_id }
let(:backfill_via_foreign_key) { :release_id }
end
end

View File

@ -43,18 +43,8 @@ RSpec.describe Gitlab::Git::ObjectPool, feature_category: :source_code_managemen
subject.create # rubocop:disable Rails/SaveBang subject.create # rubocop:disable Rails/SaveBang
end end
context "when the pool doesn't exist yet" do it 'creates the pool' do
it 'creates the pool' do expect(subject.exists?).to be(true)
expect(subject.exists?).to be(true)
end
end
context 'when the pool already exists' do
it 'raises an FailedPrecondition' do
expect do
subject.create # rubocop:disable Rails/SaveBang
end.to raise_error(GRPC::FailedPrecondition)
end
end end
end end

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe QueueBackfillEvidencesProjectId, feature_category: :release_evidence do
let!(:batched_migration) { described_class::MIGRATION }
it 'schedules a new batched migration' do
reversible_migration do |migration|
migration.before -> {
expect(batched_migration).not_to have_scheduled_batched_migration
}
migration.after -> {
expect(batched_migration).to have_scheduled_batched_migration(
table_name: :evidences,
column_name: :id,
interval: described_class::DELAY_INTERVAL,
batch_size: described_class::BATCH_SIZE,
sub_batch_size: described_class::SUB_BATCH_SIZE,
gitlab_schema: :gitlab_main_cell,
job_arguments: [
:project_id,
:releases,
:project_id,
:release_id
]
)
}
end
end
end

View File

@ -42,8 +42,8 @@ RSpec.describe Analytics::CycleAnalytics::Stage, feature_category: :value_stream
describe '.distinct_stages_within_hierarchy' do describe '.distinct_stages_within_hierarchy' do
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let_it_be(:sub_group) { create(:group, parent: group) } let_it_be(:sub_group) { create(:group, organization: group.organization, parent: group) }
let_it_be(:project) { create(:project, group: sub_group).reload } let_it_be(:project) { create(:project, organization: group.organization, group: sub_group).reload }
before do before do
# event identifiers are the same # event identifiers are the same

View File

@ -314,7 +314,7 @@ RSpec.describe Namespaces::ProjectNamespace, 'Routable', :with_clean_rails_cache
it 'skips route creation for the resource' do it 'skips route creation for the resource' do
expect do expect do
described_class.create!(project: nil, parent: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC, path: 'foo', name: 'foo') described_class.create!(project: nil, organization: group.organization, parent: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC, path: 'foo', name: 'foo')
end.not_to change { Route.count } end.not_to change { Route.count }
end end
end end

View File

@ -271,7 +271,7 @@ RSpec.describe Group, feature_category: :groups_and_projects do
it 'does not allow a subgroup to have the same name as an existing subgroup' do it 'does not allow a subgroup to have the same name as an existing subgroup' do
sub_group1 = create(:group, parent: group, name: "SG", path: 'api') sub_group1 = create(:group, parent: group, name: "SG", path: 'api')
sub_group2 = described_class.new(parent: group, name: "SG", path: 'api2') sub_group2 = described_class.new(parent: group, name: "SG", path: 'api2', organization: sub_group1.organization)
expect(sub_group1).to be_valid expect(sub_group1).to be_valid
expect(sub_group2).not_to be_valid expect(sub_group2).not_to be_valid

View File

@ -1277,7 +1277,7 @@ RSpec.describe Member, feature_category: :groups_and_projects do
end end
context 'for updating organization_users' do context 'for updating organization_users' do
let_it_be(:group) { create(:group, :with_organization) } let_it_be(:group) { create(:group) }
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:member) { create(:group_member, source: group, user: user) } let(:member) { create(:group_member, source: group, user: user) }
@ -1362,12 +1362,6 @@ RSpec.describe Member, feature_category: :groups_and_projects do
it_behaves_like 'does not create an organization_user entry' it_behaves_like 'does not create an organization_user entry'
end end
context 'when organization does not exist' do
let(:member) { create(:group_member, user: user) }
it_behaves_like 'does not create an organization_user entry'
end
end end
context 'when updating' do context 'when updating' do

View File

@ -90,6 +90,7 @@ RSpec.describe Namespace, feature_category: :groups_and_projects do
it { is_expected.to validate_presence_of(:path) } it { is_expected.to validate_presence_of(:path) }
it { is_expected.to validate_length_of(:path).is_at_most(255) } it { is_expected.to validate_length_of(:path).is_at_most(255) }
it { is_expected.to validate_presence_of(:owner) } it { is_expected.to validate_presence_of(:owner) }
it { is_expected.to validate_presence_of(:organization) }
it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) } it { is_expected.to validate_numericality_of(:max_artifacts_size).only_integer.is_greater_than(0) }
context 'validating the parent of a namespace' do context 'validating the parent of a namespace' do
@ -702,6 +703,54 @@ RSpec.describe Namespace, feature_category: :groups_and_projects do
it { is_expected.to include_module(Namespaces::Traversal::LinearScopes) } it { is_expected.to include_module(Namespaces::Traversal::LinearScopes) }
end end
context 'when feature flag require_organization is disabled' do
before do
stub_feature_flags(require_organization: false)
end
it 'does not require organization' do
namespace.organization = nil
expect(namespace.valid?).to eq(true)
end
end
context 'when feature flag require_organization is enabled' do
it 'does require organization' do
namespace.organization = nil
Namespace.with_disabled_organization_validation do
expect(namespace.valid?).to eq(false)
end
end
describe '.with_disabled_organization_validation', :request_store do
it 'does not require organization' do
namespace.organization = nil
Namespace.with_disabled_organization_validation do
expect(namespace.valid?).to eq(true)
end
end
context 'with nested calls' do
it 'only last call will enable the validation' do
result = []
Namespace.with_disabled_organization_validation do
result << described_class.new.require_organization?
Namespace.with_disabled_organization_validation do
result << described_class.new.require_organization?
end
result << described_class.new.require_organization?
end
expect(result.any?(true)).to be false
expect(described_class.new.require_organization?).to be true
end
end
end
end
describe '#traversal_ids' do describe '#traversal_ids' do
let(:namespace) { build(:group) } let(:namespace) { build(:group) }

View File

@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Namespaces::ProjectNamespace, type: :model do RSpec.describe Namespaces::ProjectNamespace, type: :model, feature_category: :groups_and_projects do
let_it_be(:organization) { create(:organization) } let_it_be(:organization) { create(:organization) }
describe 'relationships' do describe 'relationships' do

View File

@ -28,7 +28,7 @@ RSpec.describe Preloaders::ProjectPolicyPreloader do
control = ActiveRecord::QueryRecorder.new { authorize_all_projects(user) } control = ActiveRecord::QueryRecorder.new { authorize_all_projects(user) }
new_project1 = create(:project, :private, maintainers: user) new_project1 = create(:project, :private, maintainers: user)
new_project2 = create(:project, :private, namespace: root_parent) new_project2 = create(:project, :private, namespace: root_parent, maintainers: user)
another_root = create(:group, :private, name: 'root-3', path: 'root-3') another_root = create(:group, :private, name: 'root-3', path: 'root-3')
new_project3 = create(:project, :private, namespace: another_root, maintainers: user) new_project3 = create(:project, :private, namespace: another_root, maintainers: user)

View File

@ -59,7 +59,7 @@ RSpec.describe 'getting merge request listings nested in a project', feature_cat
# We cannot disable SQL query limiting here, since the transaction does not # We cannot disable SQL query limiting here, since the transaction does not
# begin until we enter the controller. # begin until we enter the controller.
headers = { headers = {
'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/322979' 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/469250;205'
} }
post_graphql(query, current_user: current_user, headers: headers) post_graphql(query, current_user: current_user, headers: headers)

View File

@ -64,7 +64,7 @@ RSpec.describe API::ProjectImport, :aggregate_failures, feature_category: :impor
it 'executes a limited number of queries', :use_clean_rails_redis_caching do it 'executes a limited number of queries', :use_clean_rails_redis_caching do
control = ActiveRecord::QueryRecorder.new { perform_archive_upload } control = ActiveRecord::QueryRecorder.new { perform_archive_upload }
expect(control.count).to be <= 114 expect(control.count).to be <= 115
end end
it 'schedules an import using a namespace' do it 'schedules an import using a namespace' do

View File

@ -700,15 +700,6 @@ RSpec.describe MergeRequests::UpdateService, :mailer, feature_category: :code_re
describe 'recording the first reviewer assigned at timestamp' do describe 'recording the first reviewer assigned at timestamp' do
subject(:metrics) { merge_request.reload.metrics } subject(:metrics) { merge_request.reload.metrics }
context 'when store_first_reviewer_assignment_timestamp_in_metrics feature flag is off' do
it 'does not record anything' do
stub_feature_flags(store_first_reviewer_assignment_timestamp_in_metrics: false)
update_merge_request(reviewer_ids: [user2.id])
expect(metrics.reviewer_first_assigned_at).to eq(nil)
end
end
it 'sets the current timestamp' do it 'sets the current timestamp' do
freeze_time do freeze_time do
update_merge_request(reviewer_ids: [user2.id]) update_merge_request(reviewer_ids: [user2.id])

View File

@ -393,7 +393,7 @@ RSpec.describe ResourceAccessTokens::CreateService, feature_category: :system_ac
end end
context 'when resource organization is not set', :enable_admin_mode do context 'when resource organization is not set', :enable_admin_mode do
let_it_be(:resource) { create(:project, :private, organization: nil) } let_it_be(:resource) { create(:project, :private, organization_id: nil) }
let_it_be(:default_organization) { Organizations::Organization.default_organization } let_it_be(:default_organization) { Organizations::Organization.default_organization }
let(:user) { create(:admin) } let(:user) { create(:admin) }

View File

@ -18,7 +18,7 @@ RSpec.describe Users::RegistrationsBuildService, feature_category: :system_acces
it 'creates the user_detail record' do it 'creates the user_detail record' do
user = service.execute user = service.execute
expect { user.save! }.to change { UserDetail.count }.by(1) expect { Namespace.with_disabled_organization_validation { user.save! } }.to change { UserDetail.count }.by(1)
end end
end end

View File

@ -205,6 +205,7 @@ RSpec.configure do |config|
config.include UserWithNamespaceShim config.include UserWithNamespaceShim
config.include OrphanFinalArtifactsCleanupHelpers, :orphan_final_artifacts_cleanup config.include OrphanFinalArtifactsCleanupHelpers, :orphan_final_artifacts_cleanup
config.include ClickHouseHelpers, :click_house config.include ClickHouseHelpers, :click_house
config.include DisableNamespaceOrganizationValidationHelper
config.include_context 'when rendered has no HTML escapes', type: :view config.include_context 'when rendered has no HTML escapes', type: :view

View File

@ -0,0 +1,70 @@
---
- ee/spec/controllers/ee/groups_controller_spec.rb
- ee/spec/controllers/ee/registrations_controller_spec.rb
- ee/spec/controllers/ee/omniauth_callbacks_controller_spec.rb
- ee/spec/controllers/groups/omniauth_callbacks_controller_spec.rb
- ee/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
- ee/spec/controllers/registrations/groups_controller_spec.rb
- ee/spec/features/groups_spec.rb
- ee/spec/features/projects/settings/merge_requests_settings_spec.rb
- ee/spec/features/registrations/combined_registration_spec.rb
- ee/spec/features/registrations/saas/sso_signin_standard_flow_company_creating_project_spec.rb
- ee/spec/features/registrations/saas/standard_flow_company_creating_project_spec.rb
- ee/spec/features/registrations/saas/standard_flow_just_me_creating_project_spec.rb
- ee/spec/features/registrations/saas/standard_flow_just_me_importing_project_spec.rb
- ee/spec/features/registrations/saas/subscription_flow_company_paid_plan_spec.rb
- ee/spec/features/registrations/saas/subscription_flow_just_me_paid_plan_spec.rb
- ee/spec/features/registrations/saas/trial_flow_company_creating_project_spec.rb
- ee/spec/features/registrations/saas/trial_flow_company_importing_project_spec.rb
- ee/spec/features/registrations/saas/trial_flow_just_me_creating_project_spec.rb
- ee/spec/features/registrations/saas/trial_flow_just_me_importing_project_spec.rb
- ee/spec/features/registrations/sign_up_with_trial_from_external_site_without_confirmation_spec.rb
- ee/spec/features/registrations/start_trial_from_external_site_without_confirmation_spec.rb
- ee/spec/features/subscriptions/subscription_flow_for_existing_user_with_eligible_group_spec.rb
- ee/spec/features/trials/saas/creation_with_multiple_existing_namespace_flow_spec.rb
- ee/spec/features/trials/saas/creation_with_no_existing_namespace_flow_spec.rb
- ee/spec/features/trials/saas/creation_with_one_existing_namespace_flow_spec.rb
- ee/spec/lib/gitlab/auth/group_saml/user_spec.rb
- ee/spec/lib/gitlab/auth/ldap/user_spec.rb
- ee/spec/lib/gitlab/auth/oidc/user_spec.rb
- ee/spec/lib/gitlab/auth/saml/user_spec.rb
- ee/spec/lib/ee/gitlab/scim/provisioning_service_spec.rb
- ee/spec/lib/ee/gitlab/scim/group/provisioning_service_spec.rb
- ee/spec/services/ee/groups/create_service_spec.rb
- ee/spec/services/ee/users/create_service_spec.rb
- ee/spec/services/users/service_accounts/create_service_spec.rb
- ee/spec/services/epics/update_dates_service_spec.rb
- ee/spec/services/gitlab_subscriptions/trials/create_service_spec.rb
- ee/spec/services/registrations/import_namespace_create_service_spec.rb
- ee/spec/services/registrations/standard_namespace_create_service_spec.rb
- spec/controllers/admin/groups_controller_spec.rb
- spec/controllers/admin/users_controller_spec.rb
- spec/controllers/groups_controller_spec.rb
- spec/controllers/import/bitbucket_controller_spec.rb
- spec/controllers/omniauth_callbacks_controller_spec.rb
- spec/controllers/registrations_controller_spec.rb
- spec/features/admin/admin_groups_spec.rb
- spec/features/dashboard/group_spec.rb
- spec/features/file_uploads/group_import_spec.rb
- spec/features/groups/import_export/import_file_spec.rb
- spec/features/groups_spec.rb
- spec/frontend/fixtures/groups.rb
- spec/graphql/types/group_type_spec.rb
- spec/graphql/types/project_type_spec.rb
- spec/lib/gitlab/auth/atlassian/user_spec.rb
- spec/lib/gitlab/auth/ldap/user_spec.rb
- spec/lib/gitlab/auth/o_auth/user_spec.rb
- spec/lib/gitlab/auth/saml/user_spec.rb
- spec/lib/gitlab/import/placeholder_user_creator_spec.rb
- spec/lib/gitlab/import/source_user_mapper_spec.rb
- spec/lib/gitlab/seeders/ci/runner/runner_fleet_seeder_spec.rb
- spec/models/hooks/system_hook_spec.rb
- spec/requests/api/groups_spec.rb
- spec/requests/import/gitlab_groups_controller_spec.rb
- spec/services/users/create_service_spec.rb
- spec/services/users/registrations_build_service_spec.rb
- spec/services/groups/create_service_spec.rb
- spec/services/groups/nested_create_service_spec.rb
- spec/services/resource_access_tokens/create_service_spec.rb
- spec/tasks/gitlab/seed/runner_fleet_rake_spec.rb
- spec/tasks/gitlab/update_templates_rake_spec.rb

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
module DisableNamespaceOrganizationValidationHelper
extend ActiveSupport::Concern
SPECS_FOR_CODE_TO_FIX = File.join(__dir__, 'disable_namespace_organization_validation.yml')
class << self
include Gitlab::Utils::StrongMemoize
def todo_list
YAML.load_file(SPECS_FOR_CODE_TO_FIX).filter_map { |path| full_path(path) } || []
end
strong_memoize_attr :todo_list
def full_path(path)
return unless File.exist?(path)
Pathname.new(path).realpath.to_s
end
end
included do
spec_file = Pathname.new(example.metadata[:example_group][:file_path]).realpath.to_s
if spec_file.in?(DisableNamespaceOrganizationValidationHelper.todo_list)
around do |example|
::Gitlab::SafeRequestStore.ensure_request_store { example.run }
end
end
end
end