@mutmutco/cli 4.3.25 → 4.3.26
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 +30 -20
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -14074,7 +14074,7 @@ var GATE_RUNTIME_DEFAULTS = {
|
|
|
14074
14074
|
node: { cmd: DEFAULT_GATE_CMD, install: "npm ci" },
|
|
14075
14075
|
python: { cmd: "pytest", install: 'pip install -e ".[dev]"' }
|
|
14076
14076
|
};
|
|
14077
|
-
function gateSeedVars(cls, releaseTrack, runtime = "node", requiredCheckBranches) {
|
|
14077
|
+
function gateSeedVars(cls, releaseTrack, runtime = "node", requiredCheckBranches, requiredChecks) {
|
|
14078
14078
|
const rt = GATE_RUNTIME_DEFAULTS[runtime] ?? GATE_RUNTIME_DEFAULTS.node;
|
|
14079
14079
|
const runtimeVars = {
|
|
14080
14080
|
GATE_RUNTIME: runtime,
|
|
@@ -14094,12 +14094,14 @@ function gateSeedVars(cls, releaseTrack, runtime = "node", requiredCheckBranches
|
|
|
14094
14094
|
const trackBranches = track === "trunk" ? ["main"] : track === "direct" ? ["development", "main"] : ["development", "rc", "main"];
|
|
14095
14095
|
const rulesetBranches = requiredCheckBranches?.length ? [...requiredCheckBranches] : trackBranches;
|
|
14096
14096
|
const rulesetRefs = JSON.stringify(rulesetBranches.map((branch) => `refs/heads/${branch}`));
|
|
14097
|
+
const rulesetContexts = JSON.stringify((requiredChecks?.length ? requiredChecks : ["gate"]).map((context) => ({ context })));
|
|
14097
14098
|
if (track === "trunk") {
|
|
14098
14099
|
return {
|
|
14099
14100
|
...runtimeVars,
|
|
14100
14101
|
GATE_PUSH_BRANCHES_YAML: "[main]",
|
|
14101
14102
|
GATE_FULL_RUN_BRANCH: "main",
|
|
14102
|
-
GATE_RULESET_BRANCH_REFS_JSON: rulesetRefs
|
|
14103
|
+
GATE_RULESET_BRANCH_REFS_JSON: rulesetRefs,
|
|
14104
|
+
GATE_RULESET_CONTEXTS_JSON: rulesetContexts
|
|
14103
14105
|
};
|
|
14104
14106
|
}
|
|
14105
14107
|
if (track === "direct") {
|
|
@@ -14107,17 +14109,19 @@ function gateSeedVars(cls, releaseTrack, runtime = "node", requiredCheckBranches
|
|
|
14107
14109
|
...runtimeVars,
|
|
14108
14110
|
GATE_PUSH_BRANCHES_YAML: "[development, main]",
|
|
14109
14111
|
GATE_FULL_RUN_BRANCH: "development",
|
|
14110
|
-
GATE_RULESET_BRANCH_REFS_JSON: rulesetRefs
|
|
14112
|
+
GATE_RULESET_BRANCH_REFS_JSON: rulesetRefs,
|
|
14113
|
+
GATE_RULESET_CONTEXTS_JSON: rulesetContexts
|
|
14111
14114
|
};
|
|
14112
14115
|
}
|
|
14113
14116
|
return {
|
|
14114
14117
|
...runtimeVars,
|
|
14115
14118
|
GATE_PUSH_BRANCHES_YAML: "[development, rc, main]",
|
|
14116
14119
|
GATE_FULL_RUN_BRANCH: "development",
|
|
14117
|
-
GATE_RULESET_BRANCH_REFS_JSON: rulesetRefs
|
|
14120
|
+
GATE_RULESET_BRANCH_REFS_JSON: rulesetRefs,
|
|
14121
|
+
GATE_RULESET_CONTEXTS_JSON: rulesetContexts
|
|
14118
14122
|
};
|
|
14119
14123
|
}
|
|
14120
|
-
function withDerivedRepoVars(vars, parsed, cls, releaseTrack, requiredCheckBranches) {
|
|
14124
|
+
function withDerivedRepoVars(vars, parsed, cls, releaseTrack, requiredCheckBranches, requiredChecks) {
|
|
14121
14125
|
const out = { ...vars };
|
|
14122
14126
|
out.REPO_NAME ??= parsed.name;
|
|
14123
14127
|
out.REPO_SLUG ??= parsed.slug;
|
|
@@ -14125,7 +14129,7 @@ function withDerivedRepoVars(vars, parsed, cls, releaseTrack, requiredCheckBranc
|
|
|
14125
14129
|
out.PROJECT_OWNER ??= parsed.owner;
|
|
14126
14130
|
const track = releaseTrack ?? resolveBootstrapReleaseTrack(cls);
|
|
14127
14131
|
const runtime = out.GATE_RUNTIME === "python" ? "python" : "node";
|
|
14128
|
-
for (const [key, value] of Object.entries(gateSeedVars(cls, track, runtime, requiredCheckBranches))) {
|
|
14132
|
+
for (const [key, value] of Object.entries(gateSeedVars(cls, track, runtime, requiredCheckBranches, requiredChecks))) {
|
|
14129
14133
|
out[key] ??= value;
|
|
14130
14134
|
}
|
|
14131
14135
|
if (!out.GATE_AFFECTED_CMD.trim()) out.GATE_AFFECTED_CMD = out.GATE_CMD;
|
|
@@ -15522,10 +15526,10 @@ var rollout_plan_default = {
|
|
|
15522
15526
|
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)."
|
|
15523
15527
|
},
|
|
15524
15528
|
baseline: {
|
|
15525
|
-
version: "4.3.
|
|
15526
|
-
tag: "v4.3.
|
|
15527
|
-
commit: "
|
|
15528
|
-
npm: "@mutmutco/cli@4.3.
|
|
15529
|
+
version: "4.3.26",
|
|
15530
|
+
tag: "v4.3.26",
|
|
15531
|
+
commit: "32a20f524697",
|
|
15532
|
+
npm: "@mutmutco/cli@4.3.26"
|
|
15529
15533
|
},
|
|
15530
15534
|
exitCriterion: "fleet-n-of-n",
|
|
15531
15535
|
hubOnlyShortcut: "forbidden",
|
|
@@ -15542,14 +15546,14 @@ var rollout_plan_default = {
|
|
|
15542
15546
|
repo: "mutmutco/mmi-hub",
|
|
15543
15547
|
role: "canary",
|
|
15544
15548
|
schedule: "train",
|
|
15545
|
-
v3Target: "v4.3.
|
|
15549
|
+
v3Target: "v4.3.26"
|
|
15546
15550
|
}
|
|
15547
15551
|
],
|
|
15548
15552
|
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.",
|
|
15549
15553
|
rollback: {
|
|
15550
15554
|
independent: true,
|
|
15551
|
-
mechanism: "npm dist-tag latest -> 4.3.
|
|
15552
|
-
v3Target: "v4.3.
|
|
15555
|
+
mechanism: "npm dist-tag latest -> 4.3.26 and redeploy the Hub Lambda from tag v4.3.26 (32a20f524697); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
15556
|
+
v3Target: "v4.3.26 (@mutmutco/cli@4.3.26, tag commit 32a20f524697 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
15553
15557
|
}
|
|
15554
15558
|
},
|
|
15555
15559
|
{
|
|
@@ -24213,7 +24217,8 @@ async function seedGateYml(repo, deps, meta, result) {
|
|
|
24213
24217
|
parsed,
|
|
24214
24218
|
"deployable",
|
|
24215
24219
|
releaseTrack,
|
|
24216
|
-
meta?.requiredCheckBranches
|
|
24220
|
+
meta?.requiredCheckBranches,
|
|
24221
|
+
registryRequiredContexts(meta) ?? void 0
|
|
24217
24222
|
);
|
|
24218
24223
|
if (await contentExists(deps, repo, baseBranch, PRODUCT_GATE_PATH)) {
|
|
24219
24224
|
return await seedRulesetRefIfMissing(repo, deps, refOnlyVars(), baseBranch, result);
|
|
@@ -24240,7 +24245,8 @@ async function seedGateYml(repo, deps, meta, result) {
|
|
|
24240
24245
|
parsed,
|
|
24241
24246
|
"deployable",
|
|
24242
24247
|
releaseTrack,
|
|
24243
|
-
meta?.requiredCheckBranches
|
|
24248
|
+
meta?.requiredCheckBranches,
|
|
24249
|
+
registryRequiredContexts(meta) ?? void 0
|
|
24244
24250
|
);
|
|
24245
24251
|
const rendered = renderSeedBody(deps, GATE_TEMPLATE_SEED, PRODUCT_GATE_PATH, derivedVars);
|
|
24246
24252
|
if (rendered == null) {
|
|
@@ -26590,8 +26596,9 @@ function deployStagesForBootstrap(deployModel, track) {
|
|
|
26590
26596
|
return branchesForTrack(track).map((branch) => branch === "development" ? "dev" : branch);
|
|
26591
26597
|
}
|
|
26592
26598
|
var missingBaseDetail = (base) => `${base} is missing; no source ref exists from which bootstrap can create the train lanes`;
|
|
26593
|
-
function productRulesetMatches(fact, branches) {
|
|
26594
|
-
|
|
26599
|
+
function productRulesetMatches(fact, branches, contexts) {
|
|
26600
|
+
const wantedContexts = contexts?.length ? contexts : ["gate"];
|
|
26601
|
+
if (fact?.enforcement !== "active" || !sameNames(fact.contexts, wantedContexts)) return false;
|
|
26595
26602
|
const wanted = branches.map((branch) => branch.startsWith("refs/") ? branch : `refs/heads/${branch}`);
|
|
26596
26603
|
return sameNames(fact.branches, wanted);
|
|
26597
26604
|
}
|
|
@@ -26627,7 +26634,7 @@ function planBootstrapControlPlane(input) {
|
|
|
26627
26634
|
code: "bootstrap-gap",
|
|
26628
26635
|
detail: [input.github.gateError, input.github.rulesetError].filter(Boolean).join("; ")
|
|
26629
26636
|
});
|
|
26630
|
-
} else if (productRulesetMatches(input.github.productRuleset, input.requiredCheckBranches)) {
|
|
26637
|
+
} else if (productRulesetMatches(input.github.productRuleset, input.requiredCheckBranches, input.requiredChecks)) {
|
|
26631
26638
|
rows.push({ kind: "product-ruleset", target: "mmi-product-required-checks", action: "skip", detail: "active gate context and branch scope already match the seeded authority" });
|
|
26632
26639
|
} else if (!input.github.gateExists) {
|
|
26633
26640
|
rows.push({ kind: "product-ruleset", target: "mmi-product-required-checks", action: "park", detail: `${PRODUCT_GATE_PATH2} is not present on ${base}; install disabled and activate on the next apply after the seed lands` });
|
|
@@ -27639,6 +27646,7 @@ function registerBootstrapCommands(program3) {
|
|
|
27639
27646
|
repoClass: cls,
|
|
27640
27647
|
releaseTrack: track,
|
|
27641
27648
|
requiredCheckBranches: resolveRequiredCheckBranches(metaWithDeclaredClass(meta, cls), repo),
|
|
27649
|
+
requiredChecks: meta?.requiredChecks ?? void 0,
|
|
27642
27650
|
deployModel: meta?.deployModel,
|
|
27643
27651
|
owners: controlOwners,
|
|
27644
27652
|
github,
|
|
@@ -27778,7 +27786,7 @@ function registerBootstrapCommands(program3) {
|
|
|
27778
27786
|
for (const [k, v] of Object.entries(gateConfigToVars(meta?.gate))) if (rawVars[k] == null) rawVars[k] = v;
|
|
27779
27787
|
} catch {
|
|
27780
27788
|
}
|
|
27781
|
-
const vars = withDerivedRepoVars(rawVars, parsedRepo, o.class, bootstrapReleaseTrack, registryRequiredCheckBranches);
|
|
27789
|
+
const vars = withDerivedRepoVars(rawVars, parsedRepo, o.class, bootstrapReleaseTrack, registryRequiredCheckBranches, registryMeta?.requiredChecks);
|
|
27782
27790
|
if (!vars.PROJECT_ID) {
|
|
27783
27791
|
try {
|
|
27784
27792
|
const r = await gh(linkedProjectsQueryArgs(parsedRepo.owner, parsedRepo.name));
|
|
@@ -27837,6 +27845,7 @@ function registerBootstrapCommands(program3) {
|
|
|
27837
27845
|
repoClass: o.class,
|
|
27838
27846
|
releaseTrack: effectiveTrack,
|
|
27839
27847
|
requiredCheckBranches: resolveRequiredCheckBranches(metaWithDeclaredClass(registryMeta, o.class), repo),
|
|
27848
|
+
requiredChecks: registryMeta?.requiredChecks ?? void 0,
|
|
27840
27849
|
deployModel: applyDeployModel,
|
|
27841
27850
|
owners: controlOwners,
|
|
27842
27851
|
github,
|
|
@@ -28186,6 +28195,7 @@ ${onlyManagedBlock ? `Only the marker-bounded Hub-managed block inside repo-owne
|
|
|
28186
28195
|
repoClass: o.class,
|
|
28187
28196
|
releaseTrack: effectiveTrack,
|
|
28188
28197
|
requiredCheckBranches: resolveRequiredCheckBranches(metaWithDeclaredClass(registryMeta, o.class), repo),
|
|
28198
|
+
requiredChecks: registryMeta?.requiredChecks ?? void 0,
|
|
28189
28199
|
deployModel: applyDeployModel,
|
|
28190
28200
|
owners: controlOwners,
|
|
28191
28201
|
github,
|
|
@@ -28296,7 +28306,7 @@ LIVE apply to ${repo}:
|
|
|
28296
28306
|
if (seed.source.startsWith("seed:")) {
|
|
28297
28307
|
const project2 = projects.find((p) => (p.repos ?? []).some((repo) => repo.toLowerCase() === r.repo.toLowerCase()));
|
|
28298
28308
|
const track = resolveReleaseTrack(project2, void 0, r.repo);
|
|
28299
|
-
const vars = withDerivedRepoVars({}, parseOwnerRepo(r.repo), repoClass, track, project2?.requiredCheckBranches);
|
|
28309
|
+
const vars = withDerivedRepoVars({}, parseOwnerRepo(r.repo), repoClass, track, project2?.requiredCheckBranches, project2?.requiredChecks);
|
|
28300
28310
|
const resolved = resolveSeedWriteContent(seed, vars, readSeedFile2, content);
|
|
28301
28311
|
if (!resolved.ok || resolved.content == null) {
|
|
28302
28312
|
return fail(`bootstrap propagate: ${r.repo} ${seed.target}: ${resolved.ok ? "rendered no content" : resolved.reason} \u2014 refusing an incomplete per-repo render`);
|
package/package.json
CHANGED