Commit 3dc2ee49 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 89e85996 f363da8a
...@@ -38,7 +38,7 @@ export default { ...@@ -38,7 +38,7 @@ export default {
<div <div
v-for="panel in panels" v-for="panel in panels"
:key="panel.name" :key="panel.name"
class="new-namespace-panel-wrapper gl-display-inline-block gl-px-3 gl-mb-5" class="new-namespace-panel-wrapper gl-display-inline-block gl-float-left gl-px-3 gl-mb-5"
> >
<a <a
:href="`#${panel.name}`" :href="`#${panel.name}`"
......
...@@ -8,10 +8,11 @@ $new-namespace-panel-height: 240px; ...@@ -8,10 +8,11 @@ $new-namespace-panel-height: 240px;
} }
.new-namespace-panel-wrapper { .new-namespace-panel-wrapper {
@include media-breakpoint-down(md) { width: 50%;
@include media-breakpoint-down(lg) {
width: 100%; width: 100%;
} }
width: 50%;
} }
.new-namespace-panel { .new-namespace-panel {
......
...@@ -14,8 +14,7 @@ module WikiActions ...@@ -14,8 +14,7 @@ module WikiActions
before_action { respond_to :html } before_action { respond_to :html }
before_action :authorize_read_wiki! before_action :authorize_read_wiki!
before_action :authorize_create_wiki!, only: [:edit, :create] before_action :authorize_create_wiki!, only: [:edit, :create, :destroy]
before_action :authorize_admin_wiki!, only: :destroy
before_action :wiki before_action :wiki
before_action :page, only: [:show, :edit, :update, :history, :destroy, :diff] before_action :page, only: [:show, :edit, :update, :history, :destroy, :diff]
......
...@@ -30,7 +30,7 @@ module BulkImports ...@@ -30,7 +30,7 @@ module BulkImports
end end
def portable_relations def portable_relations
import_export_config.dig(:tree, portable_class_sym).keys.map(&:to_s) import_export_config.dig(:tree, portable_class_sym).keys.map(&:to_s) - skipped_relations
end end
private private
...@@ -66,6 +66,10 @@ module BulkImports ...@@ -66,6 +66,10 @@ module BulkImports
def base_export_path def base_export_path
raise NotImplementedError raise NotImplementedError
end end
def skipped_relations
[]
end
end end
end end
end end
...@@ -10,6 +10,10 @@ module BulkImports ...@@ -10,6 +10,10 @@ module BulkImports
def import_export_yaml def import_export_yaml
::Gitlab::ImportExport.group_config_file ::Gitlab::ImportExport.group_config_file
end end
def skipped_relations
@skipped_relations ||= %w(members)
end
end end
end end
end end
...@@ -10,6 +10,10 @@ module BulkImports ...@@ -10,6 +10,10 @@ module BulkImports
def import_export_yaml def import_export_yaml
::Gitlab::ImportExport.config_file ::Gitlab::ImportExport.config_file
end end
def skipped_relations
@skipped_relations ||= %w(project_members group_members)
end
end end
end end
end end
- attribute = local_assigns.fetch(:attribute, nil) - attribute = local_assigns.fetch(:attribute, nil)
- group = local_assigns.fetch(:group, nil)
- form = local_assigns.fetch(:form, nil) - form = local_assigns.fetch(:form, nil)
- setting_locked = local_assigns.fetch(:setting_locked, false) - setting_locked = local_assigns.fetch(:setting_locked, false)
- help_text = local_assigns.fetch(:help_text, s_('CascadingSettings|Subgroups cannot change this setting.')) - help_text = local_assigns.fetch(:help_text, s_('CascadingSettings|Subgroups cannot change this setting.'))
......
- attribute = local_assigns.fetch(:attribute, nil) - attribute = local_assigns.fetch(:attribute, nil)
- group = local_assigns.fetch(:group, nil)
- settings_path_helper = local_assigns.fetch(:settings_path_helper, nil) - settings_path_helper = local_assigns.fetch(:settings_path_helper, nil)
- form = local_assigns.fetch(:form, nil) - form = local_assigns.fetch(:form, nil)
- setting_locked = local_assigns.fetch(:setting_locked, false) - setting_locked = local_assigns.fetch(:setting_locked, false)
- help_text = local_assigns.fetch(:help_text, nil) - help_text = local_assigns.fetch(:help_text, nil)
- return unless attribute && form && settings_path_helper - return unless attribute && group && form && settings_path_helper
= form.label attribute, class: 'custom-control-label', aria: { disabled: setting_locked } do = form.label attribute, class: 'custom-control-label', aria: { disabled: setting_locked } do
= render 'shared/namespaces/cascading_settings/setting_label_container' do = render 'shared/namespaces/cascading_settings/setting_label_container' do
......
- attribute = local_assigns.fetch(:attribute, nil) - attribute = local_assigns.fetch(:attribute, nil)
- group = local_assigns.fetch(:group, nil)
- settings_path_helper = local_assigns.fetch(:settings_path_helper, nil) - settings_path_helper = local_assigns.fetch(:settings_path_helper, nil)
- setting_locked = local_assigns.fetch(:setting_locked, false) - setting_locked = local_assigns.fetch(:setting_locked, false)
- help_text = local_assigns.fetch(:help_text, nil) - help_text = local_assigns.fetch(:help_text, nil)
- return unless attribute && settings_path_helper - return unless attribute && group && settings_path_helper
%legend.h5.gl-border-none.gl-m-0 %legend.h5.gl-border-none.gl-m-0
= render 'shared/namespaces/cascading_settings/setting_label_container' do = render 'shared/namespaces/cascading_settings/setting_label_container' do
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
.nav-controls.pb-md-3.pb-lg-0 .nav-controls.pb-md-3.pb-lg-0
- if @page.persisted? - if @page.persisted?
- if can?(current_user, :admin_wiki, @wiki.container) - if can?(current_user, :create_wiki, @wiki.container)
#delete-wiki-modal-wrapper{ data: { delete_wiki_url: wiki_page_path(@wiki, @page), page_title: @page.human_title } } #delete-wiki-modal-wrapper{ data: { delete_wiki_url: wiki_page_path(@wiki, @page), page_title: @page.human_title } }
= render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url = render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url
......
...@@ -47,11 +47,36 @@ module ApplicationWorker ...@@ -47,11 +47,36 @@ module ApplicationWorker
end end
class_methods do class_methods do
extend ::Gitlab::Utils::Override
def inherited(subclass) def inherited(subclass)
subclass.set_queue subclass.set_queue
subclass.after_set_class_attribute { subclass.set_queue } subclass.after_set_class_attribute { subclass.set_queue }
end end
override :validate_worker_attributes!
def validate_worker_attributes!
super
# Since the delayed data_consistency will use sidekiq built in retry mechanism, it is required that this mechanism
# is not disabled.
if retry_disabled? && get_data_consistency == :delayed
raise ArgumentError, "Retry support cannot be disabled if data_consistency is set to :delayed"
end
end
# Checks if sidekiq retry support is disabled
def retry_disabled?
get_sidekiq_options['retry'] == 0 || get_sidekiq_options['retry'] == false
end
override :sidekiq_options
def sidekiq_options(opts = {})
super.tap do
validate_worker_attributes!
end
end
def perform_async(*args) def perform_async(*args)
# Worker execution for workers with data_consistency set to :delayed or :sticky # Worker execution for workers with data_consistency set to :delayed or :sticky
# will be delayed to give replication enough time to complete # will be delayed to give replication enough time to complete
......
--- ---
data_category: Optional
key_path: active_user_count key_path: active_user_count
description: The number of active users existing in the instance. This is named the instance_user_count in the Versions application. description: The number of active users existing in the instance. This is named the instance_user_count in the Versions application.
product_section: growth product_section: growth
...@@ -8,6 +7,7 @@ product_group: group::product intelligence ...@@ -8,6 +7,7 @@ product_group: group::product intelligence
product_category: collection product_category: collection
value_type: string value_type: string
status: data_available status: data_available
data_category: Subscription
time_frame: none time_frame: none
data_source: database data_source: database
distribution: distribution:
......
...@@ -131,6 +131,7 @@ Renders the enforcement checkbox. ...@@ -131,6 +131,7 @@ Renders the enforcement checkbox.
| Local | Description | Type | Required (default value) | | Local | Description | Type | Required (default value) |
|:-----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------|:------------------------------------------------| |:-----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------|:------------------------------------------------|
| `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` | | `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` |
| `group` | Current group. | [`Group`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/group.rb) | `true` |
| `form` | [Rails FormBuilder object](https://apidock.com/rails/ActionView/Helpers/FormBuilder). | [`ActionView::Helpers::FormBuilder`](https://apidock.com/rails/ActionView/Helpers/FormBuilder) | `true` | | `form` | [Rails FormBuilder object](https://apidock.com/rails/ActionView/Helpers/FormBuilder). | [`ActionView::Helpers::FormBuilder`](https://apidock.com/rails/ActionView/Helpers/FormBuilder) | `true` |
| `setting_locked` | If the setting is locked by an ancestor group or admin setting. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` | | `setting_locked` | If the setting is locked by an ancestor group or admin setting. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` |
| `help_text` | Text shown below the checkbox. | `String` | `false` (Subgroups cannot change this setting.) | | `help_text` | Text shown below the checkbox. | `String` | `false` (Subgroups cannot change this setting.) |
...@@ -142,6 +143,7 @@ Renders the label for a checkbox setting. ...@@ -142,6 +143,7 @@ Renders the label for a checkbox setting.
| Local | Description | Type | Required (default value) | | Local | Description | Type | Required (default value) |
|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------|:-------------------------| |:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------|:-------------------------|
| `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` | | `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` |
| `group` | Current group. | [`Group`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/group.rb) | `true` |
| `form` | [Rails FormBuilder object](https://apidock.com/rails/ActionView/Helpers/FormBuilder). | [`ActionView::Helpers::FormBuilder`](https://apidock.com/rails/ActionView/Helpers/FormBuilder) | `true` | | `form` | [Rails FormBuilder object](https://apidock.com/rails/ActionView/Helpers/FormBuilder). | [`ActionView::Helpers::FormBuilder`](https://apidock.com/rails/ActionView/Helpers/FormBuilder) | `true` |
| `setting_locked` | If the setting is locked by an ancestor group or admin setting. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` | | `setting_locked` | If the setting is locked by an ancestor group or admin setting. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` |
| `settings_path_helper` | Lambda function that generates a path to the ancestor setting. For example, `settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') }` | `Lambda` | `true` | | `settings_path_helper` | Lambda function that generates a path to the ancestor setting. For example, `settings_path_helper: -> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') }` | `Lambda` | `true` |
...@@ -154,6 +156,7 @@ Renders the label for a fieldset setting. ...@@ -154,6 +156,7 @@ Renders the label for a fieldset setting.
| Local | Description | Type | Required (default value) | | Local | Description | Type | Required (default value) |
|:-----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------|:-------------------------| |:-----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------|:-------------------------|
| `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` | | `attribute` | Name of the setting. For example, `:delayed_project_removal`. | `String` or `Symbol` | `true` |
| `group` | Current group. | [`Group`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/group.rb) | `true` |
| `setting_locked` | If the setting is locked. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` | | `setting_locked` | If the setting is locked. Can be calculated with [`cascading_namespace_setting_locked?`](https://gitlab.com/gitlab-org/gitlab/-/blob/c2736823b8e922e26fd35df4f0cd77019243c858/app/helpers/namespaces_helper.rb#L86). | `Boolean` | `true` |
| `settings_path_helper` | Lambda function that generates a path to the ancestor setting. For example, `-> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') }` | `Lambda` | `true` | | `settings_path_helper` | Lambda function that generates a path to the ancestor setting. For example, `-> (locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') }` | `Lambda` | `true` |
| `help_text` | Text shown below the checkbox. | `String` | `false` (`nil`) | | `help_text` | Text shown below the checkbox. | `String` | `false` (`nil`) |
......
...@@ -42,7 +42,7 @@ The number of active users existing in the instance. This is named the instance_ ...@@ -42,7 +42,7 @@ The number of active users existing in the instance. This is named the instance_
Group: `group::product intelligence` Group: `group::product intelligence`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -3836,7 +3836,7 @@ Count of License Scanning jobs run ...@@ -3836,7 +3836,7 @@ Count of License Scanning jobs run
Group: `group::composition analysis` Group: `group::composition analysis`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8288,7 +8288,7 @@ The peak active user count. Active is defined in UsersStatistics model. ...@@ -8288,7 +8288,7 @@ The peak active user count. Active is defined in UsersStatistics model.
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8386,7 +8386,7 @@ The date the license ends ...@@ -8386,7 +8386,7 @@ The date the license ends
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8400,7 +8400,7 @@ The ID of the license ...@@ -8400,7 +8400,7 @@ The ID of the license
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8428,7 +8428,7 @@ The plan of the GitLab license ...@@ -8428,7 +8428,7 @@ The plan of the GitLab license
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8442,7 +8442,7 @@ The date the license starts ...@@ -8442,7 +8442,7 @@ The date the license starts
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8470,7 +8470,7 @@ Whether this is a trial license or not ...@@ -8470,7 +8470,7 @@ Whether this is a trial license or not
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8484,7 +8484,7 @@ Date the trial license ends on ...@@ -8484,7 +8484,7 @@ Date the trial license ends on
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8498,7 +8498,7 @@ The number of seats included in the license ...@@ -8498,7 +8498,7 @@ The number of seats included in the license
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8512,7 +8512,7 @@ Company on the GitLab license ...@@ -8512,7 +8512,7 @@ Company on the GitLab license
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8526,7 +8526,7 @@ Email on the GitLab license ...@@ -8526,7 +8526,7 @@ Email on the GitLab license
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -8540,7 +8540,7 @@ Name on the GitLab license ...@@ -8540,7 +8540,7 @@ Name on the GitLab license
Group: `group::license` Group: `group::license`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
...@@ -9002,7 +9002,7 @@ When the EE-specific features were computed ...@@ -9002,7 +9002,7 @@ When the EE-specific features were computed
Group: `group::product intelligence` Group: `group::product intelligence`
Data Category: `Optional` Data Category: `Subscription`
Status: `data_available` Status: `data_available`
......
...@@ -712,18 +712,22 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF ...@@ -712,18 +712,22 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF
Aggregation on a `daily` basis does not pull more fine grained data. Aggregation on a `daily` basis does not pull more fine grained data.
- `feature_flag`: optional `default_enabled: :yaml`. If no feature flag is set then the tracking is enabled. One feature flag can be used for multiple events. For details, see our [GitLab internal Feature flags](../feature_flags/index.md) documentation. The feature flags are owned by the group adding the event tracking. - `feature_flag`: optional `default_enabled: :yaml`. If no feature flag is set then the tracking is enabled. One feature flag can be used for multiple events. For details, see our [GitLab internal Feature flags](../feature_flags/index.md) documentation. The feature flags are owned by the group adding the event tracking.
Use one of the following methods to track events: 1. Use one of the following methods to track the event:
1. Track event in controller using `RedisTracking` module with `track_redis_hll_event(*controller_actions, name:, if: nil, &block)`. - In the controller using the `RedisTracking` module and the following format:
```ruby
track_redis_hll_event(*controller_actions, name:, if: nil, &block)
```
Arguments: Arguments:
- `controller_actions`: controller actions we want to track. - `controller_actions`: the controller actions to track.
- `name`: event name. - `name`: the event name.
- `if`: optional custom conditions, using the same format as with Rails callbacks. - `if`: optional custom conditions. Uses the same format as Rails callbacks.
- `&block`: optional block that computes and returns the `custom_id` that we want to track. This will override the `visitor_id`. - `&block`: optional block that computes and returns the `custom_id` that we want to track. This overrides the `visitor_id`.
Example usage: Example:
```ruby ```ruby
# controller # controller
...@@ -747,14 +751,14 @@ Use one of the following methods to track events: ...@@ -747,14 +751,14 @@ Use one of the following methods to track events:
end end
``` ```
1. Track event in API using `increment_unique_values(event_name, values)` helper method. - In the API using the `increment_unique_values(event_name, values)` helper method.
Arguments: Arguments:
- `event_name`: event name. - `event_name`: the event name.
- `values`: values counted, one value or array of values. - `values`: the values counted. Can be one value or an array of values.
Example usage: Example:
```ruby ```ruby
get ':id/registry/repositories' do get ':id/registry/repositories' do
...@@ -768,27 +772,26 @@ Use one of the following methods to track events: ...@@ -768,27 +772,26 @@ Use one of the following methods to track events:
end end
``` ```
1. Track event using `track_usage_event(event_name, values)` in services and GraphQL - Using `track_usage_event(event_name, values)` in services and GraphQL.
Increment unique values count using Redis HLL, for given event name. Increment unique values count using Redis HLL, for a given event name.
Example: Examples:
[Track usage event for incident created in service](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/services/issues/update_service.rb#L66)
[Track usage event for incident created in GraphQL](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/graphql/mutations/alert_management/update_alert_status.rb#L16) - [Track usage event for an incident in a service](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/services/issues/update_service.rb#L66)
- [Track usage event for an incident in GraphQL](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/app/graphql/mutations/alert_management/update_alert_status.rb#L16)
```ruby ```ruby
track_usage_event(:incident_management_incident_created, current_user.id) track_usage_event(:incident_management_incident_created, current_user.id)
``` ```
<!-- There's nearly identical content in `##### UsageData API Tracking`. If you find / fix errors here, you may need to fix errors in that section too. --> - Using the `UsageData` API.
<!-- There's nearly identical content in `##### UsageData API Tracking`. If you find / fix errors here, you may need to fix errors in that section too. -->
1. Track event using `UsageData` API Increment unique users count using Redis HLL, for a given event name.
Increment unique users count using Redis HLL, for given event name. To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
Tracking events using the `UsageData` API requires the `usage_data_api` feature flag to be enabled, which is enabled by default.
API requests are protected by checking for a valid CSRF token. API requests are protected by checking for a valid CSRF token.
...@@ -798,23 +801,21 @@ Use one of the following methods to track events: ...@@ -798,23 +801,21 @@ Use one of the following methods to track events:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| :-------- | :--- | :------- | :---------- | | :-------- | :--- | :------- | :---------- |
| `event` | string | yes | The event name it should be tracked | | `event` | string | yes | The event name to track |
Response
Return 200 if tracking failed for any reason. Response:
- `200` if event was tracked or any errors - `200` if the event was tracked, or if tracking failed for any reason.
- `400 Bad request` if event parameter is missing - `400 Bad request` if an event parameter is missing.
- `401 Unauthorized` if user is not authenticated - `401 Unauthorized` if the user is not authenticated.
- `403 Forbidden` for invalid CSRF token provided - `403 Forbidden` if an invalid CSRF token is provided.
1. Track events using JavaScript/Vue API helper which calls the API above - Using the JavaScript/Vue API helper, which calls the `UsageData` API.
Example usage for an existing event already defined in [known events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/): To track events using the `UsageData` API, ensure the `usage_data_api` feature flag
is set to `default_enabled: true`. Enabled by default in GitLab 13.7 and later.
Usage Data API is behind `usage_data_api` feature flag which, as of GitLab 13.7, is Example for an existing event already defined in [known events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/):
now set to `default_enabled: true`.
```javascript ```javascript
import api from '~/api'; import api from '~/api';
......
...@@ -6,8 +6,6 @@ module Elastic ...@@ -6,8 +6,6 @@ module Elastic
included do included do
include ApplicationWorker include ApplicationWorker
sidekiq_options retry: 3
include Gitlab::ExclusiveLeaseHelpers include Gitlab::ExclusiveLeaseHelpers
# There is no onward scheduling and this cron handles work from across the # There is no onward scheduling and this cron handles work from across the
# application, so there's no useful context to add. # application, so there's no useful context to add.
......
...@@ -7,7 +7,7 @@ class ElasticIndexBulkCronWorker # rubocop:disable Scalability/IdempotentWorker ...@@ -7,7 +7,7 @@ class ElasticIndexBulkCronWorker # rubocop:disable Scalability/IdempotentWorker
urgency :throttled urgency :throttled
# Even though this worker is idempotent, until https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is done # Even though this worker is idempotent, until https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is done
# we can't use it with read-only database replicas # we can't use it with read-only database replicas
data_consistency :delayed data_consistency :sticky
private private
......
...@@ -7,7 +7,7 @@ class ElasticIndexInitialBulkCronWorker # rubocop:disable Scalability/Idempotent ...@@ -7,7 +7,7 @@ class ElasticIndexInitialBulkCronWorker # rubocop:disable Scalability/Idempotent
urgency :throttled urgency :throttled
# Even though this worker is idempotent, until https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is done # Even though this worker is idempotent, until https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is done
# we can't use it with read-only database replicas # we can't use it with read-only database replicas
data_consistency :delayed data_consistency :sticky
private private
......
--- ---
data_category: Optional
key_path: counts.license_management_jobs key_path: counts.license_management_jobs
description: Count of License Scanning jobs run description: Count of License Scanning jobs run
product_section: sec product_section: sec
...@@ -10,6 +9,7 @@ value_type: number ...@@ -10,6 +9,7 @@ value_type: number
status: data_available status: data_available
time_frame: all time_frame: all
data_source: database data_source: database
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: license_id key_path: license_id
description: The ID of the license description: The ID of the license
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: number ...@@ -10,6 +9,7 @@ value_type: number
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: historical_max_users key_path: historical_max_users
description: The peak active user count. Active is defined in UsersStatistics model. description: The peak active user count. Active is defined in UsersStatistics model.
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: number ...@@ -10,6 +9,7 @@ value_type: number
status: data_available status: data_available
time_frame: none time_frame: none
data_source: database data_source: database
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: licensee.Name key_path: licensee.Name
description: Name on the GitLab license description: Name on the GitLab license
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: string ...@@ -10,6 +9,7 @@ value_type: string
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: licensee.Email key_path: licensee.Email
description: Email on the GitLab license description: Email on the GitLab license
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: string ...@@ -10,6 +9,7 @@ value_type: string
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: licensee.Company key_path: licensee.Company
description: Company on the GitLab license description: Company on the GitLab license
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: string ...@@ -10,6 +9,7 @@ value_type: string
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: license_user_count key_path: license_user_count
description: The number of seats included in the license description: The number of seats included in the license
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: number ...@@ -10,6 +9,7 @@ value_type: number
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: license_starts_at key_path: license_starts_at
description: The date the license starts description: The date the license starts
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: string ...@@ -10,6 +9,7 @@ value_type: string
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: license_expires_at key_path: license_expires_at
description: The date the license ends description: The date the license ends
product_section: fulfillment product_section: fulfillment
...@@ -8,6 +7,7 @@ product_group: group::license ...@@ -8,6 +7,7 @@ product_group: group::license
product_category: license product_category: license
value_type: string value_type: string
status: data_available status: data_available
data_category: Subscription
time_frame: none time_frame: none
data_source: license data_source: license
distribution: distribution:
......
--- ---
data_category: Optional
key_path: license_plan key_path: license_plan
description: The plan of the GitLab license description: The plan of the GitLab license
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: string ...@@ -10,6 +9,7 @@ value_type: string
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: license_trial key_path: license_trial
description: Whether this is a trial license or not description: Whether this is a trial license or not
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: boolean ...@@ -10,6 +9,7 @@ value_type: boolean
status: data_available status: data_available
time_frame: none time_frame: none
data_source: license data_source: license
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: license_trial_ends_on key_path: license_trial_ends_on
description: Date the trial license ends on description: Date the trial license ends on
product_section: fulfillment product_section: fulfillment
...@@ -10,6 +9,7 @@ value_type: string ...@@ -10,6 +9,7 @@ value_type: string
status: data_available status: data_available
time_frame: none time_frame: none
data_source: database data_source: database
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
--- ---
data_category: Optional
key_path: recording_ee_finished_at key_path: recording_ee_finished_at
description: When the EE-specific features were computed description: When the EE-specific features were computed
product_section: growth product_section: growth
...@@ -10,6 +9,7 @@ value_type: string ...@@ -10,6 +9,7 @@ value_type: string
status: data_available status: data_available
time_frame: none time_frame: none
data_source: system data_source: system
data_category: Subscription
distribution: distribution:
- ee - ee
tier: tier:
......
...@@ -50,5 +50,5 @@ RSpec.describe ElasticIndexBulkCronWorker do ...@@ -50,5 +50,5 @@ RSpec.describe ElasticIndexBulkCronWorker do
it_behaves_like 'worker with data consistency', it_behaves_like 'worker with data consistency',
described_class, described_class,
data_consistency: :delayed data_consistency: :sticky
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ElasticIndexInitialBulkCronWorker do
it_behaves_like 'worker with data consistency',
described_class,
data_consistency: :sticky
end
...@@ -78,7 +78,7 @@ module QA ...@@ -78,7 +78,7 @@ module QA
end end
def wait_for_license_compliance_report def wait_for_license_compliance_report
has_no_text?('Loading License Compliance report', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME) has_text?('License Compliance detected', wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
end end
def approvals_required_from def approvals_required_from
......
...@@ -101,7 +101,11 @@ module QA ...@@ -101,7 +101,11 @@ module QA
@merge_request.visit! @merge_request.visit!
Page::MergeRequest::Show.perform do |show| Page::MergeRequest::Show.perform do |show|
# Give time for the runner to complete pipeline
show.has_pipeline_status?('passed')
Support::Retrier.retry_until(max_attempts: 5, sleep_interval: 5) do
show.wait_for_license_compliance_report show.wait_for_license_compliance_report
end
show.click_manage_licenses_button show.click_manage_licenses_button
end end
......
...@@ -34,6 +34,10 @@ RSpec.describe BulkImports::FileTransfer::GroupConfig do ...@@ -34,6 +34,10 @@ RSpec.describe BulkImports::FileTransfer::GroupConfig do
it 'returns a list of top level exportable relations' do it 'returns a list of top level exportable relations' do
expect(subject.portable_relations).to include('milestones', 'badges', 'boards', 'labels') expect(subject.portable_relations).to include('milestones', 'badges', 'boards', 'labels')
end end
it 'does not include skipped relations' do
expect(subject.portable_relations).not_to include('members')
end
end end
describe '#top_relation_tree' do describe '#top_relation_tree' do
......
...@@ -34,6 +34,10 @@ RSpec.describe BulkImports::FileTransfer::ProjectConfig do ...@@ -34,6 +34,10 @@ RSpec.describe BulkImports::FileTransfer::ProjectConfig do
it 'returns a list of top level exportable relations' do it 'returns a list of top level exportable relations' do
expect(subject.portable_relations).to include('issues', 'labels', 'milestones', 'merge_requests') expect(subject.portable_relations).to include('issues', 'labels', 'milestones', 'merge_requests')
end end
it 'does not include skipped relations' do
expect(subject.portable_relations).not_to include('project_members', 'group_members')
end
end end
describe '#top_relation_tree' do describe '#top_relation_tree' do
......
# frozen_string_literal: true # frozen_string_literal: true
RSpec.shared_examples 'wiki controller actions' do RSpec.shared_examples 'wiki controller actions' do
let_it_be(:user) { create(:user) }
let_it_be(:other_user) { create(:user) }
let(:container) { raise NotImplementedError } let(:container) { raise NotImplementedError }
let(:routing_params) { raise NotImplementedError } let(:routing_params) { raise NotImplementedError }
let_it_be(:user) { create(:user) }
let(:wiki) { Wiki.for_container(container, user) } let(:wiki) { Wiki.for_container(container, user) }
let(:wiki_title) { 'page title test' } let(:wiki_title) { 'page title test' }
...@@ -458,6 +459,7 @@ RSpec.shared_examples 'wiki controller actions' do ...@@ -458,6 +459,7 @@ RSpec.shared_examples 'wiki controller actions' do
describe 'DELETE #destroy' do describe 'DELETE #destroy' do
let(:id_param) { wiki_title } let(:id_param) { wiki_title }
let(:delete_user) { user }
subject(:request) do subject(:request) do
delete(:destroy, delete(:destroy,
...@@ -466,12 +468,20 @@ RSpec.shared_examples 'wiki controller actions' do ...@@ -466,12 +468,20 @@ RSpec.shared_examples 'wiki controller actions' do
)) ))
end end
before do
sign_in(delete_user)
end
context 'when page exists' do context 'when page exists' do
it 'deletes the page' do shared_examples 'deletes the page' do
specify do
expect do expect do
request request
end.to change { wiki.list_pages.size }.by(-1) end.to change { wiki.list_pages.size }.by(-1)
end end
end
it_behaves_like 'deletes the page'
context 'but page cannot be deleted' do context 'but page cannot be deleted' do
before do before do
...@@ -489,6 +499,28 @@ RSpec.shared_examples 'wiki controller actions' do ...@@ -489,6 +499,28 @@ RSpec.shared_examples 'wiki controller actions' do
expect(assigns(:error)).to eq('Could not delete wiki page') expect(assigns(:error)).to eq('Could not delete wiki page')
end end
end end
context 'when user is a developer' do
let(:delete_user) { other_user }
before do
container.add_developer(other_user)
end
it_behaves_like 'deletes the page'
end
context 'when user is a reporter' do
let(:delete_user) { other_user }
before do
container.add_reporter(other_user)
end
it 'returns 404' do
is_expected.to have_gitlab_http_status(:not_found)
end
end
end end
context 'when page does not exist' do context 'when page does not exist' do
......
...@@ -7,18 +7,34 @@ ...@@ -7,18 +7,34 @@
RSpec.shared_examples 'User deletes wiki page' do RSpec.shared_examples 'User deletes wiki page' do
include WikiHelpers include WikiHelpers
let_it_be(:developer) { create(:user) }
let(:wiki_page) { create(:wiki_page, wiki: wiki) } let(:wiki_page) { create(:wiki_page, wiki: wiki) }
before do before do
wiki.container.add_developer(developer)
sign_in(user) sign_in(user)
visit wiki_page_path(wiki, wiki_page) visit wiki_page_path(wiki, wiki_page)
end end
it 'deletes a page', :js do shared_examples 'deletes a wiki page' do
specify 'deletes a page', :js do
click_on('Edit') click_on('Edit')
click_on('Delete') click_on('Delete')
find('[data-testid="confirm_deletion_button"]').click find('[data-testid="confirm_deletion_button"]').click
expect(page).to have_content('Wiki page was successfully deleted.') expect(page).to have_content('Wiki page was successfully deleted.')
end end
end
context 'when user is the owner or maintainer' do
it_behaves_like 'deletes a wiki page'
end
context 'when user is a developer' do
let(:user) { developer }
it_behaves_like 'deletes a wiki page'
end
end end
...@@ -176,6 +176,77 @@ RSpec.describe ApplicationWorker do ...@@ -176,6 +176,77 @@ RSpec.describe ApplicationWorker do
end end
end end
describe '.data_consistency' do
using RSpec::Parameterized::TableSyntax
where(:data_consistency, :sidekiq_option_retry, :expect_error) do
:delayed | false | true
:delayed | 0 | true
:delayed | 3 | false
:delayed | nil | false
:sticky | false | false
:sticky | 0 | false
:sticky | 3 | false
:sticky | nil | false
:always | false | false
:always | 0 | false
:always | 3 | false
:always | nil | false
end
with_them do
before do
worker.sidekiq_options retry: sidekiq_option_retry unless sidekiq_option_retry.nil?
end
context "when workers data consistency is #{params['data_consistency']}" do
it "#{params['expect_error'] ? '' : 'not to '}raise an exception" do
if expect_error
expect { worker.data_consistency data_consistency }
.to raise_error("Retry support cannot be disabled if data_consistency is set to :delayed")
else
expect { worker.data_consistency data_consistency }
.not_to raise_error
end
end
end
end
end
describe '.retry' do
using RSpec::Parameterized::TableSyntax
where(:data_consistency, :sidekiq_option_retry, :expect_error) do
:delayed | false | true
:delayed | 0 | true
:delayed | 3 | false
:sticky | false | false
:sticky | 0 | false
:sticky | 3 | false
:always | false | false
:always | 0 | false
:always | 3 | false
end
with_them do
before do
worker.data_consistency(data_consistency)
end
context "when retry sidekiq option is #{params['sidekiq_option_retry']}" do
it "#{params['expect_error'] ? '' : 'not to '}raise an exception" do
if expect_error
expect { worker.sidekiq_options retry: sidekiq_option_retry }
.to raise_error("Retry support cannot be disabled if data_consistency is set to :delayed")
else
expect { worker.sidekiq_options retry: sidekiq_option_retry }
.not_to raise_error
end
end
end
end
end
describe '.perform_async' do describe '.perform_async' do
shared_examples_for 'worker utilizes load balancing capabilities' do |data_consistency| shared_examples_for 'worker utilizes load balancing capabilities' do |data_consistency|
before do before do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment