From 9c7202b7a6ee43905bad9e4a13ad51c29217a7fa Mon Sep 17 00:00:00 2001 From: GitLab Housekeeping Bot Date: Mon, 1 Sep 2025 09:43:13 +0000 Subject: [PATCH] Delete the `pipeline_delete_gitaly_refs_in_batches` feature flag This feature flag was introduced in 16.3, which is more than 12 milestones ago. As part of our process we want to ensure [feature flags don't stay too long in the codebase](https://docs.gitlab.com/ee/development/feature_flags/#types-of-feature-flags). Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/416969
Remaining mentions of the feature flag (click to expand) ``` doc/user/project/repository/monorepos/troubleshooting.md 95:> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/416969) in GitLab 18.5. Feature flag `pipeline_delete_gitaly_refs_in_batches` removed. ```
**Currently the feature flag is `disabled` on production** It is possible that this MR will still need some changes to remove references to the feature flag in the code. At the moment the `gitlab-housekeeper` is not always capable of removing all references so you must check the diff and pipeline failures to confirm if there are any issues. It is the responsibility of ~"group::gitaly" to push those changes to this branch. **Note:** If you do not want to remove this feature flag at this time, you can add an `intended_to_rollout_by_date` attribute in the feature flag YAML file to prevent automated removal. ## TODO for the reviewers before merging this MR - [ ] See the status of the rollout by checking https://gitlab.com/gitlab-org/gitlab/-/issues/416969, https://gitlab.com/gitlab-com/gl-infra/feature-flag-log/-/issues/?search=pipeline_delete_gitaly_refs_in_batches&sort=created_date&state=all&label_name%5B%5D=host%3A%3Agitlab.com - [ ] Verify the feature flag status via chatops by running `/chatops run feature get pipeline_delete_gitaly_refs_in_batches`. - [ ] [Search for references to `PipelineDeleteGitalyRefsInBatches` in frontend part of code](https://gitlab.com/search?project_id=278964&scope=blobs&search=PipelineDeleteGitalyRefsInBatches®ex=false) - [ ] [Search for references to `pipeline_delete_gitaly_refs_in_batches` in code](https://gitlab.com/search?project_id=278964&scope=blobs&search=pipeline_delete_gitaly_refs_in_batches®ex=false) - [ ] Check if we need to remove any Gem or other related code by looking at the changes in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125333 This change was generated by [gitlab-housekeeper](https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/gitlab-housekeeper) in [CI](https://gitlab.com/gitlab-org/quality/engineering-productivity/team/-/jobs/11202603532) using the `Keeps::DeleteOldFeatureFlags` keep. To provide feedback on your experience with `gitlab-housekeeper` please create an issue with the label ~"GitLab Housekeeper" and consider pinging the author of this keep. Changelog: removed --- .../pipelines/clear_persistent_ref_service.rb | 4 +- ...pipeline_delete_gitaly_refs_in_batches.yml | 8 ---- .../repository/monorepos/troubleshooting.md | 3 +- spec/models/ci/persistent_ref_spec.rb | 28 +++++------ spec/models/ci/pipeline_spec.rb | 33 +++---------- .../clear_persistent_ref_service_spec.rb | 47 ++++++++----------- 6 files changed, 40 insertions(+), 83 deletions(-) delete mode 100644 config/feature_flags/development/pipeline_delete_gitaly_refs_in_batches.yml diff --git a/app/services/ci/pipelines/clear_persistent_ref_service.rb b/app/services/ci/pipelines/clear_persistent_ref_service.rb index a3980d5905590c..c2e4928e59154e 100644 --- a/app/services/ci/pipelines/clear_persistent_ref_service.rb +++ b/app/services/ci/pipelines/clear_persistent_ref_service.rb @@ -6,9 +6,7 @@ class ClearPersistentRefService < CreatePersistentRefService def execute Rails.cache.delete(pipeline_persistent_ref_cache_key) - if Feature.enabled?(:pipeline_delete_gitaly_refs_in_batches, pipeline.project) - pipeline.persistent_ref.async_delete - elsif Feature.enabled?(:pipeline_cleanup_ref_worker_async, pipeline.project) + if Feature.enabled?(:pipeline_cleanup_ref_worker_async, pipeline.project) ::Ci::PipelineCleanupRefWorker.perform_async(pipeline.id) else pipeline.persistent_ref.delete diff --git a/config/feature_flags/development/pipeline_delete_gitaly_refs_in_batches.yml b/config/feature_flags/development/pipeline_delete_gitaly_refs_in_batches.yml deleted file mode 100644 index 66e23fa424a339..00000000000000 --- a/config/feature_flags/development/pipeline_delete_gitaly_refs_in_batches.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: pipeline_delete_gitaly_refs_in_batches -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125333 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/416969 -milestone: '16.3' -type: development -group: group::gitaly -default_enabled: false diff --git a/doc/user/project/repository/monorepos/troubleshooting.md b/doc/user/project/repository/monorepos/troubleshooting.md index 769a6094caa44f..763d6ac492dccf 100644 --- a/doc/user/project/repository/monorepos/troubleshooting.md +++ b/doc/user/project/repository/monorepos/troubleshooting.md @@ -90,8 +90,9 @@ These feature flags do not need downtime to enable. - `merge_request_cleanup_ref_worker_async` - `pipeline_cleanup_ref_worker_async` -- `pipeline_delete_gitaly_refs_in_batches` - `merge_request_delete_gitaly_refs_in_batches` +> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/416969) in GitLab 18.5. Feature flag `pipeline_delete_gitaly_refs_in_batches` removed. + [Epic 4220](https://gitlab.com/groups/gitlab-org/-/epics/4220) proposes to add RefTable support in GitLab, which is considered a long-term solution. diff --git a/spec/models/ci/persistent_ref_spec.rb b/spec/models/ci/persistent_ref_spec.rb index 9b3f9a8e094b99..edfc76376c0331 100644 --- a/spec/models/ci/persistent_ref_spec.rb +++ b/spec/models/ci/persistent_ref_spec.rb @@ -11,32 +11,26 @@ .by(1) end - context 'when pipeline_delete_gitaly_refs_in_batches is disabled' do + it 'cleans up persistent refs after pipeline finished' do + pipeline = create(:ci_pipeline, :running) + + expect(Ci::PipelineCleanupRefWorker).to receive(:perform_async).with(pipeline.id) + + pipeline.succeed! + end + + context 'when pipeline_cleanup_ref_worker_async is disabled' do before do - stub_feature_flags(pipeline_delete_gitaly_refs_in_batches: false) + stub_feature_flags(pipeline_cleanup_ref_worker_async: false) end it 'cleans up persistent refs after pipeline finished' do pipeline = create(:ci_pipeline, :running) - expect(Ci::PipelineCleanupRefWorker).to receive(:perform_async).with(pipeline.id) + expect(pipeline.persistent_ref).to receive(:delete).once pipeline.succeed! end - - context 'when pipeline_cleanup_ref_worker_async is disabled' do - before do - stub_feature_flags(pipeline_cleanup_ref_worker_async: false) - end - - it 'cleans up persistent refs after pipeline finished' do - pipeline = create(:ci_pipeline, :running) - - expect(pipeline.persistent_ref).to receive(:delete).once - - pipeline.succeed! - end - end end describe '#exist?' do diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 61d7ec4bad0f54..6b0015c6b04992 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -1903,40 +1903,19 @@ def create_build(name, status) pipeline.public_send(action) end - context 'when pipeline_delete_gitaly_refs_in_batches is disabled' do + context 'when pipeline_cleanup_ref_worker_async is disabled' do before do - stub_feature_flags(pipeline_delete_gitaly_refs_in_batches: false) + stub_feature_flags(pipeline_cleanup_ref_worker_async: false) end - it 'deletes a persistent ref asynchronously via ::Ci::PipelineCleanupRefWorker', :sidekiq_inline do - expect(pipeline.persistent_ref).not_to receive(:delete_refs) + it 'deletes a persistent ref synchronously' do + expect(Ci::PipelineCleanupRefWorker).not_to receive(:perform_async).with(pipeline.id) - expect(Ci::PipelineCleanupRefWorker).to receive(:perform_async) - .with(pipeline.id).and_call_original - - expect_next_instance_of(Ci::PersistentRef) do |persistent_ref| - expect(persistent_ref).to receive(:delete_refs) - .with("refs/#{Repository::REF_PIPELINES}/#{pipeline.id}").once - end + expect(pipeline.persistent_ref).to receive(:delete_refs).once + .with("refs/#{Repository::REF_PIPELINES}/#{pipeline.id}") pipeline.public_send(action) end - - context 'when pipeline_cleanup_ref_worker_async is disabled' do - before do - stub_feature_flags(pipeline_delete_gitaly_refs_in_batches: false) - stub_feature_flags(pipeline_cleanup_ref_worker_async: false) - end - - it 'deletes a persistent ref synchronously' do - expect(Ci::PipelineCleanupRefWorker).not_to receive(:perform_async).with(pipeline.id) - - expect(pipeline.persistent_ref).to receive(:delete_refs).once - .with("refs/#{Repository::REF_PIPELINES}/#{pipeline.id}") - - pipeline.public_send(action) - end - end end end end diff --git a/spec/services/ci/pipelines/clear_persistent_ref_service_spec.rb b/spec/services/ci/pipelines/clear_persistent_ref_service_spec.rb index 8216e39f9eff23..7411c178c838ad 100644 --- a/spec/services/ci/pipelines/clear_persistent_ref_service_spec.rb +++ b/spec/services/ci/pipelines/clear_persistent_ref_service_spec.rb @@ -20,41 +20,34 @@ .to change { Rails.cache.read(service.send(:pipeline_persistent_ref_cache_key)) }.from(true).to(nil) end - context 'when pipeline_delete_gitaly_refs_in_batches is disabled' do - before do - stub_feature_flags(pipeline_delete_gitaly_refs_in_batches: false) - end + it 'deletes a persistent ref asynchronously via ::Ci::PipelineCleanupRefWorker', :sidekiq_inline do + expect(pipeline.persistent_ref).not_to receive(:delete_refs) - it 'deletes a persistent ref asynchronously via ::Ci::PipelineCleanupRefWorker', :sidekiq_inline do - expect(pipeline.persistent_ref).not_to receive(:delete_refs) + expect(Ci::PipelineCleanupRefWorker).to receive(:perform_async) + .with(pipeline.id).and_call_original - expect(Ci::PipelineCleanupRefWorker).to receive(:perform_async) - .with(pipeline.id).and_call_original + expect_next_instance_of(Ci::PersistentRef) do |persistent_ref| + expect(persistent_ref).to receive(:delete_refs) + .with("refs/#{Repository::REF_PIPELINES}/#{pipeline.id}").once + end - expect_next_instance_of(Ci::PersistentRef) do |persistent_ref| - expect(persistent_ref).to receive(:delete_refs) - .with("refs/#{Repository::REF_PIPELINES}/#{pipeline.id}").once - end + expect { service.execute } + .to change { Rails.cache.read(service.send(:pipeline_persistent_ref_cache_key)) }.from(true).to(nil) + end - expect { service.execute } - .to change { Rails.cache.read(service.send(:pipeline_persistent_ref_cache_key)) }.from(true).to(nil) + context 'when pipeline_cleanup_ref_worker_async is disabled' do + before do + stub_feature_flags(pipeline_cleanup_ref_worker_async: false) end - context 'when pipeline_cleanup_ref_worker_async is disabled' do - before do - stub_feature_flags(pipeline_delete_gitaly_refs_in_batches: false) - stub_feature_flags(pipeline_cleanup_ref_worker_async: false) - end + it 'deletes a persistent ref synchronously' do + expect(Ci::PipelineCleanupRefWorker).not_to receive(:perform_async).with(pipeline.id) - it 'deletes a persistent ref synchronously' do - expect(Ci::PipelineCleanupRefWorker).not_to receive(:perform_async).with(pipeline.id) + expect(pipeline.persistent_ref).to receive(:delete_refs).once + .with("refs/#{Repository::REF_PIPELINES}/#{pipeline.id}") - expect(pipeline.persistent_ref).to receive(:delete_refs).once - .with("refs/#{Repository::REF_PIPELINES}/#{pipeline.id}") - - expect { service.execute } - .to change { Rails.cache.read(service.send(:pipeline_persistent_ref_cache_key)) }.from(true).to(nil) - end + expect { service.execute } + .to change { Rails.cache.read(service.send(:pipeline_persistent_ref_cache_key)) }.from(true).to(nil) end end end -- GitLab