Skip to content

A scripted merge train for the Zephyr main tree #117117

Description

@nashif

Problem Description

The merge list already decides which pull requests are mergeable: it evaluates multiple gates per PR (conflict-free, assignee approval, minimum review window, 2 approvals, ...) and labels the result ready, waiting, or blocked. What happens next is still manual. A release engineer opens the page, scans roughly 20-40 ready rows, and for each ready PR opens GitHub, re-checks the gates by eye, and presses Rebase and merge. On a typical day that is 20–30 PRs against main at least 3-4 times plus a handful of backports.

Few things are wrong with this beyond how tedious this is:

  • Every PR is tested alone. PR CI runs against the PR's own merge with main at the time it was pushed. Two ready PRs that each pass can still break the tree together, and that breakage is discovered only after both are merged, on main, by everyone.
  • The process is not reproducible. There is no record of what the list said when the merges happened, what order they went in, or why a PR was skipped. Post-mortems start from GitHub timestamps.
  • It does not scale with the queue. The cost is linear in the number of ready PRs, and it lands entirely on the few people with merge rights, at the time of day they happen to be awake.
  • PRs CI testing is limited depending on what has changed in a PR. A one line change in a PR might pass the few tests associated with the files changed but might have side-effects that impacts other areas.
  • Some PR changes do not trigger any tests or coverage is missed due to other factors (i.e. in PRs we run twister with --integration, so only integration platforms are scoped, when merged, more platforms are scoped and issues might arise

Proposed Change (Summary)

Replace the manual loop of reading the merge list in a browser, opening each ready pull request, and clicking Merge one at a time with a reproducible pipeline: build one branch with every ready PR merged in, push it and let full CI run, verify it is green, then merge exactly the PRs that rode that branch, from the terminal.

Proposed Change (Detailed)

Treat the merge list as a data source rather than a web page, and run a short, scripted merge train against it. Each run snapshots the list, builds an integration branch containing every ready PR for a target, runs the test suite on that branch, and then do a scripted batch merge that merges those PRs that passed the integration test.
Nothing in the merge policy changes; the gates the merge list already enforces remain the only criteria for inclusion. What changes is that the batch is tested as a batch before it lands, and every step leaves an artifact.

possible policy items:

  • The merge list is the sole source of eligibility. The tools never compute readiness themselves; they read the gates the list publishes. If the list is wrong, fix the list.
  • A PR is merged only from a green train. Being on the list is necessary, not sufficient. A PR that cannot be integrated (conflict) or whose inclusion turns the train red waits for the next one.
  • Merge method is rebase, matching current project practice, so commit hygiene requirements on contributors are unchanged.
  • Order is deterministic: ascending PR number. Older PRs get the earlier seat; a newer PR that conflicts with an older one is the one that has to rebase.

Dependencies

  • need the https://merge-list.zephyrproject.io/ to generate machine readable queue with more data that can be consumed by scripts
  • need to maintain store the data as artifcats to enable reproducibility and tracking
  • scripts to create the integration branch in a reproducible way
  • a gh extension that works with all of the above and allow merges of verified PRs

Concerns and Unresolved Questions

  • What lands is not byte-for-byte what was tested
  • A PR can change after it was tested
  • A PR can stop being ready after it was tested
  • Attribution when the train is red
  • ....

Alternatives Considered

  • GH Merge queues: Solves the "tested together" problem natively but replaces the merge list's gate logic with branch-protection rules, has no notion of the review window, and removes the human checkpoint before landing. Could be revisited if the merge list's rules can be expressed as required checks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions