Address PR review feedback (#1461)
- pr-nodes: forward post-increment entity to deps.respond (responseRounds off-by-one); branch-group entity fallback now keys on task.branchContext.groupId, not task.id - core: hoist shared autoMergeGateReason into @fusion/core pr-entity.ts; CLI + dashboard import the single definition (R13) - cli: fn pr create also writes the unified PR entity (ensure → open), keeping legacy prInfo; resolveBranchHeadOid uses argv-safe execFileAsync (injection fix) - changeset: fn-pr-commands bumped minor → major (breaking CLI removal per AGENTS.md) - tests: bin.test.ts daemon fixture off reserved port 4040; lazy-loaded-views title 19 → 20 views Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
autoMergeGateReason,
|
||||
isPrBacked,
|
||||
isPrEntityActionable,
|
||||
isPrEntityActive,
|
||||
@@ -71,4 +72,19 @@ describe("PR entity predicates", () => {
|
||||
expect(isPrEntityAutoMergeReady({ ...base, mergeable: "unknown" })).toBe(false);
|
||||
expect(isPrEntityAutoMergeReady({ ...base, unverified: true })).toBe(false);
|
||||
});
|
||||
|
||||
it("autoMergeGateReason is the single R13-shared status string for both surfaces", () => {
|
||||
const ready = entity({
|
||||
autoMerge: true,
|
||||
reviewDecision: "APPROVED",
|
||||
checksRollup: "success",
|
||||
mergeable: "clean",
|
||||
});
|
||||
expect(autoMergeGateReason(ready)).toBe("Ready to merge");
|
||||
expect(autoMergeGateReason({ ...ready, autoMerge: false })).toBe("Auto-merge off");
|
||||
expect(autoMergeGateReason({ ...ready, mergeable: "conflicting" })).toBe("Blocked: conflict");
|
||||
expect(autoMergeGateReason({ ...ready, reviewDecision: "CHANGES_REQUESTED" })).toBe("Waiting for approval");
|
||||
expect(autoMergeGateReason({ ...ready, checksRollup: "pending" })).toBe("Waiting for checks");
|
||||
expect(autoMergeGateReason({ ...ready, mergeable: "unknown" })).toBe("Waiting for checks");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -611,6 +611,7 @@ export {
|
||||
isPrBacked,
|
||||
isPrEntityActionable,
|
||||
isPrEntityAutoMergeReady,
|
||||
autoMergeGateReason,
|
||||
} from "./pr-entity.js";
|
||||
export {
|
||||
findVitestProcessIds,
|
||||
|
||||
@@ -63,3 +63,21 @@ export function isPrEntityAutoMergeReady(
|
||||
if (entity.mergeable !== "clean") return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The live auto-merge gate reason shown next to the toggle (R11). Mirrors the
|
||||
* auto-merge-ready predicate ordering so every surface (the dashboard route and
|
||||
* the `fn pr` CLI) reports the same status and never disagrees with what the gate
|
||||
* will actually do. Shared in @fusion/core (R13) so the two surfaces cannot drift.
|
||||
*/
|
||||
export function autoMergeGateReason(
|
||||
entity: Pick<PrEntity, "state" | "unverified" | "autoMerge" | "reviewDecision" | "checksRollup" | "mergeable">,
|
||||
): string {
|
||||
if (!entity.autoMerge) return "Auto-merge off";
|
||||
if (entity.mergeable === "conflicting") return "Blocked: conflict";
|
||||
if (entity.reviewDecision !== "APPROVED") return "Waiting for approval";
|
||||
if (entity.checksRollup !== "success") return "Waiting for checks";
|
||||
if (entity.mergeable !== "clean") return "Waiting for checks";
|
||||
if (isPrEntityAutoMergeReady(entity)) return "Ready to merge";
|
||||
return "Waiting for checks";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user