Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-09-21 00:10:06 +00:00
parent 5bbc92d39c
commit 11bda5e7e1
48 changed files with 331 additions and 204 deletions

View File

@ -277,6 +277,12 @@ class Projects::IssuesController < Projects::ApplicationController
@issues = @issuables
end
def discussions
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/425834')
super
end
protected
def index_html_request?

View File

@ -3542,7 +3542,7 @@
:tags: []
- :name: projects_record_target_platforms
:worker_name: Projects::RecordTargetPlatformsWorker
:feature_category: :experimentation_activation
:feature_category: :activation
:has_external_dependencies: false
:urgency: :low
:resource_boundary: :unknown

View File

@ -8,7 +8,7 @@ module Projects
LEASE_TIMEOUT = 1.hour.to_i
APPLE_PLATFORM_LANGUAGES = %w[swift objective-c].freeze
feature_category :experimentation_activation
feature_category :activation
data_consistency :always
deduplicate :until_executed
urgency :low

View File

@ -7,6 +7,8 @@
# PLEASE DO NOT EDIT THIS FILE MANUALLY.
#
---
- acquisition
- activation
- advisory_database
- ai_abstraction_layer
- ai_evaluation
@ -58,10 +60,6 @@
- environment_management
- error_budgets
- error_tracking
- experimentation_activation
- experimentation_adoption
- experimentation_conversion
- experimentation_expansion
- feature_flags
- five_minute_production_app
- fulfillment_admin_tooling
@ -81,7 +79,6 @@
- insider_threat
- instance_resiliency
- integrations
- interactive_application_security_testing
- internationalization
- logging
- measurement_and_locking
@ -120,7 +117,6 @@
- seat_cost_management
- secret_detection
- secrets_management
- security_benchmarking
- security_policy_management
- service_desk
- service_ping

View File

@ -0,0 +1,8 @@
---
name: compliance_framework_report_ui
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131838
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/425242
milestone: '16.5'
type: development
group: group::compliance
default_enabled: false

View File

@ -3,7 +3,7 @@ table_name: experiment_subjects
classes:
- ExperimentSubject
feature_categories:
- experimentation_conversion
- acquisition
description:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47042
milestone: '13.7'

View File

@ -3,7 +3,7 @@ table_name: experiment_users
classes:
- ExperimentUser
feature_categories:
- experimentation_conversion
- acquisition
description:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38397
milestone: '13.3'

View File

@ -3,7 +3,7 @@ table_name: experiments
classes:
- Experiment
feature_categories:
- experimentation_conversion
- acquisition
description:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38397
milestone: '13.3'

View File

@ -3,7 +3,7 @@ table_name: in_product_marketing_emails
classes:
- Users::InProductMarketingEmail
feature_categories:
- experimentation_activation
- activation
description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55840
milestone: '13.10'

View File

@ -3,7 +3,7 @@ table_name: member_tasks
classes:
- MemberTask
feature_categories:
- experimentation_activation
- activation
description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69299
milestone: '14.5'

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddIndexToViolationsOnTargetProjIdSync < Gitlab::Database::Migration[2.1]
TABLE_NAME = 'merge_requests_compliance_violations'
INDEX_NAME = 'i_compliance_violations_for_export'
disable_ddl_transaction!
def up
add_concurrent_index TABLE_NAME, [:target_project_id, :id], name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
end
end

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
class SynchronouslyCreateIndexForUuidTypeCasting < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
TABLE_NAME = :vulnerability_occurrences
INDEX_NAME = "tmp_index_vulnerability_occurrences_uuid_cast"
def up
disable_statement_timeout do
execute <<~SQL
CREATE INDEX CONCURRENTLY IF NOT EXISTS #{INDEX_NAME}
ON #{TABLE_NAME}((uuid::uuid))
SQL
end
end
def down
remove_concurrent_index_by_name(
TABLE_NAME,
INDEX_NAME
)
end
end

View File

@ -0,0 +1 @@
ba22699c5942b9974479664f404bb7eb39df919035e4dc487b7ed744b44c06a7

View File

@ -0,0 +1 @@
68e5f72af0a54a06cb7e0f3f784c3ad7e472e966bd9f93181cc7a87fbd69b8e6

View File

@ -30575,6 +30575,8 @@ CREATE UNIQUE INDEX i_bulk_import_trackers_id_batch_number ON bulk_import_batch_
CREATE INDEX i_compliance_frameworks_on_id_and_created_at ON compliance_management_frameworks USING btree (id, created_at, pipeline_configuration_full_path);
CREATE INDEX i_compliance_violations_for_export ON merge_requests_compliance_violations USING btree (target_project_id, id);
CREATE INDEX i_compliance_violations_on_project_id_merged_at_and_id ON merge_requests_compliance_violations USING btree (target_project_id, merged_at, id);
CREATE INDEX i_compliance_violations_on_project_id_reason_and_id ON merge_requests_compliance_violations USING btree (target_project_id, reason, id);
@ -34525,6 +34527,8 @@ CREATE INDEX tmp_index_project_statistics_updated_at ON project_statistics USING
CREATE INDEX tmp_index_vulnerability_dismissal_info ON vulnerabilities USING btree (id) WHERE ((state = 2) AND ((dismissed_at IS NULL) OR (dismissed_by_id IS NULL)));
CREATE INDEX tmp_index_vulnerability_occurrences_uuid_cast ON vulnerability_occurrences USING btree (((uuid)::uuid));
CREATE INDEX tmp_index_vulnerability_overlong_title_html ON vulnerabilities USING btree (id) WHERE (length(title_html) > 800);
CREATE UNIQUE INDEX u_project_compliance_standards_adherence_for_reporting ON project_compliance_standards_adherence USING btree (project_id, check_name, standard);

View File

