Skip to content

feat(runway): wire the git merger into the server - #463

Draft
behinddwalls wants to merge 1 commit into
preetam/runway-git-merger-promotefrom
preetam/runway-wire-git-merger
Draft

feat(runway): wire the git merger into the server#463
behinddwalls wants to merge 1 commit into
preetam/runway-git-merger-promotefrom
preetam/runway-wire-git-merger

Conversation

@behinddwalls

@behinddwalls behinddwalls commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Why?

The git merger exists but nothing constructs it — the server still builds the noop factory, so a deployed Runway acknowledges every merge as an instant success. This is the change that makes Runway actually merge.

It is deliberately last in the stack and deliberately opt-in: the switch is the presence of MERGE_CHECKOUT_PATH. Unset, the server keeps wiring noop, which is what local development, the compose stack, and the e2e suite depend on — none of them have a git checkout to hand the merger.

What?

newMergerFactory now reads the environment and returns either backend. With MERGE_CHECKOUT_PATH set it builds a git merger from the MERGE_* / GIT_* variables — remote, target branch, default strategy, committer identity, and the pinned git runtime — and logs the resolved configuration at startup. Without it, noop, with a log line saying so. A malformed configuration fails startup rather than degrading silently: parseStrategy rejects an unrecognized MERGE_DEFAULT_STRATEGY, and DEFAULT itself is rejected because it cannot be the value a DEFAULT step resolves to.

gitMergerFactory hands the same merger instance to every queue. The merger owns one checkout and serializes its own operations, so a second instance over the same directory would race; a deployment that lands multiple targets wires a per-queue map instead. This is also why the factory is built once at startup rather than per request.

Documents the new variables in the service README and adds the merger-extension overview to the Runway README.

Test Plan

bazel build //service/runway/... — wiring compiles
bazel test //runway/... — 6/6 pass

Not covered by automated tests: the git path only engages when MERGE_CHECKOUT_PATH points at a real checkout, so the env-to-Params mapping is exercised by the merger's own suite rather than through main. Watch the git merger configured startup log — with checkout, target, and default strategy — on the first deployment that sets the variable; its absence means the server silently fell back to noop.

Stack

  1. chore(submitqueue): remove dead pusher extension #457
  2. feat(runway): classify invalid merge requests as terminal #458
  3. feat(runway): dlq reconciler for merge topics #459
  4. feat(runway): git-backed merger with REBASE #460
  5. feat(runway): git merger SQUASH_REBASE and MERGE #461
  6. feat(runway): git merger PROMOTE #462
  7. @ feat(runway): wire the git merger into the server #463

## Summary

### Why?

The git merger exists but nothing constructs it — the server still builds the noop factory, so a deployed Runway acknowledges every merge as an instant success. This is the change that makes Runway actually merge.

It is deliberately last in the stack and deliberately opt-in: the switch is the presence of `MERGE_CHECKOUT_PATH`. Unset, the server keeps wiring noop, which is what local development, the compose stack, and the e2e suite depend on — none of them have a git checkout to hand the merger.

### What?

`newMergerFactory` now reads the environment and returns either backend. With `MERGE_CHECKOUT_PATH` set it builds a git merger from the `MERGE_*` / `GIT_*` variables — remote, target branch, default strategy, committer identity, and the pinned git runtime — and logs the resolved configuration at startup. Without it, noop, with a log line saying so. A malformed configuration fails startup rather than degrading silently: `parseStrategy` rejects an unrecognized `MERGE_DEFAULT_STRATEGY`, and `DEFAULT` itself is rejected because it cannot be the value a `DEFAULT` step resolves to.

`gitMergerFactory` hands the same merger instance to every queue. The merger owns one checkout and serializes its own operations, so a second instance over the same directory would race; a deployment that lands multiple targets wires a per-queue map instead. This is also why the factory is built once at startup rather than per request.

Documents the new variables in the service README and adds the merger-extension overview to the Runway README.

## Test Plan

✅ `bazel build //service/runway/...` — wiring compiles
✅ `bazel test //runway/...` — 6/6 pass

Not covered by automated tests: the git path only engages when `MERGE_CHECKOUT_PATH` points at a real checkout, so the env-to-`Params` mapping is exercised by the merger's own suite rather than through `main`. Watch the `git merger configured` startup log — with checkout, target, and default strategy — on the first deployment that sets the variable; its absence means the server silently fell back to noop.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant