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: prefer add_to_merge_train_when_checks_pass, fall back to merge_train if checks already passed
  • auto_merge: false: use merge_train directly (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 RequestFailed to merge 201 Created
POST /merge_trains/merge_requests/:iid (no auto_merge) 201 Created 201 Created
  • The old code returns 400 on auto_merge=true because it hardcodes STRATEGY_ADD_TO_MERGE_TRAIN_WHEN_CHECKS_PASS which is unavailable when checks already passed.
  • The new code falls back to STRATEGY_MERGE_TRAIN and succeeds.
  • The baseline (no auto_merge) works in both versions, confirming no regression.
Edited by Marc Shaw

Merge request reports

Loading