@ -37,10 +37,10 @@ The following metrics are available:
| Metric | Type | Since | Description | Labels |
| :--------------------------------------------------------------- | :---------- | ------: | :-------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------- |
| `gitlab_cache_misses_total` | Counter | 10.2 | Cache read miss | `controller`, `action`, `store`, `endpoint_id` |
| `gitlab_cache_operation_duration_seconds` | Histogram | 10.2 | Cache access time | `operation`, `store`, `endpoint_id` |
| `gitlab_cache_operations_total` | Counter | 12.2 | Cache operations by controller or action | `controller`, `action`, `operation`, `store`, `endpoint_id` |
| `gitlab_cache_read_multikey_count` | Histogram | 15.7 | Count of keys in multi-key cache read operations | `controller`, `action`, `store`, `endpoint_id` |
| `gitlab_cache_misses_total` | Counter | 10.2 | Cache read miss | `controller`, `action`, `store` |
| `gitlab_cache_operation_duration_seconds` | Histogram | 10.2 | Cache access time | `operation`, `store` |
| `gitlab_cache_operations_total` | Counter | 12.2 | Cache operations by controller or action | `controller`, `action`, `operation`, `store` |
| `gitlab_cache_read_multikey_count` | Histogram | 15.7 | Count of keys in multi-key cache read operations | `controller`, `action`, `store` |
| `gitlab_ci_pipeline_builder_scoped_variables_duration` | Histogram | 14.5 | Time in seconds it takes to create the scoped variables for a CI/CD job
| `gitlab_ci_pipeline_creation_duration_seconds` | Histogram | 13.0 | Time in seconds it takes to create a CI/CD pipeline | `gitlab` |
| `gitlab_ci_pipeline_size_builds` | Histogram | 13.1 | Total number of builds within a pipeline grouped by a pipeline source | `source` |
@ -65,9 +65,9 @@ The following metrics are available:
| `gitlab_transaction_cache_<key>_duration_total` | Counter | 10.2 | Counter for total time (seconds) spent in Rails cache calls (per key) | |
| `gitlab_transaction_cache_count_total` | Counter | 10.2 | Counter for total Rails cache calls (aggregate) | |
| `gitlab_transaction_cache_duration_total` | Counter | 10.2 | Counter for total time (seconds) spent in Rails cache calls (aggregate) | |
| `gitlab_transaction_cache_read_hit_count_total` | Counter | 10.2 | Counter for cache hits for Rails cache calls | `controller`, `action`, `store`, `endpoint_id` |
| `gitlab_transaction_cache_read_miss_count_total` | Counter | 10.2 | Counter for cache misses for Rails cache calls | `controller`, `action`, `store`, `endpoint_id` |
| `gitlab_transaction_duration_seconds` | Histogram | 10.2 | Duration for successful requests (`gitlab_transaction_*` metrics) | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_cache_read_hit_count_total` | Counter | 10.2 | Counter for cache hits for Rails cache calls | `controller`, `action`, `store` |
| `gitlab_transaction_cache_read_miss_count_total` | Counter | 10.2 | Counter for cache misses for Rails cache calls | `controller`, `action`, `store` |
| `gitlab_transaction_duration_seconds` | Histogram | 10.2 | Duration for successful requests (`gitlab_transaction_*` metrics) | `controller`, `action` |
| `gitlab_transaction_event_build_found_total` | Counter | 9.4 | Counter for build found for API /jobs/request | |
| `gitlab_transaction_event_build_invalid_total` | Counter | 9.4 | Counter for build invalid due to concurrency conflict for API /jobs/request | |
| `gitlab_transaction_event_build_not_found_cached_total` | Counter | 9.4 | Counter for cached response of build not found for API /jobs/request | |
@ -95,20 +95,20 @@ The following metrics are available:
| `gitlab_transaction_event_stuck_import_jobs_total` | Counter | 9.4 | Count of stuck import jobs | `projects_without_jid_count`, `projects_with_jid_count` |
| `gitlab_transaction_event_update_build_total` | Counter | 9.4 | Counter for update build for API `/jobs/request/:id` | |
| `gitlab_transaction_new_redis_connections_total` | Counter | 9.4 | Counter for new Redis connections | |
| `gitlab_transaction_rails_queue_duration_total` | Counter | 9.4 | Measures latency between GitLab Workhorse forwarding a request to Rails | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_view_duration_total` | Counter | 9.4 | Duration for views | `controller`, `action`, `view`, `endpoint_id` |
| `gitlab_view_rendering_duration_seconds` | Histogram | 10.2 | Duration for views (histogram) | `controller`, `action`, `view`, `endpoint_id` |
| `gitlab_transaction_rails_queue_duration_total` | Counter | 9.4 | Measures latency between GitLab Workhorse forwarding a request to Rails | `controller`, `action` |
| `gitlab_transaction_view_duration_total` | Counter | 9.4 | Duration for views | `controller`, `action`, `view` |
| `gitlab_view_rendering_duration_seconds` | Histogram | 10.2 | Duration for views (histogram) | `controller`, `action`, `view` |
| `http_requests_total` | Counter | 9.4 | Rack request count | `method`, `status` |
| `http_request_duration_seconds` | Histogram | 9.4 | HTTP response time from rack middleware for successful requests | `method` |
| `gitlab_transaction_db_count_total` | Counter | 13.1 | Counter for total number of SQL calls | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_db_<role>_count_total` | Counter | 13.10 | Counter for total number of SQL calls, grouped by database roles (primary/replica) | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_db_write_count_total` | Counter | 13.1 | Counter for total number of write SQL calls | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_db_cached_count_total` | Counter | 13.1 | Counter for total number of cached SQL calls | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_db_<role>_cached_count_total` | Counter | 13.1 | Counter for total number of cached SQL calls, grouped by database roles (primary/replica) | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_db_<role>_wal_count_total` | Counter | 14.0 | Counter for total number of WAL (write ahead log location) queries, grouped by database roles (primary/replica) | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_db_<role>_wal_cached_count_total` | Counter | 14.1 | Counter for total number of cached WAL (write ahead log location) queries, grouped by database roles (primary/replica)| `controller`, `action`, `endpoint_id` |
| `http_elasticsearch_requests_duration_seconds` **(PREMIUM ALL)** | Histogram | 13.1 | Elasticsearch requests duration during web transactions | `controller`, `action`, `endpoint_id` |
| `http_elasticsearch_requests_total` **(PREMIUM ALL)** | Counter | 13.1 | Elasticsearch requests count during web transactions | `controller`, `action`, `endpoint_id` |
| `gitlab_transaction_db_count_total` | Counter | 13.1 | Counter for total number of SQL calls | `controller`, `action` |
| `gitlab_transaction_db_<role>_count_total` | Counter | 13.10 | Counter for total number of SQL calls, grouped by database roles (primary/replica) | `controller`, `action` |
| `gitlab_transaction_db_write_count_total` | Counter | 13.1 | Counter for total number of write SQL calls | `controller`, `action` |
| `gitlab_transaction_db_cached_count_total` | Counter | 13.1 | Counter for total number of cached SQL calls | `controller`, `action` |
| `gitlab_transaction_db_<role>_cached_count_total` | Counter | 13.1 | Counter for total number of cached SQL calls, grouped by database roles (primary/replica) | `controller`, `action` |
| `gitlab_transaction_db_<role>_wal_count_total` | Counter | 14.0 | Counter for total number of WAL (write ahead log location) queries, grouped by database roles (primary/replica) | `controller`, `action` |
| `gitlab_transaction_db_<role>_wal_cached_count_total` | Counter | 14.1 | Counter for total number of cached WAL (write ahead log location) queries, grouped by database roles (primary/replica)| `controller`, `action` |
| `http_elasticsearch_requests_duration_seconds` **(PREMIUM ALL)** | Histogram | 13.1 | Elasticsearch requests duration during web transactions | `controller`, `action` |
| `http_elasticsearch_requests_total` **(PREMIUM ALL)** | Counter | 13.1 | Elasticsearch requests count during web transactions | `controller`, `action` |
| `pipelines_created_total` | Counter | 9.4 | Counter of pipelines created | |
| `rack_uncaught_errors_total` | Counter | 9.4 | Rack connections handling uncaught errors count | |
| `user_session_logins_total` | Counter | 9.4 | Counter of how many users have logged in since GitLab was started or restarted | |
@ -137,7 +137,7 @@ The following metrics are available:
| `gitlab_ci_trace_finalize_duration_seconds` | Histogram | 13.6 | Duration of build trace chunks migration to object storage | |
| `gitlab_vulnerability_report_branch_comparison_real_duration_seconds` | Histogram | 15.11 | Execution duration of vulnerability report present on default branch sql query | |
| `gitlab_vulnerability_report_branch_comparison_cpu_duration_seconds` | Histogram | 15.11 | Execution duration of vulnerability report present on default branch sql query | |
| `gitlab_external_http_total` | Counter | 13.8 | Total number of HTTP calls to external systems | `controller`, `action`, `endpoint_id` |
| `gitlab_external_http_total` | Counter | 13.8 | Total number of HTTP calls to external systems | `controller`, `action` |
| `gitlab_external_http_duration_seconds` | Counter | 13.8 | Duration in seconds spent on each HTTP call to external systems | |
| `gitlab_external_http_exception_total` | Counter | 13.8 | Total number of exceptions raised when making external HTTP calls | |
| `ci_report_parser_duration_seconds` | Histogram | 13.9 | Time to parse CI/CD report artifacts | `parser` |
@ -153,18 +153,18 @@ The following metrics are available:
| `gitlab_snowplow_failed_events_total` | Counter | 14.1 | Total number of GitLab Snowplow Analytics Instrumentation events emission failures | |
| `gitlab_snowplow_successful_events_total` | Counter | 14.1 | Total number of GitLab Snowplow Analytics Instrumentation events emission successes | |
| `gitlab_ci_build_trace_errors_total` | Counter | 14.4 | Total amount of different error types on a build trace | `error_reason` |
| `gitlab_presentable_object_cacheless_render_real_duration_seconds` | Histogram | 15.3 | Duration of real time spent caching and representing specific web request objects | `controller`, `action`, `endpoint_id` |
| `cached_object_operations_total` | Counter | 15.3 | Total number of objects cached for specific web requests | `controller`, `action`, `endpoint_id` |
| `gitlab_presentable_object_cacheless_render_real_duration_seconds` | Histogram | 15.3 | Duration of real time spent caching and representing specific web request objects | `controller`, `action` |
| `cached_object_operations_total` | Counter | 15.3 | Total number of objects cached for specific web requests | `controller`, `action` |
| `redis_hit_miss_operations_total` | Counter | 15.6 | Total number of Redis cache hits and misses | `cache_hit`, `cache_identifier`, `feature_category`, `backing_resource` |
| `redis_cache_generation_duration_seconds` | Histogram | 15.6 | Time to generate Redis cache | `cache_hit`, `cache_identifier`, `feature_category`, `backing_resource` |
| `gitlab_diffs_reorder_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spend on reordering of diff files on diffs batch request | `controller`, `action`, `endpoint_id` |
| `gitlab_diffs_collection_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on querying merge request diff files on diffs batch request | `controller`, `action`, `endpoint_id` |
| `gitlab_diffs_comparison_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on getting comparison data on diffs batch request | `controller`, `action`, `endpoint_id` |
| `gitlab_diffs_reorder_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spend on reordering of diff files on diffs batch request | `controller`, `action` |
| `gitlab_diffs_collection_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on querying merge request diff files on diffs batch request | `controller`, `action` |
| `gitlab_diffs_comparison_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on getting comparison data on diffs batch request | `controller`, `action` |
| `gitlab_diffs_unfoldable_positions_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on getting unfoldable note positions on diffs batch request | `controller`, `action` |
| `gitlab_diffs_unfold_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on unfolding positions on diffs batch request | `controller`, `action`, `endpoint_id` |
| `gitlab_diffs_write_cache_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on caching highlighted lines and stats on diffs batch request | `controller`, `action`, `endpoint_id` |
| `gitlab_diffs_highlight_cache_decorate_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on setting highlighted lines from cache on diffs batch request | `controller`, `action`, `endpoint_id` |
| `gitlab_diffs_render_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on serializing and rendering diffs on diffs batch request | `controller`, `action`, `endpoint_id` |
| `gitlab_diffs_unfold_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on unfolding positions on diffs batch request | `controller`, `action` |
| `gitlab_diffs_write_cache_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on caching highlighted lines and stats on diffs batch request | `controller`, `action` |
| `gitlab_diffs_highlight_cache_decorate_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on setting highlighted lines from cache on diffs batch request | `controller`, `action` |
| `gitlab_diffs_render_real_duration_seconds` | Histogram | 15.8 | Duration in seconds spent on serializing and rendering diffs on diffs batch request | `controller`, `action` |
| `gitlab_memwd_violations_total` | Counter | 15.9 | Total number of times a Ruby process violated a memory threshold | |
| `gitlab_memwd_violations_handled_total` | Counter | 15.9 | Total number of times Ruby process memory violations were handled | |
| `gitlab_sli_rails_request_apdex_total` | Counter | 14.4 | Total number of request Apdex measurements. For more information, see [Rails request SLIs](../../../development/application_slis/rails_request.md) | `endpoint_id`, `feature_category`, `request_urgency` |

