@plexus-ms/cli-ci 0.118.0 → 0.120.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.
Files changed (2) hide show
  1. package/dist/plx-ci.js +57 -75
  2. package/package.json +3 -3
package/dist/plx-ci.js CHANGED
@@ -5358,10 +5358,10 @@ var require_cst_scalar = __commonJS({
5358
5358
  case "|":
5359
5359
  case ">": {
5360
5360
  const he = source.indexOf("\n");
5361
- const head = source.substring(0, he);
5361
+ const head2 = source.substring(0, he);
5362
5362
  const body2 = source.substring(he + 1) + "\n";
5363
5363
  const props = [
5364
- { type: "block-scalar-header", offset, indent: indent2, source: head }
5364
+ { type: "block-scalar-header", offset, indent: indent2, source: head2 }
5365
5365
  ];
5366
5366
  if (!addEndtoBlockProps(props, end))
5367
5367
  props.push({ type: "newline", offset: -1, indent: indent2, source: "\n" });
@@ -5421,19 +5421,19 @@ var require_cst_scalar = __commonJS({
5421
5421
  }
5422
5422
  function setBlockScalarValue(token, source) {
5423
5423
  const he = source.indexOf("\n");
5424
- const head = source.substring(0, he);
5424
+ const head2 = source.substring(0, he);
5425
5425
  const body2 = source.substring(he + 1) + "\n";
5426
5426
  if (token.type === "block-scalar") {
5427
5427
  const header = token.props[0];
5428
5428
  if (header.type !== "block-scalar-header")
5429
5429
  throw new Error("Invalid block scalar header");
5430
- header.source = head;
5430
+ header.source = head2;
5431
5431
  token.source = body2;
5432
5432
  } else {
5433
5433
  const { offset } = token;
5434
5434
  const indent2 = "indent" in token ? token.indent : -1;
5435
5435
  const props = [
5436
- { type: "block-scalar-header", offset, indent: indent2, source: head }
5436
+ { type: "block-scalar-header", offset, indent: indent2, source: head2 }
5437
5437
  ];
5438
5438
  if (!addEndtoBlockProps(props, "end" in token ? token.end : void 0))
5439
5439
  props.push({ type: "newline", offset: -1, indent: indent2, source: "\n" });
@@ -7389,6 +7389,15 @@ ${stderr.trimEnd()}` : ""}`);
7389
7389
  this.stderr = stderr;
7390
7390
  }
7391
7391
  };
7392
+ async function orAbsent(read, absent = () => true) {
7393
+ try {
7394
+ return await read;
7395
+ } catch (error) {
7396
+ if (error instanceof ExecError && absent(error))
7397
+ return void 0;
7398
+ throw error;
7399
+ }
7400
+ }
7392
7401
  var isInteractive = () => process.stdin.isTTY === true && process.stderr.isTTY === true;
7393
7402
  function realIo(prompt) {
7394
7403
  return {
@@ -7462,22 +7471,20 @@ function body(step) {
7462
7471
  }
7463
7472
  }
7464
7473
 
7465
- // ../lib/dist/train.js
7466
- var PRIMITIVES = "primitives";
7474
+ // ../lib/dist/version.js
7467
7475
  var COMPENDIUM = "compendium";
7468
- var TRAIN_REPOS = [
7469
- PRIMITIVES,
7470
- "preset-repo-turbo",
7471
- "preset-app-nextjs",
7472
- "preset-repo-operations",
7476
+ var VERSIONED_REPOS = [
7477
+ "tooling",
7478
+ "template-repo-turbo",
7479
+ "template-app-nextjs",
7480
+ "template-repo-operations",
7473
7481
  COMPENDIUM
7474
7482
  ];
7475
- var PHASES = [[PRIMITIVES], TRAIN_REPOS.filter((r) => r !== PRIMITIVES)];
7476
7483
  var UsageError = class extends Error {
7477
7484
  };
7478
7485
 
7479
7486
  // ../lib/dist/consumers.js
7480
- var PRESETS = TRAIN_REPOS.filter((r) => r.startsWith("preset-"));
7487
+ var TEMPLATES = VERSIONED_REPOS.filter((r) => r.startsWith("template-"));
7481
7488
 
7482
7489
  // ../lib/dist/context.js
7483
7490
  var Context = class {
@@ -7686,10 +7693,7 @@ async function readDeployTargets(ctx, inventory) {
7686
7693
  var DAY = 24 * 60 * 60 * 1e3;
7687
7694
 
7688
7695
  // ../lib/dist/update.js
7689
- var TRAINS = `plexus-ms/${COMPENDIUM}`;
7690
-
7691
- // ../lib/dist/ship.js
7692
- var DEFAULT_WAIT = { interval: 15e3, timeout: 20 * 6e4 };
7696
+ var RELEASES_REPO = `plexus-ms/${COMPENDIUM}`;
7693
7697
 
7694
7698
  // src/program.ts
7695
7699
  import { createRequire } from "node:module";
@@ -11383,66 +11387,50 @@ async function startSidecars(ctx, storage, owner, now = /* @__PURE__ */ new Date
11383
11387
  );
11384
11388
  return { current: buckets.current, previous: buckets.previous, previousAnswers };
11385
11389
  }
11386
- async function manifestStatus(ctx, port, app, tag) {
11390
+ var curlNotFound = (error) => error.code === 22 && /\b404\b/.test(error.stderr);
11391
+ var craneNotFound = (error) => /MANIFEST_UNKNOWN|NAME_UNKNOWN|\b404\b/.test(error.stderr);
11392
+ async function lookUp(ctx, ref, command, args, absent) {
11387
11393
  try {
11388
- return (await ctx.read("curl", [
11389
- "-s",
11390
- "-o",
11391
- "/dev/null",
11392
- "-w",
11393
- "%{http_code}",
11394
- "-I",
11395
- "-H",
11396
- `Accept: ${ACCEPT}`,
11397
- `http://127.0.0.1:${port}/v2/${app}/manifests/${tag}`
11398
- ])).trim();
11399
- } catch {
11400
- return "000";
11394
+ return await orAbsent(ctx.read(command, args), absent);
11395
+ } catch (error) {
11396
+ const why = error instanceof ExecError ? `could not look up ${ref}: ${error.message}` : `${command} could not run to look up ${ref}; is it installed in this job?`;
11397
+ if (!ctx.dryRun) throw new Error(why, { cause: error });
11398
+ ctx.say(`[dry-run] ${why.split("\n")[0]}; taken for absent`);
11399
+ return void 0;
11401
11400
  }
11402
11401
  }
11402
+ var manifestUrl = (port, app, tag) => `http://127.0.0.1:${port}/v2/${app}/manifests/${tag}`;
11403
+ var head = (ctx, port, app, tag, absent = curlNotFound) => lookUp(
11404
+ ctx,
11405
+ `localhost:${port}/${app}:${tag}`,
11406
+ "curl",
11407
+ ["-fsS", "-I", "-H", `Accept: ${ACCEPT}`, manifestUrl(port, app, tag)],
11408
+ absent
11409
+ );
11403
11410
  async function tagExists(ctx, app, tag) {
11404
- for (const port of [CURRENT_PORT, PREVIOUS_PORT]) {
11405
- if (await manifestStatus(ctx, port, app, tag) === "200") return port;
11406
- }
11411
+ if (await head(ctx, CURRENT_PORT, app, tag) !== void 0) return CURRENT_PORT;
11412
+ if (await head(ctx, PREVIOUS_PORT, app, tag, () => true) !== void 0) return PREVIOUS_PORT;
11407
11413
  return void 0;
11408
11414
  }
11409
11415
  async function digest(ctx, app, tag, port = CURRENT_PORT) {
11410
- try {
11411
- const head = await ctx.read("curl", [
11412
- "-fsS",
11413
- "-I",
11414
- "-H",
11415
- `Accept: ${ACCEPT}`,
11416
- `http://127.0.0.1:${port}/v2/${app}/manifests/${tag}`
11417
- ]);
11418
- return head.match(/^docker-content-digest:\s*(\S+)/im)?.[1];
11419
- } catch {
11420
- return void 0;
11421
- }
11416
+ return (await head(ctx, port, app, tag))?.match(/^docker-content-digest:\s*(\S+)/im)?.[1];
11422
11417
  }
11423
11418
  async function layers(ctx, app, tag, port = CURRENT_PORT) {
11424
- try {
11425
- const body2 = await ctx.read("curl", [
11426
- "-fsS",
11427
- "-H",
11428
- `Accept: ${ACCEPT}`,
11429
- `http://127.0.0.1:${port}/v2/${app}/manifests/${tag}`
11430
- ]);
11431
- const data = JSON.parse(body2);
11432
- return (data.layers ?? []).map((l) => ({ digest: l.digest, size: l.size }));
11433
- } catch {
11434
- return void 0;
11435
- }
11419
+ const manifest = await lookUp(
11420
+ ctx,
11421
+ `localhost:${port}/${app}:${tag}`,
11422
+ "curl",
11423
+ ["-fsS", "-H", `Accept: ${ACCEPT}`, manifestUrl(port, app, tag)],
11424
+ curlNotFound
11425
+ );
11426
+ return manifest === void 0 ? void 0 : layersIn(manifest);
11436
11427
  }
11428
+ var layersIn = (manifest) => (JSON.parse(manifest).layers ?? []).map((l) => ({ digest: l.digest, size: l.size }));
11437
11429
  function candidateRef(registry, app, tag) {
11438
11430
  return registry.kind === "own" ? `localhost:${CURRENT_PORT}/${app}:${tag}` : `${imageName(registry.prefix, app)}:${tag}`;
11439
11431
  }
11440
11432
  async function craneDigest(ctx, ref) {
11441
- try {
11442
- return (await ctx.read("crane", ["digest", ref])).trim() || void 0;
11443
- } catch {
11444
- return void 0;
11445
- }
11433
+ return (await lookUp(ctx, ref, "crane", ["digest", ref], craneNotFound))?.trim() || void 0;
11446
11434
  }
11447
11435
  async function findTag(ctx, registry, app, tag) {
11448
11436
  if (registry.kind === "own") {
@@ -11457,12 +11445,9 @@ function digestOf(ctx, registry, app, tag) {
11457
11445
  }
11458
11446
  async function layersOf(ctx, registry, app, tag) {
11459
11447
  if (registry.kind === "own") return layers(ctx, app, tag);
11460
- try {
11461
- const data = JSON.parse(await ctx.read("crane", ["manifest", candidateRef(registry, app, tag)]));
11462
- return (data.layers ?? []).map((l) => ({ digest: l.digest, size: l.size }));
11463
- } catch {
11464
- return void 0;
11465
- }
11448
+ const ref = candidateRef(registry, app, tag);
11449
+ const manifest = await lookUp(ctx, ref, "crane", ["manifest", ref], craneNotFound);
11450
+ return manifest === void 0 ? void 0 : layersIn(manifest);
11466
11451
  }
11467
11452
  async function loggedIn(ctx, host, env = process.env) {
11468
11453
  const file = `${env.DOCKER_CONFIG || `${env.HOME}/.docker`}/config.json`;
@@ -12734,11 +12719,8 @@ function packageOf(prefix, app) {
12734
12719
  async function prune(ctx, packages, names, now = /* @__PURE__ */ new Date()) {
12735
12720
  const pruned = [];
12736
12721
  for (const name of names) {
12737
- let versions;
12738
- try {
12739
- versions = await packages.versions(name);
12740
- } catch (error) {
12741
- if (!(error instanceof ExecError)) throw error;
12722
+ const versions = await orAbsent(packages.versions(name), curlNotFound);
12723
+ if (versions === void 0) {
12742
12724
  ctx.say(`rotate: no package ${name} in ghcr.io/${packages.org}`);
12743
12725
  continue;
12744
12726
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plexus-ms/cli-ci",
3
- "version": "0.118.0",
3
+ "version": "0.120.0",
4
4
  "description": "plx-ci, the CI verbs of Plexus: throwaway runners on a cloud, a registry on object storage, reproducible image builds, and their teardown",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "type": "module",
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://github.com/plexus-ms/primitives.git",
15
+ "url": "git+https://github.com/plexus-ms/tooling.git",
16
16
  "directory": "packages/cli-ci"
17
17
  },
18
18
  "publishConfig": {
@@ -23,7 +23,7 @@
23
23
  "node": ">=24.22.1"
24
24
  },
25
25
  "dependencies": {
26
- "@plexus-ms/lib": "0.118.0",
26
+ "@plexus-ms/lib": "0.120.0",
27
27
  "commander": "^15.0.0",
28
28
  "yaml": "^2.9.1"
29
29
  },