@smoothbricks/cli 0.10.4 โ†’ 0.10.6

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 (56) hide show
  1. package/dist/cli.js +5 -5
  2. package/dist/github-ci/index.d.ts.map +1 -1
  3. package/dist/github-ci/index.js +5 -3
  4. package/dist/lib/json.d.ts +5 -1
  5. package/dist/lib/json.d.ts.map +1 -1
  6. package/dist/lib/json.js +18 -16
  7. package/dist/monorepo/ci-workflow.d.ts +2 -0
  8. package/dist/monorepo/ci-workflow.d.ts.map +1 -1
  9. package/dist/monorepo/ci-workflow.js +10 -4
  10. package/dist/monorepo/github-runs-on.d.ts +14 -0
  11. package/dist/monorepo/github-runs-on.d.ts.map +1 -0
  12. package/dist/monorepo/github-runs-on.js +43 -0
  13. package/dist/monorepo/index.d.ts +3 -3
  14. package/dist/monorepo/index.d.ts.map +1 -1
  15. package/dist/monorepo/index.js +20 -8
  16. package/dist/monorepo/lockfile.d.ts +2 -1
  17. package/dist/monorepo/lockfile.d.ts.map +1 -1
  18. package/dist/monorepo/lockfile.js +1 -1
  19. package/dist/monorepo/managed-files.d.ts +30 -3
  20. package/dist/monorepo/managed-files.d.ts.map +1 -1
  21. package/dist/monorepo/managed-files.js +83 -63
  22. package/dist/monorepo/packs/index.js +2 -2
  23. package/dist/monorepo/publish-workflow.d.ts +3 -0
  24. package/dist/monorepo/publish-workflow.d.ts.map +1 -1
  25. package/dist/monorepo/publish-workflow.js +17 -14
  26. package/dist/monorepo/tool-validation.d.ts +2 -2
  27. package/dist/monorepo/tool-validation.d.ts.map +1 -1
  28. package/dist/monorepo/tool-validation.js +110 -16
  29. package/dist/release/index.d.ts.map +1 -1
  30. package/dist/release/index.js +6 -0
  31. package/managed/raw/envrc +5 -3
  32. package/managed/raw/patches/ttsc@0.19.3.patch +67 -0
  33. package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +24 -7
  34. package/managed/raw/tooling/direnv/setup-environment.ts +23 -3
  35. package/managed/templates/github/actions/cache-nix-devenv/action.yml +13 -11
  36. package/managed/templates/github/actions/save-nix-devenv/action.yml +34 -3
  37. package/managed/templates/github/actions/setup-devenv/action.yml +44 -15
  38. package/managed/templates/github/workflows/managed-files.yml +64 -12
  39. package/package.json +2 -2
  40. package/src/cli.ts +6 -6
  41. package/src/github-ci/index.test.ts +3 -3
  42. package/src/github-ci/index.ts +6 -3
  43. package/src/lib/json.ts +5 -1
  44. package/src/monorepo/__tests__/ci-workflow.test.ts +37 -1
  45. package/src/monorepo/__tests__/publish-workflow.test.ts +28 -1
  46. package/src/monorepo/ci-workflow.ts +14 -4
  47. package/src/monorepo/github-runs-on.ts +45 -0
  48. package/src/monorepo/index.ts +20 -8
  49. package/src/monorepo/lockfile.ts +3 -2
  50. package/src/monorepo/managed-files.test.ts +49 -0
  51. package/src/monorepo/managed-files.ts +105 -64
  52. package/src/monorepo/packs/index.ts +2 -2
  53. package/src/monorepo/publish-workflow.ts +23 -15
  54. package/src/monorepo/tool-validation.test.ts +38 -16
  55. package/src/monorepo/tool-validation.ts +114 -16
  56. package/src/release/index.ts +6 -0
@@ -1,9 +1,9 @@
1
- import { execFileSync } from 'node:child_process';
2
1
  import { appendFileSync, existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
2
  import { dirname, join, resolve } from 'node:path';
4
3
  import { fileURLToPath } from 'node:url';
5
4
  import { PLATFORM_TARGET_GLOBS } from '@smoothbricks/nx-plugin/workspace-config-policy';
6
- import { parseNxProjectJsonText, parseStringArrayText } from '../lib/json.js';
5
+ // Nx package exports are CLI-oriented; this is the module the CLI uses for graph + daemon IPC.
6
+ import { createProjectGraphAsync } from 'nx/src/project-graph/project-graph.js';
7
7
  import { listReleasePackages, readPackageJson } from '../lib/workspace.js';
8
8
  import { renderCiWorkflowYaml } from './ci-workflow.js';
9
9
  import { renderPublishWorkflowYaml } from './publish-workflow.js';
@@ -146,6 +146,11 @@ const managedFiles = [
146
146
  target: 'tooling/direnv/merge-newer-pins.sh',
147
147
  executable: true,
148
148
  },
149
+ {
150
+ kind: 'raw',
151
+ source: 'patches/ttsc@0.19.3.patch',
152
+ target: 'patches/ttsc@0.19.3.patch',
153
+ },
149
154
  {
150
155
  kind: 'generated',
151
156
  source: 'ci-workflow',
@@ -194,8 +199,8 @@ const managedFiles = [
194
199
  },
195
200
  ];
196
201
  const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
197
- export function applyManagedFiles(root, mode) {
198
- const context = getManagedFileContext(root);
202
+ export async function applyManagedFiles(root, mode) {
203
+ const context = await getManagedFileContext(root);
199
204
  return managedFiles.map((file) => applyManagedFile(root, file, mode, context));
200
205
  }
201
206
  function applyManagedFile(root, file, mode, context) {
@@ -239,6 +244,7 @@ function getManagedContent(file, context) {
239
244
  deploy: context.hasStagingDeployTargets,
240
245
  deployProvider: context.stagingDeployProvider,
241
246
  pushBranches: context.ciPushBranches,
247
+ runsOn: context.ciRunsOn,
242
248
  });
243
249
  }
244
250
  if (file.source === 'publish-workflow') {
@@ -247,6 +253,7 @@ function getManagedContent(file, context) {
247
253
  deployProvider: context.productionDeployProvider,
248
254
  repoName: context.repoName,
249
255
  platformTargetGlobs: context.platformTargetGlobs,
256
+ runsOn: context.ciRunsOn,
250
257
  });
251
258
  }
252
259
  throw new Error(`Unknown generated managed file source ${file.source}`);
@@ -259,13 +266,16 @@ function getManagedContent(file, context) {
259
266
  }
260
267
  return renderTemplate(context, content);
261
268
  }
262
- function getManagedFileContext(root) {
269
+ async function getManagedFileContext(root) {
263
270
  const packageJson = readPackageJson(join(root, 'package.json'));
264
271
  const repoName = packageJson?.name ?? 'monorepo';
265
272
  const ciPushBranches = getCiPushBranches(packageJson?.json);
266
- const stagingDeploy = getDeployTargetInfo(root, 'staging');
267
- const productionDeploy = getDeployTargetInfo(root, 'production');
268
- const platformTargetGlobs = platformTargetGlobsForTest(readResolvedNxTargetNames(root));
273
+ const ciRunsOn = getCiRunsOn(packageJson?.json);
274
+ // In-process Nx API โ†’ daemon socket (no second Node/`nx` CLI process).
275
+ const nxProjects = await loadNxGraphProjects(root);
276
+ const stagingDeploy = deployTargetInfoFromProjects(nxProjects, 'staging');
277
+ const productionDeploy = deployTargetInfoFromProjects(nxProjects, 'production');
278
+ const platformTargetGlobs = platformTargetGlobsForTest(targetNamesFromProjects(nxProjects));
269
279
  const nodeModulesCacheKey = existsSync(join(root, 'bun.lock'))
270
280
  ? `$${"{{ hashFiles('bun.lock', 'package.json', 'packages/*/package.json') }}"}`
271
281
  : `$${"{{ hashFiles('bun.lockb', 'package.json', 'packages/*/package.json') }}"}`;
@@ -276,6 +286,7 @@ function getManagedFileContext(root) {
276
286
  stagingDeployProvider: stagingDeploy.provider,
277
287
  productionDeployProvider: productionDeploy.provider,
278
288
  ciPushBranches,
289
+ ciRunsOn,
279
290
  nodeModulesCacheKey,
280
291
  repoName,
281
292
  platformTargetGlobs,
@@ -288,77 +299,86 @@ export function platformTargetGlobsForTest(targetNames) {
288
299
  return names.some((name) => name.endsWith(suffix));
289
300
  });
290
301
  }
291
- function readResolvedNxTargetNames(root) {
292
- const output = execFileSync('nx', ['show', 'projects', '--json'], {
293
- cwd: root,
294
- encoding: 'utf8',
295
- stdio: ['ignore', 'pipe', 'inherit'],
296
- });
297
- const projects = parseStringArrayText(output);
298
- if (!projects) {
299
- return [];
302
+ /**
303
+ * Load resolved project nodes via Nx's programmatic API.
304
+ *
305
+ * `createProjectGraphAsync` is what the CLI uses: with the daemon up it speaks the
306
+ * daemon unix socket instead of rebuilding the graph in a fresh Node process.
307
+ * Spawning `nx graph` / `nx show` only added CLI boot + plugin-worker overhead on
308
+ * top of that. smoo runs under Bun; Bun can import this CJS module directly.
309
+ */
310
+ async function loadNxGraphProjects(root) {
311
+ const prevCwd = process.cwd();
312
+ process.chdir(root);
313
+ try {
314
+ const graph = (await createProjectGraphAsync());
315
+ const out = {};
316
+ for (const [name, node] of Object.entries(graph.nodes)) {
317
+ out[name] = { data: { targets: node.data?.targets ?? {} } };
318
+ }
319
+ return out;
320
+ }
321
+ finally {
322
+ process.chdir(prevCwd);
300
323
  }
324
+ }
325
+ function targetsOfProject(node) {
326
+ return node.data?.targets ?? node.targets ?? {};
327
+ }
328
+ /** Test seam: collect target names from a graph.nodes map. */
329
+ export function targetNamesFromProjects(nodes) {
301
330
  const targetNames = new Set();
302
- for (const project of projects) {
303
- const projectOutput = execFileSync('nx', ['show', 'project', project, '--json'], {
304
- cwd: root,
305
- encoding: 'utf8',
306
- stdio: ['ignore', 'pipe', 'inherit'],
307
- });
308
- const projectJson = parseNxProjectJsonText(projectOutput);
309
- const targets = projectJson?.targets;
310
- if (targets) {
311
- for (const targetName of Object.keys(targets)) {
312
- targetNames.add(targetName);
313
- }
331
+ for (const node of Object.values(nodes)) {
332
+ for (const name of Object.keys(targetsOfProject(node))) {
333
+ targetNames.add(name);
314
334
  }
315
335
  }
316
336
  return [...targetNames];
317
337
  }
318
- function renderTemplate(context, template) {
319
- return template
320
- .replaceAll('{{REPO_NAME}}', context.repoName)
321
- .replaceAll('__SMOO_CI_PUSH_BRANCHES__', renderYamlFlowList(context.ciPushBranches))
322
- .replaceAll('{{NODE_MODULES_CACHE_KEY}}', context.nodeModulesCacheKey);
323
- }
324
- function getDeployTargetInfo(root, configuration) {
325
- const output = execFileSync('nx', ['show', 'projects', '--withTarget', 'deploy', '--json'], {
326
- cwd: root,
327
- encoding: 'utf8',
328
- stdio: ['ignore', 'pipe', 'inherit'],
329
- });
330
- const projects = parseStringArrayText(output);
331
- if (!projects) {
332
- return { exists: false };
333
- }
338
+ /** Test seam: deploy configuration presence/provider from graph nodes. */
339
+ export function deployTargetInfoFromProjects(nodes, configuration) {
334
340
  let exists = false;
335
341
  let provider;
336
- for (const project of projects) {
337
- const target = nxDeployTarget(root, project, configuration);
338
- if (!target.exists) {
342
+ for (const node of Object.values(nodes)) {
343
+ const info = deployTargetInfoFromTargets(targetsOfProject(node), configuration);
344
+ if (!info.exists) {
339
345
  continue;
340
346
  }
341
347
  exists = true;
342
- provider ??= target.provider;
348
+ provider ??= info.provider;
343
349
  }
344
350
  return { exists, provider };
345
351
  }
346
- function nxDeployTarget(root, project, configuration) {
347
- const output = execFileSync('nx', ['show', 'project', project, '--json'], {
348
- cwd: root,
349
- encoding: 'utf8',
350
- stdio: ['ignore', 'pipe', 'inherit'],
351
- });
352
- const projectJson = parseNxProjectJsonText(output);
353
- const deploy = projectJson?.targets?.deploy;
354
- const config = deploy?.configurations?.[configuration];
352
+ function deployTargetInfoFromTargets(targets, configuration) {
353
+ const deploy = targets.deploy;
354
+ if (!deploy) {
355
+ return { exists: false };
356
+ }
357
+ const config = deploy.configurations?.[configuration];
355
358
  if (!config) {
356
359
  return { exists: false };
357
360
  }
358
- const commandValue = config.command ?? config.options?.command ?? deploy?.options?.command;
361
+ const commandValue = config.command ?? config.options?.command ?? deploy.options?.command ?? deploy.command;
359
362
  const command = typeof commandValue === 'string' ? commandValue : '';
360
363
  return { exists: true, provider: command.includes('wrangler ') ? 'cloudflare' : undefined };
361
364
  }
365
+ function renderTemplate(context, template) {
366
+ return template
367
+ .replaceAll('{{REPO_NAME}}', context.repoName)
368
+ .replaceAll('__SMOO_CI_PUSH_BRANCHES__', renderYamlFlowList(context.ciPushBranches))
369
+ .replaceAll('{{NODE_MODULES_CACHE_KEY}}', context.nodeModulesCacheKey);
370
+ }
371
+ function getCiRunsOn(packageJson) {
372
+ const configured = packageJson?.smoo?.github?.runsOn;
373
+ if (configured === undefined) {
374
+ return 'ubuntu-latest';
375
+ }
376
+ if (typeof configured === 'string') {
377
+ return configured.length > 0 ? configured : 'ubuntu-latest';
378
+ }
379
+ const labels = configured.filter((label) => label.length > 0);
380
+ return labels.length > 0 ? labels : 'ubuntu-latest';
381
+ }
362
382
  function getCiPushBranches(packageJson) {
363
383
  const configured = readCiPushBranches(packageJson);
364
384
  return configured.length > 0 ? configured : ['main'];
@@ -379,8 +399,8 @@ export function printResults(results) {
379
399
  console.log(`${result.action.padEnd(15)} ${result.target}`);
380
400
  }
381
401
  }
382
- export function validateManagedFiles(root) {
383
- const results = applyManagedFiles(root, 'check');
402
+ export async function validateManagedFiles(root) {
403
+ const results = await applyManagedFiles(root, 'check');
384
404
  printResults(results);
385
405
  const failures = results.filter((result) => result.action === 'drifted').length;
386
406
  if (failures > 0) {
@@ -398,8 +418,8 @@ export function validateManagedFiles(root) {
398
418
  * Under GitHub Actions the drifted-file count is published as the step output
399
419
  * `drifted`, so downstream steps gate declaratively instead of parsing logs.
400
420
  */
401
- export function warnOnManagedFileDrift(root) {
402
- const results = applyManagedFiles(root, 'check');
421
+ export async function warnOnManagedFileDrift(root) {
422
+ const results = await applyManagedFiles(root, 'check');
403
423
  printResults(results);
404
424
  const drifted = results.filter((result) => result.action === 'drifted');
405
425
  if (process.env.GITHUB_OUTPUT) {
@@ -40,10 +40,10 @@ const packs = [
40
40
  // Managed-file drift is derived state (CLI template x pinned version) with
41
41
  // its own remediation flow; it warns instead of failing so validation only
42
42
  // blocks on actual package issues. See warnOnManagedFileDrift.
43
- warnOnManagedFileDrift(ctx.root);
43
+ await warnOnManagedFileDrift(ctx.root);
44
44
  return (runtimeFailures +
45
45
  validateRootPackagePolicy(ctx.root) +
46
- validateToolConfig(ctx.root) +
46
+ (await validateToolConfig(ctx.root)) +
47
47
  validateNxProjectNames(ctx.root) +
48
48
  validateNxReleaseConfig(ctx.root) +
49
49
  validateBunLockfileVersions(ctx.root) +
@@ -1,3 +1,4 @@
1
+ import { type WorkflowRunsOn } from './github-runs-on.js';
1
2
  export type PublishWorkflowBump = 'auto' | 'patch' | 'minor' | 'major' | 'prerelease';
2
3
  export type PublishWorkflowCondition = 'version-mode-not-none' | 'deploy-production' | 'failure' | 'always';
3
4
  export type PublishWorkflowNxTarget = 'build' | 'lint' | 'test';
@@ -35,6 +36,8 @@ export interface PublishWorkflowDefinitionOptions {
35
36
  deployProvider?: 'cloudflare';
36
37
  repoName?: string;
37
38
  platformTargetGlobs?: readonly string[];
39
+ /** Linux jobs only. Default ubuntu-latest. Same smoo.github.runsOn as CI. */
40
+ runsOn?: WorkflowRunsOn;
38
41
  }
39
42
  export interface PublishWorkflowInputs {
40
43
  bump: PublishWorkflowBump;
@@ -1 +1 @@
1
- {"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  import synchronizedPrettier from '@prettier/sync';
3
3
  import { LINUX_PLATFORM_TARGET_GLOBS, MACOS_PLATFORM_TARGET_GLOBS, } from '@smoothbricks/nx-plugin/workspace-config-policy';
4
4
  import { isSmoothBricksCodebasePackageName } from '../lib/cli-package.js';
5
+ import { renderRunsOnLine } from './github-runs-on.js';
5
6
  const PUBLISH_WORKFLOW_FORMAT_OPTIONS = Object.freeze({
6
7
  parser: 'yaml',
7
8
  printWidth: 120,
@@ -338,7 +339,8 @@ function yamlLinesForStep(step, options) {
338
339
  case PublishWorkflowStepKind.UploadTraceDbs:
339
340
  return [
340
341
  ` - name: ${step.name}`,
341
- ` if: ${githubExpression('failure()')}`,
342
+ ' # Default is success(); failure() uploads traces only when the job already failed.',
343
+ ' if: failure()',
342
344
  ' uses: actions/upload-artifact@v7.0.1',
343
345
  ' with:',
344
346
  ` name: trace-results-${githubExpression('github.run_id')}`,
@@ -362,7 +364,8 @@ function yamlLinesForStep(step, options) {
362
364
  case PublishWorkflowStepKind.SaveNixDevenv:
363
365
  return [
364
366
  ` - name: ${step.name}`,
365
- ` if: ${githubExpression('always()')}`,
367
+ ' # success() is default; always() still saves GH Nix cache after a red job.',
368
+ ' if: always()',
366
369
  ' uses: ./.github/actions/save-nix-devenv',
367
370
  ' with:',
368
371
  ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`,
@@ -392,7 +395,7 @@ function deployEnvLines(options) {
392
395
  }
393
396
  function conditionalRunStep(step, run) {
394
397
  const condition = "steps.version.outputs.mode != 'none'";
395
- return [` - name: ${step.name}`, ` if: ${githubExpression(condition)}`, ` run: ${run}`];
398
+ return [` - name: ${step.name}`, ` if: ${condition}`, ` run: ${run}`];
396
399
  }
397
400
  function renderSingleJobPublishWorkflowSteps(steps, options) {
398
401
  const lines = [];
@@ -402,7 +405,7 @@ function renderSingleJobPublishWorkflowSteps(steps, options) {
402
405
  lines.push(...yamlLinesForStep(step, options));
403
406
  lines.push('');
404
407
  if (step.kind === PublishWorkflowStepKind.Build) {
405
- lines.push(' - name: ๐Ÿง Build supplemental Linux targets', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ` run: smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}"`, '');
408
+ lines.push(' - name: ๐Ÿง Build supplemental Linux targets', " if: steps.version.outputs.mode != 'none'", ` run: smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}"`, '');
406
409
  }
407
410
  }
408
411
  return `${lines.join('\n').trimEnd()}\n`;
@@ -447,7 +450,7 @@ defaults:
447
450
 
448
451
  jobs:
449
452
  linux-release-candidate:
450
- runs-on: ubuntu-latest
453
+ ${renderRunsOnLine(options.runsOn)}
451
454
  permissions:
452
455
  contents: write
453
456
  id-token: none
@@ -508,7 +511,7 @@ function renderLinuxReleaseCandidateSteps(steps, options) {
508
511
  lines.push(` - name: ${step.name}`, ' uses: actions/checkout@v6.0.2', ' with:', ` ref: ${githubExpression('github.sha')}`, ' filter: blob:none', ' fetch-depth: 0');
509
512
  }
510
513
  else if (step.kind === PublishWorkflowStepKind.Build) {
511
- lines.push(` - name: ${step.name}`, ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' run:', ` smoo github-ci nx-run-many --targets build --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/release-build-outputs"`);
514
+ lines.push(` - name: ${step.name}`, " if: steps.version.outputs.mode != 'none'", ' run:', ` smoo github-ci nx-run-many --targets build --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/release-build-outputs"`);
512
515
  }
513
516
  else {
514
517
  lines.push(...yamlLinesForStep(step, options));
@@ -519,16 +522,16 @@ function renderLinuxReleaseCandidateSteps(steps, options) {
519
522
  stepNumber += 1;
520
523
  }
521
524
  if (step.kind === PublishWorkflowStepKind.Build && hasLinuxPlatformTargets(options)) {
522
- lines.push('', ` # Step ${stepNumber}`, ' - name: ๐Ÿง Build supplemental Linux targets', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' run:', ` smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/linux-platform-outputs"`);
525
+ lines.push('', ` # Step ${stepNumber}`, ' - name: ๐Ÿง Build supplemental Linux targets', " if: steps.version.outputs.mode != 'none'", ' run:', ` smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/linux-platform-outputs"`);
523
526
  stepNumber += 1;
524
527
  }
525
528
  lines.push('');
526
529
  }
527
- lines.push(' # --- Candidate transfer --------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ฆ Bundle validated release state', ' run:', ` mkdir -p "${githubExpression('runner.temp')}/publish-release-state" && git bundle create`, ` "${githubExpression('runner.temp')}/publish-release-state/release-state.bundle" HEAD --tags && git rev-parse HEAD >`, ` "${githubExpression('runner.temp')}/publish-release-state/release-head"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload validated release state', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-state-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/publish-release-state`, ' if-no-files-found: error', ' retention-days: 1', '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload validated build outputs', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/release-build-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
530
+ lines.push(' # --- Candidate transfer --------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ฆ Bundle validated release state', ' run:', ` mkdir -p "${githubExpression('runner.temp')}/publish-release-state" && git bundle create`, ` "${githubExpression('runner.temp')}/publish-release-state/release-state.bundle" HEAD --tags && git rev-parse HEAD >`, ` "${githubExpression('runner.temp')}/publish-release-state/release-head"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload validated release state', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-state-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/publish-release-state`, ' if-no-files-found: error', ' retention-days: 1', '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload validated build outputs', " if: steps.version.outputs.mode != 'none'", ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/release-build-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
528
531
  if (hasLinuxPlatformTargets(options)) {
529
- lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload supplemental Linux outputs', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-linux-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/linux-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
532
+ lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload supplemental Linux outputs', " if: steps.version.outputs.mode != 'none'", ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-linux-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/linux-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
530
533
  }
531
- lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ` if: ${githubExpression('always()')}`, ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
534
+ lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
532
535
  return lines.join('\n').trimEnd();
533
536
  }
534
537
  function renderMacosPlatformSteps(options) {
@@ -554,7 +557,7 @@ function renderMacosPlatformSteps(options) {
554
557
  if (isSmoothBricksCodebasePackageName(options.repoName)) {
555
558
  lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ—๏ธ Build self-hosted smoo', ' # SmoothBricks self-hosts smoo from source for release commands.', ' run: nx build cli');
556
559
  }
557
- lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ŸŽ Build selected macOS and iOS release outputs', ' run:', ` smoo release build-platform-outputs --bump "${githubExpression('inputs.bump')}" --ref "${githubExpression('github.sha')}" --targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}" --output`, ` "${githubExpression('runner.temp')}/macos-platform-outputs"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload macOS platform outputs', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-macos-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/macos-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true', '', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ` if: ${githubExpression('always()')}`, ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
560
+ lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ŸŽ Build selected macOS and iOS release outputs', ' run:', ` smoo release build-platform-outputs --bump "${githubExpression('inputs.bump')}" --ref "${githubExpression('github.sha')}" --targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}" --output`, ` "${githubExpression('runner.temp')}/macos-platform-outputs"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload macOS platform outputs', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-macos-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/macos-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true', '', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
558
561
  return lines.join('\n').trimEnd();
559
562
  }
560
563
  function renderFinalLinuxPublishSteps(options) {
@@ -597,15 +600,15 @@ function renderFinalLinuxPublishSteps(options) {
597
600
  lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ—๏ธ Build self-hosted smoo', ' # SmoothBricks self-hosts smoo from source for release commands.', ' run: nx build cli');
598
601
  }
599
602
  lines.push('', ' # --- Repair -------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿงฏ Repair pending releases', ' run:', ` smoo release repair-pending --ref "${githubExpression('github.sha')}" --platform-outputs "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/repairs" --dry-run`, ` "${githubExpression('inputs.dry_run')}"`, '', ` # Step ${stepNumber++}`, ' - name: โ™ป๏ธ Restore validated release state', ' run:', ` git fetch "${githubExpression('runner.temp')}/publish-artifacts/publish-release-state-${githubExpression('github.run_id')}/release-state.bundle" HEAD --tags && git reset`, ` --hard "$(cat "${githubExpression('runner.temp')}/publish-artifacts/publish-release-state-${githubExpression('github.run_id')}/release-head")"`);
600
- lines.push('', ' # --- Validation ---------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ฆ Apply verified Linux outputs', ` if: ${githubExpression(`${mode} != 'none'`)}`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('needs.linux-release-candidate.outputs.release-sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-release-outputs-${githubExpression('github.run_id')}"`);
603
+ lines.push('', ' # --- Validation ---------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ฆ Apply verified Linux outputs', ` if: ${mode} != 'none'`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('needs.linux-release-candidate.outputs.release-sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-release-outputs-${githubExpression('github.run_id')}"`);
601
604
  if (hasLinuxPlatformTargets(options)) {
602
605
  lines.push(` "${githubExpression('runner.temp')}/publish-artifacts/publish-linux-outputs-${githubExpression('github.run_id')}"`);
603
606
  }
604
- lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ŸŽ Apply verified macOS outputs', ` if: ${githubExpression(`${mode} != 'none'`)}`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('github.sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/current"`, '', ` # Step ${stepNumber++}`, ` - name: โœ… Validate restored release (${githubExpression(mode)})`, ` if: ${githubExpression(`${mode} != 'none'`)}`, ' run: smoo monorepo validate', '', ' # --- Release ------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ` - name: ๐Ÿ“ฆ Publish release (${githubExpression(mode)})`, ' # smoo packs with Bun, then publishes tarballs with npm. Existing', ' # packages must already exist on npm and use trusted publishing/OIDC.', ' # Missing package names are bootstrapped locally before trust setup.', ` run: smoo release publish --bump "${githubExpression('inputs.bump')}" --dry-run "${githubExpression('inputs.dry_run')}"`);
607
+ lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ŸŽ Apply verified macOS outputs', ` if: ${mode} != 'none'`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('github.sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/current"`, '', ` # Step ${stepNumber++}`, ` - name: โœ… Validate restored release (${githubExpression(mode)})`, ` if: ${mode} != 'none'`, ' run: smoo monorepo validate', '', ' # --- Release ------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ` - name: ๐Ÿ“ฆ Publish release (${githubExpression(mode)})`, ' # smoo packs with Bun, then publishes tarballs with npm. Existing', ' # packages must already exist on npm and use trusted publishing/OIDC.', ' # Missing package names are bootstrapped locally before trust setup.', ` run: smoo release publish --bump "${githubExpression('inputs.bump')}" --dry-run "${githubExpression('inputs.dry_run')}"`);
605
608
  if (options.deploy === true) {
606
609
  lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿš€ Deploy production', ' if:', " ${{ needs.linux-release-candidate.outputs.mode != 'none' && inputs.deploy_environment == 'production' &&", " inputs.dry_run != 'true' }}", ...deployEnvLines(options), ' run: smoo github-ci nx-deploy --configuration production --mode run-many --verify --name "Deploy Production"');
607
610
  }
608
- lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ` if: ${githubExpression('always()')}`, ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
611
+ lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
609
612
  return lines.join('\n').trimEnd();
610
613
  }
611
614
  function hasMacosPlatformTargets(options) {
@@ -9,7 +9,7 @@ export interface ToolContext {
9
9
  policy: ToolPolicy;
10
10
  }
11
11
  export declare function applyToolConfigDefaults(root: string): Promise<void>;
12
- export declare function validateToolConfig(root: string): number;
12
+ export declare function validateToolConfig(root: string): Promise<number>;
13
13
  export declare function applyRootDevDependencyDefaults(root: string, context: ToolContext): Promise<void>;
14
14
  export declare function applyToolingPackageDefaults(root: string, policy: ToolPolicy): void;
15
15
  export declare function applyToolingWorkspaceDefault(root: string): void;
@@ -18,5 +18,5 @@ export declare function validateRootDevDependencies(policy: ToolPolicy, rootPack
18
18
  export declare function validateToolingPackage(root: string, policy: ToolPolicy): number;
19
19
  export declare function validateToolingWorkspace(rootPackage: PackageJson | null): number;
20
20
  export declare function validateDevenvPackages(root: string): number;
21
- export declare function readToolContext(root: string): ToolContext;
21
+ export declare function readToolContext(root: string): Promise<ToolContext>;
22
22
  //# sourceMappingURL=tool-validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-validation.d.ts","sourceRoot":"","sources":["../../src/monorepo/tool-validation.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,qBAAqB,CAAC;AAU9E,MAAM,WAAW,UAAU;IACzB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,UAAU,CAAC;CACpB;AA0CD,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBtG;AAoCD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAkBlF;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAY/D;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA0B7D;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAyBvG;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAoB/E;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAWhF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqB3D;AA0DD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAQzD"}
1
+ {"version":3,"file":"tool-validation.d.ts","sourceRoot":"","sources":["../../src/monorepo/tool-validation.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,qBAAqB,CAAC;AAU9E,MAAM,WAAW,UAAU;IACzB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,UAAU,CAAC;CACpB;AAkDD,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAStE;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBtG;AA2CD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAkBlF;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAY/D;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA0B7D;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAyBvG;AAsBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAoB/E;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAWhF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqB3D;AAsED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAQxE"}