Resolve "Prevent bypassing the merge trains"
What does this MR do and why?
This is the foundation MR for enforcing merge trains
(#597962). It introduces a new
project-level setting, merge_train_enforcement, that will later control
whether direct merges (via the UI "Merge immediately" option and the REST
/merge endpoint) are allowed to bypass the merge train.
The setting is an enum with three levels:
| Value | Meaning |
|---|---|
allow_bypass (default) |
Users with permission to merge can bypass the merge train through the UI or API. Existing behaviour — no change. |
enforce_for_all_users |
All merge requests must go through the merge train. The train cannot be bypassed. |
enforce_with_owner_override |
All merge requests must go through the merge train; Owners and administrators can still bypass it for individual merge requests. |
Scope of this MR: the setting only — column, model enum, GraphQL + REST
read/write surface, and the project Settings > Merge requests UI. It is
inert: selecting a value persists it but changes no behaviour yet. The
actual enforcement (UI hiding, REST 405, GraphQL guard) ships in follow-up
MRs.
Everything is gated behind the merge_train_enforcement feature flag
(type wip, default off) and requires the merge_trains licensed feature, so
there is no impact on any project until the feature is complete and rolled out.
What's included
- Migration adding
merge_train_enforcement(smallint, default0) toproject_ci_cd_settings ProjectCiCdSettingenum + delegation onProject- GraphQL:
MergeTrainEnforcementenum type, field onProjectCiCdSetting, and mutation argument (feature-flag gated) - REST: project create/update param + entity exposure (licensed-feature gated)
- Settings UI: radio group under "Merge options" (feature-flag gated)
- Specs for all of the above
References
Screenshots or screen recordings
| Before | After |
|---|---|
| No "Merge train enforcement" option | Radio group under Merge options with the three levels; Allow bypass selected by default. |
How to set up and validate locally
Note: GDK in SaaS-simulation mode evaluates licensed features by namespace plan, not the global license. The project's group needs a Premium/Ultimate plan for the merge-trains section to appear.
- Enable the feature flag:
Feature.enable(:merge_train_enforcement) - Ensure merge trains are available for a project (Ultimate/Premium namespace, CI/CD enabled).
- Visit Settings > Merge requests > Merge options — the Merge train enforcement radio group appears, defaulting to
Allow bypass. - Select a value, save, and reload — the choice persists.
- Confirm it is also readable/writable via GraphQL (
ProjectCiCdSetting.mergeTrainEnforcement) and REST (merge_train_enforcementon the project endpoint).
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.