Fix broken merge train merge when target branch deleted for add to merge train when checks pass
Problem
This bug can leave a car on the train that should have been removed for merge trains using 'auto merge when checks pass' . Users can end up with MRs where the only workaround is to create a new MR. Please see: #483097 (closed) for full details around the bug.
Fix
The following discussion from !165216 (merged) should be addressed:
-
@panoskanell started a discussion: (+1 comment) Thank you @allison.browne!
I believe we need to add this functionality to
add_to_merge_train_when_checks_pass_service.rbtoo.
Implementation guide
module AutoMerge
class AddToMergeTrainWhenChecksPassService < AutoMerge::BaseService
...
def abort(merge_request, reason)
# If the merge request is already on a merge train, we need to destroy the car
# i.e. If the target branch is deleted which causes an abort with this strategy,
# after the pipeline succeeded and was added
#
if merge_request.merge_train_car
AutoMerge::MergeTrainService.new(project, current_user).abort(merge_request, reason)
# Before the pipeline checks pass and was added to the merge train
else
super do
SystemNoteService.abort_add_to_merge_train_when_checks_pass(merge_request, project, current_user, reason)
end
end
end
...
Tweaking the availability check might work as well but it's still prone to be a bit racy as this stuff happens in the background.
follow-up
We should be able to create a base class AutoMerge::MergeTrain::AddToMergeTrainService because the two SystemNoteService methods go through many layers of abstraction but the underlying implementation is actually 100% same.
module AutoMerge
module MergeTrain
class AddToMergeTrainService < AutoMerge::BaseService
...
def abort(merge_request, reason)
# If the merge request is already on a merge train, we need to destroy the car
# i.e. If the target branch is deleted which causes an abort with this strategy,
# after the pipeline succeeded and was added
#
if merge_request.merge_train_car
AutoMerge::MergeTrainService.new(project, current_user).abort(merge_request, reason)
# Before the pipeline checks pass and was added to the merge train
else
super do
SystemNoteService.abort_add_to_merge_train(merge_request, project, current_user, reason)
end
end
end
...