@theholocron/cli 4.10.2 → 4.10.3
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/README.md +5 -3
- package/dist/cli.mjs +39 -87
- package/dist/cli.mjs.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -306,9 +306,11 @@ all three. See the [telemetry guide](https://docs.theholocron.dev/holocron/telem
|
|
|
306
306
|
capability config packages, builds the capability registry
|
|
307
307
|
- `src/cli.ts` — yargs entry, dispatches subcommands. `holocron run` / `ci` are
|
|
308
308
|
delegated to [`@theholocron/astromech`](../astromech) (`createAstromech`).
|
|
309
|
-
`holocron sync
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
`holocron sync` / `holocron setup` write each repo's `.github/workflows/*.yml`
|
|
310
|
+
thin callers from `astromech.thinCallers()`; `holocron sync-github` pushes the
|
|
311
|
+
reusable `workflow_call` implementations + composite actions from
|
|
312
|
+
`astromech.reusableTemplates()` to `theholocron/.github` (a pure sync target —
|
|
313
|
+
never hand-edit its `.github/workflows/*`).
|
|
312
314
|
- `src/commands/` — `setup`, `sync`, `doctor`, `deploy`, `secret set`,
|
|
313
315
|
`secrets sync`, `npm publish-initial`, `sync-github`, `upgrade node`,
|
|
314
316
|
`plugin create`, `auth`
|
package/dist/cli.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import path, { basename, dirname, join, relative, resolve } from "node:path";
|
|
5
5
|
import { checkbox, input, select } from "@inquirer/prompts";
|
|
6
|
-
import { KNOWN_WORKFLOWS, createAstromech,
|
|
6
|
+
import { KNOWN_WORKFLOWS, createAstromech, extractPreviewConfig, reusableTemplates } from "@theholocron/astromech";
|
|
7
7
|
import { loadTasksConfig } from "@theholocron/astromech/config";
|
|
8
8
|
import yargs from "yargs";
|
|
9
9
|
import { hideBin } from "yargs/helpers";
|
|
@@ -4385,31 +4385,16 @@ async function runSetup(input) {
|
|
|
4385
4385
|
if (loader.has("source") && tasks && tasks.length > 0) {
|
|
4386
4386
|
const source = loader.get("source");
|
|
4387
4387
|
print(style.step("workflows"));
|
|
4388
|
+
const files = createAstromech({
|
|
4389
|
+
cwd: input.context.repoRoot,
|
|
4390
|
+
config: { tasks },
|
|
4391
|
+
orgContext: {
|
|
4392
|
+
org: config.org,
|
|
4393
|
+
domain: config.domain
|
|
4394
|
+
}
|
|
4395
|
+
}).thinCallers();
|
|
4388
4396
|
for (const entry of tasks) {
|
|
4389
4397
|
const name = typeof entry === "string" ? entry : entry.name;
|
|
4390
|
-
const rawWith = typeof entry === "object" ? entry.with : void 0;
|
|
4391
|
-
const normalized = rawWith ? normalizeWorkflowWith(rawWith) : void 0;
|
|
4392
|
-
let withOverrides = normalized;
|
|
4393
|
-
let comments;
|
|
4394
|
-
if (name === "lint") {
|
|
4395
|
-
let rootFiles = [];
|
|
4396
|
-
try {
|
|
4397
|
-
rootFiles = readdirSync(input.context.repoRoot);
|
|
4398
|
-
} catch {}
|
|
4399
|
-
const lint = lintThinCallerWith({
|
|
4400
|
-
explicit: typeof entry === "object" ? entry.linters : void 0,
|
|
4401
|
-
rootFiles,
|
|
4402
|
-
extra: normalized
|
|
4403
|
-
});
|
|
4404
|
-
withOverrides = lint.withOverrides;
|
|
4405
|
-
comments = lint.comments;
|
|
4406
|
-
}
|
|
4407
|
-
const additionalPaths = (typeof entry === "object" ? entry.paths : void 0) ?? (name === "deploy" && rawWith ? deriveDeployPaths(rawWith) : void 0);
|
|
4408
|
-
if (name === "test" && withOverrides) {
|
|
4409
|
-
const runUnit = withOverrides["run-unit"];
|
|
4410
|
-
const runStorybook = withOverrides["run-storybook"];
|
|
4411
|
-
if (runUnit === false && runStorybook === false) throw new ConfigError("test workflow: at least one of \"run-unit\" or \"run-storybook\" must be true. Library repos use run-unit: true; UI/Storybook repos use run-storybook: true.");
|
|
4412
|
-
}
|
|
4413
4398
|
if (!KNOWN_WORKFLOWS.has(name)) {
|
|
4414
4399
|
steps.push({
|
|
4415
4400
|
capability: "source",
|
|
@@ -4420,22 +4405,12 @@ async function runSetup(input) {
|
|
|
4420
4405
|
print(formatStep(steps[steps.length - 1]));
|
|
4421
4406
|
continue;
|
|
4422
4407
|
}
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
const paths = additionalPaths;
|
|
4430
|
-
steps.push(await runStep("source", "write workflow deploy (with preview)", dryRun, async () => {
|
|
4431
|
-
await source.writeWorkflowFile("deploy.yml", `${workflowHeader$1()}${generateCombinedDeployContent(withOverrides, paths, previewCfg)}`);
|
|
4432
|
-
}));
|
|
4433
|
-
print(formatStep(steps[steps.length - 1]));
|
|
4434
|
-
continue;
|
|
4435
|
-
}
|
|
4436
|
-
}
|
|
4437
|
-
steps.push(await runStep("source", `write workflow ${name}`, dryRun, async () => {
|
|
4438
|
-
await source.writeWorkflowFile(`${name}.yml`, `${workflowHeader$1()}${generateThinCallerContent(name, withOverrides, additionalPaths, void 0, comments)}`);
|
|
4408
|
+
const filename = name === "deploy" ? "deploy.yml" : `${name}.yml`;
|
|
4409
|
+
const content = files.get(filename);
|
|
4410
|
+
if (content === void 0) continue;
|
|
4411
|
+
const step = name === "deploy" && content.includes("workflows/preview.yml@main") ? "write workflow deploy (with preview)" : `write workflow ${name}`;
|
|
4412
|
+
steps.push(await runStep("source", step, dryRun, async () => {
|
|
4413
|
+
await source.writeWorkflowFile(filename, `${workflowHeader$1()}${content}`);
|
|
4439
4414
|
}));
|
|
4440
4415
|
print(formatStep(steps[steps.length - 1]));
|
|
4441
4416
|
}
|
|
@@ -5647,51 +5622,36 @@ async function runSync(input) {
|
|
|
5647
5622
|
message: "no tasks configured"
|
|
5648
5623
|
});
|
|
5649
5624
|
print(formatSyncStep(steps[steps.length - 1]));
|
|
5650
|
-
} else
|
|
5651
|
-
const
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
let comments;
|
|
5656
|
-
if (name === "lint") {
|
|
5657
|
-
const lint = lintThinCallerWith({
|
|
5658
|
-
explicit: typeof entry === "object" ? entry.linters : void 0,
|
|
5659
|
-
rootFiles: safeReaddir(input.context.repoRoot),
|
|
5660
|
-
extra: normalized
|
|
5661
|
-
});
|
|
5662
|
-
withOverrides = lint.withOverrides;
|
|
5663
|
-
comments = lint.comments;
|
|
5664
|
-
}
|
|
5665
|
-
const additionalPaths = (typeof entry === "object" ? entry.paths : void 0) ?? (name === "deploy" && rawWith ? deriveDeployPaths(rawWith) : void 0);
|
|
5666
|
-
if (!KNOWN_WORKFLOWS.has(name)) {
|
|
5667
|
-
steps.push({
|
|
5668
|
-
capability: "local",
|
|
5669
|
-
step: `sync workflow ${name}`,
|
|
5670
|
-
status: "skip",
|
|
5671
|
-
message: `unknown workflow "${name}" — no template available`
|
|
5672
|
-
});
|
|
5673
|
-
print(formatSyncStep(steps[steps.length - 1]));
|
|
5674
|
-
continue;
|
|
5675
|
-
}
|
|
5676
|
-
if (name === "deploy" && rawWith) {
|
|
5677
|
-
const previewCfg = extractPreviewConfig(rawWith, {
|
|
5625
|
+
} else {
|
|
5626
|
+
const files = createAstromech({
|
|
5627
|
+
cwd: input.context.repoRoot,
|
|
5628
|
+
config: { tasks: config.tasks },
|
|
5629
|
+
orgContext: {
|
|
5678
5630
|
org: config.org,
|
|
5679
5631
|
domain: config.domain
|
|
5680
|
-
}
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5632
|
+
}
|
|
5633
|
+
}).thinCallers();
|
|
5634
|
+
for (const entry of taskEntries) {
|
|
5635
|
+
const name = typeof entry === "string" ? entry : entry.name;
|
|
5636
|
+
if (!KNOWN_WORKFLOWS.has(name)) {
|
|
5637
|
+
steps.push({
|
|
5638
|
+
capability: "local",
|
|
5639
|
+
step: `sync workflow ${name}`,
|
|
5640
|
+
status: "skip",
|
|
5641
|
+
message: `unknown workflow "${name}" — no template available`
|
|
5642
|
+
});
|
|
5686
5643
|
print(formatSyncStep(steps[steps.length - 1]));
|
|
5687
5644
|
continue;
|
|
5688
5645
|
}
|
|
5646
|
+
const filename = name === "deploy" ? "deploy.yml" : `${name}.yml`;
|
|
5647
|
+
const content = files.get(filename);
|
|
5648
|
+
if (content === void 0) continue;
|
|
5649
|
+
const step = `sync workflow ${name}${name === "deploy" && content.includes("workflows/preview.yml@main") ? " (with preview)" : ""}`;
|
|
5650
|
+
steps.push(await runSyncStep("local", step, dryRun, async () => {
|
|
5651
|
+
await writeWorkflowFile(input.context.repoRoot, filename, `${workflowHeader()}${content}`);
|
|
5652
|
+
}));
|
|
5653
|
+
print(formatSyncStep(steps[steps.length - 1]));
|
|
5689
5654
|
}
|
|
5690
|
-
steps.push(await runSyncStep("local", `sync workflow ${name}`, dryRun, async () => {
|
|
5691
|
-
const content = `${workflowHeader()}${generateThinCallerContent(name, withOverrides, additionalPaths, void 0, comments)}`;
|
|
5692
|
-
await writeWorkflowFile(input.context.repoRoot, `${name}.yml`, content);
|
|
5693
|
-
}));
|
|
5694
|
-
print(formatSyncStep(steps[steps.length - 1]));
|
|
5695
5655
|
}
|
|
5696
5656
|
}
|
|
5697
5657
|
if (stepName === "scripts") if (config.syncScripts === false) {
|
|
@@ -5781,14 +5741,6 @@ function formatSyncStep(step) {
|
|
|
5781
5741
|
const detail = step.message ? ` (${step.message})` : "";
|
|
5782
5742
|
return ` ${icon} ${step.step}${detail}`;
|
|
5783
5743
|
}
|
|
5784
|
-
/** Repo-root filenames for linter auto-detection; `[]` when the dir is unreadable. */
|
|
5785
|
-
function safeReaddir(dir) {
|
|
5786
|
-
try {
|
|
5787
|
-
return readdirSync(dir);
|
|
5788
|
-
} catch {
|
|
5789
|
-
return [];
|
|
5790
|
-
}
|
|
5791
|
-
}
|
|
5792
5744
|
async function writePackageJsonField(repoRoot, field, value) {
|
|
5793
5745
|
const pkgPath = join(repoRoot, "package.json");
|
|
5794
5746
|
let content;
|