@mutmutco/cli 4.3.3 → 4.3.4
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/main.cjs +65 -20
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -15375,10 +15375,10 @@ var rollout_plan_default = {
|
|
|
15375
15375
|
note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
|
|
15376
15376
|
},
|
|
15377
15377
|
baseline: {
|
|
15378
|
-
version: "4.3.
|
|
15379
|
-
tag: "v4.3.
|
|
15380
|
-
commit: "
|
|
15381
|
-
npm: "@mutmutco/cli@4.3.
|
|
15378
|
+
version: "4.3.4",
|
|
15379
|
+
tag: "v4.3.4",
|
|
15380
|
+
commit: "cd7d0dd9cc3a",
|
|
15381
|
+
npm: "@mutmutco/cli@4.3.4"
|
|
15382
15382
|
},
|
|
15383
15383
|
exitCriterion: "fleet-n-of-n",
|
|
15384
15384
|
hubOnlyShortcut: "forbidden",
|
|
@@ -15395,14 +15395,14 @@ var rollout_plan_default = {
|
|
|
15395
15395
|
repo: "mutmutco/mmi-hub",
|
|
15396
15396
|
role: "canary",
|
|
15397
15397
|
schedule: "train",
|
|
15398
|
-
v3Target: "v4.3.
|
|
15398
|
+
v3Target: "v4.3.4"
|
|
15399
15399
|
}
|
|
15400
15400
|
],
|
|
15401
15401
|
rollbackTrigger: "Any red inside the post-contract soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a pre-v4 client admitted instead of receiving actionable HTTP 426, or npm consumer install/doctor failure on the v4-only dist.",
|
|
15402
15402
|
rollback: {
|
|
15403
15403
|
independent: true,
|
|
15404
|
-
mechanism: "npm dist-tag latest -> 4.3.
|
|
15405
|
-
v3Target: "v4.3.
|
|
15404
|
+
mechanism: "npm dist-tag latest -> 4.3.4 and redeploy the Hub Lambda from tag v4.3.4 (cd7d0dd9cc3a); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
15405
|
+
v3Target: "v4.3.4 (@mutmutco/cli@4.3.4, tag commit cd7d0dd9cc3a \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
15406
15406
|
}
|
|
15407
15407
|
},
|
|
15408
15408
|
{
|
|
@@ -35429,6 +35429,10 @@ function ghPrMergeLocalBranchDeleteWarning(message) {
|
|
|
35429
35429
|
function mergeAutoRejectedPrAlreadyClean(message) {
|
|
35430
35430
|
return /clean status \(enablePullRequestAutoMerge\)|is in clean status/i.test(message);
|
|
35431
35431
|
}
|
|
35432
|
+
function mergeRejectedBaseBranchModified(message) {
|
|
35433
|
+
return /base branch was modified\. review and try the merge again/i.test(message);
|
|
35434
|
+
}
|
|
35435
|
+
var PR_MERGE_BASE_RACE_RETRY_DELAY_MS = 3e3;
|
|
35432
35436
|
function assertRemoteBranchPreservedOnMerge(repo, deleteBranchOnMerge) {
|
|
35433
35437
|
if (deleteBranchOnMerge === false) return;
|
|
35434
35438
|
throw new Error(
|
|
@@ -35709,14 +35713,16 @@ async function deleteMergedRemoteBranch(options) {
|
|
|
35709
35713
|
if (options.existedBefore === false) {
|
|
35710
35714
|
const exists2 = await options.branchExists(options.branch);
|
|
35711
35715
|
if (exists2 === false) return { branch: options.branch, existedBefore: false, attempted: false, status: "already-gone" };
|
|
35712
|
-
|
|
35713
|
-
|
|
35714
|
-
|
|
35715
|
-
|
|
35716
|
-
|
|
35717
|
-
|
|
35718
|
-
|
|
35719
|
-
|
|
35716
|
+
if (exists2 !== true) {
|
|
35717
|
+
return {
|
|
35718
|
+
branch: options.branch,
|
|
35719
|
+
existedBefore: false,
|
|
35720
|
+
attempted: false,
|
|
35721
|
+
status: "failed",
|
|
35722
|
+
error: `could not verify absence of origin/${options.branch}`,
|
|
35723
|
+
remediation
|
|
35724
|
+
};
|
|
35725
|
+
}
|
|
35720
35726
|
}
|
|
35721
35727
|
try {
|
|
35722
35728
|
await options.execGit(["push", "origin", "--delete", options.branch]);
|
|
@@ -36389,6 +36395,22 @@ function samePath(a, b) {
|
|
|
36389
36395
|
const nb = normPath2(b);
|
|
36390
36396
|
return process.platform === "win32" ? na.toLowerCase() === nb.toLowerCase() : na === nb;
|
|
36391
36397
|
}
|
|
36398
|
+
function isPathAtOrWithin(path2, worktreePath) {
|
|
36399
|
+
if (!path2) return false;
|
|
36400
|
+
const candidate = normPath2(path2);
|
|
36401
|
+
const target = normPath2(worktreePath);
|
|
36402
|
+
const normalize = (value) => process.platform === "win32" ? value.toLowerCase() : value;
|
|
36403
|
+
const normalizedCandidate = normalize(candidate);
|
|
36404
|
+
const normalizedTarget = normalize(target);
|
|
36405
|
+
return normalizedCandidate === normalizedTarget || normalizedCandidate.startsWith(`${normalizedTarget}/`);
|
|
36406
|
+
}
|
|
36407
|
+
function isWindowsCwdLockResidueError(error) {
|
|
36408
|
+
return process.platform === "win32" && /\bEPERM\b|access(?: is)? denied/i.test(error);
|
|
36409
|
+
}
|
|
36410
|
+
function deferredCwdLockRemediation(primaryRoot, wtPath) {
|
|
36411
|
+
const quote = (path2) => path2.replace(/'/g, "''");
|
|
36412
|
+
return `After this command exits: Set-Location -LiteralPath '${quote(primaryRoot)}'; Remove-Item -LiteralPath '${quote(wtPath)}' -Recurse -Force`;
|
|
36413
|
+
}
|
|
36392
36414
|
function selectPrMergeCleanupWorktree(branch, before, after, startingPath) {
|
|
36393
36415
|
if (!branch) return void 0;
|
|
36394
36416
|
const current = after.find((w) => w.branch === branch)?.path;
|
|
@@ -36559,7 +36581,7 @@ async function removeWorktreeWithReconcile(wtPath, git3, listWorktrees, pathExis
|
|
|
36559
36581
|
}
|
|
36560
36582
|
function isPrMergeWorktreePartial(cleanup) {
|
|
36561
36583
|
const worktree = cleanup?.worktree;
|
|
36562
|
-
return Boolean(worktree?.path && worktree.status !== "removed" && worktree.status !== "preserved");
|
|
36584
|
+
return Boolean(worktree?.path && worktree.status !== "removed" && worktree.status !== "preserved" && worktree.status !== "retained-locked");
|
|
36563
36585
|
}
|
|
36564
36586
|
function prMergeLocalCleanupExitCode(cleanup) {
|
|
36565
36587
|
return cleanup?.worktree?.status === "failed" || cleanup?.localBranch?.status === "failed" ? 1 : void 0;
|
|
@@ -36731,11 +36753,17 @@ async function cleanupPrMergeLocalBranch(branch, options) {
|
|
|
36731
36753
|
if (residue.ok) {
|
|
36732
36754
|
report.worktree.residue = "swept";
|
|
36733
36755
|
} else {
|
|
36734
|
-
report.worktree.status = "failed";
|
|
36735
|
-
report.worktree.reason = "residue-remains";
|
|
36736
36756
|
report.worktree.residue = "left";
|
|
36737
36757
|
report.worktree.residueError = residue.error;
|
|
36738
|
-
|
|
36758
|
+
if (isWindowsCwdLockResidueError(residue.error) && isPathAtOrWithin(options.startingPath, wtPath)) {
|
|
36759
|
+
report.worktree.status = "retained-locked";
|
|
36760
|
+
report.worktree.reason = "parent-cwd-lock";
|
|
36761
|
+
report.worktree.remediation = deferredCwdLockRemediation(options.primaryRoot, wtPath);
|
|
36762
|
+
} else {
|
|
36763
|
+
report.worktree.status = "failed";
|
|
36764
|
+
report.worktree.reason = "residue-remains";
|
|
36765
|
+
report.worktree.remediation = `Remove-Item -LiteralPath '${wtPath.replace(/'/g, "''")}' -Force`;
|
|
36766
|
+
}
|
|
36739
36767
|
}
|
|
36740
36768
|
}
|
|
36741
36769
|
try {
|
|
@@ -36764,8 +36792,10 @@ function renderPrMergeCleanupLines(cleanup) {
|
|
|
36764
36792
|
lines.push(`pr merge: worktree ${wt.path} removal failed${wt.error ? ` \u2014 ${wt.error}` : ""}`);
|
|
36765
36793
|
} else if (wt.status === "preserved") {
|
|
36766
36794
|
lines.push(`pr merge: preserved worktree ${wt.path} (--preserve-worktree)`);
|
|
36795
|
+
} else if (wt.status === "retained-locked") {
|
|
36796
|
+
lines.push(`pr merge: worktree ${wt.path} cleanup deferred \u2014 its Windows parent shell still holds the cwd; ${wt.remediation ?? "exit the shell and remove the residue from the primary checkout"}`);
|
|
36767
36797
|
}
|
|
36768
|
-
if (wt.residue === "left") {
|
|
36798
|
+
if (wt.residue === "left" && wt.status !== "retained-locked") {
|
|
36769
36799
|
lines.push(`pr merge: worktree ${wt.path} registration is gone but residue remains \u2014 ${wt.residueError ?? wt.path}; remediate: ${wt.remediation ?? wt.path}`);
|
|
36770
36800
|
}
|
|
36771
36801
|
if (wt.artifactsArchive?.status === "archived" && wt.artifactsArchive.path) {
|
|
@@ -37979,6 +38009,21 @@ ${list}`);
|
|
|
37979
38009
|
});
|
|
37980
38010
|
return;
|
|
37981
38011
|
}
|
|
38012
|
+
if (!o.auto && mergeRejectedBaseBranchModified(message)) {
|
|
38013
|
+
console.warn(`pr merge: the base branch was modified by a concurrent merge \u2014 waiting ${PR_MERGE_BASE_RACE_RETRY_DELAY_MS / 1e3}s and retrying PR #${number}'s merge once (#6052).`);
|
|
38014
|
+
await new Promise((resolve7) => setTimeout(resolve7, PR_MERGE_BASE_RACE_RETRY_DELAY_MS));
|
|
38015
|
+
await execFileP("gh", buildPrMergeArgs({ number, repoArgs, method, auto: false, deleteBranch: false, bodyFile }), { timeout: GH_MUTATION_TIMEOUT_MS }).catch((e2) => {
|
|
38016
|
+
const m2 = String(e2.message || "");
|
|
38017
|
+
if (/already been merged/i.test(m2)) {
|
|
38018
|
+
remoteNotAttemptedReason = "pr-already-merged";
|
|
38019
|
+
return;
|
|
38020
|
+
}
|
|
38021
|
+
const note2 = timeoutKillNote(e2, GH_MUTATION_TIMEOUT_MS);
|
|
38022
|
+
if (note2) throw new Error(`gh pr merge ${number}: ${note2}`);
|
|
38023
|
+
if (!ghPrMergeLocalBranchDeleteWarning(m2)) throw e2;
|
|
38024
|
+
});
|
|
38025
|
+
return;
|
|
38026
|
+
}
|
|
37982
38027
|
if (o.auto && mergeAutoRejectedPrAlreadyClean(message)) {
|
|
37983
38028
|
await execFileP("gh", buildPrMergeArgs({ number, repoArgs, method, auto: false, deleteBranch: false, bodyFile }), { timeout: GH_MUTATION_TIMEOUT_MS }).catch((e2) => {
|
|
37984
38029
|
const m2 = String(e2.message || "");
|
package/package.json
CHANGED