@computesdk/cli 1.0.12 → 1.0.13
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/index.js +117 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -981,6 +981,19 @@ function sanitizePathPart(name) {
|
|
|
981
981
|
async function client(opts) {
|
|
982
982
|
return new ActionsClient(await resolveActionsAuth(opts));
|
|
983
983
|
}
|
|
984
|
+
function assertVaultValueHost(auth) {
|
|
985
|
+
if (!isTrustedActionsHost(auth.baseUrl)) {
|
|
986
|
+
throw new ActionsCliError(
|
|
987
|
+
"untrusted_host",
|
|
988
|
+
`Refusing to send or read vault values at ${auth.baseUrl} \u2014 only computesdk.com and localhost hosts are allowed, even with --allow-untrusted-host.`
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
async function vaultValueClient(opts) {
|
|
993
|
+
const auth = await resolveActionsAuth(opts);
|
|
994
|
+
assertVaultValueHost(auth);
|
|
995
|
+
return new ActionsClient(auth);
|
|
996
|
+
}
|
|
984
997
|
function output(opts, data, render) {
|
|
985
998
|
if (opts.json) {
|
|
986
999
|
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
@@ -1384,6 +1397,42 @@ function dispatchBody(workflow, opts) {
|
|
|
1384
1397
|
}
|
|
1385
1398
|
};
|
|
1386
1399
|
}
|
|
1400
|
+
function parseVaultKind(kind) {
|
|
1401
|
+
if (kind === void 0 || kind === "secret" || kind === "variable") return kind ?? "secret";
|
|
1402
|
+
throw new ActionsCliError("invalid_argument", `--kind must be secret or variable, got "${kind}".`);
|
|
1403
|
+
}
|
|
1404
|
+
function vaultPath(path5, params) {
|
|
1405
|
+
const search = new URLSearchParams();
|
|
1406
|
+
for (const [key, value] of Object.entries(params)) {
|
|
1407
|
+
if (value !== void 0) search.set(key, value);
|
|
1408
|
+
}
|
|
1409
|
+
const query = search.toString();
|
|
1410
|
+
return query ? `${path5}?${query}` : path5;
|
|
1411
|
+
}
|
|
1412
|
+
function vaultSetBody(name, value, opts) {
|
|
1413
|
+
if (value === "") throw new ActionsCliError("invalid_argument", "The value is empty.");
|
|
1414
|
+
if (opts.revealable && opts.kind === "variable") {
|
|
1415
|
+
throw new ActionsCliError("invalid_argument", "--revealable applies to secrets; variables are always readable.");
|
|
1416
|
+
}
|
|
1417
|
+
return {
|
|
1418
|
+
name,
|
|
1419
|
+
kind: opts.kind,
|
|
1420
|
+
value,
|
|
1421
|
+
...opts.revealable && { revealable: true },
|
|
1422
|
+
...opts.description !== void 0 && { description: opts.description },
|
|
1423
|
+
...opts.labels !== void 0 && opts.labels.length > 0 && { labels: opts.labels }
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
function formatVaultRow(item) {
|
|
1427
|
+
const flags = [
|
|
1428
|
+
item.kind,
|
|
1429
|
+
...item.revealable && item.kind === "secret" ? ["revealable"] : [],
|
|
1430
|
+
`v${item.version}`,
|
|
1431
|
+
...item.source === "organization" ? ["inherited"] : [],
|
|
1432
|
+
...item.overridesOrganization ? ["overrides org"] : []
|
|
1433
|
+
];
|
|
1434
|
+
return `${pc.cyan(safeTerm(item.name))} ${pc.dim(flags.join(", "))} ${pc.dim(`updated ${safeTerm(item.updatedAt)}`)}`;
|
|
1435
|
+
}
|
|
1387
1436
|
function registerActionsCommands(program2) {
|
|
1388
1437
|
const actions = program2.command("actions").alias("ci").description("Drive the benchmarks-platform Actions API").configureOutput({ outputError: usageErrorOutput });
|
|
1389
1438
|
const common = (cmd) => cmd.option("--api-key <key>", "API key (default: $COMPUTE_API_KEY)").option("--base-url <url>", "API base URL (default: https://platform.computesdk.com)").option("--allow-untrusted-host", "send an explicit --api-key/env key to a non-computesdk, non-localhost --base-url (stored login credentials are never sent)").option("--json", "print machine-readable JSON");
|
|
@@ -1714,6 +1763,74 @@ function registerActionsCommands(program2) {
|
|
|
1714
1763
|
fail(e, opts);
|
|
1715
1764
|
}
|
|
1716
1765
|
});
|
|
1766
|
+
const vault = actions.command("vault").description("The org vault: secrets and variables (owner/admin key)");
|
|
1767
|
+
const vaultScope = (cmd) => common(cmd).option("--repo <owner/repo>", "scope to a repo's own items instead of the org's").option("--kind <kind>", "secret or variable", "secret");
|
|
1768
|
+
vaultScope(
|
|
1769
|
+
vault.command("ls").description("List names and metadata (never values)")
|
|
1770
|
+
).action(async (opts) => {
|
|
1771
|
+
try {
|
|
1772
|
+
const path5 = vaultPath("/api/v1/vault", { repo: opts.repo, kind: parseVaultKind(opts.kind) });
|
|
1773
|
+
const data = await (await client(opts)).get(path5);
|
|
1774
|
+
output(opts, data, (d) => {
|
|
1775
|
+
for (const item of d.items) console.log(formatVaultRow(item));
|
|
1776
|
+
});
|
|
1777
|
+
} catch (e) {
|
|
1778
|
+
fail(e, opts);
|
|
1779
|
+
}
|
|
1780
|
+
});
|
|
1781
|
+
vaultScope(
|
|
1782
|
+
vault.command("set").description("Store a value, read from stdin (or --from-file) and sent exactly as read").argument("<name>", "item name, e.g. NPM_TOKEN").option("--from-file <path>", "read the value from a file instead of stdin").option("--revealable", "let the value be read back with `vault get` (secrets; fixed at creation)").option("--description <text>", "what the item is for").option("--labels <labels...>", "labels (fixed at creation)")
|
|
1783
|
+
).action(async (name, opts) => {
|
|
1784
|
+
try {
|
|
1785
|
+
if (opts.fromFile === void 0 && process.stdin.isTTY) {
|
|
1786
|
+
throw new ActionsCliError(
|
|
1787
|
+
"invalid_argument",
|
|
1788
|
+
'Pipe the value on stdin (e.g. printf %s "$VALUE" | compute actions vault set NAME) or pass --from-file.'
|
|
1789
|
+
);
|
|
1790
|
+
}
|
|
1791
|
+
const value = readFileSync(opts.fromFile ?? 0, "utf8");
|
|
1792
|
+
const kind = parseVaultKind(opts.kind);
|
|
1793
|
+
const body = vaultSetBody(name, value, { ...opts, kind });
|
|
1794
|
+
const result = await (await vaultValueClient(opts)).put(
|
|
1795
|
+
vaultPath("/api/v1/vault", { repo: opts.repo }),
|
|
1796
|
+
body
|
|
1797
|
+
);
|
|
1798
|
+
output(opts, result, (r) => {
|
|
1799
|
+
const where = opts.repo ? safeTerm(opts.repo) : "org";
|
|
1800
|
+
console.log(`saved ${pc.cyan(safeTerm(r.item.name))} ${pc.dim(`(${r.item.kind}, v${r.item.version}, ${where})`)}`);
|
|
1801
|
+
if (/\r?\n$/.test(value)) {
|
|
1802
|
+
console.error(pc.yellow("note: the stored value ends with a newline; use printf %s rather than echo to avoid one."));
|
|
1803
|
+
}
|
|
1804
|
+
});
|
|
1805
|
+
} catch (e) {
|
|
1806
|
+
fail(e, opts);
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
vaultScope(
|
|
1810
|
+
vault.command("get").description("Print a value: any variable, or a secret created --revealable").argument("<name>", "item name")
|
|
1811
|
+
).action(async (name, opts) => {
|
|
1812
|
+
try {
|
|
1813
|
+
const kind = parseVaultKind(opts.kind);
|
|
1814
|
+
const result = await (await vaultValueClient(opts)).post(
|
|
1815
|
+
vaultPath("/api/v1/vault/reveal", { repo: opts.repo }),
|
|
1816
|
+
{ name, kind }
|
|
1817
|
+
);
|
|
1818
|
+
output(opts, result, (r) => process.stdout.write(r.value));
|
|
1819
|
+
} catch (e) {
|
|
1820
|
+
fail(e, opts);
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
vaultScope(
|
|
1824
|
+
vault.command("rm").description("Delete an item (with --repo, only the repo's override)").argument("<name>", "item name")
|
|
1825
|
+
).action(async (name, opts) => {
|
|
1826
|
+
try {
|
|
1827
|
+
const path5 = vaultPath("/api/v1/vault", { repo: opts.repo, kind: parseVaultKind(opts.kind), name });
|
|
1828
|
+
const result = await (await client(opts)).del(path5);
|
|
1829
|
+
output(opts, result, (r) => console.log(`deleted ${pc.cyan(safeTerm(r.name))} ${pc.dim(`(${r.kind})`)}`));
|
|
1830
|
+
} catch (e) {
|
|
1831
|
+
fail(e, opts);
|
|
1832
|
+
}
|
|
1833
|
+
});
|
|
1717
1834
|
common(
|
|
1718
1835
|
actions.command("cancel").description("Cancel a run").argument("<run-id>", "run ID")
|
|
1719
1836
|
).action(async (runId, opts) => {
|