diff --git a/.gitlab/lint/unused_helper_methods/potential_methods_to_remove.yml b/.gitlab/lint/unused_helper_methods/potential_methods_to_remove.yml index 9401d141098..5ce9a44108f 100644 --- a/.gitlab/lint/unused_helper_methods/potential_methods_to_remove.yml +++ b/.gitlab/lint/unused_helper_methods/potential_methods_to_remove.yml @@ -23,10 +23,6 @@ discover_duo_pro_hand_raise_lead_data: file: ee/app/helpers/gitlab_subscriptions/hand_raise_leads_helper.rb buy_addon_data: file: ee/app/helpers/subscriptions_helper.rb -group_icon: - file: app/helpers/avatars_helper.rb -topic_icon: - file: app/helpers/avatars_helper.rb can_view_namespace_catalog?: file: app/helpers/ci/catalog/resources_helper.rb js_ci_catalog_data: diff --git a/.rubocop.yml b/.rubocop.yml index b562db994a8..80ea34d26e9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -570,6 +570,18 @@ Gitlab/AvoidCurrentOrganization: - 'spec/**/*' - 'ee/spec/**/*' +Gitlab/DisallowCurrentOrganizationIdSafeNavigation: + Description: 'Use `Current.organization.id` instead of `Current.organization&.id`. `Current.organization` is expected to be assigned.' + Enabled: true + Include: + - 'app/**/*.rb' + - 'ee/app/**/*.rb' + - 'lib/**/*.rb' + - 'ee/lib/**/*.rb' + Exclude: + # Exclude the cop's own spec file to prevent self-reporting. + - 'spec/rubocop/cop/gitlab/disallow_current_organization_id_safe_navigation_spec.rb' + # See https://gitlab.com/groups/gitlab-org/-/epics/7374 Gitlab/AvoidGitlabInstanceChecks: Enabled: true diff --git a/app/assets/javascripts/graphql_shared/possible_types.json b/app/assets/javascripts/graphql_shared/possible_types.json index f1dd965ceb5..d6bd2e3cbf8 100644 --- a/app/assets/javascripts/graphql_shared/possible_types.json +++ b/app/assets/javascripts/graphql_shared/possible_types.json @@ -60,6 +60,10 @@ "MergeRequest", "WorkItemWidgetCurrentUserTodos" ], + "CustomRoleInterface": [ + "AdminMemberRole", + "MemberRole" + ], "DependencyInterface": [ "Dependency", "DependencyAggregation" @@ -144,6 +148,10 @@ "PendingProjectMember", "ProjectMember" ], + "MemberRoleInterface": [ + "MemberRole", + "StandardRole" + ], "NamespaceUnion": [ "CiDeletedNamespace", "Namespace" diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/fragments/container_repository_tag_protection.fragment.graphql b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/fragments/container_repository_tag_protection.fragment.graphql new file mode 100644 index 00000000000..c3c7c29bd76 --- /dev/null +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/fragments/container_repository_tag_protection.fragment.graphql @@ -0,0 +1,4 @@ +fragment ContainerRepositoryTagProtection on ContainerProtectionAccessLevel { + minimumAccessLevelForPush + minimumAccessLevelForDelete +} diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql index 3cfe45d9c18..a598722cf4c 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql @@ -1,4 +1,5 @@ #import "~/graphql_shared/fragments/page_info.fragment.graphql" +#import "ee_else_ce/packages_and_registries/container_registry/explorer/graphql/fragments/container_repository_tag_protection.fragment.graphql" query getContainerRepositoryTags( $id: ContainerRepositoryID! @@ -40,9 +41,7 @@ query getContainerRepositoryTags( destroyContainerRepositoryTag } protection { - minimumAccessLevelForPush - minimumAccessLevelForDelete - immutable + ...ContainerRepositoryTagProtection } referrers { artifactType diff --git a/app/assets/javascripts/packages_and_registries/settings/project/graphql/fragments/container_protection_tag_rule.fragment.graphql b/app/assets/javascripts/packages_and_registries/settings/project/graphql/fragments/container_protection_tag_rule.fragment.graphql new file mode 100644 index 00000000000..ceb4f064962 --- /dev/null +++ b/app/assets/javascripts/packages_and_registries/settings/project/graphql/fragments/container_protection_tag_rule.fragment.graphql @@ -0,0 +1,3 @@ +fragment ContainerProtectionTagRuleFragment on ContainerProtectionTagRule { + id +} diff --git a/app/assets/javascripts/packages_and_registries/settings/project/graphql/queries/get_container_protection_tag_rules.query.graphql b/app/assets/javascripts/packages_and_registries/settings/project/graphql/queries/get_container_protection_tag_rules.query.graphql index c1391cc1313..04eb8e751ca 100644 --- a/app/assets/javascripts/packages_and_registries/settings/project/graphql/queries/get_container_protection_tag_rules.query.graphql +++ b/app/assets/javascripts/packages_and_registries/settings/project/graphql/queries/get_container_protection_tag_rules.query.graphql @@ -1,16 +1,17 @@ +#import "ee_else_ce/packages_and_registries/settings/project/graphql/fragments/container_protection_tag_rule.fragment.graphql" + query getProjectContainerProtectionTagRules($projectPath: ID!, $first: Int) { project(fullPath: $projectPath) { id containerProtectionTagRules(first: $first) { nodes { - id tagNamePattern - immutable minimumAccessLevelForPush minimumAccessLevelForDelete userPermissions { destroyContainerRegistryProtectionTagRule } + ...ContainerProtectionTagRuleFragment } } } diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index dad603261ca..a5030ed7937 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -224,19 +224,19 @@ class ProjectsFinder < UnionFinder def by_marked_for_deletion_on(items) return items unless params[:marked_for_deletion_on].present? - items.by_marked_for_deletion_on(params[:marked_for_deletion_on]) + items.marked_for_deletion_on(params[:marked_for_deletion_on]) end def by_aimed_for_deletion(items) if ::Gitlab::Utils.to_boolean(params[:aimed_for_deletion]) - items.aimed_for_deletion(Date.current) + items.self_or_ancestors_aimed_for_deletion else items end end def by_not_aimed_for_deletion(items) - params[:not_aimed_for_deletion].present? ? items.not_aimed_for_deletion : items + params[:not_aimed_for_deletion].present? ? items.self_and_ancestors_not_aimed_for_deletion : items end def by_last_activity_after(items) @@ -280,14 +280,14 @@ class ProjectsFinder < UnionFinder def by_archived(projects) if params[:non_archived] - projects.non_archived + projects.self_and_ancestors_non_archived elsif params.key?(:archived) && !params[:archived].nil? if params[:archived] == 'only' - projects.archived + projects.self_or_ancestors_archived elsif Gitlab::Utils.to_boolean(params[:archived]) projects else - projects.non_archived + projects.self_and_ancestors_non_archived end else projects @@ -310,15 +310,7 @@ class ProjectsFinder < UnionFinder def by_active(items) return items if params[:active].nil? - params[:active] ? active(items) : inactive(items) - end - - def active(items) - items.non_archived.not_aimed_for_deletion - end - - def inactive(items) - items.archived.or(items.aimed_for_deletion(Date.current)) + params[:active] ? items.self_and_ancestors_active : items.self_or_ancestors_inactive end def finder_params diff --git a/app/graphql/mutations/container_registry/protection/tag_rule/create.rb b/app/graphql/mutations/container_registry/protection/tag_rule/create.rb index ba04ddab568..8cc88ba80b7 100644 --- a/app/graphql/mutations/container_registry/protection/tag_rule/create.rb +++ b/app/graphql/mutations/container_registry/protection/tag_rule/create.rb @@ -29,7 +29,7 @@ module Mutations argument :minimum_access_level_for_delete, Types::ContainerRegistry::Protection::TagRuleAccessLevelEnum, - required: false, + required: true, description: copy_field_description( Types::ContainerRegistry::Protection::TagRuleType, :minimum_access_level_for_delete @@ -37,7 +37,7 @@ module Mutations argument :minimum_access_level_for_push, Types::ContainerRegistry::Protection::TagRuleAccessLevelEnum, - required: false, + required: true, description: copy_field_description( Types::ContainerRegistry::Protection::TagRuleType, :minimum_access_level_for_push @@ -65,3 +65,5 @@ module Mutations end end end + +Mutations::ContainerRegistry::Protection::TagRule::Create.prepend_mod diff --git a/app/graphql/types/container_registry/protection/access_level_interface.rb b/app/graphql/types/container_registry/protection/access_level_interface.rb index 382a8446c69..d0b819cf0e9 100644 --- a/app/graphql/types/container_registry/protection/access_level_interface.rb +++ b/app/graphql/types/container_registry/protection/access_level_interface.rb @@ -8,29 +8,22 @@ module Types field :minimum_access_level_for_delete, Types::ContainerRegistry::Protection::TagRuleAccessLevelEnum, - null: true, + null: false, experiment: { milestone: '17.8' }, description: 'Minimum GitLab access level required to delete container image tags from the container repository. ' \ - 'Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. ' \ - 'If the value is `nil`, no access level can delete tags. ' + 'Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. ' field :minimum_access_level_for_push, Types::ContainerRegistry::Protection::TagRuleAccessLevelEnum, - null: true, + null: false, experiment: { milestone: '17.8' }, description: 'Minimum GitLab access level required to push container image tags to the container repository. ' \ - 'Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. ' \ - 'If the value is `nil`, no access level can push tags. ' - - field :immutable, - GraphQL::Types::Boolean, - null: false, - method: :immutable?, - experiment: { milestone: '17.11' }, - description: 'Returns true when tag rule is for tag immutability. Otherwise, false.' + 'Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. ' end end end end + +Types::ContainerRegistry::Protection::AccessLevelInterface.prepend_mod diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index cdf524816a9..4aaba8d2e63 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -876,12 +876,8 @@ module Types end def container_protection_tag_rules - rules = object.container_registry_protection_tag_rules - - return rules.mutable unless Feature.enabled?(:container_registry_immutable_tags, object) - - # mutable tag rules come first before immutable - rules.mutable + rules.immutable + # Immutable tag rules are added in EE extension + object.container_registry_protection_tag_rules.mutable end { diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb index 599978af0a9..bfc344e88cf 100644 --- a/app/helpers/avatars_helper.rb +++ b/app/helpers/avatars_helper.rb @@ -3,14 +3,6 @@ module AvatarsHelper DEFAULT_AVATAR_PATH = 'no_avatar.png' - def group_icon(group, options = {}) - source_icon(group, options) - end - - def topic_icon(topic, options = {}) - source_icon(topic, options) - end - # Takes both user and email and returns the avatar_icon by # user (preferred) or email. def avatar_icon_for(user = nil, email = nil, size = nil, scale = 2, only_path: true) diff --git a/app/models/project.rb b/app/models/project.rb index a5cdfa5a27d..79d68dc7892 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -658,13 +658,30 @@ class Project < ApplicationRecord scope :not_hidden, -> { where(hidden: false) } scope :not_in_groups, ->(groups) { where.not(group: groups) } scope :by_not_in_root_id, ->(root_id) { joins(:project_namespace).where('namespaces.traversal_ids[1] NOT IN (?)', root_id) } + + scope :aimed_for_deletion, -> { where.not(marked_for_deletion_at: nil).without_deleted } + scope :self_or_ancestors_aimed_for_deletion, -> do + left_joins(:group) + .where.not(marked_for_deletion_at: nil) + .or(where(Group.self_or_ancestors_deletion_schedule_subquery.exists)) + .without_deleted + end + scope :not_aimed_for_deletion, -> { where(marked_for_deletion_at: nil).without_deleted } - scope :aimed_for_deletion, ->(date) { where('marked_for_deletion_at <= ?', date).without_deleted } - scope :with_deleting_user, -> { includes(:deleting_user) } - scope :by_marked_for_deletion_on, ->(marked_for_deletion_on) do + scope :self_and_ancestors_not_aimed_for_deletion, -> do + left_joins(:group) + .where(marked_for_deletion_at: nil) + .where.not(Group.self_or_ancestors_deletion_schedule_subquery.exists) + .without_deleted + end + + scope :marked_for_deletion_before, ->(date) { where('marked_for_deletion_at <= ?', date).without_deleted } + scope :marked_for_deletion_on, ->(marked_for_deletion_on) do where(marked_for_deletion_at: marked_for_deletion_on) end + scope :with_deleting_user, -> { includes(:deleting_user) } + scope :with_storage_feature, ->(feature) do where(arel_table[:storage_version].gteq(HASHED_STORAGE_FEATURES[feature])) end @@ -798,8 +815,24 @@ class Project < ApplicationRecord scope :starred_by, ->(user) { joins(:users_star_projects).where('users_star_projects.user_id': user.id) } scope :visible_to_user, ->(user) { where(id: user.authorized_projects.select(:id).reorder(nil)) } scope :visible_to_user_and_access_level, ->(user, access_level) { where(id: user.authorized_projects.where('project_authorizations.access_level >= ?', access_level).select(:id).reorder(nil)) } + scope :archived, -> { where(archived: true) } + scope :self_or_ancestors_archived, -> do + left_joins(:group) + .where(archived: true) + .or(where(Group.self_or_ancestors_archived_setting_subquery.exists)) + end + scope :non_archived, -> { where(archived: false) } + scope :self_and_ancestors_non_archived, -> do + left_joins(:group) + .where(archived: false) + .where.not(Group.self_or_ancestors_archived_setting_subquery.exists) + end + + scope :self_and_ancestors_active, -> { self_and_ancestors_non_archived.self_and_ancestors_not_aimed_for_deletion } + scope :self_or_ancestors_inactive, -> { self_or_ancestors_archived.or(self_or_ancestors_aimed_for_deletion) } + scope :with_push, -> { joins(:events).merge(Event.pushed_action) } scope :with_project_feature, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id') } scope :with_jira_dvcs_server, -> { joins(:feature_usage).merge(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) } diff --git a/app/workers/adjourned_projects_deletion_cron_worker.rb b/app/workers/adjourned_projects_deletion_cron_worker.rb index 57a14c054e0..6db0b593a14 100644 --- a/app/workers/adjourned_projects_deletion_cron_worker.rb +++ b/app/workers/adjourned_projects_deletion_cron_worker.rb @@ -17,7 +17,7 @@ class AdjournedProjectsDeletionCronWorker def perform deletion_cutoff = Gitlab::CurrentSettings.deletion_adjourned_period.days.ago.to_date - Project.with_route.with_deleting_user.aimed_for_deletion(deletion_cutoff).find_each(batch_size: 100).with_index do |project, index| # rubocop: disable CodeReuse/ActiveRecord -- existing class moved from EE to CE + Project.with_route.with_deleting_user.marked_for_deletion_before(deletion_cutoff).find_each(batch_size: 100).with_index do |project, index| # rubocop: disable CodeReuse/ActiveRecord -- existing class moved from EE to CE delay = index * INTERVAL with_context(project: project, user: project.deleting_user) do diff --git a/config/events/collect_sast_scan_metrics_from_pipeline.yml b/config/events/collect_sast_scan_metrics_from_pipeline.yml index 1bf6fed082e..05082606c6b 100644 --- a/config/events/collect_sast_scan_metrics_from_pipeline.yml +++ b/config/events/collect_sast_scan_metrics_from_pipeline.yml @@ -21,11 +21,11 @@ additional_properties: property: description: "a UUID that identifies a scan" value: - description: "exit status of the analyer where 0 indicates success and 1 indicates error" + description: "exit status of the analyzer where 0 indicates success and 1 indicates error" version: description: "version of the analyzer" exit_code: - description: "exit code of the analyer" + description: "exit code of the analyzer" override_count: description: "number of configured overrides" passthrough_count: @@ -36,3 +36,5 @@ additional_properties: description: "scan time duration in seconds" file_count: description: "project size in terms of number of files" + language_feature_usage: + description: "counts of programming language features used in the project" diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml index f2bf8de8b98..186a07263e9 100644 --- a/config/sidekiq_queues.yml +++ b/config/sidekiq_queues.yml @@ -639,6 +639,8 @@ - 1 - - namespaces_cascade_duo_features_enabled - 1 +- - namespaces_cascade_web_based_commit_signing_enabled + - 1 - - namespaces_free_user_cap_group_over_limit_notification - 1 - - namespaces_process_sync_events diff --git a/db/migrate/20250529002831_add_created_by_id_to_custom_statuses.rb b/db/migrate/20250529002831_add_created_by_id_to_custom_statuses.rb new file mode 100644 index 00000000000..0551a296326 --- /dev/null +++ b/db/migrate/20250529002831_add_created_by_id_to_custom_statuses.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddCreatedByIdToCustomStatuses < Gitlab::Database::Migration[2.3] + milestone '18.1' + + def change + add_column :work_item_custom_statuses, :created_by_id, :bigint + end +end diff --git a/db/migrate/20250529005223_add_created_by_id_index_to_custom_statuses.rb b/db/migrate/20250529005223_add_created_by_id_index_to_custom_statuses.rb new file mode 100644 index 00000000000..212e7a71a7c --- /dev/null +++ b/db/migrate/20250529005223_add_created_by_id_index_to_custom_statuses.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddCreatedByIdIndexToCustomStatuses < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + INDEX_NAME = 'index_work_item_custom_statuses_on_created_by_id' + + def up + add_concurrent_index :work_item_custom_statuses, :created_by_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :work_item_custom_statuses, name: INDEX_NAME + end +end diff --git a/db/migrate/20250529005709_add_created_by_foreign_key_to_custom_statuses.rb b/db/migrate/20250529005709_add_created_by_foreign_key_to_custom_statuses.rb new file mode 100644 index 00000000000..4f7f4b4a843 --- /dev/null +++ b/db/migrate/20250529005709_add_created_by_foreign_key_to_custom_statuses.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddCreatedByForeignKeyToCustomStatuses < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + def up + add_concurrent_foreign_key :work_item_custom_statuses, :users, + column: :created_by_id, on_delete: :nullify + end + + def down + remove_foreign_key_if_exists :work_item_custom_statuses, column: :created_by_id + end +end diff --git a/db/migrate/20250529010458_add_created_by_id_to_custom_lifecycles.rb b/db/migrate/20250529010458_add_created_by_id_to_custom_lifecycles.rb new file mode 100644 index 00000000000..2db48e76a15 --- /dev/null +++ b/db/migrate/20250529010458_add_created_by_id_to_custom_lifecycles.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddCreatedByIdToCustomLifecycles < Gitlab::Database::Migration[2.3] + milestone '18.1' + + def change + add_column :work_item_custom_lifecycles, :created_by_id, :bigint + end +end diff --git a/db/migrate/20250529010756_add_created_by_id_index_to_custom_lifecycles.rb b/db/migrate/20250529010756_add_created_by_id_index_to_custom_lifecycles.rb new file mode 100644 index 00000000000..a9652752531 --- /dev/null +++ b/db/migrate/20250529010756_add_created_by_id_index_to_custom_lifecycles.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddCreatedByIdIndexToCustomLifecycles < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + INDEX_NAME = 'index_work_item_custom_lifecycles_on_created_by_id' + + def up + add_concurrent_index :work_item_custom_lifecycles, :created_by_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :work_item_custom_lifecycles, name: INDEX_NAME + end +end diff --git a/db/migrate/20250529010905_add_created_by_foreign_key_to_custom_lifecycles.rb b/db/migrate/20250529010905_add_created_by_foreign_key_to_custom_lifecycles.rb new file mode 100644 index 00000000000..0e1a86995d5 --- /dev/null +++ b/db/migrate/20250529010905_add_created_by_foreign_key_to_custom_lifecycles.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddCreatedByForeignKeyToCustomLifecycles < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + def up + add_concurrent_foreign_key :work_item_custom_lifecycles, :users, + column: :created_by_id, on_delete: :nullify + end + + def down + remove_foreign_key_if_exists :work_item_custom_lifecycles, column: :created_by_id + end +end diff --git a/db/migrate/20250529011429_add_updated_by_id_to_custom_statuses.rb b/db/migrate/20250529011429_add_updated_by_id_to_custom_statuses.rb new file mode 100644 index 00000000000..986dd5c823d --- /dev/null +++ b/db/migrate/20250529011429_add_updated_by_id_to_custom_statuses.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddUpdatedByIdToCustomStatuses < Gitlab::Database::Migration[2.3] + milestone '18.1' + + def change + add_column :work_item_custom_statuses, :updated_by_id, :bigint + end +end diff --git a/db/migrate/20250529011732_add_updated_by_id_index_to_custom_statuses.rb b/db/migrate/20250529011732_add_updated_by_id_index_to_custom_statuses.rb new file mode 100644 index 00000000000..82a2c9511c1 --- /dev/null +++ b/db/migrate/20250529011732_add_updated_by_id_index_to_custom_statuses.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddUpdatedByIdIndexToCustomStatuses < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + INDEX_NAME = 'index_work_item_custom_statuses_on_updated_by_id' + + def up + add_concurrent_index :work_item_custom_statuses, :updated_by_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :work_item_custom_statuses, name: INDEX_NAME + end +end diff --git a/db/migrate/20250529011941_add_updated_by_foreign_key_to_custom_statuses.rb b/db/migrate/20250529011941_add_updated_by_foreign_key_to_custom_statuses.rb new file mode 100644 index 00000000000..e4864a9d83e --- /dev/null +++ b/db/migrate/20250529011941_add_updated_by_foreign_key_to_custom_statuses.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddUpdatedByForeignKeyToCustomStatuses < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + def up + add_concurrent_foreign_key :work_item_custom_statuses, :users, + column: :updated_by_id, on_delete: :nullify + end + + def down + remove_foreign_key_if_exists :work_item_custom_statuses, column: :updated_by_id + end +end diff --git a/db/migrate/20250529012147_add_updated_by_id_to_custom_lifecycles.rb b/db/migrate/20250529012147_add_updated_by_id_to_custom_lifecycles.rb new file mode 100644 index 00000000000..b1b7dae710d --- /dev/null +++ b/db/migrate/20250529012147_add_updated_by_id_to_custom_lifecycles.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddUpdatedByIdToCustomLifecycles < Gitlab::Database::Migration[2.3] + milestone '18.1' + + def change + add_column :work_item_custom_lifecycles, :updated_by_id, :bigint + end +end diff --git a/db/migrate/20250529012327_add_updated_by_id_index_to_custom_lifecycles.rb b/db/migrate/20250529012327_add_updated_by_id_index_to_custom_lifecycles.rb new file mode 100644 index 00000000000..135f0039755 --- /dev/null +++ b/db/migrate/20250529012327_add_updated_by_id_index_to_custom_lifecycles.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddUpdatedByIdIndexToCustomLifecycles < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + INDEX_NAME = 'index_work_item_custom_lifecycles_on_updated_by_id' + + def up + add_concurrent_index :work_item_custom_lifecycles, :updated_by_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :work_item_custom_lifecycles, name: INDEX_NAME + end +end diff --git a/db/migrate/20250529012446_add_updated_by_foreign_key_to_custom_lifecycles.rb b/db/migrate/20250529012446_add_updated_by_foreign_key_to_custom_lifecycles.rb new file mode 100644 index 00000000000..e65105a5272 --- /dev/null +++ b/db/migrate/20250529012446_add_updated_by_foreign_key_to_custom_lifecycles.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddUpdatedByForeignKeyToCustomLifecycles < Gitlab::Database::Migration[2.3] + disable_ddl_transaction! + milestone '18.1' + + def up + add_concurrent_foreign_key :work_item_custom_lifecycles, :users, + column: :updated_by_id, on_delete: :nullify + end + + def down + remove_foreign_key_if_exists :work_item_custom_lifecycles, column: :updated_by_id + end +end diff --git a/db/post_migrate/20250602191335_remove_idx_ci_job_variables_on_partition_id_job_id.rb b/db/post_migrate/20250602191335_remove_idx_ci_job_variables_on_partition_id_job_id.rb new file mode 100644 index 00000000000..f1c4fa56234 --- /dev/null +++ b/db/post_migrate/20250602191335_remove_idx_ci_job_variables_on_partition_id_job_id.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class RemoveIdxCiJobVariablesOnPartitionIdJobId < Gitlab::Database::Migration[2.3] + milestone '18.1' + + disable_ddl_transaction! + + TABLE_NAME = :ci_job_variables + INDEX_NAME = :index_ci_job_variables_on_partition_id_job_id + COLUMNS = [:partition_id, :job_id] + + def up + remove_concurrent_index_by_name TABLE_NAME, name: INDEX_NAME + end + + def down + add_concurrent_index TABLE_NAME, COLUMNS, name: INDEX_NAME + end +end diff --git a/db/post_migrate/20250603033828_remove_project_fingerprint_from_security_findings.rb b/db/post_migrate/20250603033828_remove_project_fingerprint_from_security_findings.rb new file mode 100644 index 00000000000..17070a9692d --- /dev/null +++ b/db/post_migrate/20250603033828_remove_project_fingerprint_from_security_findings.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class RemoveProjectFingerprintFromSecurityFindings < Gitlab::Database::Migration[2.3] + include Gitlab::Database::PartitioningMigrationHelpers + + disable_ddl_transaction! + milestone '18.1' + + def up + remove_check_constraint :security_findings, 'check_b9508c6df8' + remove_column :security_findings, :project_fingerprint + end + + def down + add_column :security_findings, :project_fingerprint, :text, if_not_exists: true + add_check_constraint :security_findings, 'char_length(project_fingerprint) <= 40', 'check_b9508c6df8' + add_concurrent_partitioned_index :security_findings, :project_fingerprint, + name: 'security_findings_project_fingerprint_idx' + end +end diff --git a/db/schema_migrations/20250529002831 b/db/schema_migrations/20250529002831 new file mode 100644 index 00000000000..99078088546 --- /dev/null +++ b/db/schema_migrations/20250529002831 @@ -0,0 +1 @@ +8dc9aa1a310798758d7b115d50d20142af56c35af11ada707708a8d521389021 \ No newline at end of file diff --git a/db/schema_migrations/20250529005223 b/db/schema_migrations/20250529005223 new file mode 100644 index 00000000000..56a8463776b --- /dev/null +++ b/db/schema_migrations/20250529005223 @@ -0,0 +1 @@ +363c5d217044ac211c3bdadf3d8d2e582f4c1c8c705ab5b6d2d141c18431e861 \ No newline at end of file diff --git a/db/schema_migrations/20250529005709 b/db/schema_migrations/20250529005709 new file mode 100644 index 00000000000..94c46a1170a --- /dev/null +++ b/db/schema_migrations/20250529005709 @@ -0,0 +1 @@ +76f7874268107ae4a9d8bdbbfcdf522a869726b67a87a95ca184fa0409519c83 \ No newline at end of file diff --git a/db/schema_migrations/20250529010458 b/db/schema_migrations/20250529010458 new file mode 100644 index 00000000000..8cf105f9b47 --- /dev/null +++ b/db/schema_migrations/20250529010458 @@ -0,0 +1 @@ +ccb4e487017f8742eaffb87048a6ea7c6b2bbb59a31b276abef1c4b921725f73 \ No newline at end of file diff --git a/db/schema_migrations/20250529010756 b/db/schema_migrations/20250529010756 new file mode 100644 index 00000000000..d4260cf8782 --- /dev/null +++ b/db/schema_migrations/20250529010756 @@ -0,0 +1 @@ +cc592eedda6586088a1049c9ca27618a73b50281335ccac5ea4c425c0c5f9444 \ No newline at end of file diff --git a/db/schema_migrations/20250529010905 b/db/schema_migrations/20250529010905 new file mode 100644 index 00000000000..568509b5b79 --- /dev/null +++ b/db/schema_migrations/20250529010905 @@ -0,0 +1 @@ +e3a4587ea36f0c4b266a8e908b73e867e5df0afefa202417a439cf099a112e63 \ No newline at end of file diff --git a/db/schema_migrations/20250529011429 b/db/schema_migrations/20250529011429 new file mode 100644 index 00000000000..d1a855ef0dd --- /dev/null +++ b/db/schema_migrations/20250529011429 @@ -0,0 +1 @@ +a3f50469cd58afe7fb6012ff7b27eef52e45c966f7cffb0516d499b70b0de666 \ No newline at end of file diff --git a/db/schema_migrations/20250529011732 b/db/schema_migrations/20250529011732 new file mode 100644 index 00000000000..459b8255aad --- /dev/null +++ b/db/schema_migrations/20250529011732 @@ -0,0 +1 @@ +f0c69d5d3bfdcc30df065db0c658ee86bbe4e28dc4eb50233308d947faaf0b3f \ No newline at end of file diff --git a/db/schema_migrations/20250529011941 b/db/schema_migrations/20250529011941 new file mode 100644 index 00000000000..df209f154c1 --- /dev/null +++ b/db/schema_migrations/20250529011941 @@ -0,0 +1 @@ +4a373f4a79e4bf14b5509ce63a9fb79267246b2dfc03c83d20868142f6eaca9d \ No newline at end of file diff --git a/db/schema_migrations/20250529012147 b/db/schema_migrations/20250529012147 new file mode 100644 index 00000000000..42ea3c0b270 --- /dev/null +++ b/db/schema_migrations/20250529012147 @@ -0,0 +1 @@ +5674253dd6f59541e4a396635aceffd7963bf4fef38bbebb58851ecd8b10b1ee \ No newline at end of file diff --git a/db/schema_migrations/20250529012327 b/db/schema_migrations/20250529012327 new file mode 100644 index 00000000000..efe81355c34 --- /dev/null +++ b/db/schema_migrations/20250529012327 @@ -0,0 +1 @@ +e0ae0be50f1fd197267e524d0bed195be8692dec84c3ddb24ad5bf754fa26a02 \ No newline at end of file diff --git a/db/schema_migrations/20250529012446 b/db/schema_migrations/20250529012446 new file mode 100644 index 00000000000..9f18e3d9546 --- /dev/null +++ b/db/schema_migrations/20250529012446 @@ -0,0 +1 @@ +d8de1cea7fdafa9d31cab776eff7ea66015d253abed20056cff1fcfd4334561b \ No newline at end of file diff --git a/db/schema_migrations/20250602191335 b/db/schema_migrations/20250602191335 new file mode 100644 index 00000000000..30b27a423e5 --- /dev/null +++ b/db/schema_migrations/20250602191335 @@ -0,0 +1 @@ +a05765899ad07672f1c007ac86087e799aeb507328675566585cfd684878b4ba \ No newline at end of file diff --git a/db/schema_migrations/20250603033828 b/db/schema_migrations/20250603033828 new file mode 100644 index 00000000000..96819f8dd5a --- /dev/null +++ b/db/schema_migrations/20250603033828 @@ -0,0 +1 @@ +1826f2a6ec247577a18af2a0c6d14713ef817760ca0607c0a8f49badce883504 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 51fc8fe5443..48934b7283d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -4965,15 +4965,13 @@ CREATE TABLE security_findings ( scan_id bigint NOT NULL, scanner_id bigint NOT NULL, severity smallint NOT NULL, - project_fingerprint text, deduplicated boolean DEFAULT false NOT NULL, uuid uuid, overridden_uuid uuid, partition_number integer DEFAULT 1 NOT NULL, finding_data jsonb DEFAULT '{}'::jsonb NOT NULL, project_id bigint, - CONSTRAINT check_6c2851a8c9 CHECK ((uuid IS NOT NULL)), - CONSTRAINT check_b9508c6df8 CHECK ((char_length(project_fingerprint) <= 40)) + CONSTRAINT check_6c2851a8c9 CHECK ((uuid IS NOT NULL)) ) PARTITION BY LIST (partition_number); @@ -25788,6 +25786,8 @@ CREATE TABLE work_item_custom_lifecycles ( created_at timestamp with time zone NOT NULL, updated_at timestamp with time zone NOT NULL, name text NOT NULL, + created_by_id bigint, + updated_by_id bigint, CONSTRAINT check_1feff2de99 CHECK ((char_length(name) <= 255)) ); @@ -25809,6 +25809,8 @@ CREATE TABLE work_item_custom_statuses ( name text NOT NULL, description text, color text NOT NULL, + created_by_id bigint, + updated_by_id bigint, CONSTRAINT check_4789467800 CHECK ((char_length(color) <= 7)), CONSTRAINT check_720a7c4d24 CHECK ((char_length(name) <= 255)), CONSTRAINT check_8ea8b3c991 CHECK ((char_length(description) <= 255)), @@ -34438,8 +34440,6 @@ CREATE INDEX index_ci_job_variables_on_job_id ON ci_job_variables USING btree (j CREATE UNIQUE INDEX index_ci_job_variables_on_key_and_job_id ON ci_job_variables USING btree (key, job_id); -CREATE INDEX index_ci_job_variables_on_partition_id_job_id ON ci_job_variables USING btree (partition_id, job_id); - CREATE INDEX index_ci_job_variables_on_project_id ON ci_job_variables USING btree (project_id); CREATE INDEX index_ci_minutes_additional_packs_on_namespace_id_purchase_xid ON ci_minutes_additional_packs USING btree (namespace_id, purchase_xid); @@ -38204,10 +38204,18 @@ CREATE INDEX index_work_item_current_statuses_on_namespace_id ON work_item_curre CREATE UNIQUE INDEX index_work_item_current_statuses_on_work_item_id ON work_item_current_statuses USING btree (work_item_id); +CREATE INDEX index_work_item_custom_lifecycles_on_created_by_id ON work_item_custom_lifecycles USING btree (created_by_id); + CREATE UNIQUE INDEX index_work_item_custom_lifecycles_on_namespace_id_and_name ON work_item_custom_lifecycles USING btree (namespace_id, name); +CREATE INDEX index_work_item_custom_lifecycles_on_updated_by_id ON work_item_custom_lifecycles USING btree (updated_by_id); + +CREATE INDEX index_work_item_custom_statuses_on_created_by_id ON work_item_custom_statuses USING btree (created_by_id); + CREATE UNIQUE INDEX index_work_item_custom_statuses_on_namespace_id_and_lower_name ON work_item_custom_statuses USING btree (namespace_id, TRIM(BOTH FROM lower(name))); +CREATE INDEX index_work_item_custom_statuses_on_updated_by_id ON work_item_custom_statuses USING btree (updated_by_id); + CREATE INDEX index_work_item_hierarchy_restrictions_on_child_type_id ON work_item_hierarchy_restrictions USING btree (child_type_id); CREATE UNIQUE INDEX index_work_item_hierarchy_restrictions_on_parent_and_child ON work_item_hierarchy_restrictions USING btree (parent_type_id, child_type_id); @@ -38708,8 +38716,6 @@ CREATE INDEX scan_finding_approval_project_rule_index_created_at_project_id ON a CREATE INDEX scan_finding_approval_project_rule_index_project_id ON approval_project_rules USING btree (project_id) WHERE (report_type = 4); -CREATE INDEX security_findings_project_fingerprint_idx ON ONLY security_findings USING btree (project_fingerprint); - CREATE INDEX security_findings_scan_id_deduplicated_idx ON ONLY security_findings USING btree (scan_id, deduplicated); CREATE INDEX security_findings_scan_id_id_idx ON ONLY security_findings USING btree (scan_id, id); @@ -42339,6 +42345,9 @@ ALTER TABLE ONLY deployment_approvals ALTER TABLE ONLY bulk_import_trackers ADD CONSTRAINT fk_2d0e051bc3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY work_item_custom_lifecycles + ADD CONSTRAINT fk_2d0f7ebf48 FOREIGN KEY (updated_by_id) REFERENCES users(id) ON DELETE SET NULL; + ALTER TABLE ONLY audit_events_instance_external_audit_event_destinations ADD CONSTRAINT fk_2d3ebd0fbc FOREIGN KEY (stream_destination_id) REFERENCES audit_events_instance_external_streaming_destinations(id) ON DELETE SET NULL; @@ -42708,6 +42717,9 @@ ALTER TABLE ONLY deploy_keys_projects ALTER TABLE ONLY merge_requests_approval_rules_groups ADD CONSTRAINT fk_59068f09e5 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY work_item_custom_statuses + ADD CONSTRAINT fk_590e87b7c7 FOREIGN KEY (updated_by_id) REFERENCES users(id) ON DELETE SET NULL; + ALTER TABLE ONLY oauth_access_grants ADD CONSTRAINT fk_59cdb2323c FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE; @@ -42777,6 +42789,9 @@ ALTER TABLE ONLY user_achievements ALTER TABLE ONLY merge_requests ADD CONSTRAINT fk_6149611a04 FOREIGN KEY (assignee_id) REFERENCES users(id) ON DELETE SET NULL; +ALTER TABLE ONLY work_item_custom_lifecycles + ADD CONSTRAINT fk_614a3cdb95 FOREIGN KEY (created_by_id) REFERENCES users(id) ON DELETE SET NULL; + ALTER TABLE ONLY member_approvals ADD CONSTRAINT fk_619f381144 FOREIGN KEY (member_role_id) REFERENCES member_roles(id) ON DELETE SET NULL; @@ -44139,6 +44154,9 @@ ALTER TABLE ONLY merge_requests_approval_rules ALTER TABLE ONLY clusters_managed_resources ADD CONSTRAINT fk_fad3c3b2e2 FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE; +ALTER TABLE ONLY work_item_custom_statuses + ADD CONSTRAINT fk_fb28a15e7b FOREIGN KEY (created_by_id) REFERENCES users(id) ON DELETE SET NULL; + ALTER TABLE ONLY agent_group_authorizations ADD CONSTRAINT fk_fb70782616 FOREIGN KEY (agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE; diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 69812467d22..26ecb98826a 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -4261,8 +4261,8 @@ Input type: `createContainerProtectionTagRuleInput` | Name | Type | Description | | ---- | ---- | ----------- | | `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | -| `minimumAccessLevelForDelete` | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can delete tags. Introduced in GitLab 17.8: **Status**: Experiment. | -| `minimumAccessLevelForPush` | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can push tags. Introduced in GitLab 17.8: **Status**: Experiment. | +| `minimumAccessLevelForDelete` | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. Introduced in GitLab 17.8: **Status**: Experiment. If the value is `nil`, no access level can delete tags. | +| `minimumAccessLevelForPush` | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. Introduced in GitLab 17.8: **Status**: Experiment. If the value is `nil`, no access level can push tags. | | `projectPath` | [`ID!`](#id) | Full path of the project containing the container image tags. | | `tagNamePattern` | [`String!`](#string) | The pattern that matches container image tags to protect. For example, `v1.*`. Wildcard character `*` allowed. Introduced in GitLab 17.8: **Status**: Experiment. | @@ -21197,9 +21197,9 @@ Represents an admin member role. | `editPath` {{< icon name="warning-solid" >}} | [`String!`](#string) | **Introduced** in GitLab 16.11. **Status**: Experiment. Web UI path to edit the custom role. | | `enabledPermissions` {{< icon name="warning-solid" >}} | [`CustomizableAdminPermissionConnection!`](#customizableadminpermissionconnection) | **Introduced** in GitLab 17.7. **Status**: Experiment. Array of all permissions enabled for the custom role. | | `id` | [`ID!`](#id) | Role ID. | -| `membersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Introduced** in GitLab 17.3. **Status**: Experiment. Number of times the role has been directly assigned to a group or project member. | +| `ldapAdminRoleLinks` {{< icon name="warning-solid" >}} | [`LdapAdminRoleLinkConnection`](#ldapadminrolelinkconnection) | **Introduced** in GitLab 18.1. **Status**: Experiment. LDAP admin role sync configurations that will assign the admin member role. | | `name` | [`String`](#string) | Role name. | -| `usersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Introduced** in GitLab 17.5. **Status**: Experiment. Number of users who have been directly assigned the role in at least one group or project. | +| `usersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Introduced** in GitLab 17.5. **Status**: Experiment. Number of users who have been directly assigned the admin member role. | ### `AgentConfiguration` @@ -24455,8 +24455,8 @@ Represents the most restrictive permissions for a container image tag. | Name | Type | Description | | ---- | ---- | ----------- | | `immutable` {{< icon name="warning-solid" >}} | [`Boolean!`](#boolean) | **Introduced** in GitLab 17.11. **Status**: Experiment. Returns true when tag rule is for tag immutability. Otherwise, false. | -| `minimumAccessLevelForDelete` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can delete tags. | -| `minimumAccessLevelForPush` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can push tags. | +| `minimumAccessLevelForDelete` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. | +| `minimumAccessLevelForPush` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. | ### `ContainerProtectionRepositoryRule` @@ -24481,8 +24481,8 @@ A container repository tag protection rule designed to prevent users with a cert | ---- | ---- | ----------- | | `id` {{< icon name="warning-solid" >}} | [`ContainerRegistryProtectionTagRuleID!`](#containerregistryprotectiontagruleid) | **Introduced** in GitLab 17.8. **Status**: Experiment. ID of the container repository tag protection rule. | | `immutable` {{< icon name="warning-solid" >}} | [`Boolean!`](#boolean) | **Introduced** in GitLab 17.11. **Status**: Experiment. Returns true when tag rule is for tag immutability. Otherwise, false. | -| `minimumAccessLevelForDelete` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can delete tags. | -| `minimumAccessLevelForPush` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can push tags. | +| `minimumAccessLevelForDelete` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. | +| `minimumAccessLevelForPush` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. | | `tagNamePattern` {{< icon name="warning-solid" >}} | [`String!`](#string) | **Introduced** in GitLab 17.8. **Status**: Experiment. The pattern that matches container image tags to protect. For example, `v1.*`. Wildcard character `*` allowed. | | `userPermissions` | [`ContainerRegistryProtectionTagRulePermissions!`](#containerregistryprotectiontagrulepermissions) | Permissions for the current user on the resource. | @@ -48627,8 +48627,8 @@ Implementations: | Name | Type | Description | | ---- | ---- | ----------- | | `immutable` {{< icon name="warning-solid" >}} | [`Boolean!`](#boolean) | **Introduced** in GitLab 17.11. **Status**: Experiment. Returns true when tag rule is for tag immutability. Otherwise, false. | -| `minimumAccessLevelForDelete` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can delete tags. | -| `minimumAccessLevelForPush` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. If the value is `nil`, no access level can push tags. | +| `minimumAccessLevelForDelete` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to delete container image tags from the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. | +| `minimumAccessLevelForPush` {{< icon name="warning-solid" >}} | [`ContainerProtectionTagRuleAccessLevel`](#containerprotectiontagruleaccesslevel) | **Introduced** in GitLab 17.8. **Status**: Experiment. Minimum GitLab access level required to push container image tags to the container repository. Valid values include `MAINTAINER`, `OWNER`, or `ADMIN`. | #### `AlertManagementIntegration` @@ -48870,6 +48870,20 @@ four standard [pagination arguments](#pagination-arguments): | ---- | ---- | ----------- | | `state` | [`TodoStateEnum`](#todostateenum) | State of the to-do items. | +#### `CustomRoleInterface` + +Implementations: + +- [`AdminMemberRole`](#adminmemberrole) +- [`MemberRole`](#memberrole) + +##### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `createdAt` | [`Time!`](#time) | Timestamp of when the member role was created. | +| `editPath` {{< icon name="warning-solid" >}} | [`String!`](#string) | **Introduced** in GitLab 16.11. **Status**: Experiment. Web UI path to edit the custom role. | + #### `DependencyInterface` Implementations: @@ -49110,6 +49124,20 @@ Returns [`UserMergeRequestInteraction`](#usermergerequestinteraction). | ---- | ---- | ----------- | | `id` | [`MergeRequestID!`](#mergerequestid) | Global ID of the merge request. | +#### `MemberRoleInterface` + +Implementations: + +- [`MemberRole`](#memberrole) +- [`StandardRole`](#standardrole) + +##### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `membersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Introduced** in GitLab 17.3. **Status**: Experiment. Number of times the role has been directly assigned to a group or project member. | +| `usersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Introduced** in GitLab 17.5. **Status**: Experiment. Number of users who have been directly assigned the role in at least one group or project. | + #### `NamespacesLinkPaths` Implementations: @@ -49323,9 +49351,7 @@ Implementations: | `description` | [`String`](#string) | Role description. | | `detailsPath` {{< icon name="warning-solid" >}} | [`String`](#string) | **Introduced** in GitLab 17.4. **Status**: Experiment. URL path to the role details webpage. | | `id` | [`ID!`](#id) | Role ID. | -| `membersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Introduced** in GitLab 17.3. **Status**: Experiment. Number of times the role has been directly assigned to a group or project member. | | `name` | [`String`](#string) | Role name. | -| `usersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Introduced** in GitLab 17.5. **Status**: Experiment. Number of users who have been directly assigned the role in at least one group or project. | #### `Service` diff --git a/doc/development/sidekiq/logging.md b/doc/development/sidekiq/logging.md index 7d37efc1e6c..436785745ea 100644 --- a/doc/development/sidekiq/logging.md +++ b/doc/development/sidekiq/logging.md @@ -58,7 +58,7 @@ somewhere within the worker: deletion_cutoff = Gitlab::CurrentSettings .deletion_adjourned_period.days.ago.to_date projects = Project.with_route.with_namespace - .aimed_for_deletion(deletion_cutoff) + .marked_for_deletion_before(deletion_cutoff) projects.find_each(batch_size: 100).with_index do |project, index| delay = index * INTERVAL diff --git a/doc/user/compliance/compliance_frameworks.md b/doc/user/compliance/compliance_frameworks.md index 6355d0624c6..33b10448463 100644 --- a/doc/user/compliance/compliance_frameworks.md +++ b/doc/user/compliance/compliance_frameworks.md @@ -195,6 +195,11 @@ You can use GitLab compliance controls or external controls for framework requir GitLab compliance controls can be used in GitLab compliance frameworks. Controls are checks against the configuration or behavior of projects that are assigned to a compliance framework. +Combine GitLab compliance controls to help you meet +[compliance standards](compliance_frameworks/compliance_standards.md). + + + | Control name | Control ID | Description | |:---------------------------------------------------------|:-----------------------------------------------------------|:------------| | API security running | `scanner_api_security_running` | Ensures that [API security scanning](../application_security/api_security/_index.md) is configured and running in the project pipelines. | diff --git a/doc/user/compliance/compliance_frameworks/compliance_standards.md b/doc/user/compliance/compliance_frameworks/compliance_standards.md new file mode 100644 index 00000000000..3dd06d941ff --- /dev/null +++ b/doc/user/compliance/compliance_frameworks/compliance_standards.md @@ -0,0 +1,28 @@ +--- +stage: Software Supply Chain Security +group: Compliance +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments +title: Compliance standards +--- + +You can use [GitLab compliance controls](../compliance_frameworks.md#gitlab-compliance-controls) to help meet the +requirements of many compliance standards. + +## ISO 27001 compliance requirements + +ISO 27001 is an internationally recognized standard that provides a framework for implementing and managing an +Information Security Management System (ISMS). + +The following table lists the requirements supported by GitLab for ISO 27001 and the controls for the requirements. + +| ISO 27001 requirement | Description | Supported controls | +|:----------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------| +| 5.3 Segregation of duties | Conflicting duties and conflicting areas of responsibility shall be segregated. |