@smoothbricks/cli 0.10.1 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +25 -13
  2. package/dist/cli.js +24 -0
  3. package/dist/github-ci/index.d.ts +17 -2
  4. package/dist/github-ci/index.d.ts.map +1 -1
  5. package/dist/github-ci/index.js +145 -14
  6. package/dist/github-ci/outputs.d.ts +22 -0
  7. package/dist/github-ci/outputs.d.ts.map +1 -0
  8. package/dist/github-ci/outputs.js +649 -0
  9. package/dist/lib/conflict-markers.d.ts.map +1 -1
  10. package/dist/lib/workspace.d.ts +1 -1
  11. package/dist/lib/workspace.d.ts.map +1 -1
  12. package/dist/monorepo/ci-workflow.d.ts.map +1 -1
  13. package/dist/monorepo/ci-workflow.js +2 -1
  14. package/dist/monorepo/managed-files.d.ts +2 -0
  15. package/dist/monorepo/managed-files.d.ts.map +1 -1
  16. package/dist/monorepo/managed-files.js +50 -5
  17. package/dist/monorepo/package-policy.d.ts.map +1 -1
  18. package/dist/monorepo/package-policy.js +26 -0
  19. package/dist/monorepo/packs/index.d.ts +3 -0
  20. package/dist/monorepo/packs/index.d.ts.map +1 -1
  21. package/dist/monorepo/packs/index.js +5 -2
  22. package/dist/monorepo/publish-workflow.d.ts +1 -0
  23. package/dist/monorepo/publish-workflow.d.ts.map +1 -1
  24. package/dist/monorepo/publish-workflow.js +240 -2
  25. package/dist/monorepo/tool-validation.d.ts.map +1 -1
  26. package/dist/monorepo/tool-validation.js +20 -7
  27. package/dist/nx/index.d.ts +6 -0
  28. package/dist/nx/index.d.ts.map +1 -1
  29. package/dist/nx/index.js +55 -5
  30. package/dist/release/github-release.d.ts +5 -2
  31. package/dist/release/github-release.d.ts.map +1 -1
  32. package/dist/release/github-release.js +11 -0
  33. package/dist/release/index.d.ts +19 -1
  34. package/dist/release/index.d.ts.map +1 -1
  35. package/dist/release/index.js +140 -31
  36. package/dist/release/orchestration.d.ts +8 -1
  37. package/dist/release/orchestration.d.ts.map +1 -1
  38. package/dist/release/orchestration.js +38 -1
  39. package/dist/wrangler/prepare-env.d.ts.map +1 -1
  40. package/dist/wrangler/prepare-env.js +1 -1
  41. package/dist/wrangler/scaffold.d.ts.map +1 -1
  42. package/dist/wrangler/scaffold.js +1 -1
  43. package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +5 -0
  44. package/managed/raw/tooling/direnv/setup-environment.ts +32 -1
  45. package/managed/templates/github/actions/cache-nix-devenv/action.yml +12 -10
  46. package/managed/templates/github/actions/cache-node-modules/action.yml +3 -2
  47. package/managed/templates/github/actions/cache-nx/action.yml +2 -2
  48. package/managed/templates/github/actions/save-nix-devenv/action.yml +11 -3
  49. package/package.json +7 -14
  50. package/src/cli.ts +30 -4
  51. package/src/github-ci/index.test.ts +486 -0
  52. package/src/github-ci/index.ts +177 -16
  53. package/src/github-ci/outputs.ts +506 -0
  54. package/src/monorepo/__tests__/ci-workflow.test.ts +13 -0
  55. package/src/monorepo/__tests__/publish-workflow.test.ts +234 -5
  56. package/src/monorepo/ci-workflow.ts +3 -1
  57. package/src/monorepo/managed-files.test.ts +75 -0
  58. package/src/monorepo/managed-files.ts +61 -5
  59. package/src/monorepo/package-policy.test.ts +57 -38
  60. package/src/monorepo/package-policy.ts +28 -0
  61. package/src/monorepo/packs/index.test.ts +18 -1
  62. package/src/monorepo/packs/index.ts +7 -3
  63. package/src/monorepo/publish-workflow.ts +481 -2
  64. package/src/monorepo/tool-validation.test.ts +59 -24
  65. package/src/monorepo/tool-validation.ts +21 -7
  66. package/src/monorepo/wrangler.test.ts +9 -2
  67. package/src/nx/index.test.ts +39 -0
  68. package/src/nx/index.ts +65 -5
  69. package/src/release/__tests__/fixture-repo.test.ts +18 -16
  70. package/src/release/__tests__/github-release.test.ts +11 -0
  71. package/src/release/__tests__/orchestration.test.ts +57 -2
  72. package/src/release/__tests__/trust-publisher.test.ts +91 -2
  73. package/src/release/github-release.ts +12 -0
  74. package/src/release/index.ts +218 -40
  75. package/src/release/orchestration.ts +55 -3
  76. package/src/wrangler/prepare-env.ts +14 -4
  77. package/src/wrangler/scaffold.ts +8 -3
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAElD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAOpF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYpF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBlF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAK3E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK3F;AAED,wBAAgB,oCAAoC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB7E;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7D;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhG;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAGhF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAElD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE/E;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAEpF;AAED,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CA2BzF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYpF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEpF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBlF;AAuBD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAK3E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK3F;AAED,wBAAgB,oCAAoC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB7E;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7D;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhG;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAGhF"}
package/dist/nx/index.js CHANGED
@@ -17,13 +17,39 @@ export function targetNamesFromNxProjectJson(value) {
17
17
  const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
18
18
  return targets ? Object.keys(targets).sort((a, b) => a.localeCompare(b)) : [];
19
19
  }