View File

@ -101,7 +101,8 @@ In most cases the downtime required for doing an upgrade shouldn't be substantia
### Cloud Native Hybrid (Kubernetes HA)
As an additional layer of HA resilience you can deploy select components in Kubernetes, known as a Cloud Native Hybrid Reference Architecture.
As an additional layer of HA resilience you can deploy select components in Kubernetes, known as a Cloud Native Hybrid Reference Architecture. For stability
reasons, stateful components such as Gitaly [cannot be deployed in Kubernetes](#stateful-components-in-kubernetes).
This is an alternative and more **advanced** setup compared to a standard Reference Architecture. Running services in Kubernetes is well known to be complex. **This setup is only recommended** if you have strong working knowledge and experience in Kubernetes.
@ -384,8 +385,9 @@ While we endeavour to try and have a good range of support for GitLab environmen
[Running stateful components in Kubernetes, such as Gitaly Cluster, is not supported](https://docs.gitlab.com/charts/installation/#configure-the-helm-chart-to-use-external-stateful-data).
Gitaly Cluster is only supported to be run on VMs as Git itself doesn't match well with the Kubernetes design and attempting to run it can lead to significant and complex issues.
[Refer to epic 6127 for more information](https://gitlab.com/groups/gitlab-org/-/epics/6127).
Gitaly Cluster is only supported on conventional virtual machines. Kubernetes enforces strict memory restrictions but Git memory usage is unpredictable, which
can cause sporadic OOM termination of Gitaly pods, leading to significant disruptions and potential data loss. For this reason and others, Gitaly is not tested
or supported in Kubernetes. For more information, see [epic 6127](https://gitlab.com/groups/gitlab-org/-/epics/6127).
This also applies to other third-party stateful components such as Postgres and Redis, but you can explore other third-party solutions for those components if desired such as supported Cloud Provider services unless called out specifically as unsupported.

View File

@ -1782,7 +1782,7 @@ Input type: `CiAiGenerateConfigInput`
| ---- | ---- | ----------- |
| <a id="mutationciaigenerateconfigclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationciaigenerateconfigerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationciaigenerateconfigusermessage"></a>`userMessage` | [`AiMessage`](#aimessage) | User chat message. |
| <a id="mutationciaigenerateconfigusermessage"></a>`userMessage` | [`DeprecatedAiMessage`](#deprecatedaimessage) | User chat message. |
### `Mutation.ciJobTokenScopeAddProject`
@ -7930,29 +7930,6 @@ The edge type for [`AiChatMessage`](#aichatmessage).
| <a id="aichatmessageedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="aichatmessageedgenode"></a>`node` | [`AiChatMessage`](#aichatmessage) | The item at the end of the edge. |
#### `AiMessageConnection`
The connection type for [`AiMessage`](#aimessage).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="aimessageconnectionedges"></a>`edges` | [`[AiMessageEdge]`](#aimessageedge) | A list of edges. |
| <a id="aimessageconnectionnodes"></a>`nodes` | [`[AiMessage]`](#aimessage) | A list of nodes. |
| <a id="aimessageconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
#### `AiMessageEdge`
The edge type for [`AiMessage`](#aimessage).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="aimessageedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="aimessageedgenode"></a>`node` | [`AiMessage`](#aimessage) | The item at the end of the edge. |
#### `AlertManagementAlertConnection`
The connection type for [`AlertManagementAlert`](#alertmanagementalert).
@ -9523,6 +9500,29 @@ The edge type for [`Deployment`](#deployment).
| <a id="deploymentedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="deploymentedgenode"></a>`node` | [`Deployment`](#deployment) | The item at the end of the edge. |
#### `DeprecatedAiMessageConnection`
The connection type for [`DeprecatedAiMessage`](#deprecatedaimessage).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="deprecatedaimessageconnectionedges"></a>`edges` | [`[DeprecatedAiMessageEdge]`](#deprecatedaimessageedge) | A list of edges. |
| <a id="deprecatedaimessageconnectionnodes"></a>`nodes` | [`[DeprecatedAiMessage]`](#deprecatedaimessage) | A list of nodes. |
| <a id="deprecatedaimessageconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
#### `DeprecatedAiMessageEdge`
The edge type for [`DeprecatedAiMessage`](#deprecatedaimessage).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="deprecatedaimessageedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="deprecatedaimessageedgenode"></a>`node` | [`DeprecatedAiMessage`](#deprecatedaimessage) | The item at the end of the edge. |
#### `DesignAtVersionConnection`
The connection type for [`DesignAtVersion`](#designatversion).
@ -13095,18 +13095,6 @@ GitLab Duo Chat message.
| <a id="aichatmessagerole"></a>`role` | [`AiChatMessageRole!`](#aichatmessagerole) | Message role. |
| <a id="aichatmessagetimestamp"></a>`timestamp` | [`Time!`](#time) | Message timestamp. |
### `AiMessage`
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="aimessagecontent"></a>`content` | [`String`](#string) | Content of the message or null if loading. |
| <a id="aimessageerrors"></a>`errors` | [`[String!]!`](#string) | Errors that occurred while asynchronously fetching an AI(assistant) response. |
| <a id="aimessageid"></a>`id` | [`ID`](#id) | Global ID of the message. |
| <a id="aimessageisfetching"></a>`isFetching` | [`Boolean`](#boolean) | Whether the content is still being fetched, for a message with the assistant role. |
| <a id="aimessagerole"></a>`role` | [`String!`](#string) | Role of the message (system, user, assistant). |
### `AiMessageExtras`
Extra metadata for AI message.
@ -15771,6 +15759,18 @@ Tags for a given deployment.
| <a id="deploymenttagname"></a>`name` | [`String`](#string) | Name of this git tag. |
| <a id="deploymenttagpath"></a>`path` | [`String`](#string) | Path for this tag. |
### `DeprecatedAiMessage`
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="deprecatedaimessagecontent"></a>`content` | [`String`](#string) | Content of the message or null if loading. |
| <a id="deprecatedaimessageerrors"></a>`errors` | [`[String!]!`](#string) | Errors that occurred while asynchronously fetching an AI(assistant) response. |
| <a id="deprecatedaimessageid"></a>`id` | [`ID`](#id) | Global ID of the message. |
| <a id="deprecatedaimessageisfetching"></a>`isFetching` | [`Boolean`](#boolean) | Whether the content is still being fetched, for a message with the assistant role. |
| <a id="deprecatedaimessagerole"></a>`role` | [`String!`](#string) | Role of the message (system, user, assistant). |
### `DescriptionVersion`
#### Fields
@ -23367,7 +23367,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectconversationsciconfigmessages"></a>`ciConfigMessages` **{warning-solid}** | [`AiMessageConnection`](#aimessageconnection) | **Introduced** in 16.0. This feature is an Experiment. It can be changed or removed at any time. Messages generated by open ai and the user. |
| <a id="projectconversationsciconfigmessages"></a>`ciConfigMessages` **{warning-solid}** | [`DeprecatedAiMessageConnection`](#deprecatedaimessageconnection) | **Introduced** in 16.0. This feature is an Experiment. It can be changed or removed at any time. Messages generated by open ai and the user. |
### `ProjectDataTransfer`

View File

@ -17,7 +17,7 @@ This API requires an access token with the Maintainer or Owner role.
## List all active integrations
> `vulnerability_events` field [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131831) in GitLab 16.5.
> `vulnerability_events` field [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131831) in GitLab 16.4.
Get a list of all active project integrations. The `vulnerability_events` field is only available for GitLab Enterprise Edition.

View File

@ -410,11 +410,12 @@ Actors also provide an easy way to do a percentage rollout of a feature in a sti
If a 1% rollout enabled a feature for a specific actor, that actor will continue to have the feature enabled at
10%, 50%, and 100%.
GitLab currently supports the following models as feature flag actors:
GitLab currently supports the following feature flag actors:
- `User`
- `Project`
- `Group`
- `User` model
- `Project` model
- `Group` model
- Current request
The actor is a second parameter of the `Feature.enabled?` call. The
same actor type must be used consistently for all invocations of `Feature.enabled?`.
@ -437,6 +438,40 @@ Feature.enabled?(:feature_flag_user, user)
See [Feature flags in the development of GitLab](controls.md#process) for details on how to use ChatOps
to selectively enable or disable feature flags in GitLab-provided environments, like staging and production.
#### Current request actor
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/132078) in GitLab 16.5
It is not recommended to use percentage of time rollout, as each call may return
inconsistent results.
Rather it is advised to use the current request as an actor.
```ruby
# Bad
Feature.enable_percentage_of_time(:feature_flag, 40)
Feature.enabled?(:feature_flag)
# Good
Feature.enable_percentage_of_actors(:feature_flag, 40)
Feature.enabled?(:feature_flag, Feature.current_request)
```
When using the current request as the actor, the feature flag should return the
same value within the context of a request.
As the current request actor is implemented using [`SafeRequestStore`](../caching.md#low-level), we should
have consistent feature flag values within:
- a Rack request
- a Sidekiq worker execution
- an ActionCable worker execution
To migrate an existing feature from percentage of time to the current request
actor, it is recommended that you create a new feature flag.
This is because it is difficult to control the timing between existing
`percentage_of_time` values, the deployment of the code change, and switching to
use `percentage_of_actors`.
#### Use actors for verifying in production
WARNING:

View File

@ -30,6 +30,20 @@ module Feature
superclass.table_name = 'feature_gates'
end
# Generates the same flipper_id when in a request
# If not in a request, it generates a unique flipper_id every time
class FlipperRequest
def id
Gitlab::SafeRequestStore.fetch("flipper_request_id") do
SecureRandom.uuid
end
end
def flipper_id
"FlipperRequest:#{id}"
end
end
# To enable EE overrides
class ActiveSupportCacheStoreAdapter < Flipper::Adapters::ActiveSupportCacheStore
end
@ -189,7 +203,7 @@ module Feature
@flipper = nil
end
# This method is called from config/initializers/flipper.rb and can be used
# This method is called from config/initializers/0_inject_feature_flags.rb and can be used
# to register Flipper groups.
# See https://docs.gitlab.com/ee/development/feature_flags/index.html
#
@ -206,6 +220,14 @@ module Feature
Feature::Definition.register_hot_reloader!
end
def current_request
if Gitlab::SafeRequestStore.active?
Gitlab::SafeRequestStore[:flipper_request] ||= FlipperRequest.new
else
@flipper_request ||= FlipperRequest.new
end
end
def logger
@logger ||= Feature::Logger.build
end

View File

@ -1,2 +1,2 @@
include:
template: Jobs/Code-Quality.gitlab-ci.yml
- template: Jobs/Code-Quality.gitlab-ci.yml

View File

@ -8,7 +8,7 @@
# See https://docs.gitlab.com/ee/ci/yaml/signing_examples.html for more details.
include:
template: Docker.gitlab-ci.yml
- template: Docker.gitlab-ci.yml
docker-build:
variables:

View File

@ -2,4 +2,4 @@
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/381665
include:
template: Jobs/Container-Scanning.gitlab-ci.yml
- template: Jobs/Container-Scanning.gitlab-ci.yml

View File

@ -2,4 +2,4 @@
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/381665
include:
template: Jobs/Container-Scanning.latest.gitlab-ci.yml
- template: Jobs/Container-Scanning.latest.gitlab-ci.yml

View File

@ -2,4 +2,4 @@
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/292977
include:
template: Jobs/Dependency-Scanning.gitlab-ci.yml
- template: Jobs/Dependency-Scanning.gitlab-ci.yml

View File

@ -2,4 +2,4 @@
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/292977
include:
template: Jobs/License-Scanning.gitlab-ci.yml
- template: Jobs/License-Scanning.gitlab-ci.yml

View File

@ -1,2 +1,2 @@
include:
template: Jobs/SAST-IaC.gitlab-ci.yml
- template: Jobs/SAST-IaC.gitlab-ci.yml

View File

@ -1,2 +1,2 @@
include:
template: Jobs/SAST-IaC.latest.gitlab-ci.yml
- template: Jobs/SAST-IaC.latest.gitlab-ci.yml

View File

@ -2,4 +2,4 @@
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/292977
include:
template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/SAST.gitlab-ci.yml

View File

@ -2,4 +2,4 @@
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/292977
include:
template: Jobs/Secret-Detection.gitlab-ci.yml
- template: Jobs/Secret-Detection.gitlab-ci.yml

View File

@ -9,7 +9,7 @@ module Gitlab
# etc.
class WebTransaction < Transaction
THREAD_KEY = :_gitlab_metrics_transaction
BASE_LABEL_KEYS = %i[controller action feature_category endpoint_id].freeze
BASE_LABEL_KEYS = %i[controller action feature_category].freeze
CONTROLLER_KEY = 'action_controller.instance'
ENDPOINT_KEY = 'api.endpoint'
@ -95,12 +95,7 @@ module Gitlab
action = "#{action}.#{suffix}"
end
{
controller: controller.class.name,
action: action,
feature_category: feature_category,
endpoint_id: controller.class.endpoint_id_for_action(action)
}
{ controller: controller.class.name, action: action, feature_category: feature_category }
end
def labels_from_endpoint
@ -117,12 +112,7 @@ module Gitlab
if route
path = endpoint_paths_cache[route.request_method][route.path]
{
controller: 'Grape',
action: "#{route.request_method} #{path}",
feature_category: feature_category,
endpoint_id: API::Base.endpoint_id_for_route(route)
}
{ controller: 'Grape', action: "#{route.request_method} #{path}", feature_category: feature_category }
end
end

View File

@ -7779,6 +7779,9 @@ msgstr ""
msgid "Billing|An error occurred while loading pending members list"
msgstr ""
msgid "Billing|An error occurred while loading users of the Code Suggestions add-on. If the problem persists, please %{supportLinkStart}contact support%{supportLinkEnd}."
msgstr ""
msgid "Billing|An error occurred while removing a billable member."
msgstr ""
@ -23850,6 +23853,11 @@ msgstr ""
msgid "Identities"
msgstr ""
msgid "IdentityVerification|%d country found"
msgid_plural "IdentityVerification|%d countries found"
msgstr[0] ""
msgstr[1] ""
msgid "IdentityVerification|%{linkStart}Enter a new phone number%{linkEnd}"
msgstr ""
@ -23874,6 +23882,9 @@ msgstr ""
msgid "IdentityVerification|Confirm your email address"
msgstr ""
msgid "IdentityVerification|Country or region"
msgstr ""
msgid "IdentityVerification|Didn't receive a code?"
msgstr ""
@ -23916,9 +23927,6 @@ msgstr ""
msgid "IdentityVerification|If you've lost access to the email associated to this account or having trouble with the code, %{link_start}here are some other steps you can take.%{link_end}"
msgstr ""
msgid "IdentityVerification|International dial code"
msgstr ""
msgid "IdentityVerification|Maximum login attempts exceeded. Wait %{interval} and try again."
msgstr ""
@ -23943,6 +23951,9 @@ msgstr ""
msgid "IdentityVerification|Resend code"
msgstr ""
msgid "IdentityVerification|Select country or region"
msgstr ""
msgid "IdentityVerification|Send a new code"
msgstr ""
@ -47159,9 +47170,6 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
msgid "The Code Suggestions add-on is not available."
msgstr ""
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""

View File

@ -22,7 +22,7 @@ RSpec.describe Admin::GroupsController do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
expect(assigns(:groups)).to match_array([group, group_2, group_3])
expect(assigns(:groups)).to eq([group, group_2, group_3])
end
it 'renders a correct list of sort by options' do
@ -60,7 +60,7 @@ RSpec.describe Admin::GroupsController do
it 'returns a sorted by name_asc result' do
get :index, params: { sort: 'name_asc' }
expect(assigns(:groups)).to match_array([group, group_3, group_2])
expect(assigns(:groups)).to eq([group, group_3, group_2])
end
end
@ -68,7 +68,7 @@ RSpec.describe Admin::GroupsController do
it 'returns a search by name result' do
get :index, params: { name: 'Ygr' }
expect(assigns(:groups)).to match_array([group_2])
expect(assigns(:groups)).to eq([group_2])
end
it 'returns an empty list if no match' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ApplicationExperiment, :experiment, feature_category: :experimentation_conversion do
RSpec.describe ApplicationExperiment, :experiment, feature_category: :acquisition do
subject(:application_experiment) { described_class.new('namespaced/stub', **context) }
let(:context) { {} }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe "Gitlab::Experiment", :js, feature_category: :experimentation_activation do
RSpec.describe "Gitlab::Experiment", :js, feature_category: :activation do
# This is part of a set of tests that ensure that tracking remains
# consistent at the front end layer. Since we don't want to actually
# introduce an experiment in real code, we're going to simulate it

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_category: :experimentation_expansion do
RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_category: :acquisition do
let_it_be(:owner) { create(:user, name: 'John Doe') }
# private will ensure we really have access to the group when we land on the activity page
let_it_be(:group) { create(:group, :private, name: 'Owned') }

View File

@ -67,16 +67,6 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
end
shared_examples 'signup process' do
def fill_in_signup_form
fill_in 'new_user_username', with: new_user.username
fill_in 'new_user_email', with: new_user.email
fill_in 'new_user_first_name', with: new_user.first_name
fill_in 'new_user_last_name', with: new_user.last_name
fill_in 'new_user_password', with: new_user.password
wait_for_all_requests
end
def confirm_email
new_user_token = User.find_by_email(new_user.email).confirmation_token
@ -226,9 +216,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
it 'creates the user account and sends a confirmation email, and pre-fills email address after confirming' do
visit new_user_registration_path
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
expect { fill_in_sign_up_form(new_user) }.to change { User.count }.by(1)
expect(page).to have_current_path users_almost_there_path, ignore_query: true
expect(page).to have_content("Please check your email (#{new_user.email}) to confirm your account")
@ -246,9 +234,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
it 'creates the user account and sends a confirmation email' do
visit new_user_registration_path
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
expect { fill_in_sign_up_form(new_user) }.to change { User.count }.by(1)
expect(page).to have_current_path dashboard_projects_path
end
end
@ -262,8 +248,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
it 'creates the user account and goes to dashboard' do
visit new_user_registration_path
fill_in_signup_form
click_button "Register"
fill_in_sign_up_form(new_user)
expect(page).to have_current_path dashboard_projects_path
end
@ -277,9 +262,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
it 'creates the user but does not sign them in' do
visit new_user_registration_path
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
expect { fill_in_sign_up_form(new_user) }.to change { User.count }.by(1)
expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content(<<~TEXT.squish)
You have signed up successfully. However, we could not sign you in
@ -294,8 +277,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
create(:user, email: new_user.email)
visit new_user_registration_path
fill_in_signup_form
click_button "Register"
fill_in_sign_up_form(new_user)
expect(page).to have_current_path user_registration_path, ignore_query: true
expect(page).to have_content("error prohibited this user from being saved")
@ -306,8 +288,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
create(:user, email: new_user.email)
visit new_user_registration_path
fill_in_signup_form
click_button "Register"
fill_in_sign_up_form(new_user)
expect(page).to have_current_path user_registration_path, ignore_query: true
expect(page.body).not_to match(/#{new_user.password}/)
@ -328,8 +309,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
visit new_user_registration_path
expect(page).to have_content(terms_text)
fill_in_signup_form
click_button 'Register'
fill_in_sign_up_form(new_user)
expect(page).to have_current_path(dashboard_projects_path)
end
@ -357,9 +337,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
it 'prevents from signing up' do
visit new_user_registration_path
fill_in_signup_form
expect { click_button 'Register' }.not_to change { User.count }
expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
expect(page).to have_content(_('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'))
expect(page).to have_content(
"Minimum length is #{Gitlab::CurrentSettings.minimum_password_length} characters")
@ -370,9 +348,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
it 'prevents from signing up' do
visit new_user_registration_path
fill_in_signup_form
expect { click_button 'Register' }.not_to change { User.count }
expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
expect(page).to have_content('That was a bit too quick! Please resubmit.')
end
end
@ -381,9 +357,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
it 'allows visiting of a page after initial registration' do
visit new_user_registration_path
fill_in_signup_form
click_button 'Register'
fill_in_sign_up_form(new_user)
visit new_project_path
@ -394,8 +368,7 @@ RSpec.describe 'Signup', :js, feature_category: :user_profile do
create(:user, email: new_user.email)
visit new_user_registration_path
fill_in_signup_form
click_button "Register"
fill_in_sign_up_form(new_user)
expect(page).to have_current_path user_registration_path, ignore_query: true
expect(page.body).not_to match(/#{new_user.password}/)

View File

@ -11,6 +11,38 @@ RSpec.describe Feature, :clean_gitlab_redis_feature_flag, stub_feature_flags: fa
skip_feature_flags_yaml_validation
end
describe '.current_request' do
it 'returns a FlipperRequest with a flipper_id' do
flipper_request = described_class.current_request
expect(flipper_request.flipper_id).to include("FlipperRequest:")
end
context 'when request store is inactive' do
it 'does not cache flipper_id' do
previous_id = described_class.current_request.flipper_id
expect(described_class.current_request.flipper_id).not_to eq(previous_id)
end
end
context 'when request store is active', :request_store do
it 'caches flipper_id when request store is active' do
previous_id = described_class.current_request.flipper_id
expect(described_class.current_request.flipper_id).to eq(previous_id)
end
it 'returns a new flipper_id when request ends' do
previous_id = described_class.current_request.flipper_id
RequestStore.end!
expect(described_class.current_request.flipper_id).not_to eq(previous_id)
end
end
end
describe '.get' do
let(:feature) { double(:feature) }
let(:key) { 'my_feature' }
@ -299,6 +331,36 @@ RSpec.describe Feature, :clean_gitlab_redis_feature_flag, stub_feature_flags: fa
end
end
context 'with current_request actor' do
context 'when request store is inactive' do
it 'returns the approximate percentage set' do
number_of_times = 1_000
percentage = 50
described_class.enable_percentage_of_actors(:enabled_feature_flag, percentage)
gate_values = Array.new(number_of_times) do
described_class.enabled?(:enabled_feature_flag, described_class.current_request)
end
margin_of_error = 0.05 * number_of_times
expected_size = number_of_times * percentage / 100
expect(gate_values.count { |v| v }).to be_within(margin_of_error).of(expected_size)
end
end
context 'when request store is active', :request_store do
it 'always returns the same gate value' do
described_class.enable_percentage_of_actors(:enabled_feature_flag, 50)
previous_gate_value = described_class.enabled?(:enabled_feature_flag, described_class.current_request)
1_000.times do
expect(described_class.enabled?(:enabled_feature_flag, described_class.current_request)).to eq(previous_gate_value)
end
end
end
end
context 'with a group member' do
let(:key) { :awesome_feature }
let(:guinea_pigs) { create_list(:user, 3) }

View File

@ -64,7 +64,7 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
describe '#labels' do
context 'when request goes to Grape endpoint' do
before do
route = double(:route, request_method: 'GET', path: '/:version/projects/:id/archive(.:format)', origin: '/:version/projects/:id/archive')
route = double(:route, request_method: 'GET', path: '/:version/projects/:id/archive(.:format)')
endpoint = double(:endpoint, route: route,
options: { for: API::Projects, path: [":id/archive"] },
namespace: "/projects")
@ -76,12 +76,7 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
end
it 'provides labels with the method and path of the route in the grape endpoint' do
expect(transaction.labels).to eq({
controller: 'Grape',
action: 'GET /projects/:id/archive',
feature_category: 'projects',
endpoint_id: 'GET /:version/projects/:id/archive'
})
expect(transaction.labels).to eq({ controller: 'Grape', action: 'GET /projects/:id/archive', feature_category: 'projects' })
end
it 'contains only the labels defined for transactions' do
@ -104,14 +99,11 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
before do
controller = double(:controller, class: controller_class, action_name: 'show', request: request)
allow(controller_class).to receive(:endpoint_id_for_action)
.with(controller.action_name)
.and_return("#{controller_class.name}##{controller.action_name}")
env['action_controller.instance'] = controller
end
it 'tags a transaction with the name and action of a controller' do
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT, endpoint_id: 'TestController#show' })
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT })
end
it 'contains only the labels defined for transactions' do
@ -121,14 +113,8 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
context 'when the request content type is not :html' do
let(:request) { double(:request, format: double(:format, ref: :json)) }
before do
allow(controller_class).to receive(:endpoint_id_for_action)
.with("show.json")
.and_return("#{controller_class.name}#show.json")
end
it 'appends the mime type to the transaction action' do
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show.json', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT, endpoint_id: 'TestController#show.json' })
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show.json', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT })
end
end
@ -136,7 +122,7 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
let(:request) { double(:request, format: double(:format, ref: 'http://example.com')) }
it 'does not append the MIME type to the transaction action' do
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT, endpoint_id: 'TestController#show' })
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: ::Gitlab::FeatureCategories::FEATURE_CATEGORY_DEFAULT })
end
end
@ -145,7 +131,7 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
# This is needed since we're not actually making a request, which would trigger the controller pushing to the context
::Gitlab::ApplicationContext.push(feature_category: 'source_code_management')
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: 'source_code_management', endpoint_id: 'TestController#show' })
expect(transaction.labels).to eq({ controller: 'TestController', action: 'show', feature_category: "source_code_management" })
end
end
end
@ -161,12 +147,9 @@ RSpec.describe Gitlab::Metrics::WebTransaction do
let(:controller) { double(:controller, class: controller_class, action_name: 'show', request: request) }
let(:transaction_obj) { described_class.new({ 'action_controller.instance' => controller }) }
let(:labels) { { controller: 'TestController', action: 'show', feature_category: 'projects', endpoint_id: 'TestController#show' } }
let(:labels) { { controller: 'TestController', action: 'show', feature_category: 'projects' } }
before do
allow(controller_class).to receive(:endpoint_id_for_action)
.with(controller.action_name)
.and_return("#{controller_class.name}##{controller.action_name}")
::Gitlab::ApplicationContext.push(feature_category: 'projects')
end
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ReleaseHighlights::Validator, feature_category: :experimentation_adoption do
RSpec.describe ReleaseHighlights::Validator, feature_category: :activation do
let(:validator) { described_class.new(file: yaml_path) }
let(:yaml_path) { 'spec/fixtures/whats_new/valid.yml' }
let(:invalid_yaml_path) { 'spec/fixtures/whats_new/invalid.yml' }

View File

@ -936,47 +936,43 @@ RSpec.describe Group, feature_category: :groups_and_projects do
context 'when sort by is not provided (id desc by default)' do
let(:sort) { nil }
it { is_expected.to match_array([group_1, group_2, group_3, group_4]) }
it { is_expected.to eq([group_1, group_2, group_3, group_4]) }
end
context 'when sort by name_asc' do
let(:sort) { 'name_asc' }
it { is_expected.to match_array([group_3, group_4, group_2, group_1]) }
it { is_expected.to eq([group_3, group_4, group_2, group_1]) }
end
context 'when sort by name_desc' do
let(:sort) { 'name_desc' }
it { is_expected.to match_array([group_1, group_2, group_4, group_3]) }
it { is_expected.to eq([group_1, group_2, group_4, group_3]) }
end
context 'when sort by recently_created' do
let(:sort) { 'created_desc' }
it { is_expected.to match_array([group_3, group_1, group_4, group_2]) }
it { is_expected.to eq([group_3, group_1, group_4, group_2]) }
end
context 'when sort by oldest_created' do
let(:sort) { 'created_asc' }
it { is_expected.to match_array([group_2, group_4, group_1, group_3]) }
it { is_expected.to eq([group_2, group_4, group_1, group_3]) }
end
context 'when sort by latest_activity' do
let(:sort) { 'latest_activity_desc' }
# this should be expected if latest_activity is based on updated_at
# it { is_expected.to match_array([group_3, group_1, group_4, group_2]) }
it { is_expected.to match_array([group_1, group_2, group_3, group_4]) }
it { is_expected.to eq([group_1, group_2, group_3, group_4]) }
end
context 'when sort by oldest_activity' do
let(:sort) { 'latest_activity_asc' }
# this should be expected if latest_activity is based on updated_at
# it { is_expected.to match_array([group_2, group_4, group_1, group_3]) }
it { is_expected.to match_array([group_1, group_2, group_3, group_4]) }
it { is_expected.to eq([group_1, group_2, group_3, group_4]) }
end
context 'when sort by storage_size_desc' do
@ -1058,7 +1054,7 @@ RSpec.describe Group, feature_category: :groups_and_projects do
let(:sort) { 'storage_size_desc' }
it { is_expected.to match_array([group_2, group_4, group_1, group_3]) }
it { is_expected.to eq([group_2, group_4, group_1, group_3]) }
end
end

View File

@ -4,7 +4,7 @@ require 'rubocop_spec_helper'
require_relative '../../../rubocop/cop/experiments_test_coverage'
RSpec.describe RuboCop::Cop::ExperimentsTestCoverage, feature_category: :experimentation_conversion do
RSpec.describe RuboCop::Cop::ExperimentsTestCoverage, feature_category: :acquisition do
let(:class_offense) { described_class::CLASS_OFFENSE }
let(:block_offense) { described_class::BLOCK_OFFENSE }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ml::ExperimentTracking::CandidateRepository, feature_category: :experimentation_activation do
RSpec.describe ::Ml::ExperimentTracking::CandidateRepository, feature_category: :activation do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:experiment) { create(:ml_experiments, user: user, project: project) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ml::ExperimentTracking::ExperimentRepository, feature_category: :experimentation_activation do
RSpec.describe ::Ml::ExperimentTracking::ExperimentRepository, feature_category: :activation do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:experiment) { create(:ml_experiments, user: user, project: project) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ml::ExperimentTracking::HandleCandidateGitlabMetadataService, feature_category: :experimentation_activation do
RSpec.describe ::Ml::ExperimentTracking::HandleCandidateGitlabMetadataService, feature_category: :activation do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Projects::InProductMarketingCampaignEmailsService, feature_category: :experimentation_adoption do
RSpec.describe Projects::InProductMarketingCampaignEmailsService, feature_category: :activation do
describe '#execute' do
let(:user) { create(:user) }
let(:project) { create(:project) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Projects::RecordTargetPlatformsWorker, feature_category: :experimentation_activation do
RSpec.describe Projects::RecordTargetPlatformsWorker, feature_category: :activation do
include ExclusiveLeaseHelpers
let_it_be(:swift) { create(:programming_language, name: 'Swift') }