Add with_developer_access scope to Group association
What does this MR do and why?
Add with_developer_access scope to Group association
We need to be able to filter these groups by their access level for code owners.
Related to Acceptable CODEOWNERS Groups Should Inherit fro... (#288851 - closed)
This will allows us to load all groups that have been shared with the project's group or any of the group's ancestors while filtering out any guest, planner, and reporter groups which are unable to approve MRs.
References
Acceptable CODEOWNERS Groups Should Inherit fro... (#288851 - closed)
Validate locally
- Create a top-level group
Group1 - Create a sub group
Group1/Group2 - Create an external group
Group3 - Create an external group
Group4 - Within
Group1, go to members, then inviteGroup3with max role ofDeveloperandGroup4with max role ofReporter - Go to the console and find
Group.find_by_full_path('Group1/Group2') - Check that the
with_developer_accesslevel returnsGroup3but notGroup4.
You could also test the other max role settings too if you would like to be comprehensive.
Database stats
explain SELECT "namespaces"."id", "namespaces"."name", "namespaces"."path", "namespaces"."owner_id", "namespaces"."created_at", "namespaces"."updated_at", "namespaces"."type", "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"."parent_id", "namespaces"."shared_runners_minutes_limit", "namespaces"."repository_size_limit", "namespaces"."require_two_factor_authentication", "namespaces"."two_factor_grace_period", "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"."max_pages_size", "namespaces"."max_artifacts_size", "namespaces"."mentions_disabled", "namespaces"."default_branch_protection", "namespaces"."max_personal_access_token_lifetime", "namespaces"."push_rule_id", "namespaces"."shared_runners_enabled", "namespaces"."allow_descendants_override_disabled_shared_runners", "namespaces"."traversal_ids", "namespaces"."organization_id" FROM "namespaces" INNER JOIN "group_group_links" ON "namespaces"."id" = "group_group_links"."shared_with_group_id" WHERE "namespaces"."type" = 'Group' AND "group_group_links"."shared_group_id" IN (SELECT "namespaces"."id" FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 9970) AND "group_group_links"."group_access" IN (30, 40, 50)
Nested Loop Semi Join (cost=1.56..11.77 rows=1 width=370) (actual time=0.067..0.068 rows=1 loops=1)
Buffers: shared hit=20
I/O Timings: read=0.000 write=0.000
-> Nested Loop (cost=0.99..8.17 rows=1 width=378) (actual time=0.051..0.053 rows=1 loops=1)
Buffers: shared hit=15
I/O Timings: read=0.000 write=0.000
-> Index Scan using index_group_group_links_on_shared_group_and_shared_with_group on public.group_group_links (cost=0.42..4.58 rows=1 width=16) (actual time=0.030..0.030 rows=1 loops=1)
Index Cond: (group_group_links.shared_group_id = 9970)
Filter: (group_group_links.group_access = ANY ('{30,40,50}'::integer[]))
Rows Removed by Filter: 0
Buffers: shared hit=7
I/O Timings: read=0.000 write=0.000
-> Index Scan using index_namespaces_on_type_and_id on public.namespaces (cost=0.57..3.59 rows=1 width=370) (actual time=0.019..0.019 rows=1 loops=1)
Index Cond: (((namespaces.type)::text = 'Group'::text) AND (namespaces.id = group_group_links.shared_with_group_id))
Buffers: shared hit=8
I/O Timings: read=0.000 write=0.000
-> Index Only Scan using index_namespaces_on_type_and_id on public.namespaces namespaces_1 (cost=0.57..3.59 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1)
Index Cond: ((namespaces_1.type = 'Group'::text) AND (namespaces_1.id = 9970))
Heap Fetches: 0
Buffers: shared hit=5
I/O Timings: read=0.000 write=0.000
Settings: work_mem = '100MB', random_page_cost = '1.5', seq_page_cost = '4', effective_cache_size = '472585MB', jit = 'off'
Edited by Joe Woodward