@mutmutco/cli 2.14.0 → 2.14.1

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.
Files changed (2) hide show
  1. package/dist/index.cjs +56 -2
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -6115,6 +6115,11 @@ var HUB_REPO2 = "mutmutco/MMI-Hub";
6115
6115
  var CORRELATE_ATTEMPTS = 5;
6116
6116
  var CORRELATE_DELAY_MS = 1500;
6117
6117
  var CORRELATE_SKEW_SLACK_MS = 1e4;
6118
+ var TRAIN_REQUIRED_CHECKS = ["cli", "infra", "docs"];
6119
+ var TRAIN_REQUIRED_CHECK_SET = new Set(TRAIN_REQUIRED_CHECKS);
6120
+ var TRAIN_CHECKS_JQ = '[.check_runs[]|select(.name|test("^(cli|infra|docs)$"))|{(.name):.conclusion}]';
6121
+ var TRAIN_CHECK_ATTEMPTS = 40;
6122
+ var TRAIN_CHECK_DELAY_MS = 15e3;
6118
6123
  async function correlateTenantRun(deps, since) {
6119
6124
  const sleep = deps.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
6120
6125
  const threshold = since - CORRELATE_SKEW_SLACK_MS;
@@ -6152,6 +6157,51 @@ async function watchTenantRun(deps, runId) {
6152
6157
  return "failure";
6153
6158
  }
6154
6159
  }
6160
+ function parseTrainCheckConclusions(out) {
6161
+ const parsed = JSON.parse(out);
6162
+ if (!Array.isArray(parsed)) throw new Error("check-runs response was not an array");
6163
+ const conclusions = /* @__PURE__ */ new Map();
6164
+ for (const row of parsed) {
6165
+ if (row == null || typeof row !== "object") continue;
6166
+ for (const [name, raw] of Object.entries(row)) {
6167
+ if (!TRAIN_REQUIRED_CHECK_SET.has(name)) continue;
6168
+ conclusions.set(name, raw == null ? null : String(raw));
6169
+ }
6170
+ }
6171
+ return conclusions;
6172
+ }
6173
+ function describeTrainChecks(conclusions) {
6174
+ return TRAIN_REQUIRED_CHECKS.map((name) => `${name}=${conclusions.get(name) ?? "missing"}`).join(", ");
6175
+ }
6176
+ async function waitForRequiredTrainChecks(deps, ctx, sha) {
6177
+ const sleep = deps.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
6178
+ let lastStatus = "not checked";
6179
+ let lastError;
6180
+ for (let attempt = 0; attempt < TRAIN_CHECK_ATTEMPTS; attempt++) {
6181
+ if (attempt > 0) await sleep(TRAIN_CHECK_DELAY_MS);
6182
+ let conclusions;
6183
+ try {
6184
+ const out = await deps.run("gh", ["api", `repos/${ctx.repo}/commits/${sha}/check-runs`, "--jq", TRAIN_CHECKS_JQ]);
6185
+ conclusions = parseTrainCheckConclusions(out);
6186
+ lastError = void 0;
6187
+ } catch (e) {
6188
+ lastError = e.message || String(e);
6189
+ continue;
6190
+ }
6191
+ lastStatus = describeTrainChecks(conclusions);
6192
+ const failed = TRAIN_REQUIRED_CHECKS.filter((name) => {
6193
+ const conclusion = conclusions.get(name);
6194
+ return conclusion != null && conclusion !== "success";
6195
+ });
6196
+ if (failed.length > 0) {
6197
+ throw new Error(`required train check failed: ${failed.join(", ")} (${lastStatus})`);
6198
+ }
6199
+ if (TRAIN_REQUIRED_CHECKS.every((name) => conclusions.get(name) === "success")) return;
6200
+ }
6201
+ throw new Error(
6202
+ `timed out waiting for required train checks on ${sha}: ${lastError ? `last error: ${lastError}` : lastStatus}`
6203
+ );
6204
+ }
6155
6205
  async function dispatchDeploy(deps, ctx, stage2, ref, model, watch) {
6156
6206
  if (model === "tenant-container") {
6157
6207
  const since = (deps.now ?? Date.now)();
@@ -6218,8 +6268,10 @@ async function runTrainApply(command, deps, options = {}) {
6218
6268
  await deps.run("git", ["pull", "--ff-only", "origin", "rc"]);
6219
6269
  await deps.run("git", ["merge", "development", "--no-edit"]);
6220
6270
  await deps.run("git", ["tag", tag2]);
6221
- await deps.run("git", ["push", "origin", "rc"]);
6222
6271
  await deps.run("git", ["push", "origin", tag2]);
6272
+ const rcSha = requireValue(clean(await deps.run("git", ["rev-parse", "rc"])), "rc sha");
6273
+ await waitForRequiredTrainChecks(deps, ctx, rcSha);
6274
+ await deps.run("git", ["push", "origin", "rc"]);
6223
6275
  const d2 = await dispatchDeploy(deps, ctx, "rc", "rc", deployModel2, watch);
6224
6276
  return { ...ctx, command, stage: "rc", ref: "rc", tag: tag2, deployModel: deployModel2, promoted: true, dispatch: d2.note, runId: d2.runId, runUrl: d2.runUrl, deployStatus: d2.deployStatus };
6225
6277
  }
@@ -6247,8 +6299,10 @@ async function runTrainApply(command, deps, options = {}) {
6247
6299
  const tag = requireValue(clean(await deps.run("node", ["scripts/next-version.mjs", "release"])), "release tag");
6248
6300
  await verifyHubDistributionVersion(deps, deployModel, tag);
6249
6301
  await deps.run("git", ["tag", tag]);
6250
- await deps.run("git", ["push", "origin", "main"]);
6251
6302
  await deps.run("git", ["push", "origin", tag]);
6303
+ const releaseSha = requireValue(clean(await deps.run("git", ["rev-parse", "main"])), "release sha");
6304
+ await waitForRequiredTrainChecks(deps, ctx, releaseSha);
6305
+ await deps.run("git", ["push", "origin", "main"]);
6252
6306
  await deps.run("gh", ["release", "create", tag, "--generate-notes", "--latest", "--repo", ctx.repo]);
6253
6307
  const d = await dispatchDeploy(deps, ctx, "main", "main", deployModel, watch);
6254
6308
  const retirement = await retireRcRuntime(deps, ctx, deployModel, d.deployStatus, releasedRcSha);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mutmutco/cli",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
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",