@plexus-ms/cli-ci 0.119.0 → 0.121.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.
- package/dist/plx-ci.js +85 -70
- 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
|
|
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:
|
|
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
|
|
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 =
|
|
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:
|
|
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" });
|
|
@@ -7368,6 +7368,34 @@ var require_dist = __commonJS({
|
|
|
7368
7368
|
}
|
|
7369
7369
|
});
|
|
7370
7370
|
|
|
7371
|
+
// ../lib/dist/lints.js
|
|
7372
|
+
var MONTH = "Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|Aug(?:ust)?|Sep(?:t(?:ember)?)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?";
|
|
7373
|
+
var YEAR = "(?:19|20)\\d{2}";
|
|
7374
|
+
var DATE_OR_VERSION = new RegExp([
|
|
7375
|
+
// 2026-11-04, 2026-07, 2026-11-04T10:00Z
|
|
7376
|
+
`(?<![\\w-])${YEAR}-(?:0[1-9]|1[0-2])(?:-(?:0[1-9]|[12]\\d|3[01])(?:T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:?\\d{2})?)?)?(?![\\w-])`,
|
|
7377
|
+
// November 2026, Nov. 4, 2026
|
|
7378
|
+
`\\b(?:${MONTH})\\.?\\s+(?:\\d{1,2}(?:st|nd|rd|th)?,?\\s+)?${YEAR}\\b`,
|
|
7379
|
+
// in 2026, since 2025, Q3 2026
|
|
7380
|
+
`\\b(?:[Ii]n|[Ss]ince|[Uu]ntil|[Tt]ill|[Aa]s of|[Bb]efore|[Aa]fter|[Dd]uring|[Ee]arly|[Mm]id|[Ll]ate|Q[1-4])\\s+${YEAR}\\b(?![.,]?\\d)`,
|
|
7381
|
+
// 0.111.0, 1.2.3-rc.1; not the dotted parts of an IP address, not a section number
|
|
7382
|
+
"(?<![\\w.\xA7]|\xA7\\s*)(?!1\\.0\\.0(?![\\w-]|\\.\\d))\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.]+)?(?!\\.?\\d)",
|
|
7383
|
+
// v24, v1.48
|
|
7384
|
+
"(?<![\\w./-])v\\d+(?:\\.\\d+)*\\b",
|
|
7385
|
+
// pnpm@12, hk@1.48 (three parts are caught above)
|
|
7386
|
+
"(?<=@)\\d+(?:\\.\\d+)?\\b(?!\\.\\d)"
|
|
7387
|
+
].join("|"), "g");
|
|
7388
|
+
var CODE = "PLX(?:-[A-Z][A-Za-z]+)?(?![A-Za-z])";
|
|
7389
|
+
var NUMBER = "\\d+(?:\\.\\d+)*";
|
|
7390
|
+
var NUMBERS = `${NUMBER}(?:[ \\t\\u00a0]*(?:,|and|or|&|\u2013|-|to)[ \\t\\u00a0]*${NUMBER})*`;
|
|
7391
|
+
var GAP = "(?:[ \\t\\u00a0]+|[ \\t]*\\r?\\n[ \\t]*(?:#+|//+|\\*|>)?[ \\t]*)";
|
|
7392
|
+
var SIGN = `(?<!\xA7)\xA7\xA7?[ \\t\\u00a0]*`;
|
|
7393
|
+
var NAME_LIKE = "PLX-[A-Z][A-Za-z]+(?:/[\\w-]+)+";
|
|
7394
|
+
var FORWARD = new RegExp(`${SIGN}(${NUMBERS})${GAP}(${CODE})`, "g");
|
|
7395
|
+
var REVERSE = new RegExp(`(?<![\\w-])(${CODE})[ \\t\\u00a0]*,?[ \\t\\u00a0]*${SIGN}(${NUMBERS})`, "g");
|
|
7396
|
+
var BARE = new RegExp(`${SIGN}(${NUMBERS})`, "g");
|
|
7397
|
+
var NAME_CITATION = new RegExp(`(?<![\\w/-])${NAME_LIKE}(?![\\w/])`, "g");
|
|
7398
|
+
|
|
7371
7399
|
// ../lib/dist/marker.js
|
|
7372
7400
|
var import_yaml = __toESM(require_dist(), 1);
|
|
7373
7401
|
|
|
@@ -7389,6 +7417,15 @@ ${stderr.trimEnd()}` : ""}`);
|
|
|
7389
7417
|
this.stderr = stderr;
|
|
7390
7418
|
}
|
|
7391
7419
|
};
|
|
7420
|
+
async function orAbsent(read, absent = () => true) {
|
|
7421
|
+
try {
|
|
7422
|
+
return await read;
|
|
7423
|
+
} catch (error) {
|
|
7424
|
+
if (error instanceof ExecError && absent(error))
|
|
7425
|
+
return void 0;
|
|
7426
|
+
throw error;
|
|
7427
|
+
}
|
|
7428
|
+
}
|
|
7392
7429
|
var isInteractive = () => process.stdin.isTTY === true && process.stderr.isTTY === true;
|
|
7393
7430
|
function realIo(prompt) {
|
|
7394
7431
|
return {
|
|
@@ -7462,20 +7499,20 @@ function body(step) {
|
|
|
7462
7499
|
}
|
|
7463
7500
|
}
|
|
7464
7501
|
|
|
7465
|
-
// ../lib/dist/
|
|
7502
|
+
// ../lib/dist/version.js
|
|
7466
7503
|
var COMPENDIUM = "compendium";
|
|
7467
|
-
var
|
|
7468
|
-
"
|
|
7469
|
-
"
|
|
7470
|
-
"
|
|
7471
|
-
"
|
|
7504
|
+
var VERSIONED_REPOS = [
|
|
7505
|
+
"tooling",
|
|
7506
|
+
"template-repo-turbo",
|
|
7507
|
+
"template-app-nextjs",
|
|
7508
|
+
"template-repo-operations",
|
|
7472
7509
|
COMPENDIUM
|
|
7473
7510
|
];
|
|
7474
7511
|
var UsageError = class extends Error {
|
|
7475
7512
|
};
|
|
7476
7513
|
|
|
7477
7514
|
// ../lib/dist/consumers.js
|
|
7478
|
-
var
|
|
7515
|
+
var TEMPLATES = VERSIONED_REPOS.filter((r) => r.startsWith("template-"));
|
|
7479
7516
|
|
|
7480
7517
|
// ../lib/dist/context.js
|
|
7481
7518
|
var Context = class {
|
|
@@ -7684,7 +7721,7 @@ async function readDeployTargets(ctx, inventory) {
|
|
|
7684
7721
|
var DAY = 24 * 60 * 60 * 1e3;
|
|
7685
7722
|
|
|
7686
7723
|
// ../lib/dist/update.js
|
|
7687
|
-
var
|
|
7724
|
+
var RELEASES_REPO = `plexus-ms/${COMPENDIUM}`;
|
|
7688
7725
|
|
|
7689
7726
|
// src/program.ts
|
|
7690
7727
|
import { createRequire } from "node:module";
|
|
@@ -11378,66 +11415,50 @@ async function startSidecars(ctx, storage, owner, now = /* @__PURE__ */ new Date
|
|
|
11378
11415
|
);
|
|
11379
11416
|
return { current: buckets.current, previous: buckets.previous, previousAnswers };
|
|
11380
11417
|
}
|
|
11381
|
-
|
|
11418
|
+
var curlNotFound = (error) => error.code === 22 && /\b404\b/.test(error.stderr);
|
|
11419
|
+
var craneNotFound = (error) => /MANIFEST_UNKNOWN|NAME_UNKNOWN|\b404\b/.test(error.stderr);
|
|
11420
|
+
async function lookUp(ctx, ref, command, args, absent) {
|
|
11382
11421
|
try {
|
|
11383
|
-
return
|
|
11384
|
-
|
|
11385
|
-
|
|
11386
|
-
|
|
11387
|
-
|
|
11388
|
-
|
|
11389
|
-
"-I",
|
|
11390
|
-
"-H",
|
|
11391
|
-
`Accept: ${ACCEPT}`,
|
|
11392
|
-
`http://127.0.0.1:${port}/v2/${app}/manifests/${tag}`
|
|
11393
|
-
])).trim();
|
|
11394
|
-
} catch {
|
|
11395
|
-
return "000";
|
|
11422
|
+
return await orAbsent(ctx.read(command, args), absent);
|
|
11423
|
+
} catch (error) {
|
|
11424
|
+
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?`;
|
|
11425
|
+
if (!ctx.dryRun) throw new Error(why, { cause: error });
|
|
11426
|
+
ctx.say(`[dry-run] ${why.split("\n")[0]}; taken for absent`);
|
|
11427
|
+
return void 0;
|
|
11396
11428
|
}
|
|
11397
11429
|
}
|
|
11430
|
+
var manifestUrl = (port, app, tag) => `http://127.0.0.1:${port}/v2/${app}/manifests/${tag}`;
|
|
11431
|
+
var head = (ctx, port, app, tag, absent = curlNotFound) => lookUp(
|
|
11432
|
+
ctx,
|
|
11433
|
+
`localhost:${port}/${app}:${tag}`,
|
|
11434
|
+
"curl",
|
|
11435
|
+
["-fsS", "-I", "-H", `Accept: ${ACCEPT}`, manifestUrl(port, app, tag)],
|
|
11436
|
+
absent
|
|
11437
|
+
);
|
|
11398
11438
|
async function tagExists(ctx, app, tag) {
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
}
|
|
11439
|
+
if (await head(ctx, CURRENT_PORT, app, tag) !== void 0) return CURRENT_PORT;
|
|
11440
|
+
if (await head(ctx, PREVIOUS_PORT, app, tag, () => true) !== void 0) return PREVIOUS_PORT;
|
|
11402
11441
|
return void 0;
|
|
11403
11442
|
}
|
|
11404
11443
|
async function digest(ctx, app, tag, port = CURRENT_PORT) {
|
|
11405
|
-
|
|
11406
|
-
const head = await ctx.read("curl", [
|
|
11407
|
-
"-fsS",
|
|
11408
|
-
"-I",
|
|
11409
|
-
"-H",
|
|
11410
|
-
`Accept: ${ACCEPT}`,
|
|
11411
|
-
`http://127.0.0.1:${port}/v2/${app}/manifests/${tag}`
|
|
11412
|
-
]);
|
|
11413
|
-
return head.match(/^docker-content-digest:\s*(\S+)/im)?.[1];
|
|
11414
|
-
} catch {
|
|
11415
|
-
return void 0;
|
|
11416
|
-
}
|
|
11444
|
+
return (await head(ctx, port, app, tag))?.match(/^docker-content-digest:\s*(\S+)/im)?.[1];
|
|
11417
11445
|
}
|
|
11418
11446
|
async function layers(ctx, app, tag, port = CURRENT_PORT) {
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
return (data.layers ?? []).map((l) => ({ digest: l.digest, size: l.size }));
|
|
11428
|
-
} catch {
|
|
11429
|
-
return void 0;
|
|
11430
|
-
}
|
|
11447
|
+
const manifest = await lookUp(
|
|
11448
|
+
ctx,
|
|
11449
|
+
`localhost:${port}/${app}:${tag}`,
|
|
11450
|
+
"curl",
|
|
11451
|
+
["-fsS", "-H", `Accept: ${ACCEPT}`, manifestUrl(port, app, tag)],
|
|
11452
|
+
curlNotFound
|
|
11453
|
+
);
|
|
11454
|
+
return manifest === void 0 ? void 0 : layersIn(manifest);
|
|
11431
11455
|
}
|
|
11456
|
+
var layersIn = (manifest) => (JSON.parse(manifest).layers ?? []).map((l) => ({ digest: l.digest, size: l.size }));
|
|
11432
11457
|
function candidateRef(registry, app, tag) {
|
|
11433
11458
|
return registry.kind === "own" ? `localhost:${CURRENT_PORT}/${app}:${tag}` : `${imageName(registry.prefix, app)}:${tag}`;
|
|
11434
11459
|
}
|
|
11435
11460
|
async function craneDigest(ctx, ref) {
|
|
11436
|
-
|
|
11437
|
-
return (await ctx.read("crane", ["digest", ref])).trim() || void 0;
|
|
11438
|
-
} catch {
|
|
11439
|
-
return void 0;
|
|
11440
|
-
}
|
|
11461
|
+
return (await lookUp(ctx, ref, "crane", ["digest", ref], craneNotFound))?.trim() || void 0;
|
|
11441
11462
|
}
|
|
11442
11463
|
async function findTag(ctx, registry, app, tag) {
|
|
11443
11464
|
if (registry.kind === "own") {
|
|
@@ -11452,12 +11473,9 @@ function digestOf(ctx, registry, app, tag) {
|
|
|
11452
11473
|
}
|
|
11453
11474
|
async function layersOf(ctx, registry, app, tag) {
|
|
11454
11475
|
if (registry.kind === "own") return layers(ctx, app, tag);
|
|
11455
|
-
|
|
11456
|
-
|
|
11457
|
-
|
|
11458
|
-
} catch {
|
|
11459
|
-
return void 0;
|
|
11460
|
-
}
|
|
11476
|
+
const ref = candidateRef(registry, app, tag);
|
|
11477
|
+
const manifest = await lookUp(ctx, ref, "crane", ["manifest", ref], craneNotFound);
|
|
11478
|
+
return manifest === void 0 ? void 0 : layersIn(manifest);
|
|
11461
11479
|
}
|
|
11462
11480
|
async function loggedIn(ctx, host, env = process.env) {
|
|
11463
11481
|
const file = `${env.DOCKER_CONFIG || `${env.HOME}/.docker`}/config.json`;
|
|
@@ -12729,11 +12747,8 @@ function packageOf(prefix, app) {
|
|
|
12729
12747
|
async function prune(ctx, packages, names, now = /* @__PURE__ */ new Date()) {
|
|
12730
12748
|
const pruned = [];
|
|
12731
12749
|
for (const name of names) {
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
versions = await packages.versions(name);
|
|
12735
|
-
} catch (error) {
|
|
12736
|
-
if (!(error instanceof ExecError)) throw error;
|
|
12750
|
+
const versions = await orAbsent(packages.versions(name), curlNotFound);
|
|
12751
|
+
if (versions === void 0) {
|
|
12737
12752
|
ctx.say(`rotate: no package ${name} in ghcr.io/${packages.org}`);
|
|
12738
12753
|
continue;
|
|
12739
12754
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plexus-ms/cli-ci",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.121.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/
|
|
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.
|
|
26
|
+
"@plexus-ms/lib": "0.121.0",
|
|
27
27
|
"commander": "^15.0.0",
|
|
28
28
|
"yaml": "^2.9.1"
|
|
29
29
|
},
|