@bevel-software/platform-core-backend 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +13 -2
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +5 -2
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +12 -6
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/package.json +2 -2
- package/src/modules/workflow/__tests__/pending-commits.enqueue-if-absent.test.ts +82 -72
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +44 -0
- package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +306 -306
- package/src/modules/workflow/git/git.service.ts +13 -2
- package/src/modules/workflow/workflow.service.ts +12 -6
|
@@ -1403,12 +1403,23 @@ export class GitService implements IGitService {
|
|
|
1403
1403
|
// A failed rebase leaves the repo in a "REBASE_HEAD" / detached-apply state,
|
|
1404
1404
|
// which makes every subsequent git command behave unexpectedly. Return the
|
|
1405
1405
|
// working tree to a clean state before surfacing the original error.
|
|
1406
|
-
|
|
1407
|
-
|
|
1406
|
+
let abortSucceeded = true;
|
|
1407
|
+
await this.git(cwd, ['rebase', '--abort']).catch(() => {
|
|
1408
|
+
abortSucceeded = false;
|
|
1409
|
+
});
|
|
1410
|
+
if (abortSucceeded && conflictedPaths.length > 0) {
|
|
1408
1411
|
// Typed so the workflow layer can queue background recovery — this
|
|
1409
1412
|
// divergence never resolves on its own (every retry pull hits the
|
|
1410
1413
|
// same conflict) and the unpushed local commits are someone's saved
|
|
1411
1414
|
// content stuck violating save=share.
|
|
1415
|
+
//
|
|
1416
|
+
// Gated on the abort succeeding: a failed abort means either no
|
|
1417
|
+
// rebase was ever active (the unmerged paths pre-date this pull —
|
|
1418
|
+
// some earlier operation left the index broken) or the clone is in
|
|
1419
|
+
// a state git itself can't unwind. Queueing recovery there would
|
|
1420
|
+
// point the worker's commitFile at a repo mid-conflict, risking a
|
|
1421
|
+
// commit full of conflict markers — surface the raw error instead
|
|
1422
|
+
// and leave diagnosis to a human.
|
|
1412
1423
|
throw new PullRebaseConflictError(
|
|
1413
1424
|
branch,
|
|
1414
1425
|
conflictedPaths,
|
|
@@ -327,10 +327,13 @@ export class WorkflowService implements IWorkflowService {
|
|
|
327
327
|
* `needs_attention` row: once the ladder has escalated to a human, more
|
|
328
328
|
* agent runs on the same divergence are just a loop.
|
|
329
329
|
*
|
|
330
|
-
* One row,
|
|
330
|
+
* One row, smallest conflicted path as the representative: the recovery
|
|
331
331
|
* agent's job is "bring the BRANCH into a pushable state", so one ladder
|
|
332
332
|
* per divergence — not one per conflicted file, which would multiply
|
|
333
|
-
* agent runs for a single underlying conflict.
|
|
333
|
+
* agent runs for a single underlying conflict. Sorted so the choice is
|
|
334
|
+
* stable across retries regardless of how the caller ordered the paths —
|
|
335
|
+
* a shifting representative would slip past `enqueueIfAbsent`'s
|
|
336
|
+
* per-(workspace, branch, path) dedup and start a second ladder.
|
|
334
337
|
*
|
|
335
338
|
* Best-effort by design — the caller is already surfacing the conflict
|
|
336
339
|
* error; a queue hiccup must not mask it.
|
|
@@ -344,7 +347,7 @@ export class WorkflowService implements IWorkflowService {
|
|
|
344
347
|
const queued = await this.pendingCommits.enqueueIfAbsent({
|
|
345
348
|
workspaceId,
|
|
346
349
|
branch: err.branch,
|
|
347
|
-
path: err.conflictedPaths[0],
|
|
350
|
+
path: [...err.conflictedPaths].sort()[0],
|
|
348
351
|
authorEmail: user?.email ?? RECOVERY_BOT_EMAIL,
|
|
349
352
|
authorName: user?.name ?? RECOVERY_BOT_NAME,
|
|
350
353
|
});
|
|
@@ -1418,16 +1421,19 @@ export class WorkflowService implements IWorkflowService {
|
|
|
1418
1421
|
// this a read right after a merge misses the just-merged change. Best-effort:
|
|
1419
1422
|
// the merge already succeeded on origin, so a pull hiccup must not fail the
|
|
1420
1423
|
// response (a later fetch/pull reconciles).
|
|
1424
|
+
let targetWorkspaceId: string | undefined;
|
|
1421
1425
|
try {
|
|
1422
1426
|
const targetWorkspace = await this.workspaceService.getOrCreateForBranch(baseBranch);
|
|
1427
|
+
targetWorkspaceId = targetWorkspace.id;
|
|
1423
1428
|
await this.git.pull(targetWorkspace.id);
|
|
1424
1429
|
} catch (err) {
|
|
1425
1430
|
// Still best-effort for the merge response (the merge already landed
|
|
1426
1431
|
// on origin) — but a rebase CONFLICT here means the target workspace
|
|
1427
1432
|
// is stranded (local commits vs origin, never self-heals), so queue
|
|
1428
|
-
// the background recovery ladder before shrugging.
|
|
1429
|
-
|
|
1430
|
-
|
|
1433
|
+
// the background recovery ladder before shrugging. A conflict can
|
|
1434
|
+
// only have come from the pull, so the workspace id is always set on
|
|
1435
|
+
// this arm — the guard just satisfies the narrowing.
|
|
1436
|
+
if (err instanceof PullRebaseConflictError && targetWorkspaceId) {
|
|
1431
1437
|
await this.queuePullConflictRecovery(targetWorkspaceId, err, user);
|
|
1432
1438
|
}
|
|
1433
1439
|
console.warn(
|