Appearance
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 tooling › auto-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.mjsEquivalent 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
| Flag | Value | What it does | Default |
|---|---|---|---|
--once | no value | Runs 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 |
--watch | no value | Repeats the evaluation pass forever, sleeping --interval seconds between passes. | off |
--dry-run | no value | Evaluates and reports every decision without labelling, dispatching, poking, or merging, even when ARMED is true. | off |
--json | no value | Prints 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 |
--help | no value | Prints 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 originandFORGE_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 code | Meaning |
|---|---|
0 | --help, or a full pass completed with no per-pull-request failure. |
1 | At 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. |
2 | A 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-runEvaluate one pull request and print its decision as JSON, for scripting:
bash
node tools/auto-merge.mjs --pr 42 --jsonRun continuously, checking every 5 minutes:
bash
node tools/auto-merge.mjs --watch --interval 300Notes
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