From 05fbae948bb61c3a169d60e3ac77951c5f6f23d1 Mon Sep 17 00:00:00 2001 From: Vasilii Iakliushin Date: Tue, 20 Feb 2024 10:54:48 +0100 Subject: [PATCH] Fix search by full path for forks Contributes to https://gitlab.com/gitlab-org/gitlab/-/issues/378243 **Problem** `#search` in ForkTargetsFinder does not use the full namespace path name for search. It only queries current namespace name. It prevents users from searching by the full namespace path. **Workaround** When user requests a search by the full path. We can take the last part of it and search by group's name. --- app/finders/fork_targets_finder.rb | 12 ++++++++++- .../fork_targets_finder_with_parents.yml | 9 +++++++++ spec/finders/fork_targets_finder_spec.rb | 20 ++++++++++++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 config/feature_flags/gitlab_com_derisk/fork_targets_finder_with_parents.yml diff --git a/app/finders/fork_targets_finder.rb b/app/finders/fork_targets_finder.rb index a96acd5838e662..4c40c0d7b280ca 100644 --- a/app/finders/fork_targets_finder.rb +++ b/app/finders/fork_targets_finder.rb @@ -19,7 +19,17 @@ def execute(options = {}) def by_search(items, options) return items if options[:search].blank? - items.search(options[:search]) + if Feature.enabled?(:fork_targets_finder_with_parents, user) + # Ideally, we should use `items.search(options[:search], include_parents: true)` option + # But the resulted query has a terrible performance. See issue: https://gitlab.com/gitlab-org/gitlab/-/issues/437731. + # + # As a workaround, we can fetch the group's name from the path and search by it. + search = options[:search].to_s.split('/').last + + items.search(search) + else + items.search(options[:search]) + end end def fork_targets(options) diff --git a/config/feature_flags/gitlab_com_derisk/fork_targets_finder_with_parents.yml b/config/feature_flags/gitlab_com_derisk/fork_targets_finder_with_parents.yml new file mode 100644 index 00000000000000..a3dca057dbc2f4 --- /dev/null +++ b/config/feature_flags/gitlab_com_derisk/fork_targets_finder_with_parents.yml @@ -0,0 +1,9 @@ +--- +name: fork_targets_finder_with_parents +feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/378243 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145230 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/442392 +milestone: '16.11' +group: group::source code +type: gitlab_com_derisk +default_enabled: false diff --git a/spec/finders/fork_targets_finder_spec.rb b/spec/finders/fork_targets_finder_spec.rb index 746c48a8fabe37..541ace7e8c8104 100644 --- a/spec/finders/fork_targets_finder_spec.rb +++ b/spec/finders/fork_targets_finder_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe ForkTargetsFinder do +RSpec.describe ForkTargetsFinder, feature_category: :source_code_management do subject(:finder) { described_class.new(project, user) } let_it_be(:project) { create(:project, namespace: create(:group)) } @@ -75,6 +75,24 @@ it 'filters the targets by the param' do expect(finder.execute(search: maintained_group.path)).to eq([maintained_group]) end + + context 'when searching by a full path' do + let_it_be(:subgroup) { create(:group, :nested, parent: maintained_group) } + + it 'returns a group for an exact match' do + expect(finder.execute(search: subgroup.full_path)).to eq([subgroup]) + end + + context 'when feature flag "fork_targets_finder_with_parents" is disabled' do + before do + stub_feature_flags(fork_targets_finder_with_parents: false) + end + + it 'does not return a group' do + expect(finder.execute(search: subgroup.full_path)).to eq([]) + end + end + end end end end -- GitLab