@mutmutco/cli 4.3.57 → 4.3.58
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 +87 -261
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -6046,6 +6046,15 @@ var REGISTRY_FETCH_TIMEOUT_MS = 8e3;
|
|
|
6046
6046
|
init_fetch_retry();
|
|
6047
6047
|
init_client_version();
|
|
6048
6048
|
|
|
6049
|
+
// ../shared/schedule-inventory.ts
|
|
6050
|
+
function classifyLlmValue(raw) {
|
|
6051
|
+
const value = raw.trim().toLowerCase();
|
|
6052
|
+
if (/^no\b|^none\b/.test(value)) return "no";
|
|
6053
|
+
if (/^yes\b/.test(value)) return "yes";
|
|
6054
|
+
if (/^embeddings\b/.test(value)) return "embeddings";
|
|
6055
|
+
return "unknown";
|
|
6056
|
+
}
|
|
6057
|
+
|
|
6049
6058
|
// src/workflow-context.ts
|
|
6050
6059
|
function parseWorkflowJobs(yaml) {
|
|
6051
6060
|
const lines2 = yaml.split(/\r?\n/);
|
|
@@ -6324,25 +6333,10 @@ function resolvedLabel(entry, now) {
|
|
|
6324
6333
|
var ORG = "mutmutco";
|
|
6325
6334
|
var DOC_START_MARKER = "<!-- schedules:inventory:start -->";
|
|
6326
6335
|
var DOC_END_MARKER = "<!-- schedules:inventory:end -->";
|
|
6327
|
-
function isJervResource(name) {
|
|
6328
|
-
return /^jerv-memory(?:-|$)/i.test(name);
|
|
6329
|
-
}
|
|
6330
6336
|
function llmFromHeader(yamlText) {
|
|
6331
6337
|
const m = /^#\s*llm:\s*(.+)$/im.exec(yamlText);
|
|
6332
6338
|
return m ? classifyLlmValue(m[1]) : "unknown";
|
|
6333
6339
|
}
|
|
6334
|
-
function classifyLlmValue(raw) {
|
|
6335
|
-
const value = raw.trim().toLowerCase();
|
|
6336
|
-
if (/^no\b|^none\b/.test(value)) return "no";
|
|
6337
|
-
if (/^yes\b/.test(value)) return "yes";
|
|
6338
|
-
if (/^embeddings\b/.test(value)) return "embeddings";
|
|
6339
|
-
return "unknown";
|
|
6340
|
-
}
|
|
6341
|
-
function readLlmDeclaration(text) {
|
|
6342
|
-
if (!text) return "unknown";
|
|
6343
|
-
const m = /\bllm:\s*(.+)/i.exec(text);
|
|
6344
|
-
return m ? classifyLlmValue(m[1]) : "unknown";
|
|
6345
|
-
}
|
|
6346
6340
|
function extractWorkflowCrons(yamlText) {
|
|
6347
6341
|
const crons = [];
|
|
6348
6342
|
for (const rawLine of yamlText.split("\n")) {
|
|
@@ -6366,126 +6360,6 @@ function workflowEntry(repo, workflowPath, yamlText) {
|
|
|
6366
6360
|
harbourUnmanaged: isHarbourUnmanaged(yamlText)
|
|
6367
6361
|
};
|
|
6368
6362
|
}
|
|
6369
|
-
function awsRuleEntries(payload) {
|
|
6370
|
-
if (!payload || typeof payload !== "object") {
|
|
6371
|
-
throw new Error("aws events list-rules answered a non-object payload \u2014 refusing to read it as zero rules");
|
|
6372
|
-
}
|
|
6373
|
-
const { Rules: rules } = payload;
|
|
6374
|
-
if (!Array.isArray(rules)) {
|
|
6375
|
-
throw new Error("aws events list-rules answered no Rules array \u2014 refusing to read it as zero rules");
|
|
6376
|
-
}
|
|
6377
|
-
const entries = [];
|
|
6378
|
-
for (const node of rules) {
|
|
6379
|
-
if (!node || typeof node !== "object") {
|
|
6380
|
-
throw new Error("aws events list-rules returned a non-object rule \u2014 refusing to read it as no rule");
|
|
6381
|
-
}
|
|
6382
|
-
const { Name, ScheduleExpression, State, Description } = node;
|
|
6383
|
-
if (typeof Name !== "string") {
|
|
6384
|
-
throw new Error("aws events list-rules returned a rule with no Name string \u2014 refusing to read it as no rule");
|
|
6385
|
-
}
|
|
6386
|
-
if (typeof ScheduleExpression !== "string") continue;
|
|
6387
|
-
if (State !== "ENABLED" || isJervResource(Name)) continue;
|
|
6388
|
-
entries.push({
|
|
6389
|
-
name: Name,
|
|
6390
|
-
cadence: ScheduleExpression,
|
|
6391
|
-
executor: "aws-eventbridge-rule",
|
|
6392
|
-
// An AWS rule declares `llm:` in its own Description (the shared convention) — a rule with no
|
|
6393
|
-
// Description reads `unknown`, and stack-internal plumbing like the Lambda warmer should say
|
|
6394
|
-
// `llm: no` there to go green.
|
|
6395
|
-
llm: readLlmDeclaration(typeof Description === "string" ? Description : void 0),
|
|
6396
|
-
resolved: "live",
|
|
6397
|
-
source: `aws events rule ${Name} (eu-central-1)`
|
|
6398
|
-
});
|
|
6399
|
-
}
|
|
6400
|
-
return entries;
|
|
6401
|
-
}
|
|
6402
|
-
function lambdaTargetFromArn(arn) {
|
|
6403
|
-
const marker = ":function:";
|
|
6404
|
-
const i = arn.indexOf(marker);
|
|
6405
|
-
if (i < 0) return { functionName: arn.split(":").pop() ?? "" };
|
|
6406
|
-
const rest = arn.slice(i + marker.length);
|
|
6407
|
-
const q = rest.indexOf(":");
|
|
6408
|
-
if (q < 0) return { functionName: rest };
|
|
6409
|
-
return { functionName: rest.slice(0, q), qualifier: rest.slice(q + 1) };
|
|
6410
|
-
}
|
|
6411
|
-
function awsScheduleEntry(payload) {
|
|
6412
|
-
if (!payload || typeof payload !== "object") {
|
|
6413
|
-
throw new Error("aws scheduler get-schedule answered a non-object payload \u2014 refusing to read it as no schedule");
|
|
6414
|
-
}
|
|
6415
|
-
const { Name, ScheduleExpression, State, Target, Description, CreationDate } = payload;
|
|
6416
|
-
if (typeof Name !== "string" || typeof ScheduleExpression !== "string") {
|
|
6417
|
-
throw new Error("aws scheduler get-schedule answered no Name/ScheduleExpression strings \u2014 refusing to read it as no schedule");
|
|
6418
|
-
}
|
|
6419
|
-
if (State !== "ENABLED" || isJervResource(Name)) return null;
|
|
6420
|
-
let target = "";
|
|
6421
|
-
let qualifier;
|
|
6422
|
-
let scheduleId;
|
|
6423
|
-
if (Target && typeof Target === "object") {
|
|
6424
|
-
const { Arn, Input } = Target;
|
|
6425
|
-
if (typeof Arn === "string") {
|
|
6426
|
-
const parsed = lambdaTargetFromArn(Arn);
|
|
6427
|
-
target = parsed.functionName;
|
|
6428
|
-
qualifier = parsed.qualifier;
|
|
6429
|
-
}
|
|
6430
|
-
if (typeof Input === "string") {
|
|
6431
|
-
try {
|
|
6432
|
-
const parsed = JSON.parse(Input);
|
|
6433
|
-
if (typeof parsed?.scheduleId === "string" && parsed.scheduleId) scheduleId = parsed.scheduleId;
|
|
6434
|
-
} catch {
|
|
6435
|
-
}
|
|
6436
|
-
}
|
|
6437
|
-
}
|
|
6438
|
-
const sourceBase = `aws scheduler schedule ${Name} (eu-central-1)`;
|
|
6439
|
-
const source = qualifier && target ? `${sourceBase} \u2192 ${target}:${qualifier}` : sourceBase;
|
|
6440
|
-
const armedAt = armedAtFromCreationDate(CreationDate);
|
|
6441
|
-
return {
|
|
6442
|
-
name: Name,
|
|
6443
|
-
cadence: ScheduleExpression,
|
|
6444
|
-
executor: target ? `aws-scheduler \u2192 ${target}` : "aws-scheduler",
|
|
6445
|
-
llm: readLlmDeclaration(typeof Description === "string" ? Description : void 0),
|
|
6446
|
-
resolved: "live",
|
|
6447
|
-
source,
|
|
6448
|
-
...scheduleId ? { scheduleId } : {},
|
|
6449
|
-
...armedAt ? { armedAt } : {}
|
|
6450
|
-
};
|
|
6451
|
-
}
|
|
6452
|
-
function armedAtFromCreationDate(creationDate) {
|
|
6453
|
-
if (creationDate instanceof Date) {
|
|
6454
|
-
return Number.isNaN(creationDate.getTime()) ? void 0 : creationDate.toISOString().slice(0, 10);
|
|
6455
|
-
}
|
|
6456
|
-
if (typeof creationDate === "string" && creationDate.trim()) {
|
|
6457
|
-
const parsed = Date.parse(creationDate);
|
|
6458
|
-
return Number.isNaN(parsed) ? void 0 : new Date(parsed).toISOString().slice(0, 10);
|
|
6459
|
-
}
|
|
6460
|
-
if (typeof creationDate === "number" && Number.isFinite(creationDate)) {
|
|
6461
|
-
const ms = creationDate > 1e12 ? creationDate : creationDate * 1e3;
|
|
6462
|
-
const date = new Date(ms);
|
|
6463
|
-
return Number.isNaN(date.getTime()) ? void 0 : date.toISOString().slice(0, 10);
|
|
6464
|
-
}
|
|
6465
|
-
return void 0;
|
|
6466
|
-
}
|
|
6467
|
-
function awsScheduleRefs(payload) {
|
|
6468
|
-
if (!payload || typeof payload !== "object") {
|
|
6469
|
-
throw new Error("aws scheduler list-schedules answered a non-object payload \u2014 refusing to read it as zero schedules");
|
|
6470
|
-
}
|
|
6471
|
-
const { Schedules: schedules } = payload;
|
|
6472
|
-
if (!Array.isArray(schedules)) {
|
|
6473
|
-
throw new Error("aws scheduler list-schedules answered no Schedules array \u2014 refusing to read it as zero schedules");
|
|
6474
|
-
}
|
|
6475
|
-
const refs = [];
|
|
6476
|
-
for (const s of schedules) {
|
|
6477
|
-
if (!s || typeof s !== "object") {
|
|
6478
|
-
throw new Error("aws scheduler list-schedules returned a non-object schedule \u2014 refusing to read it as no schedule");
|
|
6479
|
-
}
|
|
6480
|
-
const { Name, GroupName } = s;
|
|
6481
|
-
if (typeof Name !== "string") {
|
|
6482
|
-
throw new Error("aws scheduler list-schedules returned a schedule with no Name string \u2014 refusing to read it as no schedule");
|
|
6483
|
-
}
|
|
6484
|
-
if (isJervResource(Name)) continue;
|
|
6485
|
-
refs.push(typeof GroupName === "string" && GroupName !== "default" && GroupName !== "" ? { name: Name, group: GroupName } : { name: Name });
|
|
6486
|
-
}
|
|
6487
|
-
return refs;
|
|
6488
|
-
}
|
|
6489
6363
|
function decorateAwsModel(entries, registry2, verdicts) {
|
|
6490
6364
|
if (!registry2 || registry2.length === 0) return [...entries];
|
|
6491
6365
|
const rowById = new Map(registry2.map((r) => [r.id, r]));
|
|
@@ -6960,6 +6834,24 @@ async function fetchDeployFactsBySlug(slug, deps) {
|
|
|
6960
6834
|
return null;
|
|
6961
6835
|
}
|
|
6962
6836
|
}
|
|
6837
|
+
async function fetchScheduleInventory(deps) {
|
|
6838
|
+
try {
|
|
6839
|
+
if (!deps.baseUrl) return null;
|
|
6840
|
+
const token = await deps.token();
|
|
6841
|
+
if (!token) return null;
|
|
6842
|
+
const res = await retriedFetch(deps, `${deps.baseUrl.replace(/\/$/, "")}/schedules/inventory`, {
|
|
6843
|
+
method: "GET",
|
|
6844
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
6845
|
+
});
|
|
6846
|
+
if (!res.ok) return null;
|
|
6847
|
+
const body = await res.json();
|
|
6848
|
+
if (!body || !Array.isArray(body.entries) || !Array.isArray(body.incomplete) || !body.incomplete.every((v) => typeof v === "string") || typeof body.schedulerRead !== "boolean" || !body.schedulerRead && body.incomplete.length === 0) return null;
|
|
6849
|
+
if (!body.entries.every((e) => e && typeof e.name === "string" && typeof e.cadence === "string" && typeof e.executor === "string" && typeof e.source === "string" && e.resolved === "live" && ["yes", "no", "embeddings", "unknown"].includes(e.llm) && (e.scheduleId === void 0 || typeof e.scheduleId === "string") && (e.armedAt === void 0 || typeof e.armedAt === "string"))) return null;
|
|
6850
|
+
return body;
|
|
6851
|
+
} catch {
|
|
6852
|
+
return null;
|
|
6853
|
+
}
|
|
6854
|
+
}
|
|
6963
6855
|
async function fetchSchedulesList(deps) {
|
|
6964
6856
|
if (!deps.baseUrl) return null;
|
|
6965
6857
|
const token = await deps.token();
|
|
@@ -7071,6 +6963,9 @@ async function tenantReconcile(payload, deps) {
|
|
|
7071
6963
|
async function tenantDeploy(payload, deps) {
|
|
7072
6964
|
return postJson("/tenant-deploy", payload, deps, "POST", { noRetry: true, timeoutMs: TENANT_DEPLOY_TIMEOUT_MS });
|
|
7073
6965
|
}
|
|
6966
|
+
async function releaseAnnouncement(payload, deps) {
|
|
6967
|
+
return postJson("/release-announcement", payload, deps, "POST", { noRetry: true, timeoutMs: 3e4 });
|
|
6968
|
+
}
|
|
7074
6969
|
async function actionsCanary(payload, deps) {
|
|
7075
6970
|
return postJson("/actions-canary", payload, deps, "POST", { noRetry: true });
|
|
7076
6971
|
}
|
|
@@ -15877,10 +15772,10 @@ var rollout_plan_default = {
|
|
|
15877
15772
|
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)."
|
|
15878
15773
|
},
|
|
15879
15774
|
baseline: {
|
|
15880
|
-
version: "4.3.
|
|
15881
|
-
tag: "v4.3.
|
|
15882
|
-
commit: "
|
|
15883
|
-
npm: "@mutmutco/cli@4.3.
|
|
15775
|
+
version: "4.3.58",
|
|
15776
|
+
tag: "v4.3.58",
|
|
15777
|
+
commit: "aa4958ac3926",
|
|
15778
|
+
npm: "@mutmutco/cli@4.3.58"
|
|
15884
15779
|
},
|
|
15885
15780
|
exitCriterion: "fleet-n-of-n",
|
|
15886
15781
|
hubOnlyShortcut: "forbidden",
|
|
@@ -15897,14 +15792,14 @@ var rollout_plan_default = {
|
|
|
15897
15792
|
repo: "mutmutco/mmi-hub",
|
|
15898
15793
|
role: "canary",
|
|
15899
15794
|
schedule: "train",
|
|
15900
|
-
v3Target: "v4.3.
|
|
15795
|
+
v3Target: "v4.3.58"
|
|
15901
15796
|
}
|
|
15902
15797
|
],
|
|
15903
15798
|
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.",
|
|
15904
15799
|
rollback: {
|
|
15905
15800
|
independent: true,
|
|
15906
|
-
mechanism: "npm dist-tag latest -> 4.3.
|
|
15907
|
-
v3Target: "v4.3.
|
|
15801
|
+
mechanism: "npm dist-tag latest -> 4.3.58 and redeploy the Hub Lambda from tag v4.3.58 (aa4958ac3926); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
15802
|
+
v3Target: "v4.3.58 (@mutmutco/cli@4.3.58, tag commit aa4958ac3926 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
15908
15803
|
}
|
|
15909
15804
|
},
|
|
15910
15805
|
{
|
|
@@ -35594,15 +35489,9 @@ function writeError(res) {
|
|
|
35594
35489
|
|
|
35595
35490
|
// src/schedules-commands.ts
|
|
35596
35491
|
var import_promises5 = require("node:fs/promises");
|
|
35597
|
-
var import_node_child_process11 = require("node:child_process");
|
|
35598
|
-
var import_node_util6 = require("node:util");
|
|
35599
35492
|
init_clean_exit();
|
|
35600
35493
|
init_github_client();
|
|
35601
35494
|
init_cli_shared();
|
|
35602
|
-
var execFileP4 = (0, import_node_util6.promisify)(import_node_child_process11.execFile);
|
|
35603
|
-
var AWS_REGION = "eu-central-1";
|
|
35604
|
-
var AWS_TIMEOUT_MS = 3e4;
|
|
35605
|
-
var AWS_RETRY_DELAY_MS = 1500;
|
|
35606
35495
|
async function listWorkflows(client, repo) {
|
|
35607
35496
|
const all = [];
|
|
35608
35497
|
for (let page = 1; ; page += 1) {
|
|
@@ -35699,44 +35588,11 @@ async function githubEntries(client) {
|
|
|
35699
35588
|
drift.push(...reconciliation.map(renderDrift));
|
|
35700
35589
|
return { entries, incomplete, drift, reconciliation, readRepos, workflowNames: [...workflows.map((w) => w.name), ...unreadableNames], disabledWorkflowNames };
|
|
35701
35590
|
}
|
|
35702
|
-
async function awsJson(args) {
|
|
35703
|
-
const run = async () => {
|
|
35704
|
-
const { stdout } = await execFileP4("aws", [...args, "--region", AWS_REGION, "--output", "json"], {
|
|
35705
|
-
encoding: "utf8",
|
|
35706
|
-
windowsHide: true,
|
|
35707
|
-
timeout: AWS_TIMEOUT_MS
|
|
35708
|
-
});
|
|
35709
|
-
return JSON.parse(stdout);
|
|
35710
|
-
};
|
|
35711
|
-
try {
|
|
35712
|
-
return await run();
|
|
35713
|
-
} catch {
|
|
35714
|
-
await new Promise((resolve7) => setTimeout(resolve7, AWS_RETRY_DELAY_MS));
|
|
35715
|
-
return run();
|
|
35716
|
-
}
|
|
35717
|
-
}
|
|
35718
35591
|
async function awsEntries() {
|
|
35719
|
-
const
|
|
35720
|
-
|
|
35721
|
-
|
|
35722
|
-
|
|
35723
|
-
} catch (e) {
|
|
35724
|
-
incomplete.push(`aws: events list-rules failed \u2014 ${e.message}`);
|
|
35725
|
-
}
|
|
35726
|
-
let schedulerRead = false;
|
|
35727
|
-
try {
|
|
35728
|
-
const refs = awsScheduleRefs(await awsJson(["scheduler", "list-schedules"]));
|
|
35729
|
-
for (const ref of refs) {
|
|
35730
|
-
const args = ["scheduler", "get-schedule", "--name", ref.name, ...ref.group ? ["--group-name", ref.group] : []];
|
|
35731
|
-
const entry = awsScheduleEntry(await awsJson(args));
|
|
35732
|
-
if (entry) entries.push(entry);
|
|
35733
|
-
}
|
|
35734
|
-
schedulerRead = true;
|
|
35735
|
-
} catch (e) {
|
|
35736
|
-
incomplete.push(`aws: scheduler listing failed \u2014 ${e.message}`);
|
|
35737
|
-
}
|
|
35738
|
-
const reconciliation = unlauncheredLlmDrifts(entries);
|
|
35739
|
-
return { entries, incomplete, drift: reconciliation.map(renderDrift), reconciliation, schedulerRead };
|
|
35592
|
+
const inventory = await fetchScheduleInventory(registryClientDeps(await loadConfig()));
|
|
35593
|
+
if (!inventory) return { entries: [], incomplete: ["aws: Hub schedule inventory unavailable or unauthenticated"], drift: [], reconciliation: [], schedulerRead: false };
|
|
35594
|
+
const reconciliation = unlauncheredLlmDrifts(inventory.entries);
|
|
35595
|
+
return { ...inventory, reconciliation, drift: reconciliation.map(renderDrift) };
|
|
35740
35596
|
}
|
|
35741
35597
|
async function readOrFail(read) {
|
|
35742
35598
|
try {
|
|
@@ -36593,8 +36449,13 @@ async function resolveStageBuildSecrets(input) {
|
|
|
36593
36449
|
out[envKey] = fromVault;
|
|
36594
36450
|
continue;
|
|
36595
36451
|
}
|
|
36452
|
+
const fromGitHub = await input.githubToken?.();
|
|
36453
|
+
if (fromGitHub) {
|
|
36454
|
+
out[envKey] = fromGitHub;
|
|
36455
|
+
continue;
|
|
36456
|
+
}
|
|
36596
36457
|
missing.push(
|
|
36597
|
-
`${envKey}=${GITHUB_PACKAGES_TOKEN_REF} (
|
|
36458
|
+
`${envKey}=${GITHUB_PACKAGES_TOKEN_REF} (sign in with gh auth login using a package-readable GitHub identity, or provide process env ${envKey} or stageless project vault secret ${envKey}; npm.pkg.github.com still requires package read permission)`
|
|
36598
36459
|
);
|
|
36599
36460
|
continue;
|
|
36600
36461
|
}
|
|
@@ -36628,6 +36489,7 @@ async function fetchVaultRef(fetchVault, ref) {
|
|
|
36628
36489
|
}
|
|
36629
36490
|
|
|
36630
36491
|
// src/stage-commands.ts
|
|
36492
|
+
init_github_client();
|
|
36631
36493
|
function registerStageCommands(program3) {
|
|
36632
36494
|
function stagePortFromArgv() {
|
|
36633
36495
|
const raw = rawValue("--port", "");
|
|
@@ -36687,7 +36549,8 @@ function registerStageCommands(program3) {
|
|
|
36687
36549
|
const d = makeSecretsDeps(cfg);
|
|
36688
36550
|
const merge = await resolveStageBuildSecrets({
|
|
36689
36551
|
requiredBuildSecrets: required,
|
|
36690
|
-
fetchVault: (key, opts) => fetchSecretValue(d, key, opts ?? {})
|
|
36552
|
+
fetchVault: (key, opts) => fetchSecretValue(d, key, opts ?? {}),
|
|
36553
|
+
githubToken
|
|
36691
36554
|
});
|
|
36692
36555
|
return Object.keys(merge).length ? merge : void 0;
|
|
36693
36556
|
}
|
|
@@ -37089,7 +36952,7 @@ function renderVerifySecrets(body) {
|
|
|
37089
36952
|
}
|
|
37090
36953
|
|
|
37091
36954
|
// src/command-register-collaboration.ts
|
|
37092
|
-
var
|
|
36955
|
+
var import_node_child_process15 = require("node:child_process");
|
|
37093
36956
|
var import_node_fs41 = require("node:fs");
|
|
37094
36957
|
var import_promises7 = require("node:fs/promises");
|
|
37095
36958
|
init_clean_exit();
|
|
@@ -37475,12 +37338,12 @@ function boardAdvanceFailureMessage(result) {
|
|
|
37475
37338
|
}
|
|
37476
37339
|
|
|
37477
37340
|
// src/test-policy-core.ts
|
|
37478
|
-
var
|
|
37341
|
+
var import_node_child_process12 = require("node:child_process");
|
|
37479
37342
|
var import_node_fs35 = require("node:fs");
|
|
37480
37343
|
var import_node_path33 = require("node:path");
|
|
37481
37344
|
|
|
37482
37345
|
// src/test-command-policy-shared.mjs
|
|
37483
|
-
var
|
|
37346
|
+
var import_node_child_process11 = require("node:child_process");
|
|
37484
37347
|
var TEST_COMMAND_CLASS = "test";
|
|
37485
37348
|
var TRAILER_KEY = "Test-Policy-Override";
|
|
37486
37349
|
var OVERRIDE_RE = /^Test-Policy-Override:\s*(.+)$/im;
|
|
@@ -37597,7 +37460,7 @@ function evaluateTestCommandPolicy({ paths, mandatory, regulated = true, overrid
|
|
|
37597
37460
|
};
|
|
37598
37461
|
}
|
|
37599
37462
|
function git(args, cwd) {
|
|
37600
|
-
return (0,
|
|
37463
|
+
return (0, import_node_child_process11.execFileSync)("git", args, { windowsHide: true, cwd, encoding: "utf8", maxBuffer: 32 * 1024 * 1024 });
|
|
37601
37464
|
}
|
|
37602
37465
|
function parseScope(value) {
|
|
37603
37466
|
const scoped = /^\[([^\]]*)\]\s*([\s\S]*)$/.exec(value);
|
|
@@ -38096,14 +37959,14 @@ function evaluate(changed, policy, present = () => false) {
|
|
|
38096
37959
|
return findings;
|
|
38097
37960
|
}
|
|
38098
37961
|
function git2(args, cwd) {
|
|
38099
|
-
return (0,
|
|
37962
|
+
return (0, import_node_child_process12.execFileSync)("git", args, { windowsHide: true, cwd, encoding: "utf8", maxBuffer: 32 * 1024 * 1024 });
|
|
38100
37963
|
}
|
|
38101
37964
|
var COAUTHOR_KEY = "Co-authored-by";
|
|
38102
37965
|
var GH_MESSAGE_SEPARATOR = /^-{5,}$/;
|
|
38103
37966
|
var LIFTED_KEYS = new RegExp(`^(?:${TRAILER_KEY}|${COAUTHOR_KEY}):`, "i");
|
|
38104
37967
|
function parseTrailers(message2, cwd) {
|
|
38105
37968
|
try {
|
|
38106
|
-
return (0,
|
|
37969
|
+
return (0, import_node_child_process12.execFileSync)("git", ["interpret-trailers", "--parse", "--unfold"], {
|
|
38107
37970
|
windowsHide: true,
|
|
38108
37971
|
cwd,
|
|
38109
37972
|
input: message2,
|
|
@@ -38859,7 +38722,7 @@ function postMergeReconWarnings(input) {
|
|
|
38859
38722
|
}
|
|
38860
38723
|
|
|
38861
38724
|
// src/review-verdict.ts
|
|
38862
|
-
var
|
|
38725
|
+
var import_node_child_process13 = require("node:child_process");
|
|
38863
38726
|
var import_node_fs38 = require("node:fs");
|
|
38864
38727
|
var import_node_os19 = require("node:os");
|
|
38865
38728
|
var import_node_path36 = require("node:path");
|
|
@@ -38959,8 +38822,8 @@ async function checkPrReview(number, repo, head, deps = {
|
|
|
38959
38822
|
}
|
|
38960
38823
|
function computePrPatchId(number, repo) {
|
|
38961
38824
|
return new Promise((resolve7, reject) => {
|
|
38962
|
-
const gh = (0,
|
|
38963
|
-
const git3 = (0,
|
|
38825
|
+
const gh = (0, import_node_child_process13.spawn)("gh", ["pr", "diff", number, "--repo", repo], { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
|
|
38826
|
+
const git3 = (0, import_node_child_process13.spawn)("git", ["patch-id", "--stable"], { windowsHide: true, stdio: ["pipe", "pipe", "pipe"] });
|
|
38964
38827
|
let out = "";
|
|
38965
38828
|
let ghErr = "";
|
|
38966
38829
|
let gitErr = "";
|
|
@@ -39042,7 +38905,7 @@ async function postPrCommentFromFile(number, repo, body) {
|
|
|
39042
38905
|
}
|
|
39043
38906
|
|
|
39044
38907
|
// src/pr-create-docs-check.ts
|
|
39045
|
-
var
|
|
38908
|
+
var import_node_child_process14 = require("node:child_process");
|
|
39046
38909
|
init_cli_shared();
|
|
39047
38910
|
var GIT_TIMEOUT_MS2 = 15e3;
|
|
39048
38911
|
function catFileBatch(root, ref, paths) {
|
|
@@ -39050,7 +38913,7 @@ function catFileBatch(root, ref, paths) {
|
|
|
39050
38913
|
return new Promise((resolve7) => {
|
|
39051
38914
|
const chunks = [];
|
|
39052
38915
|
let settled = false;
|
|
39053
|
-
const child2 = (0,
|
|
38916
|
+
const child2 = (0, import_node_child_process14.spawn)("git", ["-C", root, "cat-file", "--batch", "--buffer"], { windowsHide: true });
|
|
39054
38917
|
const finish = () => {
|
|
39055
38918
|
if (settled) return;
|
|
39056
38919
|
settled = true;
|
|
@@ -40197,7 +40060,7 @@ function scheduleRelatedDiscovery(o) {
|
|
|
40197
40060
|
try {
|
|
40198
40061
|
const args = ["issue", "discover-related", "--number", String(o.number), "--title", o.title, "--body", o.body, "--fail-soft"];
|
|
40199
40062
|
if (o.repo) args.push("--repo", o.repo);
|
|
40200
|
-
spawnDetachedSelf(args, { spawn:
|
|
40063
|
+
spawnDetachedSelf(args, { spawn: import_node_child_process15.spawn, execPath: process.execPath, scriptPath: process.argv[1] }, { cwd: process.cwd() });
|
|
40201
40064
|
} catch {
|
|
40202
40065
|
}
|
|
40203
40066
|
}
|
|
@@ -41893,7 +41756,7 @@ ${SSH_RECIPE_AGENT_NOTE}`);
|
|
|
41893
41756
|
}
|
|
41894
41757
|
|
|
41895
41758
|
// src/dist-drift.ts
|
|
41896
|
-
var
|
|
41759
|
+
var import_node_child_process16 = require("node:child_process");
|
|
41897
41760
|
var import_node_crypto13 = require("node:crypto");
|
|
41898
41761
|
var import_node_fs44 = require("node:fs");
|
|
41899
41762
|
var import_node_os20 = require("node:os");
|
|
@@ -42038,7 +41901,7 @@ function bomPathFor(root) {
|
|
|
42038
41901
|
}
|
|
42039
41902
|
}
|
|
42040
41903
|
function rebuildTo(packageRoot, outDir) {
|
|
42041
|
-
(0,
|
|
41904
|
+
(0, import_node_child_process16.execFileSync)(process.execPath, ["build.mjs"], {
|
|
42042
41905
|
cwd: packageRoot,
|
|
42043
41906
|
env: { ...process.env, MMI_DIST_OUTDIR: outDir },
|
|
42044
41907
|
windowsHide: true,
|
|
@@ -42265,7 +42128,7 @@ function registerSchedulesLiftCommand(program3, deps = {}) {
|
|
|
42265
42128
|
}
|
|
42266
42129
|
|
|
42267
42130
|
// src/spawn-policy-core.ts
|
|
42268
|
-
var
|
|
42131
|
+
var import_node_child_process17 = require("node:child_process");
|
|
42269
42132
|
var import_node_fs45 = require("node:fs");
|
|
42270
42133
|
var import_node_path43 = require("node:path");
|
|
42271
42134
|
var SPAWNERS = ["spawn", "spawnSync", "exec", "execSync", "execFile", "execFileSync"];
|
|
@@ -42336,7 +42199,7 @@ function findViolationsInSource(raw) {
|
|
|
42336
42199
|
return found;
|
|
42337
42200
|
}
|
|
42338
42201
|
function policedFiles(root) {
|
|
42339
|
-
const r = (0,
|
|
42202
|
+
const r = (0, import_node_child_process17.spawnSync)("git", ["ls-files", "-z", "--cached", "--others", "--exclude-standard"], {
|
|
42340
42203
|
cwd: root,
|
|
42341
42204
|
encoding: "utf8",
|
|
42342
42205
|
windowsHide: true,
|
|
@@ -42642,50 +42505,6 @@ init_house_map();
|
|
|
42642
42505
|
// src/hotfix-apply.ts
|
|
42643
42506
|
var import_promises9 = require("node:fs/promises");
|
|
42644
42507
|
|
|
42645
|
-
// src/slack-alert.ts
|
|
42646
|
-
var SSM_REGION = "eu-central-1";
|
|
42647
|
-
var SSM_TOKEN_PARAM = "/mmi-future/_org/slack/SLACK_BOT_TOKEN";
|
|
42648
|
-
var SSM_CHANNEL_PARAM = "/mmi-future/_org/slack/SLACK_ALERTS_CHANNEL";
|
|
42649
|
-
var SLACK_TIMEOUT_MS = 1e4;
|
|
42650
|
-
async function readSsmParameter(deps, name, decrypt) {
|
|
42651
|
-
const args = [
|
|
42652
|
-
"ssm",
|
|
42653
|
-
"get-parameter",
|
|
42654
|
-
"--region",
|
|
42655
|
-
SSM_REGION,
|
|
42656
|
-
"--name",
|
|
42657
|
-
name,
|
|
42658
|
-
"--query",
|
|
42659
|
-
"Parameter.Value",
|
|
42660
|
-
"--output",
|
|
42661
|
-
"text",
|
|
42662
|
-
...decrypt ? ["--with-decryption"] : []
|
|
42663
|
-
];
|
|
42664
|
-
const value = (await deps.run("aws", args)).trim();
|
|
42665
|
-
if (!value || value === "None") throw new Error(`SSM parameter ${name} is empty`);
|
|
42666
|
-
return value;
|
|
42667
|
-
}
|
|
42668
|
-
async function postToChannel(deps, channel, text) {
|
|
42669
|
-
const resolved = channel.trim();
|
|
42670
|
-
if (!resolved || resolved === "None") throw new Error("no Slack channel resolved");
|
|
42671
|
-
const token = await readSsmParameter(deps, SSM_TOKEN_PARAM, true);
|
|
42672
|
-
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
42673
|
-
const res = await fetchImpl("https://slack.com/api/chat.postMessage", {
|
|
42674
|
-
method: "POST",
|
|
42675
|
-
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json; charset=utf-8" },
|
|
42676
|
-
body: JSON.stringify({ channel: resolved, text, unfurl_links: false }),
|
|
42677
|
-
signal: AbortSignal.timeout(SLACK_TIMEOUT_MS)
|
|
42678
|
-
});
|
|
42679
|
-
const json = await res.json().catch(() => ({}));
|
|
42680
|
-
if (!json.ok) throw new Error(`slack postMessage failed: ${json.error ?? `http ${res.status}`}`);
|
|
42681
|
-
return { status: "posted", note: "posted" };
|
|
42682
|
-
}
|
|
42683
|
-
async function postToAlertsChannel(deps, text) {
|
|
42684
|
-
const channel = await readSsmParameter(deps, SSM_CHANNEL_PARAM, false);
|
|
42685
|
-
await postToChannel(deps, channel, text);
|
|
42686
|
-
return { status: "posted", note: "posted to the alerts channel" };
|
|
42687
|
-
}
|
|
42688
|
-
|
|
42689
42508
|
// src/release-announce.ts
|
|
42690
42509
|
var ANNOUNCE_REPO = "mutmutco/MMI-Hub";
|
|
42691
42510
|
var MAX_BULLETS = 6;
|
|
@@ -42792,12 +42611,6 @@ async function announceRelease(deps, args) {
|
|
|
42792
42611
|
if (args.summaryFile) {
|
|
42793
42612
|
if (!deps.readFile) throw new Error("summary file given but deps.readFile is missing");
|
|
42794
42613
|
lines2 = summaryFileLines(await deps.readFile(args.summaryFile), neutralize);
|
|
42795
|
-
if (deps.removeFile) {
|
|
42796
|
-
try {
|
|
42797
|
-
await deps.removeFile(args.summaryFile);
|
|
42798
|
-
} catch {
|
|
42799
|
-
}
|
|
42800
|
-
}
|
|
42801
42614
|
}
|
|
42802
42615
|
if (lines2.length === 0) {
|
|
42803
42616
|
if (target.kind !== "alerts") {
|
|
@@ -42813,12 +42626,16 @@ async function announceRelease(deps, args) {
|
|
|
42813
42626
|
releaseUrl,
|
|
42814
42627
|
...target.kind === "channel" ? { language: target.language } : {}
|
|
42815
42628
|
});
|
|
42816
|
-
|
|
42817
|
-
|
|
42818
|
-
|
|
42629
|
+
const delivery = await deps.postAnnouncement({ repo: args.repo, tag: args.tag, text });
|
|
42630
|
+
if (delivery === "skipped") return { status: "skipped", note: missingChannelNote(args.repo) };
|
|
42631
|
+
if (args.summaryFile && deps.removeFile) {
|
|
42632
|
+
try {
|
|
42633
|
+
await deps.removeFile(args.summaryFile);
|
|
42634
|
+
} catch {
|
|
42635
|
+
}
|
|
42819
42636
|
}
|
|
42820
|
-
|
|
42821
|
-
return { status: "announced", note:
|
|
42637
|
+
const destination = target.kind === "alerts" ? "alerts channel" : "project release channel";
|
|
42638
|
+
return { status: "announced", note: `${delivery === "already-posted" ? "already announced" : "announced"} ${args.tag} to the ${destination}` };
|
|
42822
42639
|
} catch (e) {
|
|
42823
42640
|
return { status: "failed", note: `announce failed (release unaffected): ${e.message}` };
|
|
42824
42641
|
}
|
|
@@ -43945,12 +43762,12 @@ async function findInFlightHotfixVersion(deps, ctx, latestMainTag, workflows = H
|
|
|
43945
43762
|
}
|
|
43946
43763
|
|
|
43947
43764
|
// src/hotfix-coverage.ts
|
|
43948
|
-
var
|
|
43765
|
+
var import_node_child_process18 = require("node:child_process");
|
|
43949
43766
|
var CHERRY_TRAILER = /\(cherry picked from commit ([0-9a-f]{7,40})\)/g;
|
|
43950
43767
|
function checkHotfixCoverage(options = {}) {
|
|
43951
43768
|
const { cwd = process.cwd(), mainRef = "origin/main", rcRef = "origin/rc", manifestPaths = [] } = options;
|
|
43952
43769
|
const ack = (options.ack ?? []).filter(Boolean);
|
|
43953
|
-
const git3 = options.git ?? ((args, opts) => (0,
|
|
43770
|
+
const git3 = options.git ?? ((args, opts) => (0, import_node_child_process18.execFileSync)("git", args, { cwd, encoding: "utf8", input: opts?.input, stdio: ["pipe", "pipe", "pipe"] }));
|
|
43954
43771
|
const revList = (range) => {
|
|
43955
43772
|
const out = git3(["rev-list", "--no-merges", range]).trim();
|
|
43956
43773
|
return out ? out.split("\n") : [];
|
|
@@ -44018,7 +43835,7 @@ function checkHotfixCoverage(options = {}) {
|
|
|
44018
43835
|
}
|
|
44019
43836
|
function checkHotfixCarries(options) {
|
|
44020
43837
|
const { cwd = process.cwd(), branch, baseRef, targets } = options;
|
|
44021
|
-
const git3 = options.git ?? ((args, opts) => (0,
|
|
43838
|
+
const git3 = options.git ?? ((args, opts) => (0, import_node_child_process18.execFileSync)("git", args, { cwd, encoding: "utf8", input: opts?.input, stdio: ["pipe", "pipe", "pipe"] }));
|
|
44022
43839
|
const isAncestor = (sha, ref) => {
|
|
44023
43840
|
try {
|
|
44024
43841
|
git3(["merge-base", "--is-ancestor", sha, ref]);
|
|
@@ -44288,6 +44105,15 @@ function trainApplyDeps() {
|
|
|
44288
44105
|
// registry releaseChannel META for a product repo — best-effort inside announceRelease itself.
|
|
44289
44106
|
announce: (args) => announceRelease({
|
|
44290
44107
|
run: async (file, cmdArgs) => (await execFileP(file, cmdArgs, { timeout: GH_TRAIN_TIMEOUT_MS })).stdout,
|
|
44108
|
+
postAnnouncement: async (payload) => {
|
|
44109
|
+
const res = await releaseAnnouncement(payload, registryClientDeps(await loadConfig()));
|
|
44110
|
+
const body = res.body;
|
|
44111
|
+
if (!res.ok) throw new Error(body?.error ?? `Hub announcement failed (HTTP ${res.status}); verify delivery before retrying`);
|
|
44112
|
+
if (body?.ok !== true || body.status !== "posted" && body?.status !== "already-posted" && body?.status !== "skipped") {
|
|
44113
|
+
throw new Error("Hub announcement returned an unverified delivery result; do not resend");
|
|
44114
|
+
}
|
|
44115
|
+
return body.status;
|
|
44116
|
+
},
|
|
44291
44117
|
readFile: (path2) => (0, import_promises10.readFile)(path2, "utf8"),
|
|
44292
44118
|
removeFile: (path2) => (0, import_promises10.unlink)(path2),
|
|
44293
44119
|
// #6521/#6523: the project's own release channel AND releaseLanguage, read from registry META in ONE
|
package/package.json
CHANGED