Reuse computed mergeability checks for detailed merge status

Summary

Stacked on !255820 (merged) (its merge target).

Before

flowchart LR
  Q["One request asking for<br/>headline status + checks list"]
  Q --> D["Headline status<br/><small>its own check run</small>"]
  Q --> C["Checks list<br/><small>its own check run</small>"]

Working out whether an MR can be merged means database queries and Gitaly calls; the headline status and the checks list each did that work independently, so a request asking for both did it twice, and the two answers could describe different moments. After !255820 (merged) the widget's realtime update asks for both on every merge status change, so this applies to every such push.

After

flowchart LR
  Q["One request asking for<br/>headline status + checks list"]
  Q --> R["One check run"]
  R --> D[Headline status]
  R --> C[Checks list]

Now both come from one run, so the result no longer depends on the order the fields appear in the query. Callers that only need the headline status keep their cheaper early-exit path, untouched.

Gains

Per request asking for both Before After
Merge check runs 2 1
Headline status and checks list can disagree Yes No
Requests asking only for the headline status (REST, webhooks, widget poll) fast path fast path, unchanged

Honest size: a modest backend saving (one check run per push per viewer); the main value is that the two answers are always consistent. No status values change, and the existing specs run every scenario through both paths to prove it.

Reproduction steps

  1. Open a merge request whose pipeline is still running, or one blocked on approvals.
  2. Expand the merge checks list in the widget.
  3. Push a commit.
  4. The headline state and the listed checks stay consistent with each other as the widget updates.

🤖 Generated with Claude Code

Edited by Stanislav Lashmanov

Merge request reports

Loading
Loading