20
+ export function projectRootFromNxProjectJson(value) {
21
+ return isRecord(value) && typeof value.root === 'string' ? value.root : undefined;
22
+ }
20
23
  export function buildDependsOnFromNxProjectJson(value) {
24
+ return targetDependenciesFromNxProjectJson(value).get('build');
25
+ }
26
+ export function targetDependenciesFromNxProjectJson(value) {
21
27
  const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
22
- const build = targets ? recordProperty(targets, 'build') : null;
23
- if (!Array.isArray(build?.dependsOn) || !build.dependsOn.every((entry) => typeof entry === 'string')) {
24
- return undefined;
28
+ const dependencies = new Map();
29
+ if (!targets) {
30
+ return dependencies;
31
+ }
32
+ for (const [targetName, target] of Object.entries(targets)) {
33
+ if (!isRecord(target) || !Array.isArray(target.dependsOn)) {
34
+ continue;
35
+ }
36
+ const entries = [];
37
+ for (const dependency of target.dependsOn) {
38
+ if (typeof dependency === 'string') {
39
+ entries.push(dependency);
40
+ continue;
41
+ }
42
+ if (!isRecord(dependency) || typeof dependency.target !== 'string') {
43
+ throw new Error(`Nx target ${targetName} has an invalid dependsOn entry.`);
44
+ }
45
+ if (dependency.projects !== undefined && dependency.projects !== 'self') {
46
+ throw new Error(`Nx target ${targetName} uses unsupported cross-project dependsOn for ${dependency.target}.`);
47
+ }
48
+ entries.push(dependency.target);
49
+ }
50
+ dependencies.set(targetName, entries);
25
51
  }
26
- return build.dependsOn;
52
+ return dependencies;
27
53
  }
28
54
  export function targetExecutorsFromNxProjectJson(value) {
29
55
  const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
@@ -38,6 +64,9 @@ export function targetExecutorsFromNxProjectJson(value) {
38
64
  }
39
65
  return executors;
40
66
  }
67
+ export function targetOutputsFromNxProjectJson(value) {
68
+ return targetStringArraysFromNxProjectJson(value, 'outputs');
69
+ }
41
70
  export function targetScriptsFromNxProjectJson(value) {
42
71
  const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
43
72
  const scripts = new Map();
@@ -55,6 +84,23 @@ export function targetScriptsFromNxProjectJson(value) {
55
84
  }
56
85
  return scripts;
57
86
  }
87
+ function targetStringArraysFromNxProjectJson(value, property) {
88
+ const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
89
+ const values = new Map();
90
+ if (!targets) {
91
+ return values;
92
+ }
93
+ for (const [targetName, target] of Object.entries(targets)) {
94
+ if (!isRecord(target)) {
95
+ continue;
96
+ }
97
+ const entries = target[property];
98
+ if (Array.isArray(entries)) {
99
+ values.set(targetName, entries.filter((entry) => typeof entry === 'string'));
100
+ }
101
+ }
102
+ return values;
103
+ }
58
104
  export function formatProjectTargetLines(projects) {
59
105
  return projects
60
106
  .flatMap((project) => project.targets.map((target) => `${project.project}:${target}`))
@@ -134,11 +180,15 @@ async function readProjectTarget(root, project) {
134
180
  const command = nxShowProjectCommand(project);
135
181
  const result = await $ `${command.command} ${command.args}`.cwd(root).quiet();
136
182
  const parsed = JSON.parse(decode(result.stdout));
183
+ const targetDependencies = targetDependenciesFromNxProjectJson(parsed);
137
184
  return {
138
185
  project,
186
+ root: projectRootFromNxProjectJson(parsed),
139
187
  targets: targetNamesFromNxProjectJson(parsed),
140
- buildDependsOn: buildDependsOnFromNxProjectJson(parsed),
188
+ buildDependsOn: targetDependencies.get('build'),
189
+ targetDependencies,
141
190
  targetExecutors: targetExecutorsFromNxProjectJson(parsed),
191
+ targetOutputs: targetOutputsFromNxProjectJson(parsed),
142
192
  targetScripts: targetScriptsFromNxProjectJson(parsed),
143
193
  };
144
194
  }
@@ -18,7 +18,6 @@ export interface GithubReleaseWriteShell {
18
18
  export declare function renderNxProjectChangelogContents(input: RenderNxProjectChangelogInput): Promise<string>;
19
19
  export declare function createOrUpdateGithubRelease(pkg: ReleasePackageInfo, contents: string, shell: GithubReleaseWriteShell): Promise<void>;
20
20
  export declare function nxProjectChangelogArgs(pkg: ReleasePackageInfo, previousTag: string | null, dryRun: boolean): {
21
- from: string;
22
21
  version: string;
23
22
  projects: string[];
24
23
  gitCommit: false;
@@ -26,10 +25,11 @@ export declare function nxProjectChangelogArgs(pkg: ReleasePackageInfo, previous
26
25
  gitPush: false;
27
26
  stageChanges: false;
28
27
  createRelease: false;
28
+ forceChangelogGeneration: true;
29
29
  deleteVersionPlans: false;
30
30
  dryRun: boolean;
31
+ from: string;
31
32
  } | {
32
- firstRelease: boolean;
33
33
  version: string;
34
34
  projects: string[];
35
35
  gitCommit: false;
@@ -37,10 +37,13 @@ export declare function nxProjectChangelogArgs(pkg: ReleasePackageInfo, previous
37
37
  gitPush: false;
38
38
  stageChanges: false;
39
39
  createRelease: false;
40
+ forceChangelogGeneration: true;
40
41
  deleteVersionPlans: false;
41
42
  dryRun: boolean;
43
+ firstRelease: boolean;
42
44
  };
43
45
  export declare function projectChangelogContents(result: ProjectChangelogLookupResult, projectName: string): string;
46
+ export declare function githubReleaseLookupExists(tag: string, exitCode: number, stdout: string, stderr: string): boolean;
44
47
  export declare function githubReleaseCommandArgs(tag: string, notesFile: string, releaseExists: boolean, version: string): string[];
45
48
  export declare function withNxWorkspaceRoot<T>(root: string, run: () => Promise<T>): Promise<T>;
46
49
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"github-release.d.ts","sourceRoot":"","sources":["../../src/release/github-release.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAYhE,UAAU,4BAA4B;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;EAa1G;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAM1G;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,EACtB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CAgBV;AAMD,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAmB5F"}
1
+ {"version":3,"file":"github-release.d.ts","sourceRoot":"","sources":["../../src/release/github-release.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAYhE,UAAU,4BAA4B;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAc1G;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAM1G;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAShH;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,EACtB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CAgBV;AAMD,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAmB5F"}
@@ -41,6 +41,7 @@ export function nxProjectChangelogArgs(pkg, previousTag, dryRun) {
41
41
  gitPush: false,
42
42
  stageChanges: false,
43
43
  createRelease: false,
44
+ forceChangelogGeneration: true,
44
45
  deleteVersionPlans: false,
45
46
  dryRun,
46
47
  };
@@ -53,6 +54,16 @@ export function projectChangelogContents(result, projectName) {
53
54
  }
54
55
  return changelog.contents;
55
56
  }
57
+ export function githubReleaseLookupExists(tag, exitCode, stdout, stderr) {
58
+ if (exitCode === 0) {
59
+ return true;
60
+ }
61
+ const details = [stderr.trim(), stdout.trim()].filter(Boolean).join('\n');
62
+ if (/\bHTTP 404\b|release not found/i.test(details)) {
63
+ return false;
64
+ }
65
+ throw new Error(`Unable to inspect GitHub Release ${tag}.${details ? `\n${details}` : ''}`);
66
+ }
56
67
  export function githubReleaseCommandArgs(tag, notesFile, releaseExists, version) {
57
68
  const args = [
58
69
  'release',
@@ -11,6 +11,14 @@ export interface ReleasePublishOptions {
11
11
  }
12
12
  export interface ReleaseRepairPendingOptions {
13
13
  dryRun?: boolean;
14
+ platformOutputs?: string;
15
+ ref?: string;
16
+ }
17
+ export interface ReleasePlatformOutputsOptions {
18
+ bump: string;
19
+ output: string;
20
+ ref?: string;
21
+ targets: string;
14
22
  }
15
23
  export interface ReleaseTrustPublisherOptions {
16
24
  dryRun?: boolean;
@@ -37,7 +45,9 @@ export interface ReleaseRetagUnpublishedOptions {
37
45
  export declare function releaseVersion(root: string, options: ReleaseVersionOptions): Promise<void>;
38
46
  export declare function releasePublish(root: string, options: ReleasePublishOptions): Promise<void>;
39
47
  export declare function releaseRepairPending(root: string, options: ReleaseRepairPendingOptions): Promise<void>;
48
+ export declare function releaseCollectPlatformOutputs(root: string, options: ReleasePlatformOutputsOptions): Promise<void>;
40
49
  export declare function releaseTrustPublisher(root: string, options: ReleaseTrustPublisherOptions): Promise<void>;
50
+ export declare function npmTrustGithubArgs(packageName: string, repository: string, workflow: string, dryRun: boolean): string[];
41
51
  export interface TrustPublisherShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
42
52
  repository: string;
43
53
  workflow: string;
@@ -45,7 +55,8 @@ export interface TrustPublisherShell<Package extends ReleasePackageInfo = Releas
45
55
  packageExists(name: string): Promise<boolean>;
46
56
  bootstrapNpmPackages(options: BootstrapNpmPackagesOptions): Promise<Package[]>;
47
57
  trustPublisher(pkg: Package, dryRun: boolean, env?: Record<string, string>): Promise<TrustPublisherResult>;
48
- trustedPublishers(pkg: Package): Promise<TrustedPublisher[]>;
58
+ trustedPublishers(pkg: Package): Promise<TrustedPublisherLookup>;
59
+ login(): Promise<void>;
49
60
  log(message: string): void;
50
61
  error(message: string): void;
51
62
  }
@@ -56,9 +67,16 @@ export interface TrustedPublisher {
56
67
  file?: string;
57
68
  repository?: string;
58
69
  }
70
+ export interface NpmTrustAccessDenied {
71
+ readonly status: 'access-denied';
72
+ readonly identity: string;
73
+ readonly owners: string;
74
+ }
75
+ export type TrustedPublisherLookup = TrustedPublisher[] | NpmTrustAccessDenied;
59
76
  export declare function configureTrustedPublishers<Package extends ReleasePackageInfo>(shell: TrustPublisherShell<Package>, options: ReleaseTrustPublisherOptions): Promise<void>;
60
77
  export declare function releaseBootstrapNpmPackages(root: string, options: ReleaseBootstrapNpmPackagesOptions): Promise<void>;
61
78
  export declare function releaseRetagUnpublished(root: string, options: ReleaseRetagUnpublishedOptions): Promise<void>;
62
79
  export declare function printReleaseState(root: string): Promise<void>;
80
+ export declare function npmTrustListAccessDenied(stdout: string, stderr: string): boolean;
63
81
  export declare function parseTrustedPublishers(stdout: string, packageName: string): TrustedPublisher[];
64
82
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"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"}
@@ -1,21 +1,22 @@
1
1
  import { appendFile, mkdtemp, rm, writeFile } from 'node:fs/promises';
2
2
  import { tmpdir } from 'node:os';
3
- import { join } from 'node:path';
3
+ import { join, resolve } from 'node:path';
4
4
  import { createInterface } from 'node:readline/promises';
5
5
  import { Writable } from 'node:stream';
6
6
  import { $ } from 'bun';
7
+ import { githubCiApplyOutputs, githubCiNxRunMany } from '../github-ci/index.js';
7
8
  import { assertNoConflictMarkers } from '../lib/conflict-markers.js';
8
9
  import { withDevenvEnv } from '../lib/devenv.js';
9
10
  import { isRecord, readJsonObject, stringProperty } from '../lib/json.js';
10
- import { decode, run, runInteractiveStatus, runResult, runStatus } from '../lib/run.js';
11
+ import { decode, run, runInteractiveStatus, runResult } from '../lib/run.js';
11
12
  import { listReleasePackages, readPackageJson, repositoryInfo } from '../lib/workspace.js';
12
13
  import { readPackedPackageJson, validatePackedWorkspaceDependencies } from '../monorepo/packed-manifest.js';
13
14
  import { bootstrapNpmPackages, NPM_BOOTSTRAP_DIST_TAG, NPM_BOOTSTRAP_VERSION, } from './bootstrap-npm-packages.js';
14
15
  import { autoReleaseCandidatePackages } from './candidates.js';
15
16
  import { collectOwnedReleaseTagRecords, pendingReleaseTargets, releaseTag, releaseTagAliases, } from './core.js';
16
- import { createOrUpdateGithubRelease, renderNxProjectChangelogContents, withNxWorkspaceRoot, } from './github-release.js';
17
+ import { createOrUpdateGithubRelease, githubReleaseLookupExists, renderNxProjectChangelogContents, withNxWorkspaceRoot, } from './github-release.js';
17
18
  import { publishWithAuthDiagnostics } from './npm-auth.js';
18
- import { bumpStableReleaseToNext, completeReleaseAtHead as completeReleaseAtHeadWithShell, repairPendingTargets, runReleaseVersion, } from './orchestration.js';
19
+ import { bumpStableReleaseToNext, collectRepairPlatformOutputs, completeReleaseAtHead as completeReleaseAtHeadWithShell, repairPendingTargets, runReleaseVersion, } from './orchestration.js';
19
20
  import { retagUnpublished } from './retag-unpublished.js';
20
21
  export async function releaseVersion(root, options) {
21
22
  const bump = releaseBumpArg(options.bump);
@@ -78,23 +79,38 @@ export async function releasePublish(root, options) {
78
79
  }
79
80
  }
80
81
  export async function releaseRepairPending(root, options) {
81
- const branch = await releaseBranch(root);
82
- const remote = await releaseRemote(root, branch);
83
- console.log(`Repair pending releases: fetching ${remote}/${branch} and tags.`);
84
- await fetchReleaseRefs(root, remote, branch);
85
- const remoteRef = `${remote}/${branch}`;
86
- const restoreRef = (await gitRefExists(root, remoteRef)) ? remoteRef : await gitHead(root);
87
- console.log(`Repair pending releases: planning from ${restoreRef}.`);
88
- const targets = await listPendingReleaseTargets(root, restoreRef);
89
- console.log(targets.length === 0
90
- ? 'Repair pending releases: no pending durable state repairs found.'
91
- : `Repair pending releases: ${targets.length} release target${targets.length === 1 ? '' : 's'} need repair.`);
92
- for (const target of targets) {
93
- console.log(`Repair pending releases: target ${target.sha.slice(0, 12)} needs ${repairTargetSummary(target)}.`);
94
- }
95
- const summaries = await repairPendingTargets(releaseRepairShell(root), targets, restoreRef, options.dryRun === true);
82
+ const repairRef = await fetchReleaseRepairRef(root, options.ref);
83
+ const restoreRef = options.ref ? await gitHead(root) : repairRef;
84
+ console.log(`Repair pending releases: planning from ${repairRef}.`);
85
+ const targets = await listPendingReleaseTargets(root, repairRef);
86
+ logPendingReleaseTargets(targets);
87
+ const platformOutputs = options.platformOutputs ? resolve(root, options.platformOutputs) : undefined;
88
+ const summaries = await repairPendingTargets(releaseRepairShell(root, platformOutputs), targets, restoreRef, options.dryRun === true);
96
89
  await writeRepairSummary(summaries, options.dryRun === true);
97
90
  }
91
+ export async function releaseCollectPlatformOutputs(root, options) {
92
+ const restoreRef = await gitHead(root);
93
+ const releaseRef = await fetchReleaseRepairRef(root, options.ref);
94
+ const packages = releasePackages(root);
95
+ const packagesAtHead = await releasePackagesAtHead(root, packages);
96
+ const currentPackages = packagesAtHead.length > 0
97
+ ? packagesAtHead
98
+ : await releasePlatformPackages(root, packages, releaseBumpArg(options.bump));
99
+ console.log(currentPackages.length === 0
100
+ ? 'Release platform outputs: no current release packages selected.'
101
+ : `Release platform outputs: building current outputs for ${packageSummary(currentPackages)}.`);
102
+ const outputRoot = resolve(root, options.output);
103
+ await githubCiNxRunMany(root, {
104
+ targets: options.targets,
105
+ projects: releasePackageProjects(currentPackages),
106
+ collectOutputs: join(outputRoot, 'current'),
107
+ allowEmptyProjects: true,
108
+ });
109
+ console.log(`Repair platform outputs: planning from ${releaseRef}.`);
110
+ const targets = await listPendingReleaseTargets(root, releaseRef);
111
+ logPendingReleaseTargets(targets);
112
+ await collectRepairPlatformOutputs(releaseRepairOutputsShell(root, options.targets, join(outputRoot, 'repairs')), targets, restoreRef);
113
+ }
98
114
  export async function releaseTrustPublisher(root, options) {
99
115
  const repository = githubRepositoryFromRootPackage(root);
100
116
  const workflow = 'publish.yml';
@@ -111,18 +127,20 @@ export async function releaseTrustPublisher(root, options) {
111
127
  promptOtp: (packageName) => promptForNpmOtp(packageName),
112
128
  log: (message) => console.log(message),
113
129
  }, bootstrapOptions),
114
- trustPublisher: (pkg, dryRun, env) => {
115
- const args = ['trust', 'github', pkg.name, '--file', workflow, '--repo', repository, '--yes'];
116
- if (dryRun) {
117
- args.push('--dry-run');
118
- }
119
- return runLatestNpmTrust(root, args, env);
120
- },
130
+ trustPublisher: (pkg, dryRun, env) => runLatestNpmTrust(root, npmTrustGithubArgs(pkg.name, repository, workflow, dryRun), env),
121
131
  trustedPublishers: (pkg) => listTrustedPublishers(root, pkg),
132
+ login: () => runLatestNpm(root, ['login', '--auth-type=web']),
122
133
  log: (message) => console.log(message),
123
134
  error: (message) => console.error(message),
124
135
  }, options);
125
136
  }
137
+ export function npmTrustGithubArgs(packageName, repository, workflow, dryRun) {
138
+ const args = ['trust', 'github', packageName, '--file', workflow, '--repo', repository, '--allow-publish', '--yes'];
139
+ if (dryRun) {
140
+ args.push('--dry-run');
141
+ }
142
+ return args;
143
+ }
126
144
  export async function configureTrustedPublishers(shell, options) {
127
145
  const packages = shell.listReleasePackages();
128
146
  const selectedPackages = selectedTrustPublisherPackages(packages, options.packages ?? []);
@@ -149,7 +167,7 @@ export async function configureTrustedPublishers(shell, options) {
149
167
  const failedPackages = [];
150
168
  for (const pkg of selectedPackages) {
151
169
  if (!options.dryRun) {
152
- const trustedPublishers = await shell.trustedPublishers(pkg);
170
+ const trustedPublishers = await trustedPublishersWithOwnerLogin(shell, pkg);
153
171
  if (hasMatchingGithubTrustedPublisher(trustedPublishers, shell.repository, shell.workflow)) {
154
172
  shell.log(`${pkg.name}: npm trusted publisher is already configured; skipping.`);
155
173
  continue;
@@ -186,6 +204,23 @@ export async function configureTrustedPublishers(shell, options) {
186
204
  shell.error(`Trusted publishing was not configured for: ${failedPackages.join(', ')}`);
187
205
  }
188
206
  }
207
+ async function trustedPublishersWithOwnerLogin(shell, pkg) {
208
+ let result = await shell.trustedPublishers(pkg);
209
+ if (Array.isArray(result)) {
210
+ return result;
211
+ }
212
+ shell.error(`${pkg.name}: npm trust access denied for npm account "${result.identity}". ` +
213
+ `npm trust requires package write access. Package owners:\n${result.owners}`);
214
+ shell.log(`${pkg.name}: opening npm browser login. Sign in as a listed package owner, then return here.`);
215
+ await shell.login();
216
+ result = await shell.trustedPublishers(pkg);
217
+ if (Array.isArray(result)) {
218
+ return result;
219
+ }
220
+ throw new Error(`${pkg.name}: npm trust access denied for npm account "${result.identity}". ` +
221
+ `npm trust requires package write access. Package owners:\n${result.owners}\n` +
222
+ 'npm browser login completed, but the selected account still cannot manage this package.');
223
+ }
189
224
  function selectedTrustPublisherPackages(packages, selections) {
190
225
  if (selections.length === 0) {
191
226
  return packages;
@@ -350,6 +385,14 @@ async function releaseVersionPackages(root, packages, bump) {
350
385
  packageHasHistory: (packagePath) => packageHasHistory(root, packagePath),
351
386
  }, packages);
352
387
  }
388
+ async function releasePlatformPackages(root, packages, bump) {
389
+ const candidates = await releaseVersionPackages(root, packages, bump);
390
+ if (candidates.length === 0) {
391
+ return [];
392
+ }
393
+ // Nx may version additional reverse dependents, so use its dry-run result rather than only the direct candidates.
394
+ return runNxReleaseVersionPreview(root, releasePackageProjects(candidates), bump);
395
+ }
353
396
  async function runNxReleaseVersion(root, projects, bump, dryRun) {
354
397
  if (dryRun) {
355
398
  return runNxReleaseVersionPreview(root, projects, bump);
@@ -392,6 +435,7 @@ async function runNxReleaseVersionPreview(root, projects, bump) {
392
435
  gitPush: false,
393
436
  stageChanges: false,
394
437
  createRelease: false,
438
+ forceChangelogGeneration: true,
395
439
  dryRun: true,
396
440
  });
397
441
  releasePreviewChangelogs.clear();
@@ -568,9 +612,8 @@ function releaseNextShell(root) {
568
612
  },
569
613
  };
570
614
  }
571
- function releaseRepairShell(root) {
615
+ function releaseTargetCheckoutShell(root) {
572
616
  return {
573
- ...releaseCompletionShell(root),
574
617
  checkout: (ref) => run('git', ['switch', '--detach', ref], root),
575
618
  withDevenvEnv: (runWithEnv) => withDevenvEnv(root, runWithEnv),
576
619
  beforeRepairTarget: (target) => {
@@ -581,6 +624,30 @@ function releaseRepairShell(root) {
581
624
  },
582
625
  };
583
626
  }
627
+ function releaseRepairShell(root, platformOutputs) {
628
+ return {
629
+ ...releaseCompletionShell(root),
630
+ ...releaseTargetCheckoutShell(root),
631
+ prepareRepairTarget: async (target) => {
632
+ if (!platformOutputs || target.npmPackages.length === 0) {
633
+ return;
634
+ }
635
+ const output = join(platformOutputs, target.sha);
636
+ console.log(`Repair pending releases: applying cross-platform outputs from ${output}.`);
637
+ await githubCiApplyOutputs(root, [output], target.sha);
638
+ },
639
+ };
640
+ }
641
+ function releaseRepairOutputsShell(root, targetGlobs, outputRoot) {
642
+ return {
643
+ ...releaseTargetCheckoutShell(root),
644
+ collectRepairTargetOutputs: (target) => githubCiNxRunMany(root, {
645
+ targets: targetGlobs,
646
+ projects: releasePackageProjects(target.npmPackages),
647
+ collectOutputs: join(outputRoot, target.sha),
648
+ }),
649
+ };
650
+ }
584
651
  function releaseRetagShell(root, remote) {
585
652
  return {
586
653
  listReleasePackages: () => releasePackages(root),
@@ -596,6 +663,25 @@ function releaseRetagShell(root, remote) {
596
663
  log: (message) => console.log(message),
597
664
  };
598
665
  }
666
+ async function fetchReleaseRepairRef(root, requestedRef) {
667
+ const branch = await releaseBranch(root);
668
+ const remote = await releaseRemote(root, branch);
669
+ console.log(`Repair pending releases: fetching ${remote}/${branch} and tags.`);
670
+ await fetchReleaseRefs(root, remote, branch);
671
+ if (requestedRef) {
672
+ return requestedRef;
673
+ }
674
+ const remoteRef = `${remote}/${branch}`;
675
+ return (await gitRefExists(root, remoteRef)) ? remoteRef : gitHead(root);
676
+ }
677
+ function logPendingReleaseTargets(targets) {
678
+ console.log(targets.length === 0
679
+ ? 'Repair pending releases: no pending durable state repairs found.'
680
+ : `Repair pending releases: ${targets.length} release target${targets.length === 1 ? '' : 's'} need repair.`);
681
+ for (const target of targets) {
682
+ console.log(`Repair pending releases: target ${target.sha.slice(0, 12)} needs ${repairTargetSummary(target)}.`);
683
+ }
684
+ }
599
685
  async function listPendingReleaseTargets(root, ref) {
600
686
  const head = await gitHead(root);
601
687
  return pendingReleaseTargets(await listOwnedReleaseTagRecords(root, ref), head);
@@ -795,7 +881,8 @@ function repairReasons(target, pkg) {
795
881
  return reasons;
796
882
  }
797
883
  async function fetchReleaseRefs(root, remote, branch) {
798
- await run('git', ['fetch', '--tags', remote, branch], root);
884
+ // `retag-unpublished` intentionally moves repairable tags, so the remote tag is authoritative.
885
+ await run('git', ['fetch', '--force', '--tags', remote, branch], root);
799
886
  }
800
887
  async function gitRefExists(root, ref) {
801
888
  const result = await $ `git rev-parse --verify ${ref}`.cwd(root).quiet().nothrow();
@@ -1003,7 +1090,8 @@ async function pushRetaggedReleaseTags(root, remote, updates) {
1003
1090
  await run('git', ['push', '--atomic', ...leases, remote, ...refspecs], root);
1004
1091
  }
1005
1092
  async function githubReleaseExists(root, tag) {
1006
- return (await runStatus('gh', ['release', 'view', tag, '--json', 'tagName'], root, true)) === 0;
1093
+ const result = await $ `gh release view ${tag} --json tagName`.cwd(root).quiet().nothrow();
1094
+ return githubReleaseLookupExists(tag, result.exitCode, decode(result.stdout), decode(result.stderr));
1007
1095
  }
1008
1096
  function githubReleaseUrl(root, tag) {
1009
1097
  return `https://github.com/${githubRepositoryFromRootPackage(root)}/releases/tag/${encodeURIComponent(tag)}`;
@@ -1143,11 +1231,32 @@ async function listTrustedPublishers(root, pkg) {
1143
1231
  }
1144
1232
  result = await runResult('nix', ['shell', 'nixpkgs#nodejs_latest', '-c', 'npm', ...args], root);
1145
1233
  }
1234
+ if (result.exitCode !== 0 && npmTrustListAccessDenied(result.stdout, result.stderr)) {
1235
+ return npmTrustAccessDetails(root, pkg.name);
1236
+ }
1146
1237
  if (result.exitCode !== 0) {
1147
1238
  throw new Error(`nix shell nixpkgs#nodejs_latest -c npm ${args.join(' ')} failed with exit code ${result.exitCode}`);
1148
1239
  }
1149
1240
  return parseTrustedPublishers(result.stdout, pkg.name);
1150
1241
  }
1242
+ export function npmTrustListAccessDenied(stdout, stderr) {
1243
+ return /\bE403\b/.test(`${stdout}\n${stderr}`);
1244
+ }
1245
+ async function npmTrustAccessDetails(root, packageName) {
1246
+ const [identityResult, ownersResult] = await Promise.all([
1247
+ runResult('nix', ['shell', 'nixpkgs#nodejs_latest', '-c', 'npm', 'whoami'], root),
1248
+ runResult('nix', ['shell', 'nixpkgs#nodejs_latest', '-c', 'npm', 'owner', 'ls', packageName], root),
1249
+ ]);
1250
+ return {
1251
+ status: 'access-denied',
1252
+ identity: identityResult.exitCode === 0 && identityResult.stdout.trim().length > 0
1253
+ ? identityResult.stdout.trim()
1254
+ : '(not authenticated)',
1255
+ owners: ownersResult.exitCode === 0 && ownersResult.stdout.trim().length > 0
1256
+ ? ownersResult.stdout.trim()
1257
+ : '(owner lookup unavailable)',
1258
+ };
1259
+ }
1151
1260
  export function parseTrustedPublishers(stdout, packageName) {
1152
1261
  if (stdout.trim().length === 0) {
1153
1262
  return [];
@@ -27,12 +27,18 @@ export interface ReleaseCompletionShell<Package extends ReleasePackageInfo = Rel
27
27
  export interface ReleaseNextShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
28
28
  bumpStablePackagesToNext(packages: Package[]): Promise<void>;
29
29
  }
30
- export interface ReleaseRepairShell<Package extends ReleasePackageInfo = ReleasePackageInfo> extends ReleaseCompletionShell<Package> {
30
+ export interface ReleaseTargetCheckoutShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
31
31
  checkout(ref: string): Promise<void>;
32
32
  withDevenvEnv<T>(runWithEnv: () => Promise<T>): Promise<T>;
33
33
  beforeRepairTarget?(target: ReleaseTarget<Package>): void;
34
34
  afterRepairTarget?(target: ReleaseTarget<Package>): void;
35
35
  }
36
+ export interface ReleaseRepairShell<Package extends ReleasePackageInfo = ReleasePackageInfo> extends ReleaseCompletionShell<Package>, ReleaseTargetCheckoutShell<Package> {
37
+ prepareRepairTarget?(target: ReleaseTarget<Package>): Promise<void>;
38
+ }
39
+ export interface ReleaseRepairOutputsShell<Package extends ReleasePackageInfo = ReleasePackageInfo> extends ReleaseTargetCheckoutShell<Package> {
40
+ collectRepairTargetOutputs(target: ReleaseTarget<Package>): Promise<void>;
41
+ }
36
42
  export interface ReleaseVersionShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
37
43
  releasePackagesAtHead(): Promise<Package[]>;
38
44
  releaseVersionPackages(bump: string): Promise<Package[]>;
@@ -53,5 +59,6 @@ export declare function runReleaseVersion<Package extends ReleasePackageInfo>(sh
53
59
  export declare function completeReleaseAtHead<Package extends ReleasePackageInfo>(shell: ReleaseCompletionShell<Package>, packages: Package[], dryRun: boolean, rerunRequired: boolean): Promise<ReleaseSummary<Package>>;
54
60
  export declare function bumpStableReleaseToNext<Package extends ReleasePackageInfo>(shell: ReleaseNextShell<Package>, packages: Package[], dryRun: boolean, rerunRequired: boolean): Promise<Package[]>;
55
61
  export declare function repairPendingTargets<Package extends ReleasePackageInfo>(shell: ReleaseRepairShell<Package>, targets: Array<ReleaseTarget<Package>>, restoreRef: string, dryRun: boolean): Promise<Array<ReleaseSummary<Package>>>;
62
+ export declare function collectRepairPlatformOutputs<Package extends ReleasePackageInfo>(shell: ReleaseRepairOutputsShell<Package>, targets: Array<ReleaseTarget<Package>>, restoreRef: string): Promise<void>;
56
63
  export declare function completeRepairTargetAtHead<Package extends ReleasePackageInfo>(shell: ReleaseCompletionShell<Package>, target: ReleaseTarget<Package>, dryRun: boolean): Promise<ReleaseSummary<Package>>;
57
64
  //# sourceMappingURL=orchestration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../../src/release/orchestration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAGnE,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,cAAc,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,gBAAgB,EAAE,OAAO,EAAE,CAAC;IAC5B,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,kBAAkB,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAC7F,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,sBAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,yBAAyB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC5E;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACvF,wBAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,kBAAkB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB,CACzF,SAAQ,sBAAsB,CAAC,OAAO,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3D,kBAAkB,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1D,iBAAiB,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAC1F,qBAAqB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5C,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,sBAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5F,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAC3F,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,wBAAwB,GAAG,SAAS,GAAG,aAAa,GAAG,mBAAmB,CAAC;CACpF;AAED,wBAAsB,iBAAiB,CAAC,OAAO,SAAS,kBAAkB,EACxE,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EACnC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACzC,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAyCxC;AAED,wBAAsB,qBAAqB,CAAC,OAAO,SAAS,kBAAkB,EAC5E,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,EACtC,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,OAAO,EACf,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAYlC;AAED,wBAAsB,uBAAuB,CAAC,OAAO,SAAS,kBAAkB,EAC9E,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAChC,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,OAAO,EACf,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC,OAAO,EAAE,CAAC,CAOpB;AAED,wBAAsB,oBAAoB,CAAC,OAAO,SAAS,kBAAkB,EAC3E,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAClC,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAuBzC;AAmBD,wBAAsB,0BAA0B,CAAC,OAAO,SAAS,kBAAkB,EACjF,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,EACtC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAC9B,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAUlC"}
1
+ {"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../../src/release/orchestration.ts"],"names":[],"mappings":"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"}
@@ -72,7 +72,10 @@ export async function repairPendingTargets(shell, targets, restoreRef, dryRun) {
72
72
  }
73
73
  shell.beforeRepairTarget?.(target);
74
74
  try {
75
- summaries.push(await shell.withDevenvEnv(() => completeRepairTargetAtHead(shell, target, dryRun)));
75
+ summaries.push(await shell.withDevenvEnv(async () => {
76
+ await shell.prepareRepairTarget?.(target);
77
+ return completeRepairTargetAtHead(shell, target, dryRun);
78
+ }));
76
79
  }
77
80
  finally {
78
81
  shell.afterRepairTarget?.(target);
@@ -81,9 +84,43 @@ export async function repairPendingTargets(shell, targets, restoreRef, dryRun) {
81
84
  }
82
85
  finally {
83
86
  await shell.checkout(restoreRef);
87
+ if (targets.length > 0) {
88
+ // Loading devenv at a historical release can rebuild ignored tool outputs
89
+ // from that checkout. Refresh after restoring HEAD so later release phases
90
+ // cannot combine the current CLI with an older Nx plugin build.
91
+ await shell.withDevenvEnv(async () => undefined);
92
+ }
84
93
  }
85
94
  return summaries;
86
95
  }
96
+ export async function collectRepairPlatformOutputs(shell, targets, restoreRef) {
97
+ const outputTargets = targets.filter((target) => target.npmPackages.length > 0);
98
+ if (outputTargets.length === 0) {
99
+ return;
100
+ }
101
+ try {
102
+ for (const target of outputTargets) {
103
+ await shell.checkout(target.sha);
104
+ if (target.packages.length === 0) {
105
+ // invariant throw: release target discovery must never yield a package-free target.
106
+ throw new Error(`Release commit ${target.sha} has no release packages after checkout.`);
107
+ }
108
+ shell.beforeRepairTarget?.(target);
109
+ try {
110
+ await shell.withDevenvEnv(() => shell.collectRepairTargetOutputs(target));
111
+ }
112
+ finally {
113
+ shell.afterRepairTarget?.(target);
114
+ }
115
+ }
116
+ }
117
+ finally {
118
+ await shell.checkout(restoreRef);
119
+ // Historical devenv activation may rebuild ignored tool outputs. Restore the
120
+ // dispatch environment before the macOS job performs any further work.
121
+ await shell.withDevenvEnv(async () => undefined);
122
+ }
123
+ }
87
124
  function repairDryRunSummary(target) {
88
125
  return {
89
126
  sha: target.sha,