Skip to content

auto-merge.mjs

Merges pull requests into staging once they clear this repository's auto-merge policy, run once or on a watch interval.

Agent toolingauto-merge.mjs

What it does

Evaluates every open pull request against the policy in tools/lib/auto-merge/policy.mjs and decides one action per pull request: skip, label, dispatch a review, poke the gate, or merge. Applies that decision — labelling, dispatching the review kit, poking the gate label, or merging through forge.mjs — only when ARMED is true and --dry-run is absent. A disarmed or dry-run pass reports the same decision without writing anything. Runs one pass by default, or repeats on a --interval-second cycle under --watch.

Usage

The minimal invocation that works — one pass over every open pull request:

bash
node tools/auto-merge.mjs

Equivalent to npm run automerge, and to passing --once explicitly; a single pass is the default. The full form:

bash
node tools/auto-merge.mjs [--once|--watch] [--interval <sec>] [--dry-run] [--pr <n>] [--json]

Options

FlagValueWhat it doesDefault
--onceno valueRuns a single evaluation pass over every open pull request. This is the default; the flag exists to override an earlier --watch on the same command line — flags are applied in order, so the last of --once/--watch wins.on
--watchno valueRepeats the evaluation pass forever, sleeping --interval seconds between passes.off
--dry-runno valueEvaluates and reports every decision without labelling, dispatching, poking, or merging, even when ARMED is true.off
--jsonno valuePrints one JSON object per pull request (pr, base, head, action, reason, armed) instead of the human-readable line.off
--interval<sec>Seconds to sleep between passes under --watch. A non-finite or non-positive value throws before the first pass runs.60
--pr<n>Restricts the pass to one pull-request number instead of every open pull request.None
--helpno valuePrints the usage summary and exits 0 without evaluating anything. -h does the same.off

Inputs and outputs

Reads three things beyond the pull requests themselves:

  • git remote get-url origin and FORGE_BASE_URL/ROCKET_FORGE_BASE_URL, for the repository context.
  • The git credential store, or FORGE_TOKEN, for authentication.
  • GW_REVIEW_KIT (or a path baked in relative to the repository root), for the review kit it dispatches.

Writes nothing to disk. Every effect from an armed pass is remote — a label, a dispatched review, a poke of the gate label, a merge, or a comment recording the merge.

Exit codeMeaning
0--help, or a full pass completed with no per-pull-request failure.
1At least one pull request's evaluation or action threw and was counted as a failure, or an uncaught error stopped the run before any pass completed.
2A usage error — an unrecognized flag, or --interval/--pr given a value that fails validation.

--watch never exits on its own; it loops on --interval until the process is stopped. Dispatching a review needs its own credential, which childToken resolves from FORGE_TOKEN or the Authorization header. A pull request whose token cannot be resolved is skipped for that reason, rather than failed outright.

Examples

See what a pass would do without writing anything:

bash
node tools/auto-merge.mjs --dry-run

Evaluate one pull request and print its decision as JSON, for scripting:

bash
node tools/auto-merge.mjs --pr 42 --json

Run continuously, checking every 5 minutes:

bash
node tools/auto-merge.mjs --watch --interval 300

Notes

ARMED in tools/lib/auto-merge/policy.mjs is the pilot switch. While it is true, an armed pass merges pull requests unattended once they clear the policy — --dry-run previews a pass without it.

MERGE_TARGETS names exactly one branch this tool may merge into: staging. assertMergeableTarget throws for any other base, including main, which is merged by hand, and dev, which needs no pull request.

A merge through this tool passes deleteBranch: false (DELETE_BRANCH in policy.mjs) to mergePullRequest, so the head branch survives. Calling tools/forge.mjs merge directly always deletes it.

workflowParity compares the blob sha of each path in WORKFLOW_PATHS between head and base. A fetch failure for either file is treated the same as a real mismatch. Either one stops the pass at skip before a review is ever dispatched.

The no-automerge label takes one pull request out of consideration entirely. No flag does the same, only the label. Combining --pr and --watch re-evaluates one pull request every interval, rather than every open one.

Source

tools/auto-merge.mjs — part of Agent tooling