From 36aae58f5563edf62c3a419f5dabe4e0b4bbb7a4 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 2 Jul 2025 12:13:07 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .gitlab/ci/rules.gitlab-ci.yml | 2 + .../node_matcher_directive.yml | 20 ---- GITALY_SERVER_VERSION | 2 +- GITLAB_KAS_VERSION | 2 +- app/models/ci/processable.rb | 8 ++ app/models/concerns/ci/metadatable.rb | 18 ---- app/services/merge_requests/base_service.rb | 2 +- .../merge_requests/post_merge_service.rb | 1 + .../last_used_service.rb | 1 - ...xternal_service_reactive_caching_worker.rb | 1 + .../ci_redis_enqueue_immediately.yml | 10 -- .../pat_last_used_at_optimization.yml | 10 -- config/initializers/doorkeeper.rb | 6 +- ...versal_ids_to_vulnerability_statistics.yml | 4 +- ...namespace_id_to_duo_workflows_workflows.rb | 9 ++ ...mespace_id_to_duo_workflows_checkpoints.rb | 9 ++ ...dd_namespace_id_to_duo_workflows_events.rb | 9 ++ ...e_id_to_duo_workflows_checkpoint_writes.rb | 9 ++ ...duo_workflows_workflows_on_namespace_id.rb | 18 ++++ ...o_workflows_checkpoints_on_namespace_id.rb | 18 ++++ ...to_duo_workflows_events_on_namespace_id.rb | 18 ++++ ...flows_checkpoint_writes_on_namespace_id.rb | 18 ++++ ...espace_id_fk_to_duo_workflows_workflows.rb | 17 ++++ ...pace_id_fk_to_duo_workflows_checkpoints.rb | 17 ++++ ...namespace_id_fk_to_duo_workflows_events.rb | 17 ++++ ...d_fk_to_duo_workflows_checkpoint_writes.rb | 17 ++++ ...aversal_ids_to_vulnerability_statistics.rb | 20 +--- ...rsal_ids_to_vulnerability_statistics_v2.rb | 28 ++++++ db/schema_migrations/20250617010101 | 1 + db/schema_migrations/20250617010102 | 1 + db/schema_migrations/20250617010103 | 1 + db/schema_migrations/20250617010104 | 1 + db/schema_migrations/20250617010201 | 1 + db/schema_migrations/20250617010202 | 1 + db/schema_migrations/20250617010203 | 1 + db/schema_migrations/20250617010204 | 1 + db/schema_migrations/20250617010301 | 1 + db/schema_migrations/20250617010302 | 1 + db/schema_migrations/20250617010303 | 1 + db/schema_migrations/20250617010304 | 1 + db/schema_migrations/20250630065826 | 1 + db/structure.sql | 24 +++++ .../monitoring/performance/performance_bar.md | 4 +- doc/api/api_resources.md | 2 +- doc/api/compliance_policy_settings.md | 90 ++++++++++++++++++ doc/api/graphql/reference/_index.md | 40 +++++++- doc/api/metadata.md | 6 +- doc/api/policy_settings.md | 93 ++----------------- doc/api/version.md | 13 +-- doc/development/sidekiq/worker_attributes.md | 2 +- doc/user/search/exact_code_search.md | 10 ++ .../oauth_resource_owner_redirect_resolver.rb | 23 +++++ .../Dependency-Scanning.latest.gitlab-ci.yml | 2 +- lib/mattermost/session.rb | 2 +- locale/gitlab.pot | 33 ++++++- rubocop/cop/gitlab/policy_rule_boolean.rb | 3 + rubocop/cop/gitlab/rails/safe_format.rb | 1 + rubocop/cop/gitlab/rails_logger.rb | 1 + rubocop/cop/gitlab/service_response.rb | 1 + rubocop/cop/gitlab/strong_memoize_attr.rb | 1 + rubocop/cop/gitlab/token_without_prefix.rb | 3 + rubocop/cop/gitlab/union.rb | 1 + rubocop/cop/graphql/authorize_types.rb | 1 + rubocop/cop/graphql/descriptions.rb | 5 + rubocop/cop/graphql/enum_names.rb | 3 + rubocop/cop/graphql/enum_values.rb | 4 + rubocop/cop/graphql/graphql_name_position.rb | 1 + rubocop/cop/graphql/id_type.rb | 2 + rubocop/cop/graphql/json_type.rb | 1 + rubocop/cop/graphql/old_types.rb | 1 + rubocop/cop/graphql/resolver_type.rb | 1 + .../graphql/resource_not_available_error.rb | 2 + .../cop/group_public_or_visible_to_user.rb | 1 + rubocop/cop/ignored_columns.rb | 3 + rubocop/cop/include_sidekiq_worker.rb | 1 + spec/initializers/doorkeeper_spec.rb | 24 ++++- ...h_resource_owner_redirect_resolver_spec.rb | 34 +++++++ spec/lib/mattermost/session_spec.rb | 12 ++- ...al_ids_to_vulnerability_statistics_spec.rb | 9 +- ...ids_to_vulnerability_statistics_v2_spec.rb | 27 ++++++ spec/models/ci/processable_spec.rb | 23 +++++ spec/services/ci/retry_job_service_spec.rb | 31 ------- .../merge_requests/approval_service_spec.rb | 1 + .../handle_assignees_change_service_spec.rb | 1 + .../merge_requests/post_merge_service_spec.rb | 7 ++ .../remove_approval_service_spec.rb | 1 + .../update_reviewer_state_service_spec.rb | 1 + .../merge_requests/update_service_spec.rb | 1 + .../last_used_service_spec.rb | 37 -------- 89 files changed, 639 insertions(+), 275 deletions(-) delete mode 100644 config/feature_flags/gitlab_com_derisk/ci_redis_enqueue_immediately.yml delete mode 100644 config/feature_flags/gitlab_com_derisk/pat_last_used_at_optimization.yml create mode 100644 db/migrate/20250617010101_add_namespace_id_to_duo_workflows_workflows.rb create mode 100644 db/migrate/20250617010102_add_namespace_id_to_duo_workflows_checkpoints.rb create mode 100644 db/migrate/20250617010103_add_namespace_id_to_duo_workflows_events.rb create mode 100644 db/migrate/20250617010104_add_namespace_id_to_duo_workflows_checkpoint_writes.rb create mode 100644 db/migrate/20250617010201_add_index_to_duo_workflows_workflows_on_namespace_id.rb create mode 100644 db/migrate/20250617010202_add_index_to_duo_workflows_checkpoints_on_namespace_id.rb create mode 100644 db/migrate/20250617010203_add_index_to_duo_workflows_events_on_namespace_id.rb create mode 100644 db/migrate/20250617010204_add_index_to_duo_workflows_checkpoint_writes_on_namespace_id.rb create mode 100644 db/migrate/20250617010301_add_namespace_id_fk_to_duo_workflows_workflows.rb create mode 100644 db/migrate/20250617010302_add_namespace_id_fk_to_duo_workflows_checkpoints.rb create mode 100644 db/migrate/20250617010303_add_namespace_id_fk_to_duo_workflows_events.rb create mode 100644 db/migrate/20250617010304_add_namespace_id_fk_to_duo_workflows_checkpoint_writes.rb create mode 100644 db/post_migrate/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2.rb create mode 100644 db/schema_migrations/20250617010101 create mode 100644 db/schema_migrations/20250617010102 create mode 100644 db/schema_migrations/20250617010103 create mode 100644 db/schema_migrations/20250617010104 create mode 100644 db/schema_migrations/20250617010201 create mode 100644 db/schema_migrations/20250617010202 create mode 100644 db/schema_migrations/20250617010203 create mode 100644 db/schema_migrations/20250617010204 create mode 100644 db/schema_migrations/20250617010301 create mode 100644 db/schema_migrations/20250617010302 create mode 100644 db/schema_migrations/20250617010303 create mode 100644 db/schema_migrations/20250617010304 create mode 100644 db/schema_migrations/20250630065826 create mode 100644 doc/api/compliance_policy_settings.md create mode 100644 lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver.rb create mode 100644 spec/lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver_spec.rb create mode 100644 spec/migrations/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2_spec.rb diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 1989266adac..bce7e1dd38f 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -2780,6 +2780,8 @@ .releases:rules:canonical-dot-com-security-gitlab-stable-branch-only: rules: + # Run release environment related jobs for initial RC tag pipelines - https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/21267 + - if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/security/gitlab" && $CI_COMMIT_REF_NAME =~ /^v?[\d.]+-rc42-ee$/' - if: '$CI_COMMIT_MESSAGE =~ /\[merge-train skip\]/' when: never - if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/security/gitlab" && $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable-ee$/' diff --git a/.rubocop_todo/internal_affairs/node_matcher_directive.yml b/.rubocop_todo/internal_affairs/node_matcher_directive.yml index 7aa41161fbe..12f1ee15f1d 100644 --- a/.rubocop_todo/internal_affairs/node_matcher_directive.yml +++ b/.rubocop_todo/internal_affairs/node_matcher_directive.yml @@ -3,26 +3,6 @@ InternalAffairs/NodeMatcherDirective: Details: grace period Exclude: - - 'rubocop/cop/gitlab/policy_rule_boolean.rb' - - 'rubocop/cop/gitlab/rails/safe_format.rb' - - 'rubocop/cop/gitlab/rails_logger.rb' - - 'rubocop/cop/gitlab/service_response.rb' - - 'rubocop/cop/gitlab/strong_memoize_attr.rb' - - 'rubocop/cop/gitlab/token_without_prefix.rb' - - 'rubocop/cop/gitlab/union.rb' - - 'rubocop/cop/graphql/authorize_types.rb' - - 'rubocop/cop/graphql/descriptions.rb' - - 'rubocop/cop/graphql/enum_names.rb' - - 'rubocop/cop/graphql/enum_values.rb' - - 'rubocop/cop/graphql/graphql_name_position.rb' - - 'rubocop/cop/graphql/id_type.rb' - - 'rubocop/cop/graphql/json_type.rb' - - 'rubocop/cop/graphql/old_types.rb' - - 'rubocop/cop/graphql/resolver_type.rb' - - 'rubocop/cop/graphql/resource_not_available_error.rb' - - 'rubocop/cop/group_public_or_visible_to_user.rb' - - 'rubocop/cop/ignored_columns.rb' - - 'rubocop/cop/include_sidekiq_worker.rb' - 'rubocop/cop/migration/add_concurrent_foreign_key.rb' - 'rubocop/cop/migration/add_limit_to_text_columns.rb' - 'rubocop/cop/migration/background_migration_missing_active_concern.rb' diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 285f2c79b5b..2186bc8e702 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -9a72666ea3a0a18d2f02d2821b880daee41d9767 +02eb9160dd6a4825e892b22eb5543c5c1da5cc65 diff --git a/GITLAB_KAS_VERSION b/GITLAB_KAS_VERSION index 7648b785c4b..0f2d03f58cd 100644 --- a/GITLAB_KAS_VERSION +++ b/GITLAB_KAS_VERSION @@ -1 +1 @@ -6c90dbb27ce3609304d71ffcd2b8113a08590f5c +70acd17ccd04ef784f793b1b00a84873e798b1dd diff --git a/app/models/ci/processable.rb b/app/models/ci/processable.rb index a5aa6c77e3d..8710faf6045 100644 --- a/app/models/ci/processable.rb +++ b/app/models/ci/processable.rb @@ -286,6 +286,14 @@ module Ci end end + def enqueue_immediately? + redis_state.enqueue_immediately? + end + + def set_enqueue_immediately! + redis_state.enqueue_immediately = true + end + private def dependencies diff --git a/app/models/concerns/ci/metadatable.rb b/app/models/concerns/ci/metadatable.rb index 1852718755f..1a1fe8ecf60 100644 --- a/app/models/concerns/ci/metadatable.rb +++ b/app/models/concerns/ci/metadatable.rb @@ -89,24 +89,6 @@ module Ci ensure_metadata.id_tokens = value end - def enqueue_immediately? - if Feature.enabled?(:ci_redis_enqueue_immediately, project) - redis_state.enqueue_immediately? - else - !!options[:enqueue_immediately] - end - end - - def set_enqueue_immediately! - if Feature.enabled?(:ci_redis_enqueue_immediately, project) - redis_state.enqueue_immediately = true - else - # ensures that even if `config_options: nil` in the database we set the - # new value correctly. - self.options = options.merge(enqueue_immediately: true) - end - end - # TODO: Update this logic when column `p_ci_builds.debug_trace_enabled` is added. # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194954#note_2574776849. def debug_trace_enabled? diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index a6c56e0ac4f..896630a54ce 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -289,7 +289,7 @@ module MergeRequests end def trigger_user_merge_request_updated(merge_request) - [merge_request.assignees, merge_request.reviewers].flatten.uniq.each do |user| + [merge_request.author, *merge_request.assignees, *merge_request.reviewers].uniq.each do |user| GraphqlTriggers.user_merge_request_updated(user, merge_request) end end diff --git a/app/services/merge_requests/post_merge_service.rb b/app/services/merge_requests/post_merge_service.rb index 24aecc07103..b1932e708b8 100644 --- a/app/services/merge_requests/post_merge_service.rb +++ b/app/services/merge_requests/post_merge_service.rb @@ -34,6 +34,7 @@ module MergeRequests cleanup_refs(merge_request) deactivate_pages_deployments(merge_request) cancel_auto_merges_targeting_source_branch(merge_request) + trigger_user_merge_request_updated(merge_request) execute_hooks(merge_request, 'merge') end diff --git a/app/services/personal_access_tokens/last_used_service.rb b/app/services/personal_access_tokens/last_used_service.rb index 646bd75877a..f2a0ebe4ce7 100644 --- a/app/services/personal_access_tokens/last_used_service.rb +++ b/app/services/personal_access_tokens/last_used_service.rb @@ -43,7 +43,6 @@ module PersonalAccessTokens def needs_update? return false if ::Gitlab::Database.read_only? - return true unless Feature.enabled?(:pat_last_used_at_optimization, :request) last_used_ip_needs_update? || last_used_at_needs_update? end diff --git a/app/workers/external_service_reactive_caching_worker.rb b/app/workers/external_service_reactive_caching_worker.rb index 3ad55701b4c..badd8945cf5 100644 --- a/app/workers/external_service_reactive_caching_worker.rb +++ b/app/workers/external_service_reactive_caching_worker.rb @@ -5,4 +5,5 @@ class ExternalServiceReactiveCachingWorker # rubocop:disable Scalability/Idempot worker_has_external_dependencies! worker_resource_boundary :cpu + data_consistency :sticky end diff --git a/config/feature_flags/gitlab_com_derisk/ci_redis_enqueue_immediately.yml b/config/feature_flags/gitlab_com_derisk/ci_redis_enqueue_immediately.yml deleted file mode 100644 index d1bb94e1078..00000000000 --- a/config/feature_flags/gitlab_com_derisk/ci_redis_enqueue_immediately.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: ci_redis_enqueue_immediately -description: -feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/work_items/549077 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194746 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/550225 -milestone: '18.2' -group: group::ci platform -type: gitlab_com_derisk -default_enabled: false diff --git a/config/feature_flags/gitlab_com_derisk/pat_last_used_at_optimization.yml b/config/feature_flags/gitlab_com_derisk/pat_last_used_at_optimization.yml deleted file mode 100644 index cdc0d06ca77..00000000000 --- a/config/feature_flags/gitlab_com_derisk/pat_last_used_at_optimization.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: pat_last_used_at_optimization -description: PersonalAccessTokens::LastUsedService#execute will return early to check if the PAT needs update before obtaining exclusive lease. This reduces Redis SharedState load (from exclusive lease) but will increase DB queries (to check if PAT needs update based on last used IP). -feature_issue_url: https://gitlab.com/gitlab-com/gl-infra/data-access/durability/team/-/issues/198 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/193010 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/547121 -milestone: '18.1' -group: group::authentication -type: gitlab_com_derisk -default_enabled: false diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 38a960ba5dd..1b2bcfbb92e 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -17,7 +17,11 @@ Doorkeeper.configure do else # Ensure user is redirected to redirect_uri after login session[:user_return_to] = request.fullpath - redirect_to(new_user_session_url) + + namespace_path = request.query_parameters['top_level_namespace_path'] + + resolver = Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver.new(namespace_path) + redirect_to(resolver.resolve_redirect_url) nil end end diff --git a/db/docs/batched_background_migrations/backfill_archived_and_traversal_ids_to_vulnerability_statistics.yml b/db/docs/batched_background_migrations/backfill_archived_and_traversal_ids_to_vulnerability_statistics.yml index 208f25f32bd..5016e91a93f 100644 --- a/db/docs/batched_background_migrations/backfill_archived_and_traversal_ids_to_vulnerability_statistics.yml +++ b/db/docs/batched_background_migrations/backfill_archived_and_traversal_ids_to_vulnerability_statistics.yml @@ -3,6 +3,6 @@ migration_job_name: BackfillArchivedAndTraversalIdsToVulnerabilityStatistics description: Backfill project.archived and project.namespace.traversal_ids values to the denormalized columns of the same name on vulnerability_statistics feature_category: vulnerability_management introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177993 -milestone: '17.11' -queued_migration_version: 20250404035239 +milestone: '18.2' +queued_migration_version: 20250630065826 finalized_by: 20250422130050 diff --git a/db/migrate/20250617010101_add_namespace_id_to_duo_workflows_workflows.rb b/db/migrate/20250617010101_add_namespace_id_to_duo_workflows_workflows.rb new file mode 100644 index 00000000000..a6076909f1c --- /dev/null +++ b/db/migrate/20250617010101_add_namespace_id_to_duo_workflows_workflows.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddNamespaceIdToDuoWorkflowsWorkflows < Gitlab::Database::Migration[2.3] + milestone '18.2' + + def change + add_column :duo_workflows_workflows, :namespace_id, :bigint + end +end diff --git a/db/migrate/20250617010102_add_namespace_id_to_duo_workflows_checkpoints.rb b/db/migrate/20250617010102_add_namespace_id_to_duo_workflows_checkpoints.rb new file mode 100644 index 00000000000..4f08de54e5f --- /dev/null +++ b/db/migrate/20250617010102_add_namespace_id_to_duo_workflows_checkpoints.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddNamespaceIdToDuoWorkflowsCheckpoints < Gitlab::Database::Migration[2.3] + milestone '18.2' + + def change + add_column :duo_workflows_checkpoints, :namespace_id, :bigint + end +end diff --git a/db/migrate/20250617010103_add_namespace_id_to_duo_workflows_events.rb b/db/migrate/20250617010103_add_namespace_id_to_duo_workflows_events.rb new file mode 100644 index 00000000000..eb999cf7105 --- /dev/null +++ b/db/migrate/20250617010103_add_namespace_id_to_duo_workflows_events.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddNamespaceIdToDuoWorkflowsEvents < Gitlab::Database::Migration[2.3] + milestone '18.2' + + def change + add_column :duo_workflows_events, :namespace_id, :bigint + end +end diff --git a/db/migrate/20250617010104_add_namespace_id_to_duo_workflows_checkpoint_writes.rb b/db/migrate/20250617010104_add_namespace_id_to_duo_workflows_checkpoint_writes.rb new file mode 100644 index 00000000000..b7e61733d7c --- /dev/null +++ b/db/migrate/20250617010104_add_namespace_id_to_duo_workflows_checkpoint_writes.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddNamespaceIdToDuoWorkflowsCheckpointWrites < Gitlab::Database::Migration[2.3] + milestone '18.2' + + def change + add_column :duo_workflows_checkpoint_writes, :namespace_id, :bigint + end +end diff --git a/db/migrate/20250617010201_add_index_to_duo_workflows_workflows_on_namespace_id.rb b/db/migrate/20250617010201_add_index_to_duo_workflows_workflows_on_namespace_id.rb new file mode 100644 index 00000000000..466f94735a1 --- /dev/null +++ b/db/migrate/20250617010201_add_index_to_duo_workflows_workflows_on_namespace_id.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class AddIndexToDuoWorkflowsWorkflowsOnNamespaceId < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + TABLE_NAME = :duo_workflows_workflows + INDEX_NAME = "index_duo_workflows_workflows_on_namespace_id" + + def up + add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME + end +end diff --git a/db/migrate/20250617010202_add_index_to_duo_workflows_checkpoints_on_namespace_id.rb b/db/migrate/20250617010202_add_index_to_duo_workflows_checkpoints_on_namespace_id.rb new file mode 100644 index 00000000000..d52bb3fa4bb --- /dev/null +++ b/db/migrate/20250617010202_add_index_to_duo_workflows_checkpoints_on_namespace_id.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class AddIndexToDuoWorkflowsCheckpointsOnNamespaceId < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + TABLE_NAME = :duo_workflows_checkpoints + INDEX_NAME = "index_duo_workflows_checkpoints_on_namespace_id" + + def up + add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME + end +end diff --git a/db/migrate/20250617010203_add_index_to_duo_workflows_events_on_namespace_id.rb b/db/migrate/20250617010203_add_index_to_duo_workflows_events_on_namespace_id.rb new file mode 100644 index 00000000000..559a54ee1ce --- /dev/null +++ b/db/migrate/20250617010203_add_index_to_duo_workflows_events_on_namespace_id.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class AddIndexToDuoWorkflowsEventsOnNamespaceId < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + TABLE_NAME = :duo_workflows_events + INDEX_NAME = "index_duo_workflows_events_on_namespace_id" + + def up + add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME + end +end diff --git a/db/migrate/20250617010204_add_index_to_duo_workflows_checkpoint_writes_on_namespace_id.rb b/db/migrate/20250617010204_add_index_to_duo_workflows_checkpoint_writes_on_namespace_id.rb new file mode 100644 index 00000000000..7a0f0189a63 --- /dev/null +++ b/db/migrate/20250617010204_add_index_to_duo_workflows_checkpoint_writes_on_namespace_id.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class AddIndexToDuoWorkflowsCheckpointWritesOnNamespaceId < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + TABLE_NAME = :duo_workflows_checkpoint_writes + INDEX_NAME = "index_duo_workflows_checkpoint_writes_on_namespace_id" + + def up + add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME + end +end diff --git a/db/migrate/20250617010301_add_namespace_id_fk_to_duo_workflows_workflows.rb b/db/migrate/20250617010301_add_namespace_id_fk_to_duo_workflows_workflows.rb new file mode 100644 index 00000000000..4e698e215d7 --- /dev/null +++ b/db/migrate/20250617010301_add_namespace_id_fk_to_duo_workflows_workflows.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddNamespaceIdFkToDuoWorkflowsWorkflows < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :duo_workflows_workflows, :namespaces, column: :namespace_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key_if_exists :duo_workflows_workflows, column: :namespace_id + end + end +end diff --git a/db/migrate/20250617010302_add_namespace_id_fk_to_duo_workflows_checkpoints.rb b/db/migrate/20250617010302_add_namespace_id_fk_to_duo_workflows_checkpoints.rb new file mode 100644 index 00000000000..e844b7b0406 --- /dev/null +++ b/db/migrate/20250617010302_add_namespace_id_fk_to_duo_workflows_checkpoints.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddNamespaceIdFkToDuoWorkflowsCheckpoints < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :duo_workflows_checkpoints, :namespaces, column: :namespace_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key_if_exists :duo_workflows_checkpoints, column: :namespace_id + end + end +end diff --git a/db/migrate/20250617010303_add_namespace_id_fk_to_duo_workflows_events.rb b/db/migrate/20250617010303_add_namespace_id_fk_to_duo_workflows_events.rb new file mode 100644 index 00000000000..436f8f8c381 --- /dev/null +++ b/db/migrate/20250617010303_add_namespace_id_fk_to_duo_workflows_events.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddNamespaceIdFkToDuoWorkflowsEvents < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :duo_workflows_events, :namespaces, column: :namespace_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key_if_exists :duo_workflows_events, column: :namespace_id + end + end +end diff --git a/db/migrate/20250617010304_add_namespace_id_fk_to_duo_workflows_checkpoint_writes.rb b/db/migrate/20250617010304_add_namespace_id_fk_to_duo_workflows_checkpoint_writes.rb new file mode 100644 index 00000000000..b46f458a96c --- /dev/null +++ b/db/migrate/20250617010304_add_namespace_id_fk_to_duo_workflows_checkpoint_writes.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddNamespaceIdFkToDuoWorkflowsCheckpointWrites < Gitlab::Database::Migration[2.3] + milestone '18.2' + + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :duo_workflows_checkpoint_writes, :namespaces, column: :namespace_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key_if_exists :duo_workflows_checkpoint_writes, column: :namespace_id + end + end +end diff --git a/db/post_migrate/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics.rb b/db/post_migrate/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics.rb index c5725dc59bb..5586ea7ba12 100644 --- a/db/post_migrate/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics.rb +++ b/db/post_migrate/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics.rb @@ -3,27 +3,15 @@ class RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatistics < Gitlab::Database::Migration[2.2] milestone '17.11' - restrict_gitlab_migration gitlab_schema: :gitlab_sec - MIGRATION = "BackfillArchivedAndTraversalIdsToVulnerabilityStatistics" - DELAY_INTERVAL = 2.minutes - BATCH_SIZE = 1000 - SUB_BATCH_SIZE = 100 def up - delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, []) - - queue_batched_background_migration( - MIGRATION, - :vulnerability_statistics, - :id, - job_interval: DELAY_INTERVAL, - batch_size: BATCH_SIZE, - sub_batch_size: SUB_BATCH_SIZE - ) + # no-op + # requeue'ing once more to ensure that all vulnerability_statistics records have + # their traversal_ids and archived columns correctly set. end def down - delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, []) + # no-op end end diff --git a/db/post_migrate/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2.rb b/db/post_migrate/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2.rb new file mode 100644 index 00000000000..aad9739cde0 --- /dev/null +++ b/db/post_migrate/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +class RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatisticsV2 < Gitlab::Database::Migration[2.3] + milestone '18.2' + restrict_gitlab_migration gitlab_schema: :gitlab_sec + + MIGRATION = "BackfillArchivedAndTraversalIdsToVulnerabilityStatistics" + DELAY_INTERVAL = 2.minutes + BATCH_SIZE = 1000 + SUB_BATCH_SIZE = 100 + + def up + delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, []) + + queue_batched_background_migration( + MIGRATION, + :vulnerability_statistics, + :id, + job_interval: DELAY_INTERVAL, + batch_size: BATCH_SIZE, + sub_batch_size: SUB_BATCH_SIZE + ) + end + + def down + delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, []) + end +end diff --git a/db/schema_migrations/20250617010101 b/db/schema_migrations/20250617010101 new file mode 100644 index 00000000000..121c9ee2dde --- /dev/null +++ b/db/schema_migrations/20250617010101 @@ -0,0 +1 @@ +f85570e808e43874f01f101f4bab6acb7421ccd305095a3ae4e94ce70af95ff7 \ No newline at end of file diff --git a/db/schema_migrations/20250617010102 b/db/schema_migrations/20250617010102 new file mode 100644 index 00000000000..5d171ca2002 --- /dev/null +++ b/db/schema_migrations/20250617010102 @@ -0,0 +1 @@ +bb69920904fcdd5be8150ef281be7fa5b1c67e58c76ac2b267fd22b7d48efbe9 \ No newline at end of file diff --git a/db/schema_migrations/20250617010103 b/db/schema_migrations/20250617010103 new file mode 100644 index 00000000000..dfd2e5c5f06 --- /dev/null +++ b/db/schema_migrations/20250617010103 @@ -0,0 +1 @@ +5b61ce406ec11414f67fe57b6443982cd657083e1b8631d136a522540d5a6e9e \ No newline at end of file diff --git a/db/schema_migrations/20250617010104 b/db/schema_migrations/20250617010104 new file mode 100644 index 00000000000..440747a0fe5 --- /dev/null +++ b/db/schema_migrations/20250617010104 @@ -0,0 +1 @@ +289091a8d62edd23897e606bb631a987371b72fb388d2b56ab8697ccec185b45 \ No newline at end of file diff --git a/db/schema_migrations/20250617010201 b/db/schema_migrations/20250617010201 new file mode 100644 index 00000000000..13d402a3c58 --- /dev/null +++ b/db/schema_migrations/20250617010201 @@ -0,0 +1 @@ +415310ea40da54cb06ed2896b7290b27460a4b71b1e3ae13c9ecbc979401bd2f \ No newline at end of file diff --git a/db/schema_migrations/20250617010202 b/db/schema_migrations/20250617010202 new file mode 100644 index 00000000000..d021873d56e --- /dev/null +++ b/db/schema_migrations/20250617010202 @@ -0,0 +1 @@ +4003d8a20a087f76e19a4738f6922378f4902082339b85a5816e04899a6c5504 \ No newline at end of file diff --git a/db/schema_migrations/20250617010203 b/db/schema_migrations/20250617010203 new file mode 100644 index 00000000000..138da86d5d5 --- /dev/null +++ b/db/schema_migrations/20250617010203 @@ -0,0 +1 @@ +9187c536cfc4c114bce915372ced7095a660d61e029d03b942f11ec9b02a0382 \ No newline at end of file diff --git a/db/schema_migrations/20250617010204 b/db/schema_migrations/20250617010204 new file mode 100644 index 00000000000..bbc7f54649e --- /dev/null +++ b/db/schema_migrations/20250617010204 @@ -0,0 +1 @@ +d1d552ae62ad5c130bc396006d46ae6fccb4bafbe4b432c88515e4acbdbfc40b \ No newline at end of file diff --git a/db/schema_migrations/20250617010301 b/db/schema_migrations/20250617010301 new file mode 100644 index 00000000000..7da0382a3f8 --- /dev/null +++ b/db/schema_migrations/20250617010301 @@ -0,0 +1 @@ +060b445192ea7b6d5aee6d3875544a1bac2507e1e614b2cb0380ed21705f8d43 \ No newline at end of file diff --git a/db/schema_migrations/20250617010302 b/db/schema_migrations/20250617010302 new file mode 100644 index 00000000000..ec055c2905c --- /dev/null +++ b/db/schema_migrations/20250617010302 @@ -0,0 +1 @@ +6b3e68b7fb486214c1fa4fcab587768d3a17eee61a486884a2e90eab18727f8e \ No newline at end of file diff --git a/db/schema_migrations/20250617010303 b/db/schema_migrations/20250617010303 new file mode 100644 index 00000000000..d80f9f577db --- /dev/null +++ b/db/schema_migrations/20250617010303 @@ -0,0 +1 @@ +289af09f92d109553e6da339bc0b267537304c30e58dcd05d3e0b0ea53273b35 \ No newline at end of file diff --git a/db/schema_migrations/20250617010304 b/db/schema_migrations/20250617010304 new file mode 100644 index 00000000000..37063608b6f --- /dev/null +++ b/db/schema_migrations/20250617010304 @@ -0,0 +1 @@ +d7b4e73b4c3948a1aa4b1b43bb8c1261e39d729fa1e130f652773eb0d2031cf3 \ No newline at end of file diff --git a/db/schema_migrations/20250630065826 b/db/schema_migrations/20250630065826 new file mode 100644 index 00000000000..56e8f194ba1 --- /dev/null +++ b/db/schema_migrations/20250630065826 @@ -0,0 +1 @@ +0ab861f394be58c6fd78c70ce08df162f2d3089808f7b1248a2198c97828b9ca \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 3b60afb76db..2ea22968e5d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -14245,6 +14245,7 @@ CREATE TABLE duo_workflows_checkpoint_writes ( channel text NOT NULL, write_type text NOT NULL, data text NOT NULL, + namespace_id bigint, CONSTRAINT check_38dc205bb2 CHECK ((char_length(data) <= 10000)), CONSTRAINT check_c64af76670 CHECK ((char_length(write_type) <= 255)), CONSTRAINT check_d66d09c813 CHECK ((char_length(task) <= 255)), @@ -14271,6 +14272,7 @@ CREATE TABLE duo_workflows_checkpoints ( parent_ts text, checkpoint jsonb NOT NULL, metadata jsonb NOT NULL, + namespace_id bigint, CONSTRAINT check_3dcc551d16 CHECK ((char_length(parent_ts) <= 255)), CONSTRAINT check_5d3139b983 CHECK ((char_length(thread_ts) <= 255)) ); @@ -14294,6 +14296,7 @@ CREATE TABLE duo_workflows_events ( event_status smallint NOT NULL, message text, correlation_id_value text, + namespace_id bigint, CONSTRAINT check_125840165c CHECK ((char_length(message) <= 16384)), CONSTRAINT check_5e35596b00 CHECK ((char_length(correlation_id_value) <= 128)) ); @@ -14321,6 +14324,7 @@ CREATE TABLE duo_workflows_workflows ( pre_approved_agent_privileges smallint[] DEFAULT '{1,2}'::smallint[] NOT NULL, image text, environment smallint, + namespace_id bigint, CONSTRAINT check_30ca07a4ef CHECK ((char_length(goal) <= 16384)), CONSTRAINT check_3a9162f1ae CHECK ((char_length(image) <= 2048)), CONSTRAINT check_ec723e2a1a CHECK ((char_length(workflow_definition) <= 255)) @@ -35411,18 +35415,26 @@ CREATE INDEX index_draft_notes_on_merge_request_id ON draft_notes USING btree (m CREATE INDEX index_draft_notes_on_project_id ON draft_notes USING btree (project_id); +CREATE INDEX index_duo_workflows_checkpoint_writes_on_namespace_id ON duo_workflows_checkpoint_writes USING btree (namespace_id); + CREATE INDEX index_duo_workflows_checkpoint_writes_on_project_id ON duo_workflows_checkpoint_writes USING btree (project_id); CREATE INDEX index_duo_workflows_checkpoint_writes_thread_ts ON duo_workflows_checkpoint_writes USING btree (workflow_id, thread_ts); +CREATE INDEX index_duo_workflows_checkpoints_on_namespace_id ON duo_workflows_checkpoints USING btree (namespace_id); + CREATE INDEX index_duo_workflows_checkpoints_on_project_id ON duo_workflows_checkpoints USING btree (project_id); +CREATE INDEX index_duo_workflows_events_on_namespace_id ON duo_workflows_events USING btree (namespace_id); + CREATE INDEX index_duo_workflows_events_on_project_id ON duo_workflows_events USING btree (project_id); CREATE INDEX index_duo_workflows_events_on_workflow_id ON duo_workflows_events USING btree (workflow_id); CREATE UNIQUE INDEX index_duo_workflows_workflow_checkpoints_unique_thread ON duo_workflows_checkpoints USING btree (workflow_id, thread_ts); +CREATE INDEX index_duo_workflows_workflows_on_namespace_id ON duo_workflows_workflows USING btree (namespace_id); + CREATE INDEX index_duo_workflows_workflows_on_project_id ON duo_workflows_workflows USING btree (project_id); CREATE INDEX index_duo_workflows_workflows_on_user_id ON duo_workflows_workflows USING btree (user_id); @@ -42879,6 +42891,9 @@ ALTER TABLE p_ci_builds ALTER TABLE ONLY draft_notes ADD CONSTRAINT fk_3ac2bcb746 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY duo_workflows_checkpoint_writes + ADD CONSTRAINT fk_3ad0964729 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY agent_activity_events ADD CONSTRAINT fk_3af186389b FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE SET NULL; @@ -43233,6 +43248,9 @@ ALTER TABLE ONLY import_placeholder_memberships ALTER TABLE p_ci_builds ADD CONSTRAINT fk_6661f4f0e8 FOREIGN KEY (resource_group_id) REFERENCES ci_resource_groups(id) ON DELETE SET NULL; +ALTER TABLE ONLY duo_workflows_events + ADD CONSTRAINT fk_674e493798 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY routes ADD CONSTRAINT fk_679ff8213d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE NOT VALID; @@ -43368,6 +43386,9 @@ ALTER TABLE ONLY scan_result_policy_violations ALTER TABLE ONLY approval_project_rules ADD CONSTRAINT fk_773289d10b FOREIGN KEY (approval_policy_rule_id) REFERENCES approval_policy_rules(id) ON DELETE CASCADE; +ALTER TABLE ONLY duo_workflows_checkpoints + ADD CONSTRAINT fk_779e1a4594 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY agent_user_access_project_authorizations ADD CONSTRAINT fk_78034b05d8 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; @@ -43446,6 +43467,9 @@ ALTER TABLE ONLY namespaces ALTER TABLE ONLY pages_domain_acme_orders ADD CONSTRAINT fk_7fa123c002 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; +ALTER TABLE ONLY duo_workflows_workflows + ADD CONSTRAINT fk_7fcf81369f FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY group_import_states ADD CONSTRAINT fk_8053b3ebd6 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md index 7f48af7c780..423c8eaddf5 100644 --- a/doc/administration/monitoring/performance/performance_bar.md +++ b/doc/administration/monitoring/performance/performance_bar.md @@ -1,6 +1,6 @@ --- -stage: Systems -group: Cloud Connector +stage: Developer Experience +group: Performance Enablement 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 gitlab_dedicated: yes title: Performance bar diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md index 66d24c32bda..627d4f9d601 100644 --- a/doc/api/api_resources.md +++ b/doc/api/api_resources.md @@ -199,7 +199,7 @@ The following API resources are available outside of project and group contexts | [Merge requests](merge_requests.md) | `/merge_requests` (also available for groups and projects) | | [Namespaces](namespaces.md) | `/namespaces` | | [Notification settings](notification_settings.md) | `/notification_settings` (also available for groups and projects) | -| [Policy settings](policy_settings.md) | `/admin/security/policy_settings` | +| [Compliance and Policy settings](compliance_policy_settings.md) | `/admin/security/compliance_policy_settings` | | [Pages domains](pages_domains.md) | `/pages/domains` (also available for projects) | | [Personal access tokens](personal_access_tokens.md) | `/personal_access_tokens` | | [Plan limits](plan_limits.md) | `/application/plan_limits` | diff --git a/doc/api/compliance_policy_settings.md b/doc/api/compliance_policy_settings.md new file mode 100644 index 00000000000..ac264981354 --- /dev/null +++ b/doc/api/compliance_policy_settings.md @@ -0,0 +1,90 @@ +--- +stage: Security Risk Management +group: Security Policies +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 and policy settings API +--- + +{{< details >}} + +- Tier: Ultimate +- Offering: GitLab Self-Managed + +{{< /details >}} + +{{< history >}} + +- [Introduced](https://issue-link) in GitLab 18.2 [with a flag](../administration/feature_flags/_index.md) named `security_policies_csp`. Disabled by default. + +{{< /history >}} + +{{< alert type="flag" >}} + +The availability of this feature is controlled by a feature flag. For more information, see the history. + +{{< /alert >}} + +Use this API to interact with the security policy settings for your GitLab instance. + +Prerequisites: + +- You must have administrator access to the instance. +- Your instance must have the Ultimate tier to use security policies. + +## Get security policy settings + +Gets the current security policy settings for this GitLab instance. + +```plaintext +GET /admin/security/compliance_policy_settings +``` + +```shell +curl --request GET \ + --header "PRIVATE-TOKEN: " \ + --url "https://gitlab.example.com/api/v4/admin/security/compliance_policy_settings" +``` + +Example response: + +```json +{ + "csp_namespace_id": 42 +} +``` + +When no CSP namespace is configured: + +```json +{ + "csp_namespace_id": null +} +``` + +## Update security policy settings + +Updates the security policy settings for this GitLab instance. + +```plaintext +PUT /admin/security/compliance_policy_settings +``` + +| Attribute | Type | Required | Description | +|:------------------|:--------|:---------|:------------| +| `csp_namespace_id` | integer | yes | ID of the group designated to centrally manage security policies. Must be a top-level group. Set to `null` to clear the setting. | + +```shell +curl --request PUT \ + --header "PRIVATE-TOKEN: " \ + --header "Content-Type: application/json" \ + --data '{"csp_namespace_id": 42}' \ + --url "https://gitlab.example.com/api/v4/admin/security/compliance_policy_settings" +``` + +Example response: + +```json +{ + "csp_namespace_id": 42 +} +``` diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 4d1ec211981..3630a3c0290 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -16023,6 +16023,17 @@ The edge type for [`Dependency`](#dependency). | `cursor` | [`String!`](#string) | A cursor for use in pagination. | | `node` | [`Dependency`](#dependency) | The item at the end of the edge. | +#### `DependencyPathEdge` + +The edge type for [`DependencyPath`](#dependencypath). + +##### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `cursor` | [`String!`](#string) | Cursor for use in pagination. | +| `node` | [`DependencyPath`](#dependencypath) | Dependency path node. | + #### `DependencyProxyBlobConnection` The connection type for [`DependencyProxyBlob`](#dependencyproxyblob). @@ -26303,9 +26314,31 @@ Ancestor path of a given dependency. | Name | Type | Description | | ---- | ---- | ----------- | | `isCyclic` | [`Boolean!`](#boolean) | Indicates if the path is cyclic. | -| `maxDepthReached` | [`Boolean!`](#boolean) | Indicates if the path reached the maximum depth (8). | | `path` | [`[DependencyPathPartial!]!`](#dependencypathpartial) | Name of the dependency. | +### `DependencyPathPage` + +Paginated dependency paths for SBOM occurrences. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `edges` | [`[DependencyPathEdge!]!`](#dependencypathedge) | List of dependency path edges. | +| `nodes` | [`[DependencyPath!]!`](#dependencypath) | List of dependency paths. | +| `pageInfo` | [`DependencyPathPageInfo!`](#dependencypathpageinfo) | Pagination information for dependency paths. | + +### `DependencyPathPageInfo` + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `endCursor` | [`String`](#string) | When paginating forwards, the cursor to continue. | +| `hasNextPage` | [`Boolean!`](#boolean) | When paginating forwards, are there more items?. | +| `hasPreviousPage` | [`Boolean!`](#boolean) | When paginating backwards, are there more items?. | +| `startCursor` | [`String`](#string) | When paginating backwards, the cursor to continue. | + ### `DependencyPathPartial` Ancestor path partial of a given dependency. @@ -37008,12 +37041,15 @@ Ancestor dependency paths for a dependency used by the project. \ **Status**: Experiment. {{< /details >}} -Returns [`[DependencyPath!]`](#dependencypath). +Returns [`DependencyPathPage`](#dependencypathpage). ###### Arguments | Name | Type | Description | | ---- | ---- | ----------- | +| `after` | [`String`](#string) | Fetch paths after the cursor. | +| `before` | [`String`](#string) | Fetch paths before the cursor. | +| `limit` | [`Int`](#int) | Number of paths to fetch. | | `occurrence` | [`SbomOccurrenceID!`](#sbomoccurrenceid) | Dependency path for occurrence. | ##### `Project.deployment` diff --git a/doc/api/metadata.md b/doc/api/metadata.md index 21005912b06..28b538eaba1 100644 --- a/doc/api/metadata.md +++ b/doc/api/metadata.md @@ -49,13 +49,13 @@ Example response: ```json { - "version": "15.2-pre", - "revision": "c401a659d0c", + "version": "18.1.1-ee", + "revision": "ceb07b24cb0", "kas": { "enabled": true, "externalUrl": "grpc://gitlab.example.com:8150", "externalK8sProxyUrl": "https://gitlab.example.com:8150/k8s-proxy", - "version": "15.0.0" + "version": "18.1.1" }, "enterprise": true } diff --git a/doc/api/policy_settings.md b/doc/api/policy_settings.md index 6efae4b8e16..ca5f50ca2e1 100644 --- a/doc/api/policy_settings.md +++ b/doc/api/policy_settings.md @@ -1,90 +1,13 @@ --- -stage: Security Risk Management -group: Security Policies -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: Policy settings API +redirect_to: 'compliance_policy_settings.md' +remove_date: '2025-10-01' --- -{{< details >}} + -- Tier: Ultimate -- Offering: GitLab Self-Managed +This document was moved to [another location](compliance_policy_settings.md). -{{< /details >}} - -{{< history >}} - -- [Introduced](https://issue-link) in GitLab 18.2 [with a flag](../administration/feature_flags/_index.md) named `security_policies_csp`. Disabled by default. - -{{< /history >}} - -{{< alert type="flag" >}} - -The availability of this feature is controlled by a feature flag. For more information, see the history. - -{{< /alert >}} - -Use this API to interact with the security policy settings for your GitLab instance. - -Prerequisites: - -- You must have administrator access to the instance. -- Your instance must have the Ultimate tier to use security policies. - -## Get security policy settings - -Gets the current security policy settings for this GitLab instance. - -```plaintext -GET /admin/security/policy_settings -``` - -```shell -curl --request GET \ - --header "PRIVATE-TOKEN: " \ - --url "https://gitlab.example.com/api/v4/admin/security/policy_settings" -``` - -Example response: - -```json -{ - "csp_namespace_id": 42 -} -``` - -When no CSP namespace is configured: - -```json -{ - "csp_namespace_id": null -} -``` - -## Update security policy settings - -Updates the security policy settings for this GitLab instance. - -```plaintext -PUT /admin/security/policy_settings -``` - -| Attribute | Type | Required | Description | -|:------------------|:--------|:---------|:------------| -| `csp_namespace_id` | integer | yes | ID of the group designated to centrally manage security policies. Must be a top-level group. Set to `null` to clear the setting. | - -```shell -curl --request PUT \ - --header "PRIVATE-TOKEN: " \ - --header "Content-Type: application/json" \ - --data '{"csp_namespace_id": 42}' \ - --url "https://gitlab.example.com/api/v4/admin/security/policy_settings" -``` - -Example response: - -```json -{ - "csp_namespace_id": 42 -} -``` + + + + diff --git a/doc/api/version.md b/doc/api/version.md index 59f507bf198..b2652d27c02 100644 --- a/doc/api/version.md +++ b/doc/api/version.md @@ -16,7 +16,7 @@ title: Version API We recommend you use the [Metadata API](metadata.md) instead of the Version API. It contains additional information and is aligned with the GraphQL metadata endpoint. -As of GitLab 15.5, the Version API is a mirror of the Metadata API. +The Version API is a mirror of the Metadata API. {{< /alert >}} @@ -34,15 +34,4 @@ curl --header "PRIVATE-TOKEN: " \ ## Example responses -### GitLab 15.5 and later - See [Metadata API](metadata.md) for the response. - -### GitLab 15.4 and earlier - -```json -{ - "version": "8.13.0-pre", - "revision": "4e963fe" -} -``` diff --git a/doc/development/sidekiq/worker_attributes.md b/doc/development/sidekiq/worker_attributes.md index 1ae5a928fc6..bd96993f82b 100644 --- a/doc/development/sidekiq/worker_attributes.md +++ b/doc/development/sidekiq/worker_attributes.md @@ -258,7 +258,7 @@ they prefer read replicas and wait for replicas to catch up: | **Data consistency** | **Description** | **Guideline** | |--------------|-----------------------------|----------| | `:always` | The job is required to use the primary database for all queries. (Deprecated) | **Deprecated** Only needed for jobs that encounter edge cases around primary stickiness. | -| `:sticky` | The job prefers replicas, but switches to the primary for writes or when encountering replication lag. (Default) | This is the default option. It should be used for jobs that require to be executed as fast as possible. Replicas are guaranteed to be caught up to the point at which the job was enqueued in Sidekiq. | +| `:sticky` | The job prefers replicas, but switches to the primary for writes or when encountering replication lag. | This is the preferred option. It should be used for jobs that require to be executed as fast as possible. Replicas are guaranteed to be caught up to the point at which the job was enqueued in Sidekiq. | | `:delayed` | The job prefers replicas, but switches to the primary for writes. When encountering replication lag before the job starts, the job is retried once. If the replica is still not up to date on the next retry, it switches to the primary. | It should be used for jobs where delaying execution further typically does not matter, such as cache expiration or web hooks execution. It should not be used for jobs where retry is disabled, such as cron jobs. | In all cases workers read either from a replica that is fully caught up, diff --git a/doc/user/search/exact_code_search.md b/doc/user/search/exact_code_search.md index 41a0d87ae22..c13b6eeb992 100644 --- a/doc/user/search/exact_code_search.md +++ b/doc/user/search/exact_code_search.md @@ -62,6 +62,16 @@ The following scopes are available for exact code search: On GitLab Self-Managed, an administrator can enable global search with the [`zoekt_cross_namespace_search`](exact_code_search.md#global-code-search) feature flag. +## Use exact code search + +To use exact code search: + +1. On the left sidebar, select **Search or go to**. +1. In the search box, enter your search term. +1. On the left sidebar, select **Code**. + +You can also use exact code search in a project or group. + ## Zoekt search API {{< history >}} diff --git a/lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver.rb b/lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver.rb new file mode 100644 index 00000000000..49a81278fac --- /dev/null +++ b/lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Gitlab + module Auth + module OAuth + class OauthResourceOwnerRedirectResolver + include ::Gitlab::Routing + + attr_reader :top_level_namespace_path + + def initialize(top_level_namespace_path) + @top_level_namespace_path = top_level_namespace_path + end + + def resolve_redirect_url + new_user_session_url + end + end + end + end +end + +Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver.prepend_mod diff --git a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml index a24862d7fae..5e61542fce2 100644 --- a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.latest.gitlab-ci.yml @@ -267,7 +267,7 @@ gemnasium-python-dependency_scanning: dependency-scanning: variables: ANALYZER_SUPPORTED_FILES: "packages.lock.json,conan.lock,conda-lock.yml,pubspec.lock,go.mod,go.graph,ivy-report.xml,maven.graph.json,dependencies.lock,package-lock.json,npm-shrinkwrap.json,pnpm-lock.yaml,yarn.lock,Podfile.lock,composer.lock,pipdeptree.json,requirements.txt,Pipfile.lock,pipenv.graph.json,poetry.lock,uv.lock,Gemfile.lock,gems.locked,Cargo.lock,dependencies-compile.dot,Package.resolved" - ADDITIONAL_SUPPORTED_FILES: "pom.xml,build.gradle,build.gradle.kts,build.sbt,requirements.pip,Pipfile,requires.txt,setup.py" + ADDITIONAL_SUPPORTED_FILES: "pom.xml,build.gradle,build.gradle.kts,build.sbt,requirements.pip,Pipfile,requires.txt,setup.py,*.csproj,*.vbproj" SCA_TO_SARIF_MATCHER_VERSION: "v2.0.2" stage: !reference [.ds-analyzer, stage] image: diff --git a/lib/mattermost/session.rb b/lib/mattermost/session.rb index fa327de3f37..368bd2b2a34 100644 --- a/lib/mattermost/session.rb +++ b/lib/mattermost/session.rb @@ -72,7 +72,7 @@ module Mattermost end def params - { organization_id: Organizations::Organization::DEFAULT_ORGANIZATION_ID } + { organization_id: @current_resource_owner.organizations.first.id } .merge(Rack::Utils.parse_query(oauth_uri.query).symbolize_keys) end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 02aa4f37957..d241df7f222 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2394,10 +2394,19 @@ msgstr "" msgid "AICatalog|Agents" msgstr "" +msgid "AICatalog|Briefly describe what this agent is designed to do and its key capabilities." +msgstr "" + +msgid "AICatalog|Choose a memorable name for your AI agent." +msgstr "" + msgid "AICatalog|Create agent" msgstr "" -msgid "AICatalog|Description can't be blank." +msgid "AICatalog|Define the agent's personality, expertise, and behavioral guidelines. This shapes how the agent responds and approaches tasks." +msgstr "" + +msgid "AICatalog|Description is required." msgstr "" msgid "AICatalog|Edit agent" @@ -2412,9 +2421,18 @@ msgstr "" msgid "AICatalog|Modify the agent settings and configuration." msgstr "" +msgid "AICatalog|Name is required." +msgstr "" + +msgid "AICatalog|Please consider my background in... When explaining concepts, use... My preferred format for responses is... Always include..." +msgstr "" + msgid "AICatalog|Prompt" msgstr "" +msgid "AICatalog|Provide default instructions or context that will be included with every user interaction." +msgstr "" + msgid "AICatalog|Released %{fullDate}" msgstr "" @@ -2427,10 +2445,19 @@ msgstr "" msgid "AICatalog|Save changes" msgstr "" -msgid "AICatalog|System Prompt" +msgid "AICatalog|System Prompt (optional)" msgstr "" -msgid "AICatalog|User Prompt" +msgid "AICatalog|This agent specializes in... It can help you with... Best suited for..." +msgstr "" + +msgid "AICatalog|User Prompt (optional)" +msgstr "" + +msgid "AICatalog|You are an expert in [domain]. Your communication style is [style]. When helping users, you should always... Your key strengths include... You approach problems by..." +msgstr "" + +msgid "AICatalog|e.g., Research Assistant, Creative Writer, Code Helper" msgstr "" msgid "AISummary|Generates a summary of this issue" diff --git a/rubocop/cop/gitlab/policy_rule_boolean.rb b/rubocop/cop/gitlab/policy_rule_boolean.rb index 1c655237945..94f3490233e 100644 --- a/rubocop/cop/gitlab/policy_rule_boolean.rb +++ b/rubocop/cop/gitlab/policy_rule_boolean.rb @@ -23,14 +23,17 @@ module RuboCop # rule { conducts_electricity & can?(:magnetize) }.enable :motor # rule { ~conducts_electricity & batteries }.enable :motor class PolicyRuleBoolean < RuboCop::Cop::Base + # @!method has_and_operator?(node) def_node_search :has_and_operator?, <<~PATTERN (and ...) PATTERN + # @!method has_or_operator?(node) def_node_search :has_or_operator?, <<~PATTERN (or ...) PATTERN + # @!method has_if?(node) def_node_search :has_if?, <<~PATTERN (if ...) PATTERN diff --git a/rubocop/cop/gitlab/rails/safe_format.rb b/rubocop/cop/gitlab/rails/safe_format.rb index 7d3e01cdce9..ceb59fcebb1 100644 --- a/rubocop/cop/gitlab/rails/safe_format.rb +++ b/rubocop/cop/gitlab/rails/safe_format.rb @@ -27,6 +27,7 @@ module RuboCop RESTRICT_ON_SEND = %i[_ s_ N_ n_].freeze + # @!method wrapped_by?(node) def_node_matcher :wrapped_by?, <<~PATTERN ^(send _ %method ...) PATTERN diff --git a/rubocop/cop/gitlab/rails_logger.rb b/rubocop/cop/gitlab/rails_logger.rb index 4eaaa693e59..e8acda3afa8 100644 --- a/rubocop/cop/gitlab/rails_logger.rb +++ b/rubocop/cop/gitlab/rails_logger.rb @@ -28,6 +28,7 @@ module RuboCop LOG_METHODS = %i[debug error fatal info warn].freeze LOG_METHODS_PATTERN = LOG_METHODS.map(&:inspect).join(' ').freeze + # @!method rails_logger_log?(node) def_node_matcher :rails_logger_log?, <<~PATTERN (send (send (const nil? :Rails) :logger) diff --git a/rubocop/cop/gitlab/service_response.rb b/rubocop/cop/gitlab/service_response.rb index edde662a038..245eb31f41f 100644 --- a/rubocop/cop/gitlab/service_response.rb +++ b/rubocop/cop/gitlab/service_response.rb @@ -23,6 +23,7 @@ module RuboCop RESTRICT_ON_SEND = %i[error success new].freeze METHOD_NAMES = RESTRICT_ON_SEND.map(&:inspect).join(' ').freeze + # @!method service_response_with_http_status(node) def_node_matcher :service_response_with_http_status, <<~PATTERN (send (const {nil? cbase} :ServiceResponse) diff --git a/rubocop/cop/gitlab/strong_memoize_attr.rb b/rubocop/cop/gitlab/strong_memoize_attr.rb index 0de581f8ccd..26f19af564b 100644 --- a/rubocop/cop/gitlab/strong_memoize_attr.rb +++ b/rubocop/cop/gitlab/strong_memoize_attr.rb @@ -38,6 +38,7 @@ module RuboCop STRONG_MEMOIZE_WITH_MSG = 'Use `strong_memoize_attr`, instead of using `strong_memoize_with` without parameters.' + # @!method strong_memoize?(node) def_node_matcher :strong_memoize?, <<~PATTERN (block $(send nil? {:strong_memoize | :strong_memoize_with} diff --git a/rubocop/cop/gitlab/token_without_prefix.rb b/rubocop/cop/gitlab/token_without_prefix.rb index 3d763602629..511ce113a57 100644 --- a/rubocop/cop/gitlab/token_without_prefix.rb +++ b/rubocop/cop/gitlab/token_without_prefix.rb @@ -18,9 +18,12 @@ module RuboCop MSG = 'Tokens should be prefixed. ' \ 'See doc/development/secure_coding_guidelines.md#token-prefixes for more information.' + # @!method add_authentication_token_field?(node) def_node_matcher :add_authentication_token_field?, <<~PATTERN (send nil? :add_authentication_token_field ...) PATTERN + + # @!method format_with_prefix?(node) def_node_matcher :format_with_prefix?, <<~PATTERN (send nil? :add_authentication_token_field (sym $_)* (hash <$(pair (sym :format_with_prefix) _) ...>)) PATTERN diff --git a/rubocop/cop/gitlab/union.rb b/rubocop/cop/gitlab/union.rb index 36ec6bb9b7f..e6afc40261d 100644 --- a/rubocop/cop/gitlab/union.rb +++ b/rubocop/cop/gitlab/union.rb @@ -8,6 +8,7 @@ module RuboCop class Union < RuboCop::Cop::Base MSG = 'Use the `FromUnion` concern, instead of using `Gitlab::SQL::Union` directly' + # @!method raw_union?(node) def_node_matcher :raw_union?, <<~PATTERN (send (const (const (const nil? :Gitlab) :SQL) :Union) :new ...) PATTERN diff --git a/rubocop/cop/graphql/authorize_types.rb b/rubocop/cop/graphql/authorize_types.rb index db79a4732d9..b0b8e0ec4a5 100644 --- a/rubocop/cop/graphql/authorize_types.rb +++ b/rubocop/cop/graphql/authorize_types.rb @@ -11,6 +11,7 @@ module RuboCop ALLOWED_TYPES = %w[BaseEnum BaseEdge BaseScalar BasePermissionType MutationType SubscriptionType QueryType GraphQL::Schema BaseUnion BaseInputObject].freeze + # @!method authorize?(node) def_node_search :authorize?, <<~PATTERN (send nil? :authorize sym+) PATTERN diff --git a/rubocop/cop/graphql/descriptions.rb b/rubocop/cop/graphql/descriptions.rb index f90262ed1ba..07987ae9a6a 100644 --- a/rubocop/cop/graphql/descriptions.rb +++ b/rubocop/cop/graphql/descriptions.rb @@ -57,22 +57,27 @@ module RuboCop MSG_CONTAINS_THIS = "`description` strings should not contain the demonstrative \"this\". "\ "#{MSG_STYLE_GUIDE_LINK}".freeze + # @!method graphql_describable?(node) def_node_matcher :graphql_describable?, <<~PATTERN (send nil? {:field :argument :value} ...) PATTERN + # @!method enum?(node) def_node_matcher :enum?, <<~PATTERN (send nil? :value ...) PATTERN + # @!method resolver_kwarg(node) def_node_matcher :resolver_kwarg, <<~PATTERN (... (hash <(pair (sym :resolver) $_) ...>)) PATTERN + # @!method description_kwarg(node) def_node_matcher :description_kwarg, <<~PATTERN (... (hash <(pair (sym :description) $_) ...>)) PATTERN + # @!method enum_style_description(node) def_node_matcher :enum_style_description, <<~PATTERN (send nil? :value _ $str ...) PATTERN diff --git a/rubocop/cop/graphql/enum_names.rb b/rubocop/cop/graphql/enum_names.rb index 95df05301d4..94b32a21459 100644 --- a/rubocop/cop/graphql/enum_names.rb +++ b/rubocop/cop/graphql/enum_names.rb @@ -37,14 +37,17 @@ module RuboCop GRAPHQL_NAME_MISSING_MSG = "A `graphql_name` must be defined for a GraphQL enum. #{SEE_SG_MSG}".freeze GRAPHQL_NAME_WITH_ENUM_MSG = "The `graphql_name` must not contain the string \"Enum\". #{SEE_SG_MSG}".freeze + # @!method enum_subclass(node) def_node_matcher :enum_subclass, <<~PATTERN (class $(const nil? _) (const {nil? cbase} /.*Enum$/) ...) PATTERN + # @!method find_graphql_name(node) def_node_search :find_graphql_name, <<~PATTERN (... `(send nil? :graphql_name $(...)) ...) PATTERN + # @!method declarative_enum?(node) def_node_search :declarative_enum?, <<~PATTERN (... (send nil? :declarative_enum ...) ...) PATTERN diff --git a/rubocop/cop/graphql/enum_values.rb b/rubocop/cop/graphql/enum_values.rb index 46d6818f321..43edf6b9268 100644 --- a/rubocop/cop/graphql/enum_values.rb +++ b/rubocop/cop/graphql/enum_values.rb @@ -41,18 +41,22 @@ module RuboCop MSG = "Enum values must either be an uppercase string literal or uppercased with the `upcase` method. " \ "See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#enums" + # @!method enum_value(node) def_node_matcher :enum_value, <<~PATTERN (send nil? :value $_ $...) PATTERN + # @!method deprecated?(node) def_node_search :deprecated?, <<~PATTERN (hash <(pair (sym :deprecated) _) ...>) PATTERN + # @!method upcase_literal?(node) def_node_matcher :upcase_literal?, <<~PATTERN (str #upcase?) PATTERN + # @!method upcase_method?(node) def_node_matcher :upcase_method?, <<~PATTERN `(send _ :upcase) PATTERN diff --git a/rubocop/cop/graphql/graphql_name_position.rb b/rubocop/cop/graphql/graphql_name_position.rb index dd21ab0735c..5c7d5dbe1d2 100644 --- a/rubocop/cop/graphql/graphql_name_position.rb +++ b/rubocop/cop/graphql/graphql_name_position.rb @@ -23,6 +23,7 @@ module RuboCop MSG = '`graphql_name` should be the first line of the class: '\ 'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#naming-conventions' + # @!method graphql_name?(node) def_node_search :graphql_name?, <<~PATTERN (send nil? :graphql_name ...) PATTERN diff --git a/rubocop/cop/graphql/id_type.rb b/rubocop/cop/graphql/id_type.rb index 1fd0952de9f..2a216678f0f 100644 --- a/rubocop/cop/graphql/id_type.rb +++ b/rubocop/cop/graphql/id_type.rb @@ -12,6 +12,7 @@ module RuboCop context_namespace_path parent_path ].freeze + # @!method iid_with_id?(node) def_node_matcher :iid_with_id?, <<~PATTERN (send nil? {:field :argument} (sym #iid?) @@ -19,6 +20,7 @@ module RuboCop (...)?) PATTERN + # @!method graphql_id_allowed?(node) def_node_search :graphql_id_allowed?, <<~PATTERN (send nil? :argument (_ #does_not_match?) (const (const (const nil? :GraphQL) :Types) :ID) ...) PATTERN diff --git a/rubocop/cop/graphql/json_type.rb b/rubocop/cop/graphql/json_type.rb index 3448ff2ff7d..8727b73e0a0 100644 --- a/rubocop/cop/graphql/json_type.rb +++ b/rubocop/cop/graphql/json_type.rb @@ -21,6 +21,7 @@ module RuboCop MSG = 'Avoid using GraphQL::Types::JSON. See: ' \ 'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#json' + # @!method has_json_type?(node) def_node_matcher :has_json_type?, <<~PATTERN (send nil? {:field :argument} (sym _) diff --git a/rubocop/cop/graphql/old_types.rb b/rubocop/cop/graphql/old_types.rb index a8d59625aff..dc06640f30f 100644 --- a/rubocop/cop/graphql/old_types.rb +++ b/rubocop/cop/graphql/old_types.rb @@ -25,6 +25,7 @@ module RuboCop MSG_BOOLEAN = 'Avoid using GraphQL::BOOLEAN_TYPE. Use GraphQL::Types::Boolean instead' MSG_FLOAT = 'Avoid using GraphQL::FLOAT_TYPE. Use GraphQL::Types::Float instead' + # @!method has_old_type?(node) def_node_matcher :has_old_type?, <<~PATTERN (send nil? {:field :argument} (sym _) diff --git a/rubocop/cop/graphql/resolver_type.rb b/rubocop/cop/graphql/resolver_type.rb index 87047c2b52a..2fa0afa2425 100644 --- a/rubocop/cop/graphql/resolver_type.rb +++ b/rubocop/cop/graphql/resolver_type.rb @@ -26,6 +26,7 @@ module RuboCop MSG = 'Missing type annotation: Please add `type` DSL method call. ' \ 'e.g: type UserType.connection_type, null: true' + # @!method typed?(node) def_node_matcher :typed?, <<~PATTERN (... (begin <(send nil? :type ...) ...>)) PATTERN diff --git a/rubocop/cop/graphql/resource_not_available_error.rb b/rubocop/cop/graphql/resource_not_available_error.rb index d759e145008..30497e5fb3c 100644 --- a/rubocop/cop/graphql/resource_not_available_error.rb +++ b/rubocop/cop/graphql/resource_not_available_error.rb @@ -25,8 +25,10 @@ module RuboCop RESTRICT_ON_SEND = %i[raise].freeze + # @!method error(node) def_node_matcher :error, const_pattern(EXCEPTION) + # @!method raise_error(node) def_node_matcher :raise_error, <<~PATTERN (send nil? :raise #error $...) PATTERN diff --git a/rubocop/cop/group_public_or_visible_to_user.rb b/rubocop/cop/group_public_or_visible_to_user.rb index 2038bd6f4f6..5f691adb31f 100644 --- a/rubocop/cop/group_public_or_visible_to_user.rb +++ b/rubocop/cop/group_public_or_visible_to_user.rb @@ -8,6 +8,7 @@ module RuboCop 'Please ensure that you are not using it on its own and that the amount ' \ 'of rows being filtered is reasonable.' + # @!method public_or_visible_to_user?(node) def_node_matcher :public_or_visible_to_user?, <<~PATTERN (send (const nil? :Group) :public_or_visible_to_user ...) PATTERN diff --git a/rubocop/cop/ignored_columns.rb b/rubocop/cop/ignored_columns.rb index 44c8dfe19cc..7011e9b30bd 100644 --- a/rubocop/cop/ignored_columns.rb +++ b/rubocop/cop/ignored_columns.rb @@ -26,14 +26,17 @@ module RuboCop RESTRICT_ON_SEND = %i[ignored_columns ignored_columns= ignore_column ignore_columns].freeze + # @!method ignored_columns_add?(node) def_node_matcher :ignored_columns_add?, <<~PATTERN (send (self) :ignored_columns) PATTERN + # @!method ignored_columns_set?(node) def_node_matcher :ignored_columns_set?, <<~PATTERN (send (self) :ignored_columns= ...) PATTERN + # @!method using_ignore_columns?(node) def_node_matcher :using_ignore_columns?, <<~PATTERN (send nil? {:ignore_columns :ignore_column}...) PATTERN diff --git a/rubocop/cop/include_sidekiq_worker.rb b/rubocop/cop/include_sidekiq_worker.rb index 67acf8cf96b..813f5766125 100644 --- a/rubocop/cop/include_sidekiq_worker.rb +++ b/rubocop/cop/include_sidekiq_worker.rb @@ -8,6 +8,7 @@ module RuboCop MSG = 'Include `ApplicationWorker`, not `Sidekiq::Worker`.' + # @!method includes_sidekiq_worker?(node) def_node_matcher :includes_sidekiq_worker?, <<~PATTERN (send nil? :include (const (const nil? :Sidekiq) :Worker)) PATTERN diff --git a/spec/initializers/doorkeeper_spec.rb b/spec/initializers/doorkeeper_spec.rb index 56e0a22d59f..0665e2d0ab8 100644 --- a/spec/initializers/doorkeeper_spec.rb +++ b/spec/initializers/doorkeeper_spec.rb @@ -20,13 +20,29 @@ RSpec.describe Doorkeeper.configuration do subject { controller.instance_exec(&Doorkeeper.configuration.authenticate_resource_owner) } let(:controller) { double } + let(:base_request_params) { {} } + let(:mock_request) do + instance_double(ActionDispatch::Request, + 'request', + fullpath: '/return-path', + query_parameters: base_request_params + ) + end + + let(:resolver) { instance_double(Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver) } before do - allow(controller).to receive(:current_user).and_return(current_user) - allow(controller).to receive(:session).and_return({}) - allow(controller).to receive(:request).and_return(double('request', fullpath: '/return-path')) + allow(controller).to receive_messages( + current_user: current_user, + session: {}, + request: mock_request + ) allow(controller).to receive(:redirect_to) - allow(controller).to receive(:new_user_session_url).and_return('/login') + allow(::Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver) + .to receive(:new) + .with(nil) + .and_return(resolver) + allow(resolver).to receive(:resolve_redirect_url).and_return('/login') end context 'with a user present' do diff --git a/spec/lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver_spec.rb b/spec/lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver_spec.rb new file mode 100644 index 00000000000..b0318868232 --- /dev/null +++ b/spec/lib/gitlab/auth/o_auth/oauth_resource_owner_redirect_resolver_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver, feature_category: :system_access do + let(:resolver) { described_class.new(namespace_path) } + let(:namespace_path) { nil } + let(:group) { create(:group) } + + describe '#resolve_redirect_url' do + subject(:resolve_redirect_url) { resolver.resolve_redirect_url } + + before do + allow(resolver).to receive(:new_user_session_url).and_return('/login') + end + + context 'with any namespace path' do + let(:namespace_path) { group.full_path } + + it 'returns new_user_session_url' do + expect(resolver).to receive(:new_user_session_url) + expect(resolve_redirect_url).to eq('/login') + end + end + + context 'with nil namespace path' do + let(:namespace_path) { nil } + + it 'returns new_user_session_url' do + expect(resolve_redirect_url).to eq('/login') + end + end + end +end diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb index 1582efe17a6..4b2ccb48f13 100644 --- a/spec/lib/mattermost/session_spec.rb +++ b/spec/lib/mattermost/session_spec.rb @@ -6,7 +6,8 @@ RSpec.describe Mattermost::Session, type: :request do include ExclusiveLeaseHelpers include StubRequests - let(:user) { create(:user) } + let_it_be(:organization) { create(:organization) } + let(:user) { create(:user, organizations: [organization]) } let(:gitlab_url) { "http://gitlab.com" } let(:mattermost_url) { "http://mattermost.com" } @@ -24,8 +25,6 @@ RSpec.describe Mattermost::Session, type: :request do it { is_expected.to respond_to(:strategy) } describe '#with session' do - let_it_be(:organization) { create(:organization, :default) } - let(:location) { 'http://location.tld' } let(:cookie_header) { 'MMOAUTH=taskik8az7rq8k6rkpuas7htia; Path=/;' } let!(:stub) do @@ -110,6 +109,13 @@ RSpec.describe Mattermost::Session, type: :request do expect(result).to eq("value") end + + it 'creates token in the same organization as the user' do + expect { subject.with_session {} } + .to change { OauthAccessToken.find_by(resource_owner: user)&.organization_id } + .from(nil) + .to(user.organizations.first.id) + end end end diff --git a/spec/migrations/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb b/spec/migrations/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb index 88c5d541f1d..a40e2b3de4e 100644 --- a/spec/migrations/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb +++ b/spec/migrations/20250404035239_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb @@ -13,14 +13,7 @@ RSpec.describe RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatistics, } migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - gitlab_schema: :gitlab_sec, - table_name: :vulnerability_statistics, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - batch_size: described_class::BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) + expect(batched_migration).not_to have_scheduled_batched_migration } end end diff --git a/spec/migrations/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2_spec.rb b/spec/migrations/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2_spec.rb new file mode 100644 index 00000000000..d5728a2ad23 --- /dev/null +++ b/spec/migrations/20250630065826_requeue_backfill_archived_and_traversal_ids_to_vulnerability_statistics_v2_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatisticsV2, migration: :gitlab_sec, feature_category: :vulnerability_management do + let!(:batched_migration) { described_class::MIGRATION } + + it 'schedules a new batched migration' do + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).to have_scheduled_batched_migration( + gitlab_schema: :gitlab_sec, + table_name: :vulnerability_statistics, + column_name: :id, + interval: described_class::DELAY_INTERVAL, + batch_size: described_class::BATCH_SIZE, + sub_batch_size: described_class::SUB_BATCH_SIZE + ) + } + end + end +end diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb index 9872bb5b813..45bc2945213 100644 --- a/spec/models/ci/processable_spec.rb +++ b/spec/models/ci/processable_spec.rb @@ -736,4 +736,27 @@ RSpec.describe Ci::Processable, feature_category: :continuous_integration do expect(processable.strong_memoized?(:redis_state)).to be(true) end end + + describe '#enqueue_immediately?', :clean_gitlab_redis_shared_state do + let(:processable) { build_stubbed(:ci_processable, pipeline: pipeline) } + + [true, false].each do |value| + context "when enqueue_immediately is set to #{value}" do + before do + processable.redis_state.enqueue_immediately = value + end + + it { expect(processable.enqueue_immediately?).to be(value) } + end + end + end + + describe '#set_enqueue_immediately!', :clean_gitlab_redis_shared_state do + let(:processable) { build_stubbed(:ci_processable, pipeline: pipeline) } + + it 'changes enqueue_immediately to true' do + expect { processable.set_enqueue_immediately! } + .to change { processable.enqueue_immediately? }.to(true) + end + end end diff --git a/spec/services/ci/retry_job_service_spec.rb b/spec/services/ci/retry_job_service_spec.rb index 7373882a6de..864341b3fd1 100644 --- a/spec/services/ci/retry_job_service_spec.rb +++ b/spec/services/ci/retry_job_service_spec.rb @@ -553,37 +553,6 @@ RSpec.describe Ci::RetryJobService, :clean_gitlab_redis_shared_state, feature_ca it_behaves_like 'checks enqueue_immediately?' end - - context 'with ci_redis_enqueue_immediately disabled' do - before do - stub_feature_flags(ci_redis_enqueue_immediately: false) - end - - let!(:job) do - create(:ci_build, *[trait].compact, :failed, pipeline: pipeline, ci_stage: stage) - end - - where(:trait, :enqueue_immediately) do - nil | false - :manual | true - :expired_scheduled | true - end - - with_them do - it 'retries the given job but not the other manual/scheduled jobs' do - expect { subject } - .to change { Ci::Build.count }.by(1) - .and not_change { test_manual_build.reload.status } - .and not_change { subsequent_manual_build.reload.status } - .and not_change { test_scheduled_build.reload.status } - .and not_change { subsequent_scheduled_build.reload.status } - - expect(new_job).to be_pending - end - - it_behaves_like 'checks enqueue_immediately?' - end - end end end end diff --git a/spec/services/merge_requests/approval_service_spec.rb b/spec/services/merge_requests/approval_service_spec.rb index 5e390277a6c..531d6e9315d 100644 --- a/spec/services/merge_requests/approval_service_spec.rb +++ b/spec/services/merge_requests/approval_service_spec.rb @@ -133,6 +133,7 @@ RSpec.describe MergeRequests::ApprovalService, feature_category: :code_review_wo it 'triggers GraphQL subscription userMergeRequestUpdated' do expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user, merge_request) + expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request) service.execute(merge_request) end diff --git a/spec/services/merge_requests/handle_assignees_change_service_spec.rb b/spec/services/merge_requests/handle_assignees_change_service_spec.rb index a11ced51766..c82e3dab150 100644 --- a/spec/services/merge_requests/handle_assignees_change_service_spec.rb +++ b/spec/services/merge_requests/handle_assignees_change_service_spec.rb @@ -121,6 +121,7 @@ RSpec.describe MergeRequests::HandleAssigneesChangeService, feature_category: :c it 'triggers GraphQL subscription userMergeRequestUpdated' do expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(assignee, merge_request) + expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request) execute end diff --git a/spec/services/merge_requests/post_merge_service_spec.rb b/spec/services/merge_requests/post_merge_service_spec.rb index 43416f1c50b..9b0e7d7f833 100644 --- a/spec/services/merge_requests/post_merge_service_spec.rb +++ b/spec/services/merge_requests/post_merge_service_spec.rb @@ -78,6 +78,13 @@ RSpec.describe MergeRequests::PostMergeService, feature_category: :code_review_w subject end + it 'triggers GraphQL subscription userMergeRequestUpdated' do + expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user, merge_request) + expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request) + + subject + end + context 'when there are issues to be closed' do let_it_be(:issue) { create(:issue, project: project) } diff --git a/spec/services/merge_requests/remove_approval_service_spec.rb b/spec/services/merge_requests/remove_approval_service_spec.rb index 8390ad5d48d..8c616dd2eb1 100644 --- a/spec/services/merge_requests/remove_approval_service_spec.rb +++ b/spec/services/merge_requests/remove_approval_service_spec.rb @@ -131,6 +131,7 @@ RSpec.describe MergeRequests::RemoveApprovalService, feature_category: :code_rev it 'triggers GraphQL subscription userMergeRequestUpdated' do expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user, merge_request) + expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request) execute! end diff --git a/spec/services/merge_requests/update_reviewer_state_service_spec.rb b/spec/services/merge_requests/update_reviewer_state_service_spec.rb index 787b45710b7..920c2fb9521 100644 --- a/spec/services/merge_requests/update_reviewer_state_service_spec.rb +++ b/spec/services/merge_requests/update_reviewer_state_service_spec.rb @@ -80,6 +80,7 @@ RSpec.describe MergeRequests::UpdateReviewerStateService, feature_category: :cod it 'triggers GraphQL subscription userMergeRequestUpdated' do expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(current_user, merge_request) + expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request) result end diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index ed348ddb708..e0a6b876017 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -740,6 +740,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer, feature_category: :code_re end it 'triggers GraphQL subscription userMergeRequestUpdated' do + expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request) expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user3, merge_request) expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user2, merge_request) diff --git a/spec/services/personal_access_tokens/last_used_service_spec.rb b/spec/services/personal_access_tokens/last_used_service_spec.rb index b8701fd3f75..6c2375bf24e 100644 --- a/spec/services/personal_access_tokens/last_used_service_spec.rb +++ b/spec/services/personal_access_tokens/last_used_service_spec.rb @@ -85,27 +85,6 @@ RSpec.describe PersonalAccessTokens::LastUsedService, feature_category: :system_ service_execution end - - context 'when pat_last_used_at_optimization FF is disabled' do - before do - stub_feature_flags(pat_last_used_at_optimization: false) - end - - it "does not update the personal access token's last used ips" do - expect { service_execution }.not_to change { personal_access_token.last_used_ips.count } - expect( - Authn::PersonalAccessTokenLastUsedIp - .where(personal_access_token_id: personal_access_token.id, ip_address: Gitlab::IpAddressState.current) - .exists? - ).to be_falsy - end - - it "obtains exclusive lease" do - expect(service).to receive(:try_obtain_lease) - - service_execution - end - end end context "when the current ip address is already saved" do @@ -230,22 +209,6 @@ RSpec.describe PersonalAccessTokens::LastUsedService, feature_category: :system_ service_execution end - - context 'when pat_last_used_at_optimization FF is disabled' do - before do - stub_feature_flags(pat_last_used_at_optimization: false) - end - - it 'does not update the last_used_at timestamp' do - expect { service_execution }.not_to change { personal_access_token.last_used_at } - end - - it "obtains exclusive lease" do - expect(service).to receive(:try_obtain_lease) - - service_execution - end - end end context 'when the last_used_at timestamp is nil' do