@mutmutco/cli 4.5.125 → 4.5.127
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 +39 -16
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -8766,8 +8766,9 @@ async function retireProject(slug, deps) {
|
|
|
8766
8766
|
async function setDeployCoords(slug, payload, deps) {
|
|
8767
8767
|
return postJson(`/projects/${encodeURIComponent(slug)}/deploy`, payload, deps);
|
|
8768
8768
|
}
|
|
8769
|
-
async function retireDeployCoords(slug, stage, deps) {
|
|
8770
|
-
|
|
8769
|
+
async function retireDeployCoords(slug, stage, deps, decommissioned = false) {
|
|
8770
|
+
const q = decommissioned ? "?decommissioned=1" : "";
|
|
8771
|
+
return postJson(`/projects/${encodeURIComponent(slug)}/deploy/${encodeURIComponent(stage)}${q}`, {}, deps, "DELETE", { noRetry: true });
|
|
8771
8772
|
}
|
|
8772
8773
|
async function postSchedulesLift(repo, schedules, deps) {
|
|
8773
8774
|
const res = await postJson("/schedules/lift", { repo, schedules }, deps);
|
|
@@ -18243,10 +18244,10 @@ var rollout_plan_default = {
|
|
|
18243
18244
|
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)."
|
|
18244
18245
|
},
|
|
18245
18246
|
baseline: {
|
|
18246
|
-
version: "4.5.
|
|
18247
|
-
tag: "v4.5.
|
|
18248
|
-
commit: "
|
|
18249
|
-
npm: "@mutmutco/cli@4.5.
|
|
18247
|
+
version: "4.5.127",
|
|
18248
|
+
tag: "v4.5.127",
|
|
18249
|
+
commit: "1a7a42121998",
|
|
18250
|
+
npm: "@mutmutco/cli@4.5.127"
|
|
18250
18251
|
},
|
|
18251
18252
|
exitCriterion: "fleet-n-of-n",
|
|
18252
18253
|
hubOnlyShortcut: "forbidden",
|
|
@@ -18263,14 +18264,14 @@ var rollout_plan_default = {
|
|
|
18263
18264
|
repo: "mutmutco/mmi-hub",
|
|
18264
18265
|
role: "canary",
|
|
18265
18266
|
schedule: "train",
|
|
18266
|
-
v3Target: "v4.5.
|
|
18267
|
+
v3Target: "v4.5.127"
|
|
18267
18268
|
}
|
|
18268
18269
|
],
|
|
18269
18270
|
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.",
|
|
18270
18271
|
rollback: {
|
|
18271
18272
|
independent: true,
|
|
18272
|
-
mechanism: "npm dist-tag latest -> 4.5.
|
|
18273
|
-
v3Target: "v4.5.
|
|
18273
|
+
mechanism: "npm dist-tag latest -> 4.5.127 and redeploy the Hub Lambda from tag v4.5.127 (1a7a42121998); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
18274
|
+
v3Target: "v4.5.127 (@mutmutco/cli@4.5.127, tag commit 1a7a42121998 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
18274
18275
|
}
|
|
18275
18276
|
},
|
|
18276
18277
|
{
|
|
@@ -32313,7 +32314,7 @@ function parseTenantTasksVar(raw) {
|
|
|
32313
32314
|
if (typeof task.service !== "string" || !serviceRe.test(task.service)) throw new Error(`org project set: tenantTasks.${name}.service has an unsafe shape`);
|
|
32314
32315
|
if (!Array.isArray(task.command) || task.command.length < 1 || task.command.length > 32 || task.command.some((arg) => typeof arg !== "string" || arg.length < 1 || arg.length > 256 || /[\u0000\r\n]/.test(arg))) throw new Error(`org project set: tenantTasks.${name}.command must be 1-32 bounded argv strings`);
|
|
32315
32316
|
if (!Array.isArray(task.stages) || task.stages.length < 1 || task.stages.length > 3 || task.stages.some((stage) => typeof stage !== "string" || !validStages.has(stage)) || new Set(task.stages).size !== task.stages.length) throw new Error(`org project set: tenantTasks.${name}.stages must be unique dev/rc/main values`);
|
|
32316
|
-
const maxTimeout = task.secretOutput !== void 0 ? 3600 :
|
|
32317
|
+
const maxTimeout = task.secretOutput !== void 0 ? 3600 : 10800;
|
|
32317
32318
|
if (task.timeoutSeconds !== void 0 && (!Number.isInteger(task.timeoutSeconds) || task.timeoutSeconds < 1 || task.timeoutSeconds > maxTimeout)) throw new Error(`org project set: tenantTasks.${name}.timeoutSeconds must be an integer 1..${maxTimeout}`);
|
|
32318
32319
|
const artifact = task.artifact ?? "none";
|
|
32319
32320
|
if (artifact !== "none" && artifact !== "required") throw new Error(`org project set: tenantTasks.${name}.artifact must be none or required`);
|
|
@@ -52870,7 +52871,10 @@ function buildDeployRetirePlan(input) {
|
|
|
52870
52871
|
if (!["dev", "rc", "main"].includes(input.stage)) {
|
|
52871
52872
|
throw new Error("org project deploy retire: --stage must be dev, rc, or main");
|
|
52872
52873
|
}
|
|
52873
|
-
|
|
52874
|
+
if (input.decommissioned && input.stage !== "main") {
|
|
52875
|
+
throw new Error("org project deploy retire: --decommissioned applies to --stage main only (dev/rc always retire)");
|
|
52876
|
+
}
|
|
52877
|
+
return { slug, stage: input.stage, apply: Boolean(input.apply), decommissioned: Boolean(input.decommissioned) };
|
|
52874
52878
|
}
|
|
52875
52879
|
async function runDeployRetire(input, deps) {
|
|
52876
52880
|
const plan = buildDeployRetirePlan(input);
|
|
@@ -52879,7 +52883,20 @@ async function runDeployRetire(input, deps) {
|
|
|
52879
52883
|
if (!plan.apply) {
|
|
52880
52884
|
return { slug: plan.slug, stage: plan.stage, applied: false, ok: facts !== null, existing };
|
|
52881
52885
|
}
|
|
52882
|
-
|
|
52886
|
+
if (plan.decommissioned) {
|
|
52887
|
+
const state = deps.boxServiceState ? await deps.boxServiceState(plan.stage) : "unknown";
|
|
52888
|
+
if (state !== "missing") {
|
|
52889
|
+
return {
|
|
52890
|
+
slug: plan.slug,
|
|
52891
|
+
stage: plan.stage,
|
|
52892
|
+
applied: false,
|
|
52893
|
+
ok: false,
|
|
52894
|
+
existing,
|
|
52895
|
+
error: `--decommissioned needs the box to show ${plan.stage} gone (tenant-control status serviceState=missing), got ${state} \u2014 run tenant control <repo> ${plan.stage} retire first`
|
|
52896
|
+
};
|
|
52897
|
+
}
|
|
52898
|
+
}
|
|
52899
|
+
const res = await retireDeployCoords(plan.slug, plan.stage, deps.registry, plan.decommissioned);
|
|
52883
52900
|
if (!res.ok) {
|
|
52884
52901
|
return { slug: plan.slug, stage: plan.stage, applied: true, ok: false, existing, error: writeError2(res) };
|
|
52885
52902
|
}
|
|
@@ -56155,7 +56172,7 @@ projectDeploy.command("doctor").description("read-only estate port scan; --box l
|
|
|
56155
56172
|
if (report.error && report.status !== 403) return failGraceful(`org project deploy doctor: ${report.error}`);
|
|
56156
56173
|
if (!report.ok && !report.error) process.exitCode = 1;
|
|
56157
56174
|
});
|
|
56158
|
-
projectDeploy.command("retire [owner/repo]").description("retire (tombstone) one stage's DEPLOY# row for a project that no longer deploys through it (#7095, master-only). --stage is required. DRY-RUN by default \u2014 pass --apply to actually write; defaults to the current repo. Refuses a tenant-container project's live main row.").addOption(new Option("--stage <stage>", "dev | rc | main (required)").choices(["dev", "rc", "main"])).option("--apply", "actually retire (default is a dry-run preview of the row that would be retired)").option("--json", "machine-readable output").action(async (repoOrSlug, o) => {
|
|
56175
|
+
projectDeploy.command("retire [owner/repo]").description("retire (tombstone) one stage's DEPLOY# row for a project that no longer deploys through it (#7095, master-only). --stage is required. DRY-RUN by default \u2014 pass --apply to actually write; defaults to the current repo. Refuses a tenant-container project's live main row.").addOption(new Option("--stage <stage>", "dev | rc | main (required)").choices(["dev", "rc", "main"])).option("--apply", "actually retire (default is a dry-run preview of the row that would be retired)").option("--decommissioned", "main only (#8148): retire a tenant-container main row after `runtime tenant control <repo> main retire`; the box must show main gone").option("--json", "machine-readable output").action(async (repoOrSlug, o) => {
|
|
56159
56176
|
const stage = projectDeploy.opts().stage;
|
|
56160
56177
|
if (!stage) return fail("org project deploy retire: --stage is required (dev | rc | main)");
|
|
56161
56178
|
const cfg = await loadConfig();
|
|
@@ -56168,8 +56185,14 @@ projectDeploy.command("retire [owner/repo]").description("retire (tombstone) one
|
|
|
56168
56185
|
let result;
|
|
56169
56186
|
try {
|
|
56170
56187
|
result = await runDeployRetire(
|
|
56171
|
-
{ target, stage, apply: Boolean(o.apply) },
|
|
56172
|
-
{
|
|
56188
|
+
{ target, stage, apply: Boolean(o.apply), decommissioned: Boolean(o.decommissioned) },
|
|
56189
|
+
{
|
|
56190
|
+
registry: registryClientDeps(cfg),
|
|
56191
|
+
boxServiceState: async (s) => {
|
|
56192
|
+
const r = await runTenantControl(trainApplyDeps(), { repo: target, stage: s, action: "status", watch: true });
|
|
56193
|
+
return r.conclusion === "success" ? r.serviceState ?? "unknown" : "error";
|
|
56194
|
+
}
|
|
56195
|
+
}
|
|
56173
56196
|
);
|
|
56174
56197
|
} catch (e) {
|
|
56175
56198
|
return fail(e.message);
|
|
@@ -56434,7 +56457,7 @@ ${filelessTransitionGuide(target, o.stage)}`
|
|
|
56434
56457
|
return reportWrite("org project set-deploy", res);
|
|
56435
56458
|
});
|
|
56436
56459
|
var projectTenantTasks = project.command("tenant-tasks").description("project-admin self-declare of tenant tasks for every stage of your own repo \u2014 new-task-only; editing an existing task stays master-only (`org project set --var tenantTasks=...`)");
|
|
56437
|
-
projectTenantTasks.command("declare <name>").description("register a NEW tenant task \u2014 becomes runnable via `runtime tenant control \u2026 run-task` on its declared dev/rc/main stages. Body shape {service,command[],stages[],timeoutSeconds?,artifact?}; required artifact tasks must carry {artifact} in the command argv.").option("--service <name>", "service in the tenant runtime the task runs in (required unless --var carries it)").option("--command <argv...>", `task command as argv (repeatable; required unless --var carries it). An argv token that starts with "-" (python -m mod) is read as an option and the whole call fails to parse: declare such a command with --var '{"service":"<svc>","command":["python","-m","mod"],"stages":["dev"]}' instead (#7668)`).option("--stages <list>", "comma-separated dev,rc,main stages this task may run on (required unless --var carries it)").option("--timeout-seconds <n>", "optional wall-clock ceiling 1..
|
|
56460
|
+
projectTenantTasks.command("declare <name>").description("register a NEW tenant task \u2014 becomes runnable via `runtime tenant control \u2026 run-task` on its declared dev/rc/main stages. Body shape {service,command[],stages[],timeoutSeconds?,artifact?}; required artifact tasks must carry {artifact} in the command argv.").option("--service <name>", "service in the tenant runtime the task runs in (required unless --var carries it)").option("--command <argv...>", `task command as argv (repeatable; required unless --var carries it). An argv token that starts with "-" (python -m mod) is read as an option and the whole call fails to parse: declare such a command with --var '{"service":"<svc>","command":["python","-m","mod"],"stages":["dev"]}' instead (#7668)`).option("--stages <list>", "comma-separated dev,rc,main stages this task may run on (required unless --var carries it)").option("--timeout-seconds <n>", "optional wall-clock ceiling 1..10800 (1..3600 with a secretOutput)").option("--artifact <none|required>", "artifact contract (default none; required tasks must contain {artifact} in argv)").option("--var <json>", "full task object {service,command[],stages[],timeoutSeconds?,artifact?} \u2014 use instead of the individual flags. A task carrying secretOutput:{path,vault:{repo,key},overwrite?} is master-only; declare that via `org project set --var tenantTasks=...`").option("--repo <owner/repo>", "target repo (defaults to the current repo)").option("--json", "machine-readable output").action(async (name, o) => {
|
|
56438
56461
|
const cfg = await loadConfig();
|
|
56439
56462
|
let target;
|
|
56440
56463
|
try {
|
package/package.json
CHANGED