From edb9c4eff65a8b6ef144ce4739f188142acda8b1 Mon Sep 17 00:00:00 2001
From: Ash McKenzie <amckenzie@gitlab.com>
Date: Sat, 2 Dec 2023 02:06:23 +0000
Subject: [PATCH] Refresh protected branch cache for group's projects

Prior to this change, group-level protected branches were not applied
after they were created or edited until a new branch had been pushed.

This change ensures we refresh the cache for all projects under the
group when a group-level protected branch is created or modified.

Fixes https://gitlab.com/gitlab-org/gitlab/-/issues/411765
---
 app/services/protected_branches/base_service.rb    | 11 +++++++++++
 .../protected_branches/create_service_spec.rb      | 14 ++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/app/services/protected_branches/base_service.rb b/app/services/protected_branches/base_service.rb
index 0ab46bf236cc..62d5e04b4995 100644
--- a/app/services/protected_branches/base_service.rb
+++ b/app/services/protected_branches/base_service.rb
@@ -18,9 +18,20 @@ def after_execute(*)
 
     def refresh_cache
       CacheService.new(@project_or_group, @current_user, @params).refresh
+      refresh_cache_for_groups_projects
     rescue StandardError => e
       Gitlab::ErrorTracking.track_exception(e)
     end
+
+    private
+
+    def refresh_cache_for_groups_projects
+      return unless @project_or_group.is_a?(Group)
+
+      @project_or_group.all_projects.find_each do |project|
+        CacheService.new(project, @current_user, @params).refresh
+      end
+    end
   end
 end
 
diff --git a/spec/services/protected_branches/create_service_spec.rb b/spec/services/protected_branches/create_service_spec.rb
index 625aa4fa3773..abfb73c147ec 100644
--- a/spec/services/protected_branches/create_service_spec.rb
+++ b/spec/services/protected_branches/create_service_spec.rb
@@ -16,6 +16,8 @@
 
     describe '#execute' do
       let(:name) { 'master' }
+      let(:group_cache_service_double) { instance_double(ProtectedBranches::CacheService) }
+      let(:project_cache_service_double) { instance_double(ProtectedBranches::CacheService) }
 
       it 'creates a new protected branch' do
         expect { service.execute }.to change(ProtectedBranch, :count).by(1)
@@ -24,8 +26,12 @@
       end
 
       it 'refreshes the cache' do
-        expect_next_instance_of(ProtectedBranches::CacheService) do |cache_service|
-          expect(cache_service).to receive(:refresh)
+        expect(ProtectedBranches::CacheService).to receive(:new).with(entity, user, params).and_return(group_cache_service_double)
+        expect(group_cache_service_double).to receive(:refresh)
+
+        if entity.is_a?(Group)
+          expect(ProtectedBranches::CacheService).to receive(:new).with(project, user, params).and_return(project_cache_service_double)
+          expect(project_cache_service_double).to receive(:refresh)
         end
 
         service.execute
@@ -58,14 +64,14 @@
 
   context 'with entity project' do
     let_it_be_with_reload(:entity) { create(:project) }
-
     let(:user) { entity.first_owner }
 
     it_behaves_like 'execute with entity'
   end
 
   context 'with entity group' do
-    let_it_be_with_reload(:entity) { create(:group) }
+    let_it_be_with_reload(:project) { create(:project, :in_group) }
+    let_it_be_with_reload(:entity) { project.group }
     let_it_be_with_reload(:user) { create(:user) }
 
     before do
-- 
GitLab