feat(FN-5349): add integration branch resolver with auto-recovery fallback

FN-5349 adds a dedicated integration branch resolution module (`packages/engine/src/integration-branch.ts`) replacing ad-hoc dynamic fallbacks, routes merger branch conflict resolution through it, wires auto-recovery handlers (branch-worktree, contamination) to use integration branch fallback, and w

Fusion-Task-Id: FN-5349
This commit is contained in:
Fusion (runfusion.ai)
2026-05-21 12:04:19 -07:00
committed by gsxdsm
parent e58530aa37
commit 79850b233f
28 changed files with 525 additions and 50 deletions

View File

@@ -13,6 +13,14 @@ vi.mock("node:child_process", () => ({
cb(err as Error, "", (err as Error).message);
}
},
execFile: (file: string, args: string[] | undefined, opts: unknown, cb: (err: Error | null, stdout: string, stderr: string) => void) => {
try {
const result = execMock(`${file} ${(args ?? []).join(" ")}`.trim(), opts);
cb(null, typeof result === "string" ? result : "", "");
} catch (err) {
cb(err as Error, "", (err as Error).message);
}
},
}));
import { processPullRequestMergeTask, getTaskBranchName } from "../task-lifecycle.js";

View File

@@ -19,6 +19,7 @@ const execAsync = promisify(exec);
import type { TaskStore } from "@fusion/core";
import { resolveTaskMergeTarget } from "@fusion/core";
import type { Settings, TaskDetail, PrInfo, MergeResult } from "@fusion/core";
import { resolveIntegrationBranch } from "@fusion/engine";
/**
* Minimal interface for GitHub operations needed by the PR merge workflow.
@@ -183,8 +184,9 @@ async function finalizePullRequestMerge(
const mergedTask = movedTask ?? (await store.getTask(task.id));
await store.logEntry(task.id, message, `PR #${prInfo.number}: ${prInfo.url}`);
const settings = await store.getSettings();
const resolvedIntegrationBranch = await resolveIntegrationBranch(cwd, settings);
const mergeTargetBranch = resolveTaskMergeTarget(mergedTask, {
projectDefaultBranch: typeof settings.baseBranch === "string" ? settings.baseBranch : undefined,
projectDefaultBranch: resolvedIntegrationBranch,
});
store.emit("task:merged", {
task: mergedTask,
@@ -246,7 +248,8 @@ export async function processPullRequestMergeTask(
const branch = getTaskBranchName(task.id);
const settings = await store.getSettings();
const projectDefaultBranch = typeof settings.baseBranch === "string" ? settings.baseBranch : undefined;
const resolvedIntegrationBranch = await resolveIntegrationBranch(cwd, settings);
const projectDefaultBranch = resolvedIntegrationBranch;
const mergeTarget = resolveTaskMergeTarget(task, {
projectDefaultBranch,
});