Fix merge train API auto_merge when checks already passed
Summary
Fixes a bug where POST /projects/:id/merge_trains/merge_requests/:iid?auto_merge=true returns 400 Bad Request when all merge preconditions are already fulfilled (pipeline passed, MR is mergeable).
Root cause
AddToMergeTrainWhenChecksPassService#availability_details correctly considers itself unavailable when there are no checks to wait for. However, MergeTrains::AddMergeRequestService was hardcoding the strategy selection without falling back to STRATEGY_MERGE_TRAIN when the "when checks pass" strategy is unavailable.
Fix
Use AutoMergeService#available_strategies to select the best available merge train strategy:
-
auto_merge: true: preferadd_to_merge_train_when_checks_pass, fall back tomerge_trainif checks already passed -
auto_merge: false: usemerge_traindirectly (unchanged behavior) - No available strategy: return error (unchanged behavior)
This mirrors how the /merge REST API handles the same scenario — falling back to an immediate action when the auto-merge strategy is unavailable but the pipeline has already succeeded.
Manual API testing (GDK)
Tested locally against a GDK instance with merge trains enabled on a project. MRs were set up with a successful pipeline and can_be_merged status, so add_to_merge_train_when_checks_pass was unavailable (no checks to wait for) and only merge_train was available.
| Test | Old Code (no fix) | New Code (with fix) |
|---|---|---|
POST /merge_trains/merge_requests/:iid?auto_merge=true |
400 Bad Request — Failed to merge
|
201 Created |
POST /merge_trains/merge_requests/:iid (no auto_merge) |
201 Created | 201 Created |
- The old code returns
400onauto_merge=truebecause it hardcodesSTRATEGY_ADD_TO_MERGE_TRAIN_WHEN_CHECKS_PASSwhich is unavailable when checks already passed. - The new code falls back to
STRATEGY_MERGE_TRAINand succeeds. - The baseline (no
auto_merge) works in both versions, confirming no regression.