Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
9d5573c70a
commit
685084aaf4
|
@ -58,7 +58,7 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp
|
|||
|
||||
def record_experiment
|
||||
subject = context.value[:namespace] || context.value[:group] || context.value[:project] || context.value[:user] || context.value[:actor]
|
||||
return unless subject.is_a?(Group) || subject.is_a?(User) || subject.is_a?(Project)
|
||||
return unless ExperimentSubject.valid_subject?(subject)
|
||||
|
||||
variant = :experimental if @variant_name != :control
|
||||
|
||||
|
|
|
@ -21,4 +21,12 @@ module GitlabScriptTagHelper
|
|||
|
||||
super
|
||||
end
|
||||
|
||||
def preload_link_tag(source, options = {})
|
||||
# Chrome requires a nonce, see https://gitlab.com/gitlab-org/gitlab/-/issues/331810#note_584964908
|
||||
# It's likely to be a browser bug, but we need to work around it anyway
|
||||
options[:nonce] = content_security_policy_nonce
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,10 +42,10 @@ class Experiment < ApplicationRecord
|
|||
end
|
||||
|
||||
def record_subject_and_variant!(subject, variant)
|
||||
subject = subject.owner if subject.is_a?(Namespace) && subject.user?
|
||||
raise 'Incompatible subject provided!' unless subject.is_a?(Group) || subject.is_a?(User) || subject.is_a?(Project)
|
||||
raise 'Incompatible subject provided!' unless ExperimentSubject.valid_subject?(subject)
|
||||
|
||||
experiment_subject = experiment_subjects.find_or_initialize_by(subject.class.name.downcase => subject)
|
||||
attr_name = subject.class.table_name.singularize.to_sym
|
||||
experiment_subject = experiment_subjects.find_or_initialize_by(attr_name => subject)
|
||||
experiment_subject.assign_attributes(variant: variant)
|
||||
# We only call save when necessary because this causes the request to stick to the primary DB
|
||||
# even when the save is a no-op
|
||||
|
|
|
@ -5,7 +5,7 @@ class ExperimentSubject < ApplicationRecord
|
|||
|
||||
belongs_to :experiment, inverse_of: :experiment_subjects
|
||||
belongs_to :user
|
||||
belongs_to :group
|
||||
belongs_to :namespace
|
||||
belongs_to :project
|
||||
|
||||
validates :experiment, presence: true
|
||||
|
@ -14,15 +14,19 @@ class ExperimentSubject < ApplicationRecord
|
|||
|
||||
enum variant: { GROUP_CONTROL => 0, GROUP_EXPERIMENTAL => 1 }
|
||||
|
||||
def self.valid_subject?(subject)
|
||||
subject.is_a?(Namespace) || subject.is_a?(User) || subject.is_a?(Project)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def must_have_one_subject_present
|
||||
if non_nil_subjects.length != 1
|
||||
errors.add(:base, s_("ExperimentSubject|Must have exactly one of User, Group, or Project."))
|
||||
errors.add(:base, s_("ExperimentSubject|Must have exactly one of User, Namespace, or Project."))
|
||||
end
|
||||
end
|
||||
|
||||
def non_nil_subjects
|
||||
@non_nil_subjects ||= [user, group, project].reject(&:blank?)
|
||||
@non_nil_subjects ||= [user, namespace, project].reject(&:blank?)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,8 @@ product_stage:
|
|||
product_group: group::monitor
|
||||
product_category: metrics
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
milestone_removed: '14.0'
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
@ -6,7 +6,8 @@ product_stage: monitor
|
|||
product_group: group::monitor
|
||||
product_category: metrics
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
milestone_removed: '14.0'
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
@ -6,7 +6,8 @@ product_stage: monitor
|
|||
product_group: group::monitor
|
||||
product_category: logging
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
milestone_removed: '14.0'
|
||||
time_frame: all
|
||||
data_source: database
|
||||
distribution:
|
||||
|
|
|
@ -6,7 +6,8 @@ product_stage:
|
|||
product_group: group::configure
|
||||
product_category: kubernetes_management
|
||||
value_type: number
|
||||
status: deprecated
|
||||
status: removed
|
||||
milestone_removed: '14.0'
|
||||
time_frame: all
|
||||
data_source:
|
||||
distribution:
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RenameExperimentSubjectsGroupIdToNamespaceId < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers::V2
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
rename_column_concurrently :experiment_subjects, :group_id, :namespace_id
|
||||
end
|
||||
|
||||
def down
|
||||
undo_rename_column_concurrently :experiment_subjects, :group_id, :namespace_id
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddPreventSharingGroupsOutsideHierarchyToNamespaceSettings < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
add_column :namespace_settings, :prevent_sharing_groups_outside_hierarchy, :boolean, null: false, default: false
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_column :namespace_settings, :prevent_sharing_groups_outside_hierarchy
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CleanUpRenameExperimentSubjectsGroupIdToNamespaceId < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers::V2
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
cleanup_concurrent_column_rename :experiment_subjects, :group_id, :namespace_id
|
||||
end
|
||||
|
||||
def down
|
||||
undo_cleanup_concurrent_column_rename :experiment_subjects, :group_id, :namespace_id
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
c0d6252fc768a431513754f7d51e61c5127f5573fefb278e7e1673dcd9e1b097
|
|
@ -0,0 +1 @@
|
|||
c07ebd06892bacc936514798d970eb58ed08b6570049d2de07f787e93b5b3316
|
|
@ -0,0 +1 @@
|
|||
56efe7709f07ffe198b4a2068c7e4b1ba8507a878cbc9ac3b1b30a334cbd83ca
|
|
@ -12761,14 +12761,14 @@ CREATE TABLE experiment_subjects (
|
|||
id bigint NOT NULL,
|
||||
experiment_id bigint NOT NULL,
|
||||
user_id bigint,
|
||||
group_id bigint,
|
||||
project_id bigint,
|
||||
variant smallint DEFAULT 0 NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
converted_at timestamp with time zone,
|
||||
context jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||
CONSTRAINT chk_has_one_subject CHECK ((num_nonnulls(user_id, group_id, project_id) = 1))
|
||||
namespace_id bigint,
|
||||
CONSTRAINT check_f6411bc4b5 CHECK ((num_nonnulls(user_id, namespace_id, project_id) = 1))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE experiment_subjects_id_seq
|
||||
|
@ -14964,6 +14964,7 @@ CREATE TABLE namespace_settings (
|
|||
delayed_project_removal boolean,
|
||||
resource_access_token_creation_allowed boolean DEFAULT true NOT NULL,
|
||||
lock_delayed_project_removal boolean DEFAULT false NOT NULL,
|
||||
prevent_sharing_groups_outside_hierarchy boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255))
|
||||
);
|
||||
|
||||
|
@ -23230,7 +23231,7 @@ CREATE INDEX index_evidences_on_release_id ON evidences USING btree (release_id)
|
|||
|
||||
CREATE INDEX index_experiment_subjects_on_experiment_id ON experiment_subjects USING btree (experiment_id);
|
||||
|
||||
CREATE INDEX index_experiment_subjects_on_group_id ON experiment_subjects USING btree (group_id);
|
||||
CREATE INDEX index_experiment_subjects_on_namespace_id ON experiment_subjects USING btree (namespace_id);
|
||||
|
||||
CREATE INDEX index_experiment_subjects_on_project_id ON experiment_subjects USING btree (project_id);
|
||||
|
||||
|
@ -25655,6 +25656,9 @@ ALTER TABLE ONLY import_export_uploads
|
|||
ALTER TABLE ONLY push_rules
|
||||
ADD CONSTRAINT fk_83b29894de FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects
|
||||
ADD CONSTRAINT fk_842649f2f5 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY merge_request_diffs
|
||||
ADD CONSTRAINT fk_8483f3258f FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
|
||||
|
||||
|
@ -25670,9 +25674,6 @@ ALTER TABLE ONLY packages_package_files
|
|||
ALTER TABLE ONLY ci_builds
|
||||
ADD CONSTRAINT fk_87f4cefcda FOREIGN KEY (upstream_pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY experiment_subjects
|
||||
ADD CONSTRAINT fk_88489af1b1 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY vulnerabilities
|
||||
ADD CONSTRAINT fk_88b4d546ef FOREIGN KEY (start_date_sourcing_milestone_id) REFERENCES milestones(id) ON DELETE SET NULL;
|
||||
|
||||
|
|
|
@ -27,14 +27,13 @@ exceptions:
|
|||
- CNA
|
||||
- CNAME
|
||||
- CORE
|
||||
- CVS
|
||||
- FREE
|
||||
- CPU
|
||||
- CRIME
|
||||
- CSRF
|
||||
- CSS
|
||||
- CSV
|
||||
- CVE
|
||||
- CVS
|
||||
- DAG
|
||||
- DAST
|
||||
- DHCP
|
||||
|
@ -43,6 +42,7 @@ exceptions:
|
|||
- DSA
|
||||
- DVCS
|
||||
- ECDSA
|
||||
- ECS
|
||||
- EFS
|
||||
- EKS
|
||||
- EOL
|
||||
|
@ -63,6 +63,7 @@ exceptions:
|
|||
- GPL
|
||||
- GUI
|
||||
- HAML
|
||||
- HDD
|
||||
- HEAD
|
||||
- HIPAA
|
||||
- HTML
|
||||
|
@ -80,6 +81,7 @@ exceptions:
|
|||
- JPEG
|
||||
- JPG
|
||||
- JSON
|
||||
- JVM
|
||||
- JWT
|
||||
- LAN
|
||||
- LDAP
|
||||
|
@ -119,9 +121,10 @@ exceptions:
|
|||
- RSA
|
||||
- RSS
|
||||
- RVM
|
||||
- SAML
|
||||
- SAAS
|
||||
- SAML
|
||||
- SAST
|
||||
- SATA
|
||||
- SCIM
|
||||
- SCP
|
||||
- SCSS
|
||||
|
|
|
@ -398,7 +398,7 @@ No recommendations are provided here at this time.
|
|||
|
||||
Snowplow tracking of identifiable users or groups is prohibited, but you can still
|
||||
determine if an experiment is successful or not. We're allowed to record the ID of
|
||||
a group, project or user in our database. Therefore, we can tell the experiment
|
||||
a namespace, project or user in our database. Therefore, we can tell the experiment
|
||||
to record their ID together with the assigned experiment variant in the
|
||||
`experiment_subjects` database table for later analysis.
|
||||
|
||||
|
|
|
@ -4122,7 +4122,7 @@ Count the total number of log views
|
|||
|
||||
Group: `group::monitor`
|
||||
|
||||
Status: `deprecated`
|
||||
Status: `removed`
|
||||
|
||||
Tiers: `free`
|
||||
|
||||
|
@ -5502,7 +5502,7 @@ Projects with Prometheus alerting enabled
|
|||
|
||||
Group: `group::monitor`
|
||||
|
||||
Status: `deprecated`
|
||||
Status: `removed`
|
||||
|
||||
Tiers: `free`
|
||||
|
||||
|
@ -15896,7 +15896,7 @@ Projects with Prometheus alerting enabled
|
|||
|
||||
Group: `group::configure`
|
||||
|
||||
Status: `deprecated`
|
||||
Status: `removed`
|
||||
|
||||
Tiers: `free`, `premium`, `ultimate`
|
||||
|
||||
|
@ -17758,7 +17758,7 @@ Projects with Prometheus alerting enabled
|
|||
|
||||
Group: `group::monitor`
|
||||
|
||||
Status: `deprecated`
|
||||
Status: `removed`
|
||||
|
||||
Tiers: `free`, `premium`, `ultimate`
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ The former Ruby-based indexer was removed in [GitLab 12.3](https://gitlab.com/gi
|
|||
First, we need to install some dependencies, then we build and install
|
||||
the indexer itself.
|
||||
|
||||
This project relies on [ICU](http://site.icu-project.org/) for text encoding,
|
||||
This project relies on [International Components for Unicode](http://site.icu-project.org/) (ICU) for text encoding,
|
||||
therefore we need to ensure the development packages for your platform are
|
||||
installed before running `make`.
|
||||
|
||||
|
@ -140,7 +140,7 @@ To install on CentOS or RHEL, run:
|
|||
sudo yum install libicu-devel
|
||||
```
|
||||
|
||||
#### Mac OSX
|
||||
#### macOS
|
||||
|
||||
To install on macOS, run:
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ When visiting a board, issues appear ordered in any list. You're able to change
|
|||
that order by dragging the issues. The changed order is saved, so that anybody who visits the same
|
||||
board later sees the reordering, with some exceptions.
|
||||
|
||||
The first time a given issue appears in any board (that is, the first time a user
|
||||
The first time an issue appears in any board (that is, the first time a user
|
||||
loads a board containing that issue), it is ordered in relation to other issues in that list.
|
||||
The order is done according to [label priority](labels.md#label-priority).
|
||||
|
||||
|
@ -222,6 +222,28 @@ This ordering also affects [issue lists](issues/sorting_issue_lists.md).
|
|||
Changing the order in an issue board changes the ordering in an issue list,
|
||||
and vice versa.
|
||||
|
||||
### GraphQL-based issue boards
|
||||
|
||||
<!-- This anchor is linked from #blocked-issues as well. -->
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285074) in GitLab 13.9.
|
||||
> - [Deployed behind a feature flag](../feature_flags.md), disabled by default.
|
||||
> - Enabled on GitLab.com.
|
||||
> - Recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-graphql-based-issue-boards). **(FREE SELF)**
|
||||
|
||||
This in-development feature might not be available for your use. There can be
|
||||
[risks when enabling features still in development](../feature_flags.md#risks-when-enabling-features-still-in-development).
|
||||
Refer to this feature's version history for more details.
|
||||
|
||||
The work-in-progress GraphQL-based boards come with these features:
|
||||
|
||||
- [Edit more issue attributes](#edit-an-issue)
|
||||
- [View blocked issues](#blocked-issues)
|
||||
|
||||
The GraphQL-based Issue Board is a work in progress.
|
||||
Learn more about the known issues in [epic 5596](https://gitlab.com/groups/gitlab-org/-/epics/5596).
|
||||
|
||||
## GitLab Enterprise features for issue boards
|
||||
|
||||
GitLab issue boards are available on the GitLab Free tier, but some
|
||||
|
@ -269,40 +291,12 @@ especially in combination with [assignee lists](#assignee-lists).
|
|||
|
||||
![issue board summed weights](img/issue_board_summed_weights_v13_6.png)
|
||||
|
||||
### Group issue boards **(PREMIUM)**
|
||||
### Group issue boards
|
||||
|
||||
Accessible at the group navigation level, a group issue board offers the same features as a project-level board.
|
||||
It can display issues from all projects in that
|
||||
group and its descendant subgroups. Similarly, you can only filter by group labels for these
|
||||
boards. When updating milestones and labels for an issue through the sidebar update mechanism, again only
|
||||
group-level objects are available.
|
||||
It can display issues from all projects that fall under the group and its descendant subgroups.
|
||||
|
||||
#### GraphQL-based sidebar for group issue boards **(PREMIUM)**
|
||||
|
||||
<!-- When the feature flag is removed, integrate this section into the above ("Group issue boards"). -->
|
||||
<!-- This anchor is linked from #blocked-issues as well. -->
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285074) in GitLab 13.9.
|
||||
> - It's [deployed behind a feature flag](../feature_flags.md), disabled by default.
|
||||
> - It's disabled on GitLab.com.
|
||||
> - It's not recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-graphql-based-sidebar-for-group-issue-boards). **(PREMIUM SELF)**
|
||||
|
||||
WARNING:
|
||||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
|
||||
The work-in-progress GraphQL-based sidebar for group issue boards brings better performance and the
|
||||
ability to edit issue titles in the issue sidebar.
|
||||
|
||||
To **edit an issue's title** in the issue sidebar:
|
||||
|
||||
1. In a group issue board, select the issue card. The issue sidebar opens on the right.
|
||||
1. Next to the issue's title, select **Edit**.
|
||||
|
||||
This is work in progress as of GitLab 13.9. Learn more about the known issues in
|
||||
[MR 51480](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51480).
|
||||
|
||||
<!-- Add this at the end of the file -->
|
||||
Users on GitLab Free can use a single group issue board.
|
||||
|
||||
### Assignee lists **(PREMIUM)**
|
||||
|
||||
|
@ -386,19 +380,6 @@ To group issues by epic in an issue board:
|
|||
|
||||
![Epics Swimlanes](img/epics_swimlanes_v13.6.png)
|
||||
|
||||
To edit an issue without leaving this view, select the issue card (not its title), and a sidebar
|
||||
appears on the right. There you can see and edit the issue's:
|
||||
|
||||
- Title
|
||||
- Assignees
|
||||
- Epic **PREMIUM**
|
||||
- Milestone
|
||||
- Time tracking value (view only)
|
||||
- Due date
|
||||
- Labels
|
||||
- Weight
|
||||
- Notifications setting
|
||||
|
||||
You can also [drag issues](#drag-issues-between-lists) to change their position and epic assignment:
|
||||
|
||||
- To reorder an issue, drag it to the new position within a list.
|
||||
|
@ -442,13 +423,13 @@ status.
|
|||
|
||||
When you hover over the blocked icon (**{issue-block}**), a detailed information popover is displayed.
|
||||
|
||||
To enable this in group issue boards, enable the [GraphQL-based sidebar](#graphql-based-sidebar-for-group-issue-boards).
|
||||
The feature is enabled by default when you use group issue boards with epic swimlanes.
|
||||
This feature is only supported when using the [GraphQL-based boards](#graphql-based-issue-boards). The feature is enabled by default regardless when you use group issue boards in epic swimlanes mode.
|
||||
|
||||
![Blocked issues](img/issue_boards_blocked_icon_v13_10.png)
|
||||
|
||||
## Actions you can take on an issue board
|
||||
|
||||
- [Edit an issue](#edit-an-issue).
|
||||
- [Create a new list](#create-a-new-list).
|
||||
- [Remove an existing list](#remove-a-list).
|
||||
- [Remove an issue from a list](#remove-an-issue-from-a-list).
|
||||
|
@ -463,6 +444,28 @@ The feature is enabled by default when you use group issue boards with epic swim
|
|||
If you're not able to do some of the things above, make sure you have the right
|
||||
[permissions](#permissions).
|
||||
|
||||
### Edit an issue
|
||||
|
||||
You can edit an issue without leaving the board view.
|
||||
To open the right sidebar, select an issue card (not its title).
|
||||
|
||||
You can edit the following issue attributes in the right sidebar:
|
||||
|
||||
- Assignees
|
||||
- [Epic](../group/epics/index.md)
|
||||
- Milestone
|
||||
- Time tracking value (view only)
|
||||
- Due date
|
||||
- Labels
|
||||
- [Weight](issues/issue_weight.md)
|
||||
- Notifications setting
|
||||
|
||||
When you use [GraphQL-based boards](#graphql-based-issue-boards), you can also edit the following issue attributes:
|
||||
|
||||
- Title
|
||||
- [Iteration](../group/iterations/index.md)
|
||||
- Confidentiality
|
||||
|
||||
### Create a new list
|
||||
|
||||
Create a new list by clicking the **Add list** dropdown button in the upper right corner of the issue board.
|
||||
|
@ -516,9 +519,8 @@ The steps depend on the scope of the list:
|
|||
|
||||
### Filter issues
|
||||
|
||||
You should be able to use the filters on top of your issue board to show only
|
||||
the results you want. It's similar to the filtering used in the issue tracker,
|
||||
as the metadata from the issues and labels is re-used in the issue board.
|
||||
You can use the filters on top of your issue board to show only
|
||||
the results you want. It's similar to the filtering used in the [issue tracker](issues/index.md).
|
||||
|
||||
You can filter by the following:
|
||||
|
||||
|
@ -532,6 +534,16 @@ You can filter by the following:
|
|||
- Release
|
||||
- Weight
|
||||
|
||||
#### Filtering issues in a group board
|
||||
|
||||
When [filtering issues](#filter-issues) in a **group** board, keep this behavior in mind:
|
||||
|
||||
- Milestones: you can filter by the milestones belonging to the group and its descendant groups.
|
||||
- Labels: you can only filter by the labels belonging to the group but not its descendant groups.
|
||||
|
||||
When you edit issues individually using the right sidebar, you can additionally select the
|
||||
milestones and labels from the **project** that the issue is from.
|
||||
|
||||
### Create workflows
|
||||
|
||||
By reordering your lists, you can create workflows. As lists in issue boards are
|
||||
|
@ -634,10 +646,14 @@ A few things to remember:
|
|||
by default. If you have more than 20 issues, start scrolling down and the next
|
||||
20 appear.
|
||||
|
||||
## Enable or disable GraphQL-based sidebar for group issue boards **(PREMIUM SELF)**
|
||||
### Enable or disable GraphQL-based issue boards **(FREE SELF)**
|
||||
|
||||
GraphQL-based sidebar for group issue boards is under development and not ready for production use.
|
||||
It is deployed behind a feature flag that is **disabled by default**.
|
||||
NOTE:
|
||||
When enabling GraphQL-based issue boards, you must also enable the
|
||||
[new add list form](#enable-or-disable-new-add-list-form).
|
||||
|
||||
GraphQL-based issue boards is not ready for production use.
|
||||
It is deployed behind a feature flag that is **disabled by default** as of GitLab 13.12.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
|
||||
can enable it.
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ module Gitlab
|
|||
'media_src' => "'self'",
|
||||
'script_src' => "'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net https://apis.google.com",
|
||||
'style_src' => "'self' 'unsafe-inline'",
|
||||
'worker_src' => "'self'",
|
||||
'worker_src' => "'self' blob: data:",
|
||||
'object_src' => "'none'",
|
||||
'report_uri' => nil
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ module Gitlab
|
|||
|
||||
allow_webpack_dev_server(settings_hash) if Rails.env.development?
|
||||
allow_cdn(settings_hash) if ENV['GITLAB_CDN_HOST'].present?
|
||||
allow_snowplow(settings_hash) if Gitlab::CurrentSettings.snowplow_enabled?
|
||||
|
||||
settings_hash
|
||||
end
|
||||
|
@ -79,6 +80,11 @@ module Gitlab
|
|||
|
||||
append_to_directive(settings_hash, 'script_src', cdn_host)
|
||||
append_to_directive(settings_hash, 'style_src', cdn_host)
|
||||
append_to_directive(settings_hash, 'font_src', cdn_host)
|
||||
end
|
||||
|
||||
def self.allow_snowplow(settings_hash)
|
||||
append_to_directive(settings_hash, 'connect_src', Gitlab::CurrentSettings.snowplow_collector_hostname)
|
||||
end
|
||||
|
||||
def self.append_to_directive(settings_hash, directive, text)
|
||||
|
|
|
@ -166,7 +166,6 @@ module Gitlab
|
|||
projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)),
|
||||
projects_with_alerts_created: distinct_count(::AlertManagement::Alert, :project_id),
|
||||
projects_with_enabled_alert_integrations: distinct_count(::AlertManagement::HttpIntegration.active, :project_id),
|
||||
projects_with_prometheus_alerts: DEPRECATED_VALUE,
|
||||
projects_with_terraform_reports: distinct_count(::Ci::JobArtifact.terraform_reports, :project_id),
|
||||
projects_with_terraform_states: distinct_count(::Terraform::State, :project_id),
|
||||
protected_branches: count(ProtectedBranch),
|
||||
|
|
|
@ -13308,7 +13308,7 @@ msgstr ""
|
|||
msgid "Experienced"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExperimentSubject|Must have exactly one of User, Group, or Project."
|
||||
msgid "ExperimentSubject|Must have exactly one of User, Namespace, or Project."
|
||||
msgstr ""
|
||||
|
||||
msgid "Expiration"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'gitlab-qa'
|
||||
gem 'activesupport', '~> 6.0.3.3' # This should stay in sync with the root's Gemfile
|
||||
gem 'activesupport', '~> 6.1.3.2' # This should stay in sync with the root's Gemfile
|
||||
gem 'allure-rspec', '~> 2.13.10'
|
||||
gem 'capybara', '~> 3.29.0'
|
||||
gem 'capybara-screenshot', '~> 1.0.23'
|
||||
|
|
|
@ -2,12 +2,12 @@ GEM
|
|||
remote: https://rubygems.org/
|
||||
specs:
|
||||
abstract_type (0.0.7)
|
||||
activesupport (6.0.3.4)
|
||||
activesupport (6.1.3.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
adamantium (0.2.0)
|
||||
ice_nine (~> 0.11.0)
|
||||
memoizable (~> 0.4.0)
|
||||
|
@ -52,7 +52,7 @@ GEM
|
|||
concord (0.1.5)
|
||||
adamantium (~> 0.2.0)
|
||||
equalizer (~> 0.0.9)
|
||||
concurrent-ruby (1.1.7)
|
||||
concurrent-ruby (1.1.8)
|
||||
descendants_tracker (0.0.4)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
diff-lcs (1.3)
|
||||
|
@ -74,7 +74,7 @@ GEM
|
|||
http-accept (1.7.0)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
i18n (1.8.5)
|
||||
i18n (1.8.10)
|
||||
concurrent-ruby (~> 1.0)
|
||||
ice_nine (0.11.2)
|
||||
jwt (2.2.2)
|
||||
|
@ -92,7 +92,7 @@ GEM
|
|||
mime-types-data (3.2020.0425)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.5.0)
|
||||
minitest (5.14.2)
|
||||
minitest (5.14.4)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
|
@ -169,8 +169,8 @@ GEM
|
|||
systemu (2.6.5)
|
||||
thread_safe (0.3.6)
|
||||
timecop (0.9.1)
|
||||
tzinfo (1.2.9)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (2.0.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
|
@ -195,7 +195,7 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activesupport (~> 6.0.3.3)
|
||||
activesupport (~> 6.1.3.2)
|
||||
airborne (~> 0.3.4)
|
||||
allure-rspec (~> 2.13.10)
|
||||
capybara (~> 3.29.0)
|
||||
|
|
|
@ -127,8 +127,8 @@ RSpec.describe ApplicationExperiment, :experiment do
|
|||
|
||||
context 'when providing a compatible context' do
|
||||
where(:context_key, :object_type) do
|
||||
:namespace | :group
|
||||
:group | :group
|
||||
:namespace | :namespace
|
||||
:group | :namespace
|
||||
:project | :project
|
||||
:user | :user
|
||||
:actor | :user
|
||||
|
|
|
@ -41,4 +41,11 @@ RSpec.describe GitlabScriptTagHelper do
|
|||
expect(helper.javascript_tag( '// ignored', type: 'application/javascript') { 'alert(1)' }.to_s).to eq tag_with_nonce_and_type
|
||||
end
|
||||
end
|
||||
|
||||
describe '#preload_link_tag' do
|
||||
it 'returns a link tag with a nonce' do
|
||||
expect(helper.preload_link_tag('https://example.com/script.js').to_s)
|
||||
.to eq "<link rel=\"preload\" href=\"https://example.com/script.js\" as=\"script\" type=\"text/javascript\" nonce=\"noncevalue\">"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@ RSpec.describe WebpackHelper do
|
|||
describe '#webpack_preload_asset_tag' do
|
||||
before do
|
||||
allow(Gitlab::Webpack::Manifest).to receive(:asset_paths).and_return([asset_path])
|
||||
allow(helper).to receive(:content_security_policy_nonce).and_return('noncevalue')
|
||||
end
|
||||
|
||||
it 'preloads the resource by default' do
|
||||
|
@ -22,7 +23,7 @@ RSpec.describe WebpackHelper do
|
|||
|
||||
output = helper.webpack_preload_asset_tag(source)
|
||||
|
||||
expect(output).to eq("<link rel=\"preload\" href=\"#{asset_path}\" as=\"script\" type=\"text/javascript\">")
|
||||
expect(output).to eq("<link rel=\"preload\" href=\"#{asset_path}\" as=\"script\" type=\"text/javascript\" nonce=\"noncevalue\">")
|
||||
end
|
||||
|
||||
it 'prefetches the resource if explicitly asked' do
|
||||
|
|
|
@ -49,6 +49,21 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
|
|||
|
||||
expect(directives['script_src']).to eq("'strict-dynamic' 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com/recaptcha/ https://www.recaptcha.net https://apis.google.com https://example.com")
|
||||
expect(directives['style_src']).to eq("'self' 'unsafe-inline' https://example.com")
|
||||
expect(directives['font_src']).to eq("'self' https://example.com")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when snowplow is configured' do
|
||||
before do
|
||||
stub_application_setting(snowplow_enabled: true)
|
||||
stub_application_setting(snowplow_collector_hostname: 'snowplow.example.com')
|
||||
end
|
||||
|
||||
it 'adds snowplow to CSP' do
|
||||
settings = described_class.default_settings_hash
|
||||
directives = settings['directives']
|
||||
|
||||
expect(directives['connect_src']).to eq("'self' snowplow.example.com")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -576,7 +576,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
|||
expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
|
||||
expect(count_data[:projects_with_tracing_enabled]).to eq(1)
|
||||
expect(count_data[:projects_with_enabled_alert_integrations]).to eq(1)
|
||||
expect(count_data[:projects_with_prometheus_alerts]).to eq(Gitlab::UsageData::DEPRECATED_VALUE)
|
||||
expect(count_data[:projects_with_terraform_reports]).to eq(2)
|
||||
expect(count_data[:projects_with_terraform_states]).to eq(2)
|
||||
expect(count_data[:projects_with_alerts_created]).to eq(1)
|
||||
|
|
|
@ -251,7 +251,7 @@ RSpec.describe Experiment do
|
|||
|
||||
context 'when an existing experiment_subject exists for the given subject' do
|
||||
let_it_be(:experiment_subject) do
|
||||
create(:experiment_subject, experiment: experiment, group: subject_to_record, user: nil, variant: :experimental)
|
||||
create(:experiment_subject, experiment: experiment, namespace: subject_to_record, user: nil, variant: :experimental)
|
||||
end
|
||||
|
||||
context 'when it belongs to the same variant' do
|
||||
|
@ -273,16 +273,16 @@ RSpec.describe Experiment do
|
|||
|
||||
describe 'providing a subject to record' do
|
||||
context 'when given a group as subject' do
|
||||
it 'saves the namespace owner as experiment_subject user' do
|
||||
expect(record_subject_and_variant!.group).to eq(subject_to_record)
|
||||
it 'saves the namespace as the experiment subject' do
|
||||
expect(record_subject_and_variant!.namespace).to eq(subject_to_record)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given a users namespace as subject' do
|
||||
let_it_be(:subject_to_record) { build(:namespace) }
|
||||
|
||||
it 'saves the namespace owner as experiment_subject user' do
|
||||
expect(record_subject_and_variant!.user).to eq(subject_to_record.owner)
|
||||
it 'saves the namespace as the experiment_subject' do
|
||||
expect(record_subject_and_variant!.namespace).to eq(subject_to_record)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ RSpec.describe ExperimentSubject, type: :model do
|
|||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:experiment) }
|
||||
it { is_expected.to belong_to(:user) }
|
||||
it { is_expected.to belong_to(:group) }
|
||||
it { is_expected.to belong_to(:namespace) }
|
||||
it { is_expected.to belong_to(:project) }
|
||||
end
|
||||
|
||||
|
@ -14,8 +14,8 @@ RSpec.describe ExperimentSubject, type: :model do
|
|||
it { is_expected.to validate_presence_of(:experiment) }
|
||||
|
||||
describe 'must_have_one_subject_present' do
|
||||
let(:experiment_subject) { build(:experiment_subject, user: nil, group: nil, project: nil) }
|
||||
let(:error_message) { 'Must have exactly one of User, Group, or Project.' }
|
||||
let(:experiment_subject) { build(:experiment_subject, user: nil, namespace: nil, project: nil) }
|
||||
let(:error_message) { 'Must have exactly one of User, Namespace, or Project.' }
|
||||
|
||||
it 'fails when no subject is present' do
|
||||
expect(experiment_subject).not_to be_valid
|
||||
|
@ -27,8 +27,8 @@ RSpec.describe ExperimentSubject, type: :model do
|
|||
expect(experiment_subject).to be_valid
|
||||
end
|
||||
|
||||
it 'passes when group subject is present' do
|
||||
experiment_subject.group = build(:group)
|
||||
it 'passes when namespace subject is present' do
|
||||
experiment_subject.namespace = build(:group)
|
||||
expect(experiment_subject).to be_valid
|
||||
end
|
||||
|
||||
|
@ -40,7 +40,7 @@ RSpec.describe ExperimentSubject, type: :model do
|
|||
it 'fails when more than one subject is present', :aggregate_failures do
|
||||
# two subjects
|
||||
experiment_subject.user = build(:user)
|
||||
experiment_subject.group = build(:group)
|
||||
experiment_subject.namespace = build(:group)
|
||||
expect(experiment_subject).not_to be_valid
|
||||
expect(experiment_subject.errors[:base]).to include(error_message)
|
||||
|
||||
|
@ -51,4 +51,22 @@ RSpec.describe ExperimentSubject, type: :model do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.valid_subject?' do
|
||||
subject(:valid_subject?) { described_class.valid_subject?(subject_class.new) }
|
||||
|
||||
context 'when passing a Group, Namespace, User or Project' do
|
||||
[Group, Namespace, User, Project].each do |subject_class|
|
||||
let(:subject_class) { subject_class }
|
||||
|
||||
it { is_expected.to be(true) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passing another object' do
|
||||
let(:subject_class) { Issue }
|
||||
|
||||
it { is_expected.to be(false) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -99,7 +99,6 @@ module UsageDataHelpers
|
|||
projects_with_repositories_enabled
|
||||
projects_with_error_tracking_enabled
|
||||
projects_with_enabled_alert_integrations
|
||||
projects_with_prometheus_alerts
|
||||
projects_with_tracing_enabled
|
||||
projects_with_expiration_policy_enabled
|
||||
projects_with_expiration_policy_disabled
|
||||
|
|
Loading…
Reference in New Issue