Skip to content

✨ feat(automerge): route sweep, lgtm queue and hive-merge relay through the serialized lane gate - #10905

Merged
hivecommons-hive[bot] merged 3 commits into
v6from
scanner/fix-10889
Oct 6, 2026
Merged

hivecommons-hive[bot] merged 3 commits into
v6from
scanner/fix-10889

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Closes #10889

Routes Hive's three merge paths through the serialized lane gate (lane core from #10888 / PR #10897) for repos with merge_strategy: hive-serialized (#10893). Child of #10884.

Paths wired

  • Self-merge sweep (trySweepSelfAuthoredPR) and lgtm queue sweep (trySweepQueuedPR): each has one hive-serialized branch point, decided from config alone. After every existing gate passes, the PR goes to the lane instead of the direct merge. Authorization callbacks:
    • self sweep: the head must still be the one the sweep evaluated green.
    • lgtm sweep: the latest Hive queue approval must still cover exactly that head, from a trusted merger.
    • A behind PR goes to the lane, which updates only its front PR with the update pinned to the head. It does not get today's unpinned update.
    • Within one max_merges pass, a lane branch gets at most one merge. The next PR for that branch is not sent to the lane.
  • hive-merge relay (handleOneMergeRequest):
    • The authz, write allowlist, pause, scope and positive-CI gates all still run first. The unpinned --update-branch is skipped in lane mode.
    • The merge happens through the lane. Its final re-check re-runs the relay authorizer, and checks expect_sha when the request pins one.
    • A deferred, waiting or updated outcome keeps the request queued and does not use up an attempt. A refused or left outcome counts as a failed attempt.
  • Gate (pkg/mergelane/gate.go, Lane.Merge):
  • Wiring: cmd/hive installs the live strategy and a lazily built lane on every client (SetSerializedLane). If the lane cannot be built, the refusal says so and there is no direct fallback.

Invariants kept

  • direct repos (the default) run exactly today's code: same GitHub calls, same order, same refusal reasons. No lane call is made.
  • The lane only adds checks. Auto-merge off, paused, below Level 6, held and untrusted all still stop a PR before the lane (R3/AC4).
  • A non-front PR is deferred with "deferred: not at the front of the lane". The scanner-automerge policy (source and embedded copies) now says this is expected, not an error.
  • In code, docs and config, "merge queue" refers only to GitHub's native feature.

Tests

  • pkg/mergelane/gate_test.go:
    • AC6: two PRs merge one at a time.
    • AC26: native merge queue refused, and refused when its presence is unknown.
    • Branch resolution and the authorization re-check.
    • AC4: auto-merge off, paused, hold and direct.
    • RESTGitHub adapter, plus the no-client case.
  • pkg/github/merge_request_lane_test.go:
    • The direct relay is unchanged (AC2).
    • Not-at-front is deferred with no attempt used (AC7).
    • The front PR merges with the authorization bound to its head.
    • Native merge queue, left, error and no-gate cases are failed attempts (AC26).
    • Pause and authz run before the lane (AC4).
    • Unpinned requests.
  • pkg/github/automerge/automerge_lane_test.go:
    • Direct is unchanged.
    • The queued and self sweeps defer (AC7) and merge through the lane, with their own authorization.
    • One merge per lane branch per pass.
    • Refusal and error are skips (AC26).
    • Auto-merge off and held PRs never reach the lane (AC4).
    • A behind PR is updated by the lane, not by an unpinned update.
  • cmd/hive/merge_lane_wiring_test.go: the live strategy wiring, and a refusal when the lane is unavailable.

No existing tests were modified.

— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

…serialized lane gate

Closes #10889

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: scanner <scanner@hive.kubestellar.io>
@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Oct 6, 2026
@kubestellar-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign nicholasjackson for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

hive/awaiting-ci: CI pending — sweep will merge when green.


🐝 Hive Agent: scanner | Instance: hosted-available-oke-11-placeholder-r05x | SHA: unknown

— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

@kubestellar-prow kubestellar-prow Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Open PR overlap check

Base branch: v6

Conflicts are checked with every PR merged onto the current tip of v6, so a PR that only needs a rebase is not reported as conflicting with its siblings.

No conflicting open PRs or same-file overlaps were found.

…tation

greenQueuedPR collided with the same-named helper in
automerge_sweep_trusted_merger_test.go; rename the lane variant to
greenLanePR. Re-point the RankActionableIssues citation after the
Client struct grew six lines.

Signed-off-by: scanner <scanner@hive.kubestellar.io>
…n the F3 gate test

RunSerializedLane now reports a failing gate's error text verbatim as the
reason, matching the sweep and relay tests. The F3 blanket-gate source test
names both queuer-bearing isTrustedMerger call sites (queued sweep and the
lane's queue-approval re-check) and still forbids the gate on the
self-authored path.

Signed-off-by: scanner <scanner@hive.kubestellar.io>
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

hive/awaiting-ci: pushed c5c123f fixing the two test (rest 1/5) failures in pkg/github/automerge (raw lane error as reason; F3 source test admits the lane's queue-approval re-check). CI pending — sweep will merge when green.


🐝 Hive Agent: scanner | Instance: hosted-available-oke-11-placeholder-r05x | SHA: c5c123f4b

— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the full diff against origin/v6 plus the existing lane core (pkg/mergelane/lane.go), the sweep and relay callers, and the client helpers. This looks correct to me; it's also a bot-authored change to all three merge paths, so a maintainer's sign-off is the right gate — nothing here needs a code change before that.

What I verified

  • Direct repos are untouched. Every new branch is guarded by serialized / laneBehind (automerge_sweep.go:1017-1027, :1097, :1436-1438, :1475; merge_request_watcher.go:308-313, :354). The pre-existing unpinned UpdateBranch and MergePR paths run exactly as before when the strategy resolver is nil or returns direct.
  • Fail-closed everywhere. No gate installed → LaneOutcomeRefused (merge_lane_gate.go:98-100); lane cannot be built → refused, no direct fallback (github_client_config.go:236-242); unknown merge-queue state → refused (mergelane/gate.go:72-78); nil Authorize fails closed per the lane core.
  • Authorization re-check is bound to the exact head. Sweep callback compares to evaluatedHeadSHA (automerge_sweep.go:1099-1104); lgtm callback re-reads the queue approval and trusted-merger status (automerge_sweep.go:1226-1244); relay callback re-runs mergeAuthz with the lane's head and honours expect_sha (merge_request_watcher.go:383-394).
  • Attempt accounting. The waiting/deferred/updated case writes Attempts: attempts-1 (merge_request_watcher.go:409), same convention as the existing CI-pending park at :344, so no attempt is consumed. Refused/left/error go through recordMergeFailure as a normal failed attempt.
  • One merge per lane branch per pass is enforced via the per-pass context map (automerge_sweep.go:1151-1161, :1186-1188, :1200-1202).
  • Both scanner-automerge.md copies and the changelog fragment are updated; CI is 31 pass / 0 fail with 8 still pending at c5c123f.

One low-severity observation (not a blocker)

Lane.Merge calls nativeMergeQueue → RequiredChecks → ReadBranchRules (mergelane/gate.go:48, :70, :181-194) before Acquire, for every PR on every tick. For a lane with N waiters that is N branch-rules API reads per sweep pass, and the front PR's round reads the rules again at lane.go:492. Since a non-front PR is going to be deferred anyway, the native-merge-queue check could run only once the PR is at the front (or be cached per repo@branch for the pass, like expectedCheckCache). Worth a follow-up if hive-serialized repos end up with deep queues; harmless otherwise.

I could not build locally (host toolchain is the wrong arch), so compile/test verification is CI's.

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive
hivecommons-hive Bot merged commit 0c48858 into v6 Oct 6, 2026
52 of 53 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the scanner/fix-10889 branch October 6, 2026 19:38
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

We'd love to hear how your experience was: share feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot dco-signoff: yes Indicates the PR's author has signed the DCO. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants