Create new group value stream
What does this MR do?
Solves #222337 (closed)
With this MR we will be able to create multiple value streams for a group (till now only one value stream per group possible).
The are changes in the relation: from group -> group stage to group -> group value stream -> group stage
We are supporting "old" route: /groups/gitlab-org/-/analytics/value_stream_analytics/stages
stays for now for all stages of a group.
As well as new routes: /groups/gitlab-org/-/analytics/value_stream_analytics/value_streams
for value streams and /groups/gitlab-org/-/analytics/value_stream_analytics/value_streams/[value_stream_id]/stages
for stages of specific value stream.
For Database review:
- CreateAnalyticsCycleAnalyticsGroupValueStreams
== 20200624142107 CreateAnalyticsCycleAnalyticsGroupValueStreams: migrating ===
-- table_exists?(:analytics_cycle_analytics_group_value_streams)
-> 0.0006s
-- create_table(:analytics_cycle_analytics_group_value_streams)
-> 0.0082s
-- add_index(:analytics_cycle_analytics_group_value_streams, [:group_id, :name], {:unique=>true, :name=>"index_analytics_ca_group_value_streams_on_group_id_and_name"})
-> 0.0020s
-- transaction_open?()
-> 0.0000s
-- execute("ALTER TABLE analytics_cycle_analytics_group_value_streams\nADD CONSTRAINT check_bc1ed5f1f7\nCHECK ( char_length(name) <= 255 )\nNOT VALID;\n")
-> 0.0003s
-- execute("ALTER TABLE analytics_cycle_analytics_group_value_streams VALIDATE CONSTRAINT check_bc1ed5f1f7;")
-> 0.0004s
== 20200624142107 CreateAnalyticsCycleAnalyticsGroupValueStreams: migrated (0.0153s)
gitlab:create-new-value-stream+$ rails db:rollback ~/gitlab/gitlab-development-kit/gitlab
== 20200624142107 CreateAnalyticsCycleAnalyticsGroupValueStreams: reverting ===
-- drop_table(:analytics_cycle_analytics_group_value_streams)
-> 0.0017s
== 20200624142107 CreateAnalyticsCycleAnalyticsGroupValueStreams: reverted (0.0018s)
- AddGroupValueStreamToCycleAnalyticsGroupStages
gitlab:create-new-value-stream+?$ rails db:migrate VERSION=20200624142207 ~/gitlab/gitlab-development-kit/gitlab
== 20200624142207 AddGroupValueStreamToCycleAnalyticsGroupStages: migrating ===
-- add_column(:analytics_cycle_analytics_group_stages, :group_value_stream_id, :bigint)
-> 0.0008s
== 20200624142207 AddGroupValueStreamToCycleAnalyticsGroupStages: migrated (0.0065s)
== 20200624142207 AddGroupValueStreamToCycleAnalyticsGroupStages: reverting ===
-- remove_column(:analytics_cycle_analytics_group_stages, :group_value_stream_id)
-> 0.0009s
== 20200624142207 AddGroupValueStreamToCycleAnalyticsGroupStages: reverted (0.0072s)
- AddNotValidForeignKeyToCycleAnalyticsGroupStages
== 20200701064756 AddNotValidForeignKeyToCycleAnalyticsGroupStages: migrating =
-- transaction_open?()
-> 0.0000s
-- index_exists?(:analytics_cycle_analytics_group_stages, :group_value_stream_id, {:name=>"index_analytics_ca_group_stages_on_value_stream_id", :algorithm=>:concurrently})
-> 0.0018s
-- add_index(:analytics_cycle_analytics_group_stages, :group_value_stream_id, {:name=>"index_analytics_ca_group_stages_on_value_stream_id", :algorithm=>:concurrently})
-> 0.0020s
-- add_foreign_key(:analytics_cycle_analytics_group_stages, :analytics_cycle_analytics_group_value_streams, {:column=>:group_value_stream_id, :name=>"fk_analytics_cycle_analytics_group_stages_group_value_stream_id", :on_delete=>:cascade, :validate=>false})
-> 0.0007s
== 20200701064756 AddNotValidForeignKeyToCycleAnalyticsGroupStages: migrated (0.0049s)
gitlab:create-new-value-stream+?$ rails db:rollback ~/gitlab/gitlab-development-kit/gitlab
== 20200701064756 AddNotValidForeignKeyToCycleAnalyticsGroupStages: reverting =
-- foreign_keys(:analytics_cycle_analytics_group_stages)
-> 0.0030s
-- remove_foreign_key(:analytics_cycle_analytics_group_stages, {:column=>:group_value_stream_id, :name=>"fk_analytics_cycle_analytics_group_stages_group_value_stream_id"})
-> 0.0030s
-- transaction_open?()
-> 0.0000s
-- index_exists?(:analytics_cycle_analytics_group_stages, :group_value_stream_id, {:algorithm=>:concurrently})
-> 0.0027s
-- remove_index(:analytics_cycle_analytics_group_stages, {:algorithm=>:concurrently, :column=>:group_value_stream_id})
-> 0.0061s
== 20200701064756 AddNotValidForeignKeyToCycleAnalyticsGroupStages: reverted (0.0153s)
- AddDefaultValueStreamToGroupsWithGroupStages
== 20200701070435 AddDefaultValueStreamToGroupsWithGroupStages: migrating =====
SELECT DISTINCT "namespaces".* FROM "namespaces" INNER JOIN "analytics_cycle_analytics_group_stages" ON "analytics_cycle_analytics_group_stages"."group_id" = "namespaces"."id" WHERE "namespaces"."type" = 'Group'
-- change_column_null(:analytics_cycle_analytics_group_stages, :group_id, true)
-> 0.0007s
== 20200701070435 AddDefaultValueStreamToGroupsWithGroupStages: migrated (0.1284s)
== 20200701070435 AddDefaultValueStreamToGroupsWithGroupStages: reverting =====
-- change_column_null(:analytics_cycle_analytics_group_stages, :group_id, false)
-> 0.0006s
SELECT "analytics_cycle_analytics_group_value_streams".* FROM "analytics_cycle_analytics_group_value_streams" WHERE "analytics_cycle_analytics_group_value_streams"."name" = 'default'
== 20200701070435 AddDefaultValueStreamToGroupsWithGroupStages: reverted (0.0299s)
- ValidateForeignKeyOnCycleAnalyticsGroupStages
gitlab:create-new-value-stream+$ rails db:migrate ~/gitlab/gitlab-development-kit/gitlab
== 20200701091253 ValidateForeignKeyOnCycleAnalyticsGroupStages: migrating ====
-- foreign_keys(:analytics_cycle_analytics_group_stages)
-> 0.0029s
-- execute("ALTER TABLE analytics_cycle_analytics_group_stages VALIDATE CONSTRAINT fk_analytics_cycle_analytics_group_stages_group_value_stream_id;")
-> 0.0057s
== 20200701091253 ValidateForeignKeyOnCycleAnalyticsGroupStages: migrated (0.0088s)
gitlab:create-new-value-stream+$ rails db:rollback ~/gitlab/gitlab-development-kit/gitlab
== 20200701091253 ValidateForeignKeyOnCycleAnalyticsGroupStages: reverting ====
-- foreign_keys(:analytics_cycle_analytics_group_stages)
-> 0.0031s
-- remove_foreign_key(:analytics_cycle_analytics_group_stages, {:column=>:group_value_stream_id, :name=>"fk_analytics_cycle_analytics_group_stages_group_value_stream_id"})
-> 0.0025s
-- add_foreign_key(:analytics_cycle_analytics_group_stages, :analytics_cycle_analytics_group_value_streams, {:column=>:group_value_stream_id, :name=>"fk_analytics_cycle_analytics_group_stages_group_value_stream_id", :on_delete=>:cascade, :validate=>false})
-> 0.0008s
== 20200701091253 ValidateForeignKeyOnCycleAnalyticsGroupStages: reverted (0.0065s)
Queries:
SELECT DISTINCT
"namespaces".*
FROM
"namespaces"
INNER JOIN "analytics_cycle_analytics_group_stages" ON "analytics_cycle_analytics_group_stages"."group_id" = "namespaces"."id"
WHERE
"namespaces"."type" = 'Group'
Plan:
Unique (cost=2014.89..2028.41 rows=115 width=331) (actual time=442.228..443.709 rows=68 loops=1)
Buffers: shared hit=2218 read=197 dirtied=3
I/O Timings: read=418.781
-> Sort (cost=2014.89..2015.18 rows=115 width=331) (actual time=442.224..442.302 rows=588 loops=1)
Sort Key: namespaces.id, namespaces.name, namespaces.path, namespaces.owner_id, namespaces.created_at, namespaces.updated_at, namespaces.description, namespaces.avatar, namespaces.membership_lock, namespaces.share_with_group_lock, namespaces.visibility_level, namespaces.request_access_enabled, namespaces.ldap_sync_status, namespaces.ldap_sync_error, namespaces.ldap_sync_last_update_at, namespaces.ldap_sync_last_successful_update_at, namespaces.ldap_sync_last_sync_at, namespaces.lfs_enabled, namespaces.description_html, namespaces.parent_id, namespaces.shared_runners_minutes_limit, namespaces.repository_size_limit, namespaces.require_two_factor_authentication, namespaces.two_factor_grace_period, namespaces.cached_markdown_version, namespaces.project_creation_level, namespaces.runners_token, namespaces.file_template_project_id, namespaces.saml_discovery_token, namespaces.runners_token_encrypted, namespaces.custom_project_templates_group_id, namespaces.auto_devops_enabled, namespaces.extra_shared_runners_minutes_limit, namespaces.last_ci_minutes_notification_at, namespaces.last_ci_minutes_usage_notification_level, namespaces.subgroup_creation_level, namespaces.emails_disabled, namespaces.max_pages_size, namespaces.max_artifacts_size, namespaces.mentions_disabled, namespaces.default_branch_protection, namespaces.unlock_membership_to_ldap, namespaces.max_personal_access_token_lifetime, namespaces.push_rule_id, namespaces.shared_runners_enabled, namespaces.allow_descendants_override_disabled_shared_runners
Sort Method: quicksort Memory: 233kB
Buffers: shared hit=2218 read=197 dirtied=3
I/O Timings: read=418.781
-> Nested Loop (cost=0.71..2010.96 rows=115 width=331) (actual time=9.547..437.218 rows=588 loops=1)
Buffers: shared hit=2195 read=197 dirtied=3
I/O Timings: read=418.781
-> Index Only Scan using index_analytics_ca_group_stages_on_group_id on public.analytics_cycle_analytics_group_stages (cost=0.28..16.46 rows=579 width=8) (actual time=2.834..18.825 rows=588 loops=1)
Heap Fetches: 179
Buffers: shared hit=29 read=8 dirtied=2
I/O Timings: read=9.890
-> Index Scan using namespaces_pkey on public.namespaces (cost=0.43..3.44 rows=1 width=331) (actual time=0.709..0.709 rows=1 loops=588)
Index Cond: (namespaces.id = analytics_cycle_analytics_group_stages.group_id)
Filter: ((namespaces.type)::text = 'Group'::text)
Rows Removed by Filter: 0
Buffers: shared hit=2166 read=189 dirtied=1
I/O Timings: read=408.891
Summary:
Time: 444.749 ms
- planning: 0.817 ms
- execution: 443.932 ms
- I/O read: 418.781 ms
- I/O write: 0.000 ms
Shared buffers:
- hits: 2218 (~17.30 MiB) from the buffer pool
- reads: 197 (~1.50 MiB) from the OS file cache, including disk I/O
- dirtied: 3 (~24.00 KiB)
- writes: 0
SELECT
"analytics_cycle_analytics_group_value_streams".*
FROM
"analytics_cycle_analytics_group_value_streams"
WHERE
"analytics_cycle_analytics_group_value_streams"."name" = 'default'
Plan - not possible to run in #database-lab channel:
ERROR: failed to run explain without execution: ERROR: relation "analytics_cycle_analytics_group_value_streams" does not exist (SQLSTATE 42P01)
Screenshots
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry -
Documentation (if required) -
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. -
Tested in all supported browsers -
Informed Infrastructure department of a default or new setting change, if applicable per definition of done
Security
If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:
-
Label as security and @ mention @gitlab-com/gl-security/appsec
-
The MR includes necessary changes to maintain consistency between UI, API, email, or other methods -
Security reports checked/validated by a reviewer from the AppSec team