@mutmutco/cli 2.20.0 → 2.21.0
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 +38 -12
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -4826,6 +4826,13 @@ function parseManifestVersion(stdout) {
|
|
|
4826
4826
|
return void 0;
|
|
4827
4827
|
}
|
|
4828
4828
|
}
|
|
4829
|
+
function npmReleasedVersionArgs() {
|
|
4830
|
+
return ["view", "@mutmutco/cli", "version"];
|
|
4831
|
+
}
|
|
4832
|
+
function parseNpmVersion(stdout) {
|
|
4833
|
+
const v = stdout.trim();
|
|
4834
|
+
return /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/.test(v) ? v : void 0;
|
|
4835
|
+
}
|
|
4829
4836
|
function versionAutoUpdateAction(report, hasPluginRoot) {
|
|
4830
4837
|
if (report.ok || report.staleAgainst !== "released") return "none";
|
|
4831
4838
|
return hasPluginRoot ? "plugin-pull" : "npm";
|
|
@@ -7183,6 +7190,7 @@ var ORG_SPINE_FILES = [
|
|
|
7183
7190
|
function isSpinePath(path2) {
|
|
7184
7191
|
return ORG_SPINE_FILES.includes(path2);
|
|
7185
7192
|
}
|
|
7193
|
+
var RELEASE_TOLERATED_PATHS = [".gitignore"];
|
|
7186
7194
|
async function predictMergeConflicts(deps, ours, theirs) {
|
|
7187
7195
|
try {
|
|
7188
7196
|
await deps.run("git", ["merge-tree", "--write-tree", "--name-only", "--no-messages", ours, theirs]);
|
|
@@ -7387,7 +7395,7 @@ function resolveContextState(context, checkRuns, statuses) {
|
|
|
7387
7395
|
if (r.name !== context) continue;
|
|
7388
7396
|
if (r.status === "completed") {
|
|
7389
7397
|
if (r.conclusion === "success") return "success";
|
|
7390
|
-
sawFailure = true;
|
|
7398
|
+
if (r.conclusion !== "skipped" && r.conclusion !== "neutral") sawFailure = true;
|
|
7391
7399
|
}
|
|
7392
7400
|
}
|
|
7393
7401
|
for (const s of statuses) {
|
|
@@ -7587,8 +7595,9 @@ async function runTrainApply(command, deps, options = {}) {
|
|
|
7587
7595
|
const deployModel2 = await preflight(deps, ctx, "main", meta);
|
|
7588
7596
|
const tag2 = requireValue(clean(await deps.run("node", ["scripts/next-version.mjs", "cycle"])), "release tag");
|
|
7589
7597
|
const foldPaths2 = await resolveFoldPaths(deps, deployModel2);
|
|
7598
|
+
const tolerated2 = [...foldPaths2, ...RELEASE_TOLERATED_PATHS];
|
|
7590
7599
|
const predicted2 = await predictMergeConflicts(deps, "origin/main", "origin/development");
|
|
7591
|
-
const predictedBlocking2 = predicted2.filter((f) => !isSpinePath(f) && !
|
|
7600
|
+
const predictedBlocking2 = predicted2.filter((f) => !isSpinePath(f) && !tolerated2.includes(f));
|
|
7592
7601
|
if (predictedBlocking2.length > 0) {
|
|
7593
7602
|
throw new Error(
|
|
7594
7603
|
`development -> main merge would conflict on non-spine path(s): ${predictedBlocking2.join(", ")} \u2014 no merge was started. The train is misaligned: reconcile main and development via an approved alignment PR, then rerun release.`
|
|
@@ -7599,7 +7608,7 @@ async function runTrainApply(command, deps, options = {}) {
|
|
|
7599
7608
|
if (predicted2.length === 0) {
|
|
7600
7609
|
await deps.run("git", ["merge", "development", "--no-edit"]);
|
|
7601
7610
|
} else {
|
|
7602
|
-
await mergeWithSpineResolution(deps, "development", "development -> main", "theirs",
|
|
7611
|
+
await mergeWithSpineResolution(deps, "development", "development -> main", "theirs", tolerated2);
|
|
7603
7612
|
}
|
|
7604
7613
|
const versionFold2 = await foldReleaseVersion(deps, deployModel2, tag2, foldPaths2);
|
|
7605
7614
|
const releaseSha2 = requireValue(clean(await deps.run("git", ["rev-parse", "main"])), "release sha");
|
|
@@ -7643,8 +7652,9 @@ async function runTrainApply(command, deps, options = {}) {
|
|
|
7643
7652
|
);
|
|
7644
7653
|
const deployModel = await preflight(deps, ctx, "main", meta);
|
|
7645
7654
|
const foldPaths = await resolveFoldPaths(deps, deployModel);
|
|
7655
|
+
const tolerated = [...foldPaths, ...RELEASE_TOLERATED_PATHS];
|
|
7646
7656
|
const predicted = await predictMergeConflicts(deps, "origin/main", "origin/rc");
|
|
7647
|
-
const predictedBlocking = predicted.filter((f) => !isSpinePath(f) && !
|
|
7657
|
+
const predictedBlocking = predicted.filter((f) => !isSpinePath(f) && !tolerated.includes(f));
|
|
7648
7658
|
if (predictedBlocking.length > 0) {
|
|
7649
7659
|
throw new Error(
|
|
7650
7660
|
`rc -> main merge would conflict on non-spine path(s): ${predictedBlocking.join(", ")} \u2014 no merge was started. The train is misaligned: reconcile main and rc via an approved alignment PR (do not hand-resolve on main), then rerun release.`
|
|
@@ -7663,7 +7673,7 @@ async function runTrainApply(command, deps, options = {}) {
|
|
|
7663
7673
|
if (predicted.length === 0) {
|
|
7664
7674
|
await deps.run("git", ["merge", "rc", "--no-edit"]);
|
|
7665
7675
|
} else {
|
|
7666
|
-
await mergeWithSpineResolution(deps, "rc", "rc -> main", "theirs",
|
|
7676
|
+
await mergeWithSpineResolution(deps, "rc", "rc -> main", "theirs", tolerated);
|
|
7667
7677
|
}
|
|
7668
7678
|
const tag = requireValue(clean(await deps.run("node", ["scripts/next-version.mjs", "release"])), "release tag");
|
|
7669
7679
|
const versionFold = await foldReleaseVersion(deps, deployModel, tag, foldPaths);
|
|
@@ -7682,6 +7692,13 @@ async function runTrainApply(command, deps, options = {}) {
|
|
|
7682
7692
|
await deps.run("git", ["pull", "--ff-only", "origin", "development"]);
|
|
7683
7693
|
await deps.run("git", ["merge", "main", "--no-edit"]);
|
|
7684
7694
|
await deps.run("git", ["push", "origin", "development"]);
|
|
7695
|
+
let rcAlignment;
|
|
7696
|
+
try {
|
|
7697
|
+
await deps.run("git", ["push", "origin", "main:rc"]);
|
|
7698
|
+
rcAlignment = "origin/rc aligned to the released main";
|
|
7699
|
+
} catch (e) {
|
|
7700
|
+
rcAlignment = `rc alignment push failed \u2014 align manually with \`git push origin main:rc\`: ${e instanceof Error ? e.message : String(e)}`;
|
|
7701
|
+
}
|
|
7685
7702
|
const environments = await buildEnvironments(deps, ctx, deployModel, d.deployStatus, retirement);
|
|
7686
7703
|
return {
|
|
7687
7704
|
...ctx,
|
|
@@ -7701,6 +7718,7 @@ async function runTrainApply(command, deps, options = {}) {
|
|
|
7701
7718
|
rcRetirement: retirement.status,
|
|
7702
7719
|
rcRetirementNote: retirement.note,
|
|
7703
7720
|
rcRetirementCategory: retirement.category,
|
|
7721
|
+
rcAlignment,
|
|
7704
7722
|
announceNote,
|
|
7705
7723
|
release: { tag, url: releaseUrl, targetSha: releaseSha },
|
|
7706
7724
|
environments
|
|
@@ -8014,19 +8032,18 @@ async function findHotfixPr(deps, ctx, tag) {
|
|
|
8014
8032
|
"list",
|
|
8015
8033
|
"--repo",
|
|
8016
8034
|
ctx.repo,
|
|
8017
|
-
"--head",
|
|
8018
|
-
hotfixBranch(tag),
|
|
8019
8035
|
"--base",
|
|
8020
8036
|
"main",
|
|
8021
8037
|
"--state",
|
|
8022
8038
|
"all",
|
|
8023
8039
|
"--limit",
|
|
8024
|
-
"
|
|
8040
|
+
"50",
|
|
8025
8041
|
"--json",
|
|
8026
|
-
"number,state,url,mergeCommit"
|
|
8042
|
+
"number,state,url,mergeCommit,headRefName"
|
|
8027
8043
|
]);
|
|
8028
8044
|
const rows = JSON.parse(out || "[]");
|
|
8029
|
-
|
|
8045
|
+
const branch = hotfixBranch(tag);
|
|
8046
|
+
return rows.filter((r) => typeof r.headRefName === "string" && (r.headRefName === branch || r.headRefName.startsWith(`${branch}-`))).sort((a, b) => (b.number ?? 0) - (a.number ?? 0))[0] ?? null;
|
|
8030
8047
|
}
|
|
8031
8048
|
async function resolveHotfixSource(deps, ctx, from) {
|
|
8032
8049
|
const prMatch = /^#?(\d+)$/.exec(from.trim());
|
|
@@ -8162,9 +8179,9 @@ async function runHotfixRelease(deps, versionInput, options = {}) {
|
|
|
8162
8179
|
await deps.run("git", ["merge-base", "--is-ancestor", mergedSha, "origin/main"]).catch(() => {
|
|
8163
8180
|
throw new Error(`merged hotfix SHA ${mergedSha.slice(0, 7)} is not on origin/main \u2014 refusing to tag`);
|
|
8164
8181
|
});
|
|
8182
|
+
const tagNote = await ensureTagPushed(deps, tag, mergedSha);
|
|
8165
8183
|
const required = await discoverRequiredCheckContexts(deps, ctx, "main");
|
|
8166
8184
|
const checks = await waitForRequiredTrainChecks(deps, ctx, mergedSha, required);
|
|
8167
|
-
const tagNote = await ensureTagPushed(deps, tag, mergedSha);
|
|
8168
8185
|
let releaseNote;
|
|
8169
8186
|
let releaseExists = false;
|
|
8170
8187
|
try {
|
|
@@ -11237,6 +11254,7 @@ async function fetchReleasedVersion() {
|
|
|
11237
11254
|
}
|
|
11238
11255
|
}
|
|
11239
11256
|
var NPM_UPDATE_TIMEOUT_MS = 12e4;
|
|
11257
|
+
var NPM_VIEW_TIMEOUT_MS = 15e3;
|
|
11240
11258
|
var PLUGIN_PULL_TIMEOUT_MS = 3e4;
|
|
11241
11259
|
async function applyVersionAutoUpdate(report, log) {
|
|
11242
11260
|
const action = versionAutoUpdateAction(report, Boolean(process.env.CLAUDE_PLUGIN_ROOT));
|
|
@@ -11260,10 +11278,18 @@ async function applyVersionAutoUpdate(report, log) {
|
|
|
11260
11278
|
return report;
|
|
11261
11279
|
}
|
|
11262
11280
|
}
|
|
11281
|
+
async function fetchNpmReleasedVersion() {
|
|
11282
|
+
try {
|
|
11283
|
+
const { stdout } = await runHostBin("npm", npmReleasedVersionArgs(), { timeout: NPM_VIEW_TIMEOUT_MS });
|
|
11284
|
+
return parseNpmVersion(stdout);
|
|
11285
|
+
} catch {
|
|
11286
|
+
return void 0;
|
|
11287
|
+
}
|
|
11288
|
+
}
|
|
11263
11289
|
async function requireFreshTrainCli(commandName) {
|
|
11264
11290
|
const report = buildVersionLagReport({
|
|
11265
11291
|
currentVersion: resolveClientVersion(),
|
|
11266
|
-
releasedVersion: await
|
|
11292
|
+
releasedVersion: await fetchNpmReleasedVersion()
|
|
11267
11293
|
});
|
|
11268
11294
|
if (report.ok) return;
|
|
11269
11295
|
throw new Error(`running mmi-cli ${report.currentVersion} is stale against released ${report.releasedVersion}; run doctor/update first so ${commandName} uses the current train path`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mutmutco/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"description": "MMI Future CLI — delivers the org rules (whole-file), plus saga and KB access. The cross-IDE engine the plugin's SessionStart hook drives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|