@smoothbricks/cli 0.11.18 → 0.11.20

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 (96) hide show
  1. package/README.md +91 -11
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +28 -4
  4. package/dist/github-ci/index.d.ts.map +1 -1
  5. package/dist/github-ci/index.js +6 -20
  6. package/dist/lib/deploy-tags.d.ts +17 -3
  7. package/dist/lib/deploy-tags.d.ts.map +1 -1
  8. package/dist/lib/deploy-tags.js +23 -4
  9. package/dist/lib/json.d.ts +22 -1
  10. package/dist/lib/json.d.ts.map +1 -1
  11. package/dist/lib/json.js +15 -3
  12. package/dist/monorepo/cargo-policy.d.ts +17 -0
  13. package/dist/monorepo/cargo-policy.d.ts.map +1 -1
  14. package/dist/monorepo/cargo-policy.js +73 -1
  15. package/dist/monorepo/index.d.ts.map +1 -1
  16. package/dist/monorepo/index.js +4 -2
  17. package/dist/monorepo/managed-files.d.ts +5 -2
  18. package/dist/monorepo/managed-files.d.ts.map +1 -1
  19. package/dist/monorepo/managed-files.js +35 -21
  20. package/dist/monorepo/packs/index.d.ts.map +1 -1
  21. package/dist/monorepo/packs/index.js +6 -1
  22. package/dist/nx/index.d.ts +6 -0
  23. package/dist/nx/index.d.ts.map +1 -1
  24. package/dist/nx/index.js +14 -0
  25. package/dist/secrets/commands.d.ts +9 -5
  26. package/dist/secrets/commands.d.ts.map +1 -1
  27. package/dist/secrets/commands.js +122 -49
  28. package/dist/secrets/index.d.ts +42 -56
  29. package/dist/secrets/index.d.ts.map +1 -1
  30. package/dist/secrets/index.js +52 -79
  31. package/dist/secrets/resolver.d.ts +59 -0
  32. package/dist/secrets/resolver.d.ts.map +1 -0
  33. package/dist/secrets/resolver.js +100 -0
  34. package/dist/secrets/run.d.ts +23 -0
  35. package/dist/secrets/run.d.ts.map +1 -0
  36. package/dist/secrets/run.js +130 -0
  37. package/dist/secrets/status.d.ts +177 -0
  38. package/dist/secrets/status.d.ts.map +1 -0
  39. package/dist/secrets/status.js +724 -0
  40. package/dist/wrangler/deploy-stage.d.ts +1 -1
  41. package/dist/wrangler/deploy-stage.d.ts.map +1 -1
  42. package/dist/wrangler/deploy-stage.js +22 -20
  43. package/dist/wrangler/deployed-version.d.ts.map +1 -1
  44. package/dist/wrangler/deployed-version.js +7 -12
  45. package/dist/wrangler/flat-config.d.ts +1 -4
  46. package/dist/wrangler/flat-config.d.ts.map +1 -1
  47. package/dist/wrangler/flat-config.js +98 -44
  48. package/dist/wrangler/prepare-env.d.ts +4 -3
  49. package/dist/wrangler/prepare-env.d.ts.map +1 -1
  50. package/dist/wrangler/prepare-env.js +7 -5
  51. package/dist/wrangler/source-config.d.ts +24 -0
  52. package/dist/wrangler/source-config.d.ts.map +1 -0
  53. package/dist/wrangler/source-config.js +110 -0
  54. package/dist/wrangler/stage.d.ts +55 -23
  55. package/dist/wrangler/stage.d.ts.map +1 -1
  56. package/dist/wrangler/stage.js +81 -162
  57. package/managed/raw/tooling/direnv/devenv.smoo.nix +19 -3
  58. package/managed/raw/tooling/direnv/secret-references.ts +280 -76
  59. package/managed/raw/tooling/direnv/setup-environment.ts +58 -2
  60. package/managed/raw/tsconfig.lib.json +28 -0
  61. package/package.json +7 -2
  62. package/src/cli.ts +34 -5
  63. package/src/github-ci/index.test.ts +6 -7
  64. package/src/github-ci/index.ts +11 -19
  65. package/src/lib/deploy-tags.ts +22 -4
  66. package/src/lib/json.ts +23 -1
  67. package/src/monorepo/cargo-policy.test.ts +91 -1
  68. package/src/monorepo/cargo-policy.ts +87 -1
  69. package/src/monorepo/index.ts +8 -2
  70. package/src/monorepo/managed-files.test.ts +69 -37
  71. package/src/monorepo/managed-files.ts +38 -21
  72. package/src/monorepo/packs/index.ts +10 -1
  73. package/src/monorepo/secret-references.test.ts +412 -6
  74. package/src/monorepo/setup-environment.test.ts +181 -0
  75. package/src/nx/index.test.ts +8 -0
  76. package/src/nx/index.ts +20 -0
  77. package/src/secrets/commands.test.ts +186 -4
  78. package/src/secrets/commands.ts +142 -51
  79. package/src/secrets/index.test.ts +4 -10
  80. package/src/secrets/index.ts +54 -115
  81. package/src/secrets/resolver.ts +130 -0
  82. package/src/secrets/run.test.ts +359 -0
  83. package/src/secrets/run.ts +148 -0
  84. package/src/secrets/status.test.ts +164 -0
  85. package/src/secrets/status.ts +297 -0
  86. package/src/wrangler/deploy-stage.test.ts +95 -2
  87. package/src/wrangler/deploy-stage.ts +26 -23
  88. package/src/wrangler/deployed-version.ts +7 -11
  89. package/src/wrangler/flat-config.test.ts +9 -4
  90. package/src/wrangler/flat-config.ts +1 -20
  91. package/src/wrangler/format-parity.test.ts +433 -0
  92. package/src/wrangler/prepare-env.ts +7 -5
  93. package/src/wrangler/source-config.test.ts +102 -0
  94. package/src/wrangler/source-config.ts +110 -0
  95. package/src/wrangler/stage.test.ts +61 -32
  96. package/src/wrangler/stage.ts +124 -173
@@ -2,7 +2,7 @@ import { appendFileSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { printCommandOutput, run, runResult } from '../lib/run.js';
3
3
  import { escapeRegex, getWorkspacePackages, getWorkspacePatterns, listReleasePackages } from '../lib/workspace.js';
4
4
  import { readProjectTargets } from '../nx/index.js';
5
- import { applyCargoFeatureUnification, validateCargoCachePolicy } from './cargo-policy.js';
5
+ import { applyCargoFeatureUnification, validateCargoCachePolicy, validateCargoToolchainInputs, } from './cargo-policy.js';
6
6
  import { formatCommitMessage, stagedDeletedPublicPackages, validateBreakingDisclosure, validateCommitMessage, } from './commit-msg.js';
7
7
  import { applyWorkspaceGitConfig } from './git-config.js';
8
8
  import { syncBunLockfileVersions } from './lockfile.js';
@@ -64,7 +64,8 @@ export async function checkManagedFiles(root, options = {}) {
64
64
  }
65
65
  const results = await applyManagedFiles(root, 'check');
66
66
  printResults(results);
67
- const resolvedTargets = resolvedTargetsByProject(await readProjectTargets(root));
67
+ const projectTargets = await readProjectTargets(root);
68
+ const resolvedTargets = resolvedTargetsByProject(projectTargets);
68
69
  const packageFailures = validateRootPackagePolicy(root) +
69
70
  validateNxProjectNames(root) +
70
71
  validateNxReleaseConfig(root) +
@@ -75,6 +76,7 @@ export async function checkManagedFiles(root, options = {}) {
75
76
  validateWorkspaceDependencies(root, { resolvedTargetsByProject: resolvedTargets }) +
76
77
  validateDevenvModuleImport(root) +
77
78
  validateCargoCachePolicy(root) +
79
+ validateCargoToolchainInputs(root, projectTargets) +
78
80
  validateSccachePatches(root);
79
81
  if (results.some((result) => result.action === 'drifted') || packageFailures > 0) {
80
82
  throw new Error('Managed monorepo files or package conventions are out of date. Run: smoo monorepo update');
@@ -1,5 +1,6 @@
1
1
  import { type NonEmptyArray, type PackageCargoCredentialsConfig, type PackagePrivateNpmConfig, type PackageRemoteCacheConfig, type PackageSmooGithub, type PackageSmooGithubEnvironments, type PackageSourceCheckoutConfig } from '../lib/json.js';
2
2
  import { type NxProjects } from '../nx/index.js';
3
+ import type { DeploymentStage } from '../wrangler/stage.js';
3
4
  import { type CiCrossTestArchive } from './ci-workflow.js';
4
5
  /**
5
6
  * Repos may append their own content to a managed file below this marker —
@@ -97,6 +98,8 @@ export declare const managedFileTargetsForTest: {
97
98
  target: string;
98
99
  executable: boolean | undefined;
99
100
  }[];
101
+ /** Test seam: the managed targets a repository of this shape gets, in file order. */
102
+ export declare function managedFileTargetsForContext(context: ManagedFileContext): string[];
100
103
  export declare function applyManagedFiles(root: string, mode: 'update' | 'check' | 'diff'): Promise<FileResult[]>;
101
104
  /** Renders a generated workflow through its real managed-file descriptor, so the context wiring is covered. */
102
105
  export declare function renderManagedWorkflowForTest(source: 'ci-workflow' | 'publish-workflow', context: ManagedFileContext): string;
@@ -134,8 +137,8 @@ export declare function platformTargetGlobsForTest(targetNames: Iterable<string>
134
137
  * platform builds serialize no matter how many workers Nx is given.
135
138
  */
136
139
  export declare function macosPlatformArchitecturesForTest(targetNames: Iterable<string>): string[];
137
- /** Test seam: deploy configuration presence/provider from graph nodes. */
138
- export declare function deployTargetInfoFromProjects(projects: NxProjects, configuration: string): DeployTargetInfo;
140
+ /** Test seam: what the stage flow deploys, and with which provider, from graph nodes. */
141
+ export declare function deployTargetInfoFromProjects(projects: NxProjects, stage: DeploymentStage): DeployTargetInfo;
139
142
  /** Test seam: whether any project in the graph carries the Nx tag. */
140
143
  export declare function anyProjectHasTagForTest(projects: NxProjects, tag: string): boolean;
141
144
  export declare function printResults(results: FileResult[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { dirname, join, resolve } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { cargoCrossTestArchiveFile, cargoCrossTestTripleFromArchiveTarget, } from '@smoothbricks/nx-plugin/cross-check-policy';
5
5
  import { MACOS_PLATFORM_TARGET_GLOBS, PLATFORM_TARGET_GLOBS } from '@smoothbricks/nx-plugin/workspace-config-policy';
6
- import { isStageDerivedDeploy, PRODUCTION_PUSH_DEPLOY_TAG } from '../lib/deploy-tags.js';
6
+ import { PRODUCTION_PUSH_DEPLOY_TAG, stageDeploysProject } from '../lib/deploy-tags.js';
7
7
  import { ciPushBranches, readValidatedPackageJson, } from '../lib/json.js';
8
8
  import { listReleasePackages, packageInfo } from '../lib/workspace.js';
9
9
  import { loadNxProjects, projectRootFromNxProjectJson, targetNamesFromNxProjectJson, targetNamesFromProjects, } from '../nx/index.js';
@@ -236,15 +236,27 @@ const managedFiles = [
236
236
  ];
237
237
  export const managedFileTargetsForTest = managedFiles.map(({ target, executable }) => ({ target, executable }));
238
238
  const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
239
+ /**
240
+ * Whether a repository of this shape has the file at all. A repository that owns
241
+ * no packages has nothing to publish, and one the stage flow does not deploy to
242
+ * Cloudflare has no preview stage to clean up.
243
+ */
244
+ function managedFileApplies(file, context) {
245
+ if (file.releasePackagesOnly === true && !context.hasReleasePackages && !context.hasProductionDeployTargets) {
246
+ return false;
247
+ }
248
+ return file.cloudflareDeployOnly !== true || context.stagingDeployProvider === 'cloudflare';
249
+ }
250
+ /** Test seam: the managed targets a repository of this shape gets, in file order. */
251
+ export function managedFileTargetsForContext(context) {
252
+ return managedFiles.filter((file) => managedFileApplies(file, context)).map((file) => file.target);
253
+ }
239
254
  export async function applyManagedFiles(root, mode) {
240
255
  const context = await getManagedFileContext(root);
241
256
  return managedFiles.map((file) => applyManagedFile(root, file, mode, context));
242
257
  }
243
258
  function applyManagedFile(root, file, mode, context) {
244
- if (file.releasePackagesOnly === true && !context.hasReleasePackages && !context.hasProductionDeployTargets) {
245
- return { target: file.target, action: 'skipped' };
246
- }
247
- if (file.cloudflareDeployOnly === true && context.stagingDeployProvider !== 'cloudflare') {
259
+ if (!managedFileApplies(file, context)) {
248
260
  return { target: file.target, action: 'skipped' };
249
261
  }
250
262
  const target = resolve(root, file.target);
@@ -483,12 +495,12 @@ export function macosPlatformArchitecturesForTest(targetNames) {
483
495
  }
484
496
  return [...architectures].sort((left, right) => left.localeCompare(right));
485
497
  }
486
- /** Test seam: deploy configuration presence/provider from graph nodes. */
487
- export function deployTargetInfoFromProjects(projects, configuration) {
498
+ /** Test seam: what the stage flow deploys, and with which provider, from graph nodes. */
499
+ export function deployTargetInfoFromProjects(projects, stage) {
488
500
  let exists = false;
489
501
  let provider;
490
502
  for (const project of Object.values(projects)) {
491
- const info = deployTargetInfoFromProject(project, configuration);
503
+ const info = deployTargetInfoFromProject(project, stage);
492
504
  if (!info.exists) {
493
505
  continue;
494
506
  }
@@ -501,22 +513,24 @@ export function deployTargetInfoFromProjects(projects, configuration) {
501
513
  export function anyProjectHasTagForTest(projects, tag) {
502
514
  return Object.values(projects).some((project) => project.tags?.includes(tag));
503
515
  }
504
- function deployTargetInfoFromProject(project, configuration) {
516
+ /**
517
+ * A generated deploy job exists for the projects CI would actually deploy, which
518
+ * is `stageDeploysProject` and nothing else — the same rule `smoo github-ci
519
+ * nx-deploy` selects by, so the job and its selection cannot disagree. Reading
520
+ * the target's presence instead would render a deploy job, with cloud
521
+ * credentials, into a repository whose only wrangler manifests document a
522
+ * Durable Object binding for a published library's consumers.
523
+ *
524
+ * The command is read for the PROVIDER only: which cloud CLI runs says which
525
+ * credentials the job needs, and says nothing about whether CI runs it.
526
+ */
527
+ function deployTargetInfoFromProject(project, stage) {
505
528
  const deploy = project.targets?.deploy;
506
- if (!deploy) {
507
- return { exists: false };
508
- }
509
- const baseCommandValue = deploy.options?.command ?? deploy.command;
510
- const baseCommand = typeof baseCommandValue === 'string' ? baseCommandValue : '';
511
- if (isStageDerivedDeploy(project.tags, baseCommand)) {
512
- return { exists: true, provider: deployProvider(baseCommand) };
513
- }
514
- const config = deploy.configurations?.[configuration];
515
- if (!config) {
529
+ if (!deploy || !stageDeploysProject(project.tags, stage)) {
516
530
  return { exists: false };
517
531
  }
518
- const commandValue = config.command ?? config.options?.command ?? baseCommand;
519
- return { exists: true, provider: deployProvider(typeof commandValue === 'string' ? commandValue : '') };
532
+ const command = deploy.options?.command ?? deploy.command;
533
+ return { exists: true, provider: deployProvider(typeof command === 'string' ? command : '') };
520
534
  }
521
535
  function deployProvider(command) {
522
536
  return command.includes('wrangler ') ? 'cloudflare' : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/monorepo/packs/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAsB,MAAM,mBAAmB,CAAC;AAO5E,OAAO,EAKL,KAAK,sBAAsB,EAS5B,MAAM,sBAAsB,CAAC;AAU9B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClD,WAAW,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD,YAAY,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,gBAAgB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAClE,iBAAiB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CACpE;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC9F;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AA8ID,0DAA0D;AAC1D,eAAO,MAAM,YAAY,gBAAQ,CAAC;AAElC,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,mBAAwB,EACjC,KAAK,GAAE,oBAAyB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAwMD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAexG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/monorepo/packs/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAsB,MAAM,mBAAmB,CAAC;AAW5E,OAAO,EAKL,KAAK,sBAAsB,EAS5B,MAAM,sBAAsB,CAAC;AAU9B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClD,WAAW,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD,YAAY,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,gBAAgB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAClE,iBAAiB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CACpE;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC9F;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAmJD,0DAA0D;AAC1D,eAAO,MAAM,YAAY,gBAAQ,CAAC;AAElC,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,mBAAwB,EACjC,KAAK,GAAE,oBAAyB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAwMD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAexG"}
@@ -2,7 +2,7 @@ import { chmodSync, existsSync, statSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { printCommandOutput, runResult, runStatus } from '../../lib/run.js';
4
4
  import { readProjectTargets } from '../../nx/index.js';
5
- import { applyCargoFeatureUnification, validateCargoCachePolicy } from '../cargo-policy.js';
5
+ import { applyCargoFeatureUnification, validateCargoCachePolicy, validateCargoToolchainInputs, } from '../cargo-policy.js';
6
6
  import { validateGoToolchainAgreement } from '../go-toolchain.js';
7
7
  import { syncBunLockfileVersions, validateBunLockfileVersions } from '../lockfile.js';
8
8
  import { validateDevenvModuleImport, warnOnManagedFileDrift } from '../managed-files.js';
@@ -76,6 +76,11 @@ const packs = [
76
76
  validatePreBuild(ctx) {
77
77
  return validateCargoCachePolicy(ctx.root);
78
78
  },
79
+ // Post-build: the toolchain identity is read off the RESOLVED graph, which
80
+ // means running the inference plugin, which means its dist has to exist.
81
+ async validatePostBuild(ctx) {
82
+ return validateCargoToolchainInputs(ctx.root, await readProjectTargets(ctx.root));
83
+ },
79
84
  },
80
85
  {
81
86
  name: 'publishing',
@@ -4,8 +4,12 @@ export interface ProjectTargets {
4
4
  root?: string;
5
5
  targets: string[];
6
6
  buildDependsOn?: string[];
7
+ /** Per-target `cache`, for policies that only govern what Nx can restore. */
8
+ targetCache?: Map<string, boolean>;
7
9
  targetDependencies?: Map<string, string[]>;
8
10
  targetExecutors?: Map<string, string>;
11
+ /** Per-target string inputs; object inputs (`runtime`, `json`, …) are dropped. */
12
+ targetInputs?: Map<string, string[]>;
9
13
  targetOptions?: Map<string, NxTargetOptions>;
10
14
  targetOutputs?: Map<string, string[]>;
11
15
  targetScripts?: Map<string, string>;
@@ -22,6 +26,8 @@ export declare function targetDependenciesFromNxProjectJson(value: NxProjectJson
22
26
  export declare function targetExecutorsFromNxProjectJson(value: NxProjectJson | null | undefined): Map<string, string>;
23
27
  export declare function targetOptionsFromNxProjectJson(value: NxProjectJson | null | undefined): Map<string, NxTargetOptions>;
24
28
  export declare function targetOutputsFromNxProjectJson(value: NxProjectJson | null | undefined): Map<string, string[]>;
29
+ export declare function targetInputsFromNxProjectJson(value: NxProjectJson | null | undefined): Map<string, string[]>;
30
+ export declare function targetCacheFromNxProjectJson(value: NxProjectJson | null | undefined): Map<string, boolean>;
25
31
  export declare function targetScriptsFromNxProjectJson(value: NxProjectJson | null | undefined): Map<string, string>;
26
32
  export declare function formatProjectTargetLines(projects: ProjectTargets[]): string;
27
33
  export declare function projectNamesWithTarget(projects: ProjectTargets[], target: string): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"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"}
package/dist/nx/index.js CHANGED
@@ -91,6 +91,18 @@ export function targetOptionsFromNxProjectJson(value) {
91
91
  export function targetOutputsFromNxProjectJson(value) {
92
92
  return targetStringArraysFromNxProjectJson(value, 'outputs');
93
93
  }
94
+ export function targetInputsFromNxProjectJson(value) {
95
+ return targetStringArraysFromNxProjectJson(value, 'inputs');
96
+ }
97
+ export function targetCacheFromNxProjectJson(value) {
98
+ const cache = new Map();
99
+ for (const [targetName, target] of Object.entries(value?.targets ?? {})) {
100
+ if (typeof target.cache === 'boolean') {
101
+ cache.set(targetName, target.cache);
102
+ }
103
+ }
104
+ return cache;
105
+ }
94
106
  export function targetScriptsFromNxProjectJson(value) {
95
107
  const targets = value?.targets;
96
108
  const scripts = new Map();
@@ -277,7 +289,9 @@ export function projectTargetsFromNxProjects(projects) {
277
289
  root: projectRootFromNxProjectJson(metadata),
278
290
  targets: targetNamesFromNxProjectJson(metadata),
279
291
  buildDependsOn: targetDependencies.get('build'),
292
+ targetCache: targetCacheFromNxProjectJson(metadata),
280
293
  targetDependencies,
294
+ targetInputs: targetInputsFromNxProjectJson(metadata),
281
295
  targetExecutors: targetExecutorsFromNxProjectJson(metadata),
282
296
  targetOptions: targetOptionsFromNxProjectJson(metadata),
283
297
  targetOutputs: targetOutputsFromNxProjectJson(metadata),
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `smoo secrets` — the operator side of the reconciliation in ./index.ts.
2
+ * `smoo secrets` — the operator side of the reconciliation in ./status.ts.
3
3
  *
4
4
  * Values are handed to `gh` over stdin, never through argv (a process list is
5
5
  * world-readable) and never printed. Reading one from the terminal disables
@@ -14,7 +14,7 @@
14
14
  * repository reports values that do exist as absent, and sends an operator
15
15
  * hunting for a secret that is already set.
16
16
  */
17
- import { type SecretRow } from './index.js';
17
+ import { type SecretRow } from './status.js';
18
18
  /**
19
19
  * Every secret this checkout declares that the repository does not hold, in
20
20
  * the order an operator should fix them: the ones a workflow already promises
@@ -53,15 +53,19 @@ export declare function writeRepositorySecret(name: string, value: string, repo:
53
53
  reason: string;
54
54
  }>;
55
55
  /**
56
- * Print every known secret and the scopes holding it. Exit code 1 when a
56
+ * Print every known secret and the scopes holding it, or - with `json` - the
57
+ * same facts as one document on stdout and nothing else. Exit code 1 when a
57
58
  * workflow promises a value no scope a bound job reads can supply — that
58
59
  * combination is the one that fails a deploy, and it fails talking about the
59
- * value rather than the missing secret.
60
+ * value rather than the missing secret. `--json` reports that refusal in
61
+ * `unsatisfied` and still exits 1: a machine-readable status that always
62
+ * succeeded would be a status nobody could gate on.
60
63
  */
61
64
  export declare function secretsStatus(root: string, options: {
62
65
  repo?: string;
63
66
  env?: string;
64
- }): number;
67
+ json?: boolean;
68
+ }): Promise<number>;
65
69
  /**
66
70
  * Set one secret, or - with no name - walk every secret this checkout declares
67
71
  * and the target scope does not hold, prompting once each. The walk is the
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/secrets/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAKL,KAAK,SAAS,EAOf,MAAM,YAAY,CAAC;AAGpB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAG5E;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAOxG;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAUnD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAwB/D;AAED,sFAAsF;AACtF,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAYvD;AAyCD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAkF5F;AA8BD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,OAAO,CAAC,MAAM,CAAC,CAwDjB;AAuBD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BzG"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/secrets/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAcH,OAAO,EAIL,KAAK,SAAS,EAKf,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAG5E;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAOxG;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAUnD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAwB/D;AAED,sFAAsF;AACtF,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAYvD;AAoGD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD,OAAO,CAAC,MAAM,CAAC,CAwFjB;AA8BD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,OAAO,CAAC,MAAM,CAAC,CA8DjB;AAuBD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCzG"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `smoo secrets` — the operator side of the reconciliation in ./index.ts.
2
+ * `smoo secrets` — the operator side of the reconciliation in ./status.ts.
3
3
  *
4
4
  * Values are handed to `gh` over stdin, never through argv (a process list is
5
5
  * world-readable) and never printed. Reading one from the terminal disables
@@ -16,8 +16,9 @@
16
16
  */
17
17
  import { spawn, spawnSync } from 'node:child_process';
18
18
  import { getWorkspacePackages } from '../lib/workspace.js';
19
- import { environmentsMissing, fetchLocalSecret, localSecretCommandNames, reconcileSecrets, secretNameMapping, unsatisfiedSecrets, unwiredSecrets, workerSecretNames, workflowEnvironments, workflowSecretNames, } from './index.js';
19
+ import { fetchLocalSecret, localSecretGroups, secretNameMapping, workerSecretNames, workerSecretStages, workflowEnvironments, workflowSecretNames, } from './index.js';
20
20
  import { resolveRepository } from './repository.js';
21
+ import { projectSecretsStatus, reconcileSecrets, stringifySecretsStatusDocument, unwiredSecrets, } from './status.js';
21
22
  /**
22
23
  * Every secret this checkout declares that the repository does not hold, in
23
24
  * the order an operator should fix them: the ones a workflow already promises
@@ -108,19 +109,21 @@ export async function writeRepositorySecret(name, value, repo, environment) {
108
109
  ? { ok: true }
109
110
  : { ok: false, reason: `gh ${args.join(' ')} exited ${status ?? 'without status'}` };
110
111
  }
111
- function collectSources(root, repositorySecrets, environmentSecrets = {}) {
112
- const workspaceDirs = getWorkspacePackages(root).map((pkg) => pkg.path);
112
+ function collectSources(root, workspaceDirs, localSecrets, repositorySecrets, environmentSecrets = {}) {
113
113
  const workerSecrets = workerSecretNames(root, workspaceDirs);
114
114
  const workflowSecrets = workflowSecretNames(root);
115
- const localCommands = localSecretCommandNames(root);
116
115
  const envNames = [
117
- ...new Set([...Object.values(workerSecrets).flatMap((names) => [...names]), ...workflowSecrets, ...localCommands]),
116
+ ...new Set([
117
+ ...Object.values(workerSecrets).flatMap((names) => [...names]),
118
+ ...workflowSecrets,
119
+ ...localSecrets.map((secret) => secret.name),
120
+ ]),
118
121
  ];
119
122
  return {
120
123
  workerSecrets,
121
124
  workflowSecrets,
122
125
  secretNames: secretNameMapping(root, envNames),
123
- localCommands,
126
+ localSecrets,
124
127
  repositorySecrets,
125
128
  environmentSecrets,
126
129
  };
@@ -141,47 +144,89 @@ function describe(row, scopeWidth) {
141
144
  ].join(' ');
142
145
  }
143
146
  /**
144
- * Print every known secret and the scopes holding it. Exit code 1 when a
145
- * workflow promises a value no scope a bound job reads can supply — that
146
- * combination is the one that fails a deploy, and it fails talking about the
147
- * value rather than the missing secret.
147
+ * Everything `status` reports, read from git, `gh` and the checkout before a
148
+ * single line is printed. Gathering ahead of rendering is what lets one run
149
+ * answer either a human or a machine from exactly the same facts: `--json`
150
+ * cannot drift from the table because there is nothing for it to drift from.
148
151
  */
149
- export function secretsStatus(root, options) {
152
+ async function gatherSecretsStatus(root, options) {
150
153
  const resolved = resolveRepository(root, options.repo);
151
- if (!resolved.ok) {
152
- console.error(resolved.reason);
153
- return 1;
154
- }
154
+ if (!resolved.ok)
155
+ return resolved;
155
156
  const { repo, source } = resolved.choice;
156
157
  const repositorySecrets = readRepositorySecrets(repo);
157
- if (!repositorySecrets.ok) {
158
- console.error(repositorySecrets.reason);
159
- return 1;
160
- }
158
+ if (!repositorySecrets.ok)
159
+ return repositorySecrets;
161
160
  // The workflows decide which environments a job reads; an explicitly asked
162
161
  // for one is shown too, so an operator can inspect a scope before a workflow
163
162
  // binds it.
164
163
  const boundEnvironments = workflowEnvironments(root);
165
164
  const asked = options.env !== undefined && !boundEnvironments.includes(options.env) ? [options.env] : [];
166
165
  const environmentSecrets = {};
167
- const unreadable = [];
168
- for (const environment of [...boundEnvironments, ...asked]) {
169
- const held = readRepositorySecrets(repo, environment);
170
- if (held.ok)
171
- environmentSecrets[environment] = held.names;
172
- else
173
- unreadable.push({ environment, reason: held.reason });
166
+ const environments = [];
167
+ for (const name of [...boundEnvironments, ...asked]) {
168
+ const bound = boundEnvironments.includes(name);
169
+ const held = readRepositorySecrets(repo, name);
170
+ // An environment that cannot be read is reported, never assumed empty:
171
+ // guessing produces a refusal about a value that may well be set.
172
+ if (!held.ok) {
173
+ environments.push({ name, bound, readable: false, reason: held.reason });
174
+ continue;
175
+ }
176
+ environmentSecrets[name] = held.names;
177
+ environments.push({ name, bound, readable: true, secretCount: held.names.length });
178
+ }
179
+ const workspaceDirs = getWorkspacePackages(root).map((pkg) => pkg.path);
180
+ const stageScopes = workerSecretStages(root, workspaceDirs);
181
+ if (!stageScopes.ok)
182
+ return stageScopes;
183
+ // A `smoo.secrets` declaration smoo cannot read is a refusal, not an empty
184
+ // list: reporting "nothing is fetchable locally" for a manifest that says
185
+ // otherwise is the confident wrong answer.
186
+ const localSecrets = await localSecretGroups(root);
187
+ if (!localSecrets.ok)
188
+ return localSecrets;
189
+ return {
190
+ ok: true,
191
+ document: projectSecretsStatus({
192
+ repository: { repo, source, secretCount: repositorySecrets.names.length },
193
+ environments,
194
+ rows: reconcileSecrets(collectSources(root, workspaceDirs, localSecrets.secrets, repositorySecrets.names, environmentSecrets)),
195
+ stageScopes: stageScopes.byWorker,
196
+ }),
197
+ };
198
+ }
199
+ /**
200
+ * Print every known secret and the scopes holding it, or - with `json` - the
201
+ * same facts as one document on stdout and nothing else. Exit code 1 when a
202
+ * workflow promises a value no scope a bound job reads can supply — that
203
+ * combination is the one that fails a deploy, and it fails talking about the
204
+ * value rather than the missing secret. `--json` reports that refusal in
205
+ * `unsatisfied` and still exits 1: a machine-readable status that always
206
+ * succeeded would be a status nobody could gate on.
207
+ */
208
+ export async function secretsStatus(root, options) {
209
+ const gathered = await gatherSecretsStatus(root, options);
210
+ if (!gathered.ok) {
211
+ console.error(gathered.reason);
212
+ return 1;
213
+ }
214
+ const { document } = gathered;
215
+ const { repo, source } = document.repository;
216
+ if (options.json) {
217
+ console.log(stringifySecretsStatusDocument(document));
218
+ return document.unsatisfied.length > 0 ? 1 : 0;
174
219
  }
175
- // An environment that cannot be read is reported, never assumed empty:
176
- // guessing produces a refusal about a value that may well be set.
177
- const readable = boundEnvironments.filter((environment) => environment in environmentSecrets);
178
- const rows = reconcileSecrets(collectSources(root, repositorySecrets.names, environmentSecrets));
179
- console.log(`repository ${repo} (${source}), holding ${repositorySecrets.names.length} secrets`);
180
- for (const [environment, names] of Object.entries(environmentSecrets)) {
181
- console.log(`environment ${environment}, holding ${names.length} secrets`);
220
+ const rows = document.secrets;
221
+ console.log(`repository ${repo} (${source}), holding ${document.repository.secretCount} secrets`);
222
+ for (const environment of document.environments) {
223
+ if (environment.readable)
224
+ console.log(`environment ${environment.name}, holding ${environment.secretCount} secrets`);
182
225
  }
183
- for (const { environment, reason } of unreadable) {
184
- console.log(`environment ${environment} could not be read, so nothing below claims what it holds: ${reason}`);
226
+ for (const environment of document.environments) {
227
+ if (environment.readable)
228
+ continue;
229
+ console.log(`environment ${environment.name} could not be read, so nothing below claims what it holds: ${environment.reason}`);
185
230
  }
186
231
  const scopeWidth = Math.max('held by'.length, ...rows.map((row) => heldBy(row).length));
187
232
  console.log(`${'held by'.padEnd(scopeWidth)} ${'name'.padEnd(32)} workflow local declared by`);
@@ -195,6 +240,22 @@ export function secretsStatus(root, options) {
195
240
  'declare it in smoo.github.deploySecrets to have CI supply it.');
196
241
  }
197
242
  }
243
+ // A declared `group` that disagrees with what this repository's own
244
+ // declarations derive is the override working — and a silent override is
245
+ // how the next reader loses an hour wondering why a `.npmrc` credential
246
+ // resolves at shell entry. It is stated here, where a human is already
247
+ // looking at every declared secret.
248
+ const overridden = rows.filter((row) => row.localGroup !== undefined && row.localGroup.resolves !== row.localGroup.derived);
249
+ if (overridden.length > 0) {
250
+ console.log('');
251
+ for (const row of overridden) {
252
+ const local = row.localGroup;
253
+ if (local === undefined)
254
+ continue;
255
+ console.log(`note: ${row.name} declares group \`${local.resolves}\`, overriding the \`${local.derived}\` this ` +
256
+ `repository's declarations derive; \`smoo secrets run ${local.resolves} <command>\` is what resolves it.`);
257
+ }
258
+ }
198
259
  // A value an environment holds is not a value to duplicate at repository
199
260
  // scope: offering it invites two sources of truth for one credential, and
200
261
  // the table above already shows where it lives. Only a name no scope holds
@@ -209,23 +270,21 @@ export function secretsStatus(root, options) {
209
270
  console.log(`set them all, one prompt each: smoo secrets set -R ${repo}`);
210
271
  console.log(`set one: smoo secrets set ${needed[0]?.repositorySecret ?? 'NAME'} -R ${repo}`);
211
272
  }
212
- const unsatisfied = unsatisfiedSecrets(rows, readable);
213
- if (unsatisfied.length === 0)
273
+ if (document.unsatisfied.length === 0)
214
274
  return 0;
215
275
  console.log('');
216
- for (const row of unsatisfied) {
217
- const missing = environmentsMissing(row, readable);
218
- const scopes = missing.length > 0 ? missing.join(', ') : 'the repository';
219
- console.error(`missing: ${row.name} a workflow passes secrets.${row.name} and no value exists in ${scopes}.`);
220
- if (missing.length === 0) {
221
- console.error(` smoo secrets set ${row.repositorySecret} -R ${repo}`);
276
+ for (const { name, repositorySecret, missingIn } of document.unsatisfied) {
277
+ const scopes = missingIn.length > 0 ? missingIn.join(', ') : 'the repository';
278
+ console.error(`missing: ${name} a workflow passes secrets.${name} and no value exists in ${scopes}.`);
279
+ if (missingIn.length === 0) {
280
+ console.error(` smoo secrets set ${repositorySecret} -R ${repo}`);
222
281
  continue;
223
282
  }
224
- for (const environment of missing) {
283
+ for (const environment of missingIn) {
225
284
  const named = environment.includes(' ') ? `'${environment}'` : environment;
226
- console.error(` smoo secrets set ${row.repositorySecret} -R ${repo} --env ${named}`);
285
+ console.error(` smoo secrets set ${repositorySecret} -R ${repo} --env ${named}`);
227
286
  }
228
- console.error(` or one value for every environment: smoo secrets set ${row.repositorySecret} -R ${repo}`);
287
+ console.error(` or one value for every environment: smoo secrets set ${repositorySecret} -R ${repo}`);
229
288
  }
230
289
  return 1;
231
290
  }
@@ -290,7 +349,13 @@ export async function secretsSet(root, name, options) {
290
349
  }
291
350
  environmentSecrets[environment] = inEnvironment.names;
292
351
  }
293
- const rows = reconcileSecrets(collectSources(root, held.names, environmentSecrets));
352
+ const workspaceDirs = getWorkspacePackages(root).map((pkg) => pkg.path);
353
+ const local = await localSecretGroups(root);
354
+ if (!local.ok) {
355
+ console.error(local.reason);
356
+ return 1;
357
+ }
358
+ const rows = reconcileSecrets(collectSources(root, workspaceDirs, local.secrets, held.names, environmentSecrets));
294
359
  const needed = environment === undefined ? secretsNeedingValues(rows) : secretsMissingInEnvironment(rows, environment);
295
360
  const target = environment === undefined ? `${repo} (${source})` : `environment ${environment} on ${repo} (${source})`;
296
361
  if (needed.length === 0) {
@@ -349,7 +414,15 @@ export async function secretsSync(root, options) {
349
414
  }
350
415
  const { repo } = resolved.choice;
351
416
  const environment = options.env;
352
- const names = localSecretCommandNames(root);
417
+ const local = await localSecretGroups(root);
418
+ if (!local.ok) {
419
+ console.error(local.reason);
420
+ return 1;
421
+ }
422
+ // Every group: a repository secret store holds the credential whatever
423
+ // resolves it locally, and a `smoo secrets run` group is about which
424
+ // command pays the provider prompt, not about which values CI needs.
425
+ const names = local.secrets.map((secret) => secret.name);
353
426
  if (names.length === 0) {
354
427
  console.error('smoo.secrets declares no fetch commands; nothing to sync.');
355
428
  return 1;