feat(FN-4518): complete Step 4 — carry rebase base through self-healing
Fusion-Task-Id: FN-4518 Fusion-Task-Lineage: 48749dec-b2c9-484b-a13e-ffacc1fa9014
This commit is contained in:
@@ -5443,6 +5443,108 @@ describe("recoverDoneTaskMergeMetadata", () => {
|
||||
manager.stop();
|
||||
});
|
||||
|
||||
it("populates rebaseBaseSha from landed commit when missing", async () => {
|
||||
const store = createMockStore();
|
||||
const manager = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||
|
||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||
{
|
||||
id: "FN-4518-A",
|
||||
column: "done",
|
||||
paused: false,
|
||||
mergeDetails: { commitSha: "merge1", mergeConfirmed: false },
|
||||
},
|
||||
]);
|
||||
|
||||
vi.spyOn(manager as any, "findLandedTaskCommit").mockResolvedValue({
|
||||
sha: "merge1",
|
||||
subject: "fix(FN-4518): landed",
|
||||
filesChanged: 2,
|
||||
insertions: 4,
|
||||
deletions: 1,
|
||||
rebaseBaseSha: "base1",
|
||||
});
|
||||
|
||||
const repaired = await manager.recoverDoneTaskMergeMetadata();
|
||||
|
||||
expect(repaired).toBe(1);
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-4518-A", {
|
||||
mergeDetails: expect.objectContaining({
|
||||
commitSha: "merge1",
|
||||
rebaseBaseSha: "base1",
|
||||
}),
|
||||
});
|
||||
|
||||
manager.stop();
|
||||
});
|
||||
|
||||
it("does not overwrite existing rebaseBaseSha during reconciliation", async () => {
|
||||
const store = createMockStore();
|
||||
const manager = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||
|
||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||
{
|
||||
id: "FN-4518-B",
|
||||
column: "done",
|
||||
paused: false,
|
||||
mergeDetails: { commitSha: "merge1", mergeConfirmed: false, rebaseBaseSha: "existing-base" },
|
||||
},
|
||||
]);
|
||||
|
||||
vi.spyOn(manager as any, "findLandedTaskCommit").mockResolvedValue({
|
||||
sha: "merge1",
|
||||
subject: "fix(FN-4518): landed",
|
||||
filesChanged: 2,
|
||||
insertions: 4,
|
||||
deletions: 1,
|
||||
rebaseBaseSha: "incoming-base",
|
||||
});
|
||||
|
||||
const repaired = await manager.recoverDoneTaskMergeMetadata();
|
||||
|
||||
expect(repaired).toBe(1);
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-4518-B", {
|
||||
mergeDetails: expect.objectContaining({
|
||||
rebaseBaseSha: "existing-base",
|
||||
}),
|
||||
});
|
||||
|
||||
manager.stop();
|
||||
});
|
||||
|
||||
it("keeps rebaseBaseSha undefined when neither stored nor landed provides it", async () => {
|
||||
const store = createMockStore();
|
||||
const manager = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||
|
||||
(store.listTasks as ReturnType<typeof vi.fn>).mockResolvedValue([
|
||||
{
|
||||
id: "FN-4518-C",
|
||||
column: "done",
|
||||
paused: false,
|
||||
mergeDetails: { commitSha: "merge1", mergeConfirmed: false },
|
||||
},
|
||||
]);
|
||||
|
||||
vi.spyOn(manager as any, "findLandedTaskCommit").mockResolvedValue({
|
||||
sha: "merge1",
|
||||
subject: "fix(FN-4518): landed",
|
||||
filesChanged: 2,
|
||||
insertions: 4,
|
||||
deletions: 1,
|
||||
});
|
||||
|
||||
const repaired = await manager.recoverDoneTaskMergeMetadata();
|
||||
|
||||
expect(repaired).toBe(1);
|
||||
expect(store.updateTask).toHaveBeenCalledWith("FN-4518-C", {
|
||||
mergeDetails: expect.not.objectContaining({
|
||||
rebaseBaseSha: expect.any(String),
|
||||
}),
|
||||
});
|
||||
|
||||
manager.stop();
|
||||
});
|
||||
|
||||
it("FN-3862: confirmed task with unreachable stored SHA is preserved with warning", async () => {
|
||||
const store = createMockStore();
|
||||
const manager = new SelfHealingManager(store, { rootDir: "/tmp/test-project" });
|
||||
|
||||
@@ -238,6 +238,7 @@ interface LandedTaskCommit {
|
||||
filesChanged?: number;
|
||||
insertions?: number;
|
||||
deletions?: number;
|
||||
rebaseBaseSha?: string;
|
||||
}
|
||||
|
||||
type AlreadyMergedDetectionStrategy = "trailer" | "ancestry" | "patch-id" | "tree-equal";
|
||||
@@ -2580,6 +2581,7 @@ export class SelfHealingManager {
|
||||
if (landedCommit) {
|
||||
const mergeDetails: MergeDetails = {
|
||||
commitSha: landedCommit.sha,
|
||||
rebaseBaseSha: landedCommit.rebaseBaseSha,
|
||||
filesChanged: landedCommit.filesChanged,
|
||||
insertions: landedCommit.insertions,
|
||||
deletions: landedCommit.deletions,
|
||||
@@ -2704,6 +2706,7 @@ export class SelfHealingManager {
|
||||
insertions: nextInsertions,
|
||||
deletions: nextDeletions,
|
||||
mergeCommitMessage: task.mergeDetails?.mergeCommitMessage ?? landed.subject,
|
||||
rebaseBaseSha: task.mergeDetails?.rebaseBaseSha ?? landed.rebaseBaseSha,
|
||||
mergedAt: task.mergeDetails?.mergedAt ?? new Date().toISOString(),
|
||||
prNumber: task.prInfo?.number,
|
||||
},
|
||||
@@ -2756,6 +2759,7 @@ export class SelfHealingManager {
|
||||
insertions: landedStats.insertions,
|
||||
deletions: landedStats.deletions,
|
||||
mergeCommitMessage: landed.subject,
|
||||
rebaseBaseSha: task.mergeDetails?.rebaseBaseSha ?? landed.rebaseBaseSha,
|
||||
mergedAt: task.mergeDetails?.mergedAt ?? new Date().toISOString(),
|
||||
mergeConfirmed: true,
|
||||
prNumber: task.prInfo?.number,
|
||||
@@ -2898,6 +2902,7 @@ export class SelfHealingManager {
|
||||
if (landedCommit) {
|
||||
const mergeDetails: MergeDetails = {
|
||||
commitSha: landedCommit.sha,
|
||||
rebaseBaseSha: landedCommit.rebaseBaseSha,
|
||||
filesChanged: landedCommit.filesChanged,
|
||||
insertions: landedCommit.insertions,
|
||||
deletions: landedCommit.deletions,
|
||||
|
||||
Reference in New Issue
Block a user