@theholocron/cli 3.24.0 → 3.24.2
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/cli.mjs +65 -50
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -2808,6 +2808,65 @@ function generateThinCallerContent(name, withOverrides, additionalPaths) {
|
|
|
2808
2808
|
if (injected === result) console.warn(`[generateThinCallerContent] could not inject with: overrides into "${name}" template`);
|
|
2809
2809
|
return injected;
|
|
2810
2810
|
}
|
|
2811
|
+
/**
|
|
2812
|
+
* Expand structured with-values to flat GitHub Actions inputs before
|
|
2813
|
+
* generating the thin caller. Handles:
|
|
2814
|
+
* - deploy shorthand: docs/storybook → type + storybook-projects
|
|
2815
|
+
* - run-chromatic object → run-chromatic: true + chromatic-projects
|
|
2816
|
+
* - plain arrays → JSON-stringified for YAML scalar quoting
|
|
2817
|
+
*
|
|
2818
|
+
* Used by both `holocron setup` and `sync-workflow-templates`.
|
|
2819
|
+
*/
|
|
2820
|
+
function normalizeWorkflowWith(raw) {
|
|
2821
|
+
const result = { ...raw };
|
|
2822
|
+
const hasDocs = raw["docs"] === true || raw["docs"] !== null && typeof raw["docs"] === "object";
|
|
2823
|
+
const storybookProjects = raw["storybook"];
|
|
2824
|
+
if (hasDocs) {
|
|
2825
|
+
result["type"] = "docs";
|
|
2826
|
+
delete result["docs"];
|
|
2827
|
+
}
|
|
2828
|
+
if (Array.isArray(storybookProjects)) {
|
|
2829
|
+
if (!hasDocs) result["type"] = "storybook";
|
|
2830
|
+
result["storybook-projects"] = JSON.stringify(storybookProjects.map(({ name, path = "." }) => ({
|
|
2831
|
+
name,
|
|
2832
|
+
workingDir: path
|
|
2833
|
+
})));
|
|
2834
|
+
delete result["storybook"];
|
|
2835
|
+
}
|
|
2836
|
+
const runChromatic = raw["run-chromatic"];
|
|
2837
|
+
if (runChromatic !== null && typeof runChromatic === "object" && "projects" in runChromatic) {
|
|
2838
|
+
result["run-chromatic"] = true;
|
|
2839
|
+
const projects = runChromatic.projects.map((p) => ({
|
|
2840
|
+
...p,
|
|
2841
|
+
...Array.isArray(p.untraced) ? { untraced: p.untraced.join("\n") } : {}
|
|
2842
|
+
}));
|
|
2843
|
+
result["chromatic-projects"] = JSON.stringify(projects);
|
|
2844
|
+
}
|
|
2845
|
+
for (const [k, v] of Object.entries(result)) if (Array.isArray(v)) result[k] = JSON.stringify(v);
|
|
2846
|
+
return result;
|
|
2847
|
+
}
|
|
2848
|
+
/**
|
|
2849
|
+
* Derive on.push.paths entries from the deploy with: shorthand.
|
|
2850
|
+
* Used by both `holocron setup` and `sync-workflow-templates`.
|
|
2851
|
+
*/
|
|
2852
|
+
function deriveDeployPaths(raw) {
|
|
2853
|
+
const paths = [];
|
|
2854
|
+
const docs = raw["docs"];
|
|
2855
|
+
if (docs === true) paths.push("docs/**");
|
|
2856
|
+
else if (docs !== null && typeof docs === "object" && "path" in docs) {
|
|
2857
|
+
const p = docs.path;
|
|
2858
|
+
if (p && p !== ".") paths.push(`${p}/**`);
|
|
2859
|
+
}
|
|
2860
|
+
const storybookProjects = raw["storybook"];
|
|
2861
|
+
if (Array.isArray(storybookProjects)) for (const s of storybookProjects) {
|
|
2862
|
+
const p = s.path || ".";
|
|
2863
|
+
if (p === ".") {
|
|
2864
|
+
paths.push("src/**");
|
|
2865
|
+
paths.push(".storybook/**");
|
|
2866
|
+
} else paths.push(`${p}/**`);
|
|
2867
|
+
}
|
|
2868
|
+
return paths;
|
|
2869
|
+
}
|
|
2811
2870
|
//#endregion
|
|
2812
2871
|
//#region src/commands/setup.ts
|
|
2813
2872
|
/**
|
|
@@ -3264,52 +3323,6 @@ async function runSetup(input) {
|
|
|
3264
3323
|
print(formatStep(steps[steps.length - 1]));
|
|
3265
3324
|
}
|
|
3266
3325
|
}
|
|
3267
|
-
function normalizeWorkflowWith(raw) {
|
|
3268
|
-
const result = { ...raw };
|
|
3269
|
-
const hasDocs = raw["docs"] === true || raw["docs"] !== null && typeof raw["docs"] === "object";
|
|
3270
|
-
const storybookProjects = raw["storybook"];
|
|
3271
|
-
if (hasDocs) {
|
|
3272
|
-
result["type"] = "docs";
|
|
3273
|
-
delete result["docs"];
|
|
3274
|
-
}
|
|
3275
|
-
if (Array.isArray(storybookProjects)) {
|
|
3276
|
-
if (!hasDocs) result["type"] = "storybook";
|
|
3277
|
-
result["storybook-projects"] = JSON.stringify(storybookProjects.map(({ name, path = "." }) => ({
|
|
3278
|
-
name,
|
|
3279
|
-
workingDir: path
|
|
3280
|
-
})));
|
|
3281
|
-
delete result["storybook"];
|
|
3282
|
-
}
|
|
3283
|
-
const runChromatic = raw["run-chromatic"];
|
|
3284
|
-
if (runChromatic !== null && typeof runChromatic === "object" && "projects" in runChromatic) {
|
|
3285
|
-
result["run-chromatic"] = true;
|
|
3286
|
-
const projects = runChromatic.projects.map((p) => ({
|
|
3287
|
-
...p,
|
|
3288
|
-
...Array.isArray(p.untraced) ? { untraced: p.untraced.join("\n") } : {}
|
|
3289
|
-
}));
|
|
3290
|
-
result["chromatic-projects"] = JSON.stringify(projects);
|
|
3291
|
-
}
|
|
3292
|
-
for (const [k, v] of Object.entries(result)) if (Array.isArray(v)) result[k] = JSON.stringify(v);
|
|
3293
|
-
return result;
|
|
3294
|
-
}
|
|
3295
|
-
function deriveDeployPaths(raw) {
|
|
3296
|
-
const paths = [];
|
|
3297
|
-
const docs = raw["docs"];
|
|
3298
|
-
if (docs === true) paths.push("docs/**");
|
|
3299
|
-
else if (docs !== null && typeof docs === "object" && "path" in docs) {
|
|
3300
|
-
const p = docs.path;
|
|
3301
|
-
if (p && p !== ".") paths.push(`${p}/**`);
|
|
3302
|
-
}
|
|
3303
|
-
const storybookProjects = raw["storybook"];
|
|
3304
|
-
if (Array.isArray(storybookProjects)) for (const s of storybookProjects) {
|
|
3305
|
-
const p = s.path || ".";
|
|
3306
|
-
if (p === ".") {
|
|
3307
|
-
paths.push("src/**");
|
|
3308
|
-
paths.push(".storybook/**");
|
|
3309
|
-
} else paths.push(`${p}/**`);
|
|
3310
|
-
}
|
|
3311
|
-
return paths;
|
|
3312
|
-
}
|
|
3313
3326
|
const workflows = config.workflows;
|
|
3314
3327
|
if (loader.has("source") && workflows && workflows.length > 0) {
|
|
3315
3328
|
const source = loader.get("source");
|
|
@@ -4233,7 +4246,7 @@ var setup_default = "name: Setup\ndescription: Prepare the environment and insta
|
|
|
4233
4246
|
var setup_node_default = "name: Setup Node\ndescription: Install pnpm and Node.js with pnpm dependency caching.\n\ninputs:\n node-version:\n description: Node.js version\n required: false\n default: \"22.x\"\nruns:\n using: composite\n\n steps:\n - name: Setup pnpm\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4\n\n - name: Setup Node.js\n uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0\n with:\n node-version: ${{ hashFiles('.node-version') != '' && '' || inputs.node-version }}\n node-version-file: ${{ hashFiles('.node-version') != '' && '.node-version' || '' }}\n cache: ${{ hashFiles('pnpm-lock.yaml') != '' && 'pnpm' || '' }}\n # Do NOT add registry-url here. setup-node writes .npmrc with\n # _authToken=${NODE_AUTH_TOKEN} and sets NPM_CONFIG_USERCONFIG to it.\n # pnpm reads that file, fails env-var substitution when the token is\n # empty, and loses auth entirely. Without registry-url, pnpm 10.15+\n # handles Trusted Publishing via its own native OIDC exchange.\n\n - name: Add node_modules/.bin to PATH\n shell: bash\n run: echo \"$GITHUB_WORKSPACE/node_modules/.bin\" >> $GITHUB_PATH\n";
|
|
4234
4247
|
//#endregion
|
|
4235
4248
|
//#region src/templates/workflows/audit.yml
|
|
4236
|
-
var audit_default = "name: Audit\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n build-script:\n description: Script to build and upload bundle stats to Codecov\n type: string\n required: false\n default: pnpm build\n run-knip:\n description: Run Knip to detect unused files, exports, and dependencies\n type: boolean\n required: false\n default: false\n run-performance:\n description: Run Lighthouse CI performance audit (requires a lighthouse config file)\n type: boolean\n required: false\n default: false\n lighthouse-config:\n description: >\n Path to the Lighthouse CI config file passed as --config to lhci autorun.\n Defaults to lighthouse.config.
|
|
4249
|
+
var audit_default = "name: Audit\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n build-script:\n description: Script to build and upload bundle stats to Codecov\n type: string\n required: false\n default: pnpm build\n run-knip:\n description: Run Knip to detect unused files, exports, and dependencies\n type: boolean\n required: false\n default: false\n run-performance:\n description: Run Lighthouse CI performance audit (requires a lighthouse config file)\n type: boolean\n required: false\n default: false\n lighthouse-config:\n description: >\n Path to the Lighthouse CI config file passed as --config to lhci autorun.\n Defaults to lighthouse.config.cjs (the org standard).\n type: string\n required: false\n default: lighthouse.config.cjs\n knip-script:\n description: Script that invokes Knip (must exit non-zero on findings)\n type: string\n required: false\n default: pnpm run audit\n secrets:\n CODECOV_TOKEN:\n required: false\n LHCI_GITHUB_APP_TOKEN:\n required: false\n TURBO_TOKEN:\n required: false\n\njobs:\n bundle-size:\n name: Audit the bundle size\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: eval \"$BUILD_SCRIPT\"\n name: Build and upload bundle stats\n env:\n BUILD_SCRIPT: ${{ inputs.build-script }}\n CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n\n knip:\n name: Knip\n if: ${{ inputs.run-knip }}\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 10\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n persist-credentials: false\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: eval \"$KNIP_SCRIPT\"\n name: Run Knip\n env:\n KNIP_SCRIPT: ${{ inputs.knip-script }}\n\n performance:\n name: Audit the performance\n if: ${{ inputs.run-performance }}\n permissions:\n contents: read\n runs-on: ubuntu-latest\n timeout-minutes: 15\n env:\n TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n\n - run: npm install -g @lhci/cli@0.14.x\n name: Install Lighthouse CLI\n\n - run: lhci autorun --config=\"$LIGHTHOUSE_CONFIG\"\n name: Run Lighthouse CI\n env:\n LIGHTHOUSE_CONFIG: ${{ inputs.lighthouse-config }}\n LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}\n";
|
|
4237
4250
|
//#endregion
|
|
4238
4251
|
//#region src/templates/workflows/bookkeeping.yml
|
|
4239
4252
|
var bookkeeping_default = "name: Bookkeeping\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n configuration-path:\n description: Path to the labeler configuration file in the calling repo\n type: string\n required: false\n default: .github/labeler.yml\n\njobs:\n label:\n name: Apply Labels\n permissions:\n contents: read\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 5\n steps:\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n with:\n sparse-checkout: ${{ inputs.configuration-path || '.github/labeler.yml' }}\n sparse-checkout-cone-mode: false\n\n - uses: github/issue-labeler@c1b0f9f52a63158c4adc09425e858e87b32e9685 # v3.4\n if: ${{ github.event_name == 'pull_request' && hashFiles(inputs.configuration-path || '.github/labeler.yml') != '' }}\n # v3.4 bundles Node 20; allow it to run under Actions' current default.\n env:\n ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true\n with:\n # Fall back to default path when triggered directly (not via workflow_call)\n # because inputs.* defaults only apply on workflow_call events.\n configuration-path: ${{ inputs.configuration-path || '.github/labeler.yml' }}\n include-title: 1\n include-body: 0\n sync-labels: 1\n enable-versioned-regex: 0\n repo-token: ${{ github.token }}\n";
|
|
@@ -4327,13 +4340,14 @@ function parseWorkflowsFromTs(source) {
|
|
|
4327
4340
|
const body = source.slice(start, i - 1);
|
|
4328
4341
|
const entries = [];
|
|
4329
4342
|
const objSpans = [];
|
|
4330
|
-
const objRe = /\{\s*name\s*:\s*"([^"]+)"(?:\s*,\s*with\s*:\s*(\{[^}]*\}))?\s*\}/g;
|
|
4343
|
+
const objRe = /\{\s*name\s*:\s*"([^"]+)"(?:\s*,\s*with\s*:\s*(\{[^}]*\}))?\s*,?\s*\}/g;
|
|
4331
4344
|
let m;
|
|
4332
4345
|
while ((m = objRe.exec(body)) !== null) {
|
|
4333
4346
|
objSpans.push([m.index, m.index + m[0].length]);
|
|
4334
4347
|
let withObj;
|
|
4335
4348
|
if (m[2]) try {
|
|
4336
|
-
|
|
4349
|
+
const jsonSafe = m[2].replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, "$1\"$2\":");
|
|
4350
|
+
withObj = JSON.parse(jsonSafe);
|
|
4337
4351
|
} catch {}
|
|
4338
4352
|
entries.push({
|
|
4339
4353
|
pos: m.index,
|
|
@@ -4395,7 +4409,8 @@ function buildBatch(repo, allowedWorkflows, withOverrides) {
|
|
|
4395
4409
|
}
|
|
4396
4410
|
} else for (const name of Object.keys(REUSABLE_WORKFLOWS)) {
|
|
4397
4411
|
if (allowedWorkflows && !allowedWorkflows.has(name)) continue;
|
|
4398
|
-
const
|
|
4412
|
+
const rawWith = withOverrides?.get(name);
|
|
4413
|
+
const content = generateThinCallerContent(name, rawWith ? normalizeWorkflowWith(rawWith) : void 0, name === "deploy" && rawWith ? deriveDeployPaths(rawWith) : void 0);
|
|
4399
4414
|
if (!content) continue;
|
|
4400
4415
|
files.push({
|
|
4401
4416
|
path: `.github/workflows/${name}.yml`,
|