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, default 0) to project_ci_cd_settings
  • ProjectCiCdSetting enum + delegation on Project
  • GraphQL: MergeTrainEnforcement enum type, field on ProjectCiCdSetting, 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.

  1. Enable the feature flag:
    Feature.enable(:merge_train_enforcement)
  2. Ensure merge trains are available for a project (Ultimate/Premium namespace, CI/CD enabled).
  3. Visit Settings > Merge requests > Merge options — the Merge train enforcement radio group appears, defaulting to Allow bypass.
  4. Select a value, save, and reload — the choice persists.
  5. Confirm it is also readable/writable via GraphQL (ProjectCiCdSetting.mergeTrainEnforcement) and REST (merge_train_enforcement on the project endpoint).

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Edited by Daniel Prause

Merge request reports

Loading