From 51814c3088950247d1d899f34e3df5cba1b9dbc6 Mon Sep 17 00:00:00 2001 From: safwanuahmed Date: Thu, 16 Oct 2025 18:21:39 -0400 Subject: [PATCH 1/3] Transition MR to preparing state when suggestions are applied --- app/models/merge_request.rb | 2 +- app/models/suggestion.rb | 4 ++++ app/services/suggestions/apply_service.rb | 7 +++++++ lib/gitlab/suggestions/suggestion_set.rb | 4 ++++ .../gitlab/suggestions/suggestion_set_spec.rb | 6 ++++++ spec/models/merge_request_spec.rb | 11 +++++----- spec/models/suggestion_spec.rb | 20 +++++++++++++++++++ .../suggestions/apply_service_spec.rb | 10 ++++++++++ 8 files changed, 58 insertions(+), 6 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index af2175f2104e23..0c79c0edde52b5 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -260,7 +260,7 @@ def self.available_state_names state_machine :merge_status, initial: :unchecked do event :mark_as_preparing do - transition unchecked: :preparing + transition [:unchecked, :can_be_merged] => :preparing end event :mark_as_unchecked do diff --git a/app/models/suggestion.rb b/app/models/suggestion.rb index ca2ad8bf88cd71..5db5de3f95f327 100644 --- a/app/models/suggestion.rb +++ b/app/models/suggestion.rb @@ -16,6 +16,10 @@ def diff_file note.latest_diff_file end + def merge_request + note.merge_requests.first + end + def source_project noteable.source_project end diff --git a/app/services/suggestions/apply_service.rb b/app/services/suggestions/apply_service.rb index 43c178295bb012..79737854380a78 100644 --- a/app/services/suggestions/apply_service.rb +++ b/app/services/suggestions/apply_service.rb @@ -23,6 +23,7 @@ def execute def result multi_service.execute.tap do |result| update_suggestions(result) + update_associated_merge_request(result) end end @@ -36,6 +37,12 @@ def update_suggestions(result) .track_apply_suggestion_action(user: current_user, suggestions: suggestion_set.suggestions) end + def update_associated_merge_request(result) + return unless result[:status] == :success + + suggestion_set.merge_request.mark_as_preparing + end + def author authors = suggestion_set.authors diff --git a/lib/gitlab/suggestions/suggestion_set.rb b/lib/gitlab/suggestions/suggestion_set.rb index 21a5acf8afe49f..27e574241c1142 100644 --- a/lib/gitlab/suggestions/suggestion_set.rb +++ b/lib/gitlab/suggestions/suggestion_set.rb @@ -21,6 +21,10 @@ def branch first_suggestion.branch end + def merge_request + first_suggestion.merge_request + end + def valid? error_message.nil? end diff --git a/spec/lib/gitlab/suggestions/suggestion_set_spec.rb b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb index 4a822717c78863..a43f09d0bc9699 100644 --- a/spec/lib/gitlab/suggestions/suggestion_set_spec.rb +++ b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb @@ -74,6 +74,12 @@ def create_suggestion(file_path, new_line, to_content) end end + describe '#merge_request' do + it 'returns the merge_request associated with the suggestions' do + expect(suggestion_set.merge_request).to eq(merge_request) + end + end + describe '#valid?' do it 'returns true if no errors are found' do expect(suggestion_set.valid?).to be(true) diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 97764ed2bbfe60..06ff0ad8a9dae3 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -5869,14 +5869,15 @@ def transition! it_behaves_like 'transition not triggering mergeRequestMergeStatusUpdated GraphQL subscription' end - context 'when the status is checking' do - let(:merge_status) { :checking } + context 'when the status is can_be_merged' do + let(:merge_status) { :can_be_merged } - include_examples 'for an invalid state transition' + include_examples 'for a valid state transition' + it_behaves_like 'transition not triggering mergeRequestMergeStatusUpdated GraphQL subscription' end - context 'when the status is can_be_merged' do - let(:merge_status) { :can_be_merged } + context 'when the status is checking' do + let(:merge_status) { :checking } include_examples 'for an invalid state transition' end diff --git a/spec/models/suggestion_spec.rb b/spec/models/suggestion_spec.rb index 364a240821b370..61f7ea80c2777c 100644 --- a/spec/models/suggestion_spec.rb +++ b/spec/models/suggestion_spec.rb @@ -65,6 +65,26 @@ end end + describe '#merge_request' do + let(:merge_request) { create(:merge_request) } + + let!(:note) do + create( + :diff_note_on_merge_request, + project: merge_request.project, + noteable: merge_request + ) + end + + let(:suggestion) { build(:suggestion, note: note) } + + subject(:associated_merge_request) { suggestion.merge_request } + + it "returns the suggestion's merge request" do + is_expected.to eq(merge_request) + end + end + describe '#inapplicable_reason' do let(:merge_request) { create(:merge_request) } diff --git a/spec/services/suggestions/apply_service_spec.rb b/spec/services/suggestions/apply_service_spec.rb index 1f950548185b27..81dc8c2e2523e8 100644 --- a/spec/services/suggestions/apply_service_spec.rb +++ b/spec/services/suggestions/apply_service_spec.rb @@ -76,6 +76,13 @@ def apply(suggestions, custom_message = nil) expect(commit.committer_name).to eq(user.name) end + it 'transitions MR state to preparing' do + expect do + apply(suggestions) + merge_request.reload + end.to change { merge_request.merge_status }.from('can_be_merged').to('preparing') + end + it 'tracks apply suggestion event' do expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter) .to receive(:track_apply_suggestion_action) @@ -636,6 +643,9 @@ def popen(cmd, path=nil) message: "You are not allowed to push into this branch", status: :error ) + + expect(merge_request) + .not_to receive(:mark_as_preparing) end end end -- GitLab From 36740db1faeb37a3c08e147bf71d880776d4f93a Mon Sep 17 00:00:00 2001 From: safwanuahmed Date: Tue, 21 Oct 2025 11:25:27 -0400 Subject: [PATCH 2/3] Use existing notable delegation to get MR --- app/models/suggestion.rb | 4 ---- lib/gitlab/suggestions/suggestion_set.rb | 2 +- spec/models/suggestion_spec.rb | 20 -------------------- 3 files changed, 1 insertion(+), 25 deletions(-) diff --git a/app/models/suggestion.rb b/app/models/suggestion.rb index 5db5de3f95f327..ca2ad8bf88cd71 100644 --- a/app/models/suggestion.rb +++ b/app/models/suggestion.rb @@ -16,10 +16,6 @@ def diff_file note.latest_diff_file end - def merge_request - note.merge_requests.first - end - def source_project noteable.source_project end diff --git a/lib/gitlab/suggestions/suggestion_set.rb b/lib/gitlab/suggestions/suggestion_set.rb index 27e574241c1142..2e91fe4c6808e5 100644 --- a/lib/gitlab/suggestions/suggestion_set.rb +++ b/lib/gitlab/suggestions/suggestion_set.rb @@ -22,7 +22,7 @@ def branch end def merge_request - first_suggestion.merge_request + first_suggestion.noteable end def valid? diff --git a/spec/models/suggestion_spec.rb b/spec/models/suggestion_spec.rb index 61f7ea80c2777c..364a240821b370 100644 --- a/spec/models/suggestion_spec.rb +++ b/spec/models/suggestion_spec.rb @@ -65,26 +65,6 @@ end end - describe '#merge_request' do - let(:merge_request) { create(:merge_request) } - - let!(:note) do - create( - :diff_note_on_merge_request, - project: merge_request.project, - noteable: merge_request - ) - end - - let(:suggestion) { build(:suggestion, note: note) } - - subject(:associated_merge_request) { suggestion.merge_request } - - it "returns the suggestion's merge request" do - is_expected.to eq(merge_request) - end - end - describe '#inapplicable_reason' do let(:merge_request) { create(:merge_request) } -- GitLab From 25dec5c97e2a8003e00f274b6d8791225b0b1193 Mon Sep 17 00:00:00 2001 From: safwanuahmed Date: Wed, 22 Oct 2025 06:50:36 -0400 Subject: [PATCH 3/3] Update merge data model with state transitions --- app/models/merge_requests/merge_data.rb | 2 +- spec/models/merge_requests/merge_data_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/merge_requests/merge_data.rb b/app/models/merge_requests/merge_data.rb index 9d5c7a0823d174..4e5db754f85afb 100644 --- a/app/models/merge_requests/merge_data.rb +++ b/app/models/merge_requests/merge_data.rb @@ -40,7 +40,7 @@ class MergeData < ApplicationRecord state_machine :merge_status, initial: :unchecked do event :mark_as_preparing do - transition unchecked: :preparing + transition [:unchecked, :can_be_merged] => :preparing end event :mark_as_unchecked do diff --git a/spec/models/merge_requests/merge_data_spec.rb b/spec/models/merge_requests/merge_data_spec.rb index 7f1af1544ff419..f22e2bb4119392 100644 --- a/spec/models/merge_requests/merge_data_spec.rb +++ b/spec/models/merge_requests/merge_data_spec.rb @@ -75,7 +75,7 @@ def transition! context 'when the status is can_be_merged' do let(:merge_status) { :can_be_merged } - include_examples 'for an invalid state transition' + include_examples 'for a valid state transition' end context 'when the status is cannot_be_merged_recheck' do -- GitLab