@smoothbricks/cli 0.1.0 → 0.2.0

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 (148) hide show
  1. package/README.md +338 -88
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +136 -22
  4. package/dist/devenv/index.d.ts +10 -0
  5. package/dist/devenv/index.d.ts.map +1 -0
  6. package/dist/devenv/index.js +27 -0
  7. package/dist/lib/cli-package.d.ts +4 -0
  8. package/dist/lib/cli-package.d.ts.map +1 -0
  9. package/dist/lib/cli-package.js +15 -0
  10. package/dist/lib/devenv.d.ts +6 -0
  11. package/dist/lib/devenv.d.ts.map +1 -0
  12. package/dist/lib/devenv.js +82 -0
  13. package/dist/lib/run.d.ts +5 -0
  14. package/dist/lib/run.d.ts.map +1 -1
  15. package/dist/lib/run.js +13 -0
  16. package/dist/lib/workspace.d.ts +20 -1
  17. package/dist/lib/workspace.d.ts.map +1 -1
  18. package/dist/lib/workspace.js +87 -7
  19. package/dist/monorepo/commit-msg.d.ts +8 -1
  20. package/dist/monorepo/commit-msg.d.ts.map +1 -1
  21. package/dist/monorepo/commit-msg.js +85 -7
  22. package/dist/monorepo/index.d.ts +24 -2
  23. package/dist/monorepo/index.d.ts.map +1 -1
  24. package/dist/monorepo/index.js +136 -15
  25. package/dist/monorepo/lockfile.d.ts +5 -1
  26. package/dist/monorepo/lockfile.d.ts.map +1 -1
  27. package/dist/monorepo/lockfile.js +45 -5
  28. package/dist/monorepo/managed-files.d.ts +1 -1
  29. package/dist/monorepo/managed-files.d.ts.map +1 -1
  30. package/dist/monorepo/managed-files.js +28 -11
  31. package/dist/monorepo/nx-sync.d.ts +2 -1
  32. package/dist/monorepo/nx-sync.d.ts.map +1 -1
  33. package/dist/monorepo/nx-sync.js +8 -2
  34. package/dist/monorepo/package-hygiene.d.ts +6 -2
  35. package/dist/monorepo/package-hygiene.d.ts.map +1 -1
  36. package/dist/monorepo/package-hygiene.js +12 -4
  37. package/dist/monorepo/package-policy.d.ts +25 -2
  38. package/dist/monorepo/package-policy.d.ts.map +1 -1
  39. package/dist/monorepo/package-policy.js +1289 -27
  40. package/dist/monorepo/packed-manifest.d.ts +4 -0
  41. package/dist/monorepo/packed-manifest.d.ts.map +1 -0
  42. package/dist/monorepo/packed-manifest.js +51 -0
  43. package/dist/monorepo/packed-package.d.ts +3 -0
  44. package/dist/monorepo/packed-package.d.ts.map +1 -1
  45. package/dist/monorepo/packed-package.js +69 -31
  46. package/dist/monorepo/packs/index.d.ts +20 -1
  47. package/dist/monorepo/packs/index.d.ts.map +1 -1
  48. package/dist/monorepo/packs/index.js +240 -18
  49. package/dist/monorepo/publish-workflow.d.ts +82 -0
  50. package/dist/monorepo/publish-workflow.d.ts.map +1 -0
  51. package/dist/monorepo/publish-workflow.js +336 -0
  52. package/dist/monorepo/tool-validation.d.ts +22 -0
  53. package/dist/monorepo/tool-validation.d.ts.map +1 -0
  54. package/dist/monorepo/tool-validation.js +399 -0
  55. package/dist/nx/index.d.ts +24 -0
  56. package/dist/nx/index.d.ts.map +1 -0
  57. package/dist/nx/index.js +94 -0
  58. package/dist/nx-version-actions.cjs +25 -0
  59. package/dist/nx-version-actions.d.cts +6 -0
  60. package/dist/nx-version-actions.d.cts.map +1 -0
  61. package/dist/release/bootstrap-npm-packages.d.ts +19 -0
  62. package/dist/release/bootstrap-npm-packages.d.ts.map +1 -0
  63. package/dist/release/bootstrap-npm-packages.js +58 -0
  64. package/dist/release/candidates.d.ts +11 -0
  65. package/dist/release/candidates.d.ts.map +1 -0
  66. package/dist/release/candidates.js +181 -0
  67. package/dist/release/core.d.ts +51 -0
  68. package/dist/release/core.d.ts.map +1 -0
  69. package/dist/release/core.js +97 -0
  70. package/dist/release/github-release.d.ts +46 -0
  71. package/dist/release/github-release.d.ts.map +1 -0
  72. package/dist/release/github-release.js +97 -0
  73. package/dist/release/index.d.ts +39 -5
  74. package/dist/release/index.d.ts.map +1 -1
  75. package/dist/release/index.js +763 -130
  76. package/dist/release/npm-auth.d.ts +16 -0
  77. package/dist/release/npm-auth.d.ts.map +1 -0
  78. package/dist/release/npm-auth.js +39 -0
  79. package/dist/release/orchestration.d.ts +49 -0
  80. package/dist/release/orchestration.d.ts.map +1 -0
  81. package/dist/release/orchestration.js +113 -0
  82. package/dist/release/publish-plan.d.ts +17 -0
  83. package/dist/release/publish-plan.d.ts.map +1 -0
  84. package/dist/release/publish-plan.js +15 -0
  85. package/dist/release/retag-unpublished.d.ts +34 -0
  86. package/dist/release/retag-unpublished.d.ts.map +1 -0
  87. package/dist/release/retag-unpublished.js +77 -0
  88. package/managed/raw/git-format-staged.yml +54 -0
  89. package/managed/raw/tooling/git-hooks/commit-msg.sh +1 -1
  90. package/managed/raw/tooling/git-hooks/pre-commit.sh +2 -7
  91. package/managed/templates/github/actions/setup-devenv/action.yml +1 -7
  92. package/managed/templates/github/workflows/ci.yml +3 -0
  93. package/package.json +37 -4
  94. package/src/cli.ts +193 -40
  95. package/src/devenv/index.test.ts +49 -0
  96. package/src/devenv/index.ts +38 -0
  97. package/src/lib/cli-package.ts +18 -0
  98. package/src/lib/devenv.test.ts +28 -0
  99. package/src/lib/devenv.ts +89 -0
  100. package/src/lib/run.ts +19 -0
  101. package/src/lib/workspace.ts +117 -7
  102. package/src/monorepo/__tests__/nx-version-actions.test.ts +75 -0
  103. package/src/monorepo/__tests__/publish-workflow.test.ts +322 -0
  104. package/src/monorepo/commit-msg.test.ts +45 -0
  105. package/src/monorepo/commit-msg.ts +107 -7
  106. package/src/monorepo/index.ts +181 -15
  107. package/src/monorepo/lockfile.ts +52 -7
  108. package/src/monorepo/managed-files.ts +43 -13
  109. package/src/monorepo/nx-sync.ts +9 -2
  110. package/src/monorepo/package-hygiene.test.ts +34 -0
  111. package/src/monorepo/package-hygiene.ts +26 -4
  112. package/src/monorepo/package-policy.test.ts +902 -0
  113. package/src/monorepo/package-policy.ts +1527 -25
  114. package/src/monorepo/packed-manifest.ts +67 -0
  115. package/src/monorepo/packed-package.ts +90 -31
  116. package/src/monorepo/packs/index.test.ts +189 -0
  117. package/src/monorepo/packs/index.ts +314 -19
  118. package/src/monorepo/publish-workflow.ts +422 -0
  119. package/src/monorepo/setup-test-tracing.test.ts +120 -0
  120. package/src/monorepo/tool-validation.test.ts +261 -0
  121. package/src/monorepo/tool-validation.ts +462 -0
  122. package/src/nx/index.test.ts +64 -0
  123. package/src/nx/index.ts +119 -0
  124. package/src/nx-version-actions.cts +36 -0
  125. package/src/release/__tests__/bootstrap-npm-packages.test.ts +127 -0
  126. package/src/release/__tests__/candidates.test.ts +217 -0
  127. package/src/release/__tests__/core-properties.test.ts +149 -0
  128. package/src/release/__tests__/core-scenarios.test.ts +187 -0
  129. package/src/release/__tests__/core.test.ts +73 -0
  130. package/src/release/__tests__/fixture-repo.test.ts +314 -0
  131. package/src/release/__tests__/github-release.test.ts +149 -0
  132. package/src/release/__tests__/helpers/fixture-repo.ts +114 -0
  133. package/src/release/__tests__/npm-auth.test.ts +120 -0
  134. package/src/release/__tests__/orchestration.test.ts +246 -0
  135. package/src/release/__tests__/publish-plan.test.ts +67 -0
  136. package/src/release/__tests__/retag-unpublished.test.ts +160 -0
  137. package/src/release/__tests__/trust-publisher.test.ts +133 -0
  138. package/src/release/bootstrap-npm-packages.ts +88 -0
  139. package/src/release/candidates.ts +225 -0
  140. package/src/release/core.ts +171 -0
  141. package/src/release/github-release.ts +134 -0
  142. package/src/release/index.ts +974 -138
  143. package/src/release/npm-auth.ts +93 -0
  144. package/src/release/orchestration.ts +196 -0
  145. package/src/release/publish-plan.ts +37 -0
  146. package/src/release/retag-unpublished.ts +122 -0
  147. package/managed/raw/.git-format-staged.yml +0 -47
  148. package/managed/templates/github/workflows/publish.yml +0 -136
@@ -0,0 +1,16 @@
1
+ import type { ReleasePackageInfo } from './core.js';
2
+ export interface NpmPublishAuthFailureOptions {
3
+ tokenPresent: boolean;
4
+ repository?: string;
5
+ }
6
+ export interface NpmPublishDiagnosticShell {
7
+ publish(): Promise<void>;
8
+ versionExists(): Promise<boolean>;
9
+ log(message: string): void;
10
+ error(message: string): void;
11
+ appendSummary(markdown: string): Promise<void>;
12
+ }
13
+ export declare function publishWithAuthDiagnostics(pkg: Pick<ReleasePackageInfo, 'name' | 'version'>, shell: NpmPublishDiagnosticShell, options: NpmPublishAuthFailureOptions): Promise<void>;
14
+ export declare function npmPublishAuthFailureMessage(pkg: Pick<ReleasePackageInfo, 'name' | 'version'>, options: NpmPublishAuthFailureOptions): string;
15
+ export declare function npmPublishAuthFailureMarkdown(pkg: Pick<ReleasePackageInfo, 'name' | 'version'>, options: NpmPublishAuthFailureOptions): string;
16
+ //# sourceMappingURL=npm-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-auth.d.ts","sourceRoot":"","sources":["../../src/release/npm-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,WAAW,4BAA4B;IAC3C,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC,EACjD,KAAK,EAAE,yBAAyB,EAChC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC,EACjD,OAAO,EAAE,4BAA4B,GACpC,MAAM,CAwBR;AAED,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC,EACjD,OAAO,EAAE,4BAA4B,GACpC,MAAM,CAmBR"}
@@ -0,0 +1,39 @@
1
+ export async function publishWithAuthDiagnostics(pkg, shell, options) {
2
+ try {
3
+ await shell.publish();
4
+ }
5
+ catch (error) {
6
+ const packageVersion = `${pkg.name}@${pkg.version}`;
7
+ if (await shell.versionExists()) {
8
+ shell.log(`${packageVersion}: publish result already visible on npm; continuing.`);
9
+ return;
10
+ }
11
+ shell.error(npmPublishAuthFailureMessage(pkg, options));
12
+ await shell.appendSummary(npmPublishAuthFailureMarkdown(pkg, options));
13
+ throw new Error(`${packageVersion}: npm publish authentication failed. Run smoo release trust-publisher; see the warning banner above for details.`, { cause: error });
14
+ }
15
+ }
16
+ export function npmPublishAuthFailureMessage(pkg, options) {
17
+ const packageVersion = `${pkg.name}@${pkg.version}`;
18
+ const lines = [
19
+ `::error title=npm publish authentication failed::${packageVersion} could not be published. This usually means npm trusted publishing is not configured for this package/workflow/repo.`,
20
+ '',
21
+ `🚨 npm publish authentication failed for ${packageVersion}`,
22
+ '',
23
+ ];
24
+ lines.push('smoo expected npm trusted publishing/OIDC because this package already exists on npm.', options.tokenPresent
25
+ ? 'NODE_AUTH_TOKEN/NPM_TOKEN is set but unused: smoo intentionally clears token auth for existing packages; npm must authenticate through trusted publishing instead.'
26
+ : 'NODE_AUTH_TOKEN/NPM_TOKEN is not set, which is expected for trusted publishing; npm did not authenticate the workflow as a trusted publisher.', '', 'Fix:', '1. Run locally: smoo release trust-publisher', '2. Ensure the npm trusted publisher uses:', ` repository: ${trustedPublisherRepository(options)}`, ' workflow: publish.yml', '3. Rerun the Publish workflow.', '', 'For first-ever package publishes, run locally: smoo release trust-publisher --bootstrap.');
27
+ return lines.join('\n');
28
+ }
29
+ export function npmPublishAuthFailureMarkdown(pkg, options) {
30
+ const packageVersion = `${pkg.name}@${pkg.version}`;
31
+ const lines = ['## 🚨 npm Publish Authentication Failed', '', `Package: \`${packageVersion}\``, ''];
32
+ lines.push('smoo expected npm trusted publishing/OIDC because this package already exists on npm.', '', options.tokenPresent
33
+ ? '`NODE_AUTH_TOKEN`/`NPM_TOKEN` is set but unused: smoo intentionally clears token auth for existing packages; npm must authenticate through trusted publishing instead.'
34
+ : '`NODE_AUTH_TOKEN`/`NPM_TOKEN` is not set, which is expected for trusted publishing; npm did not authenticate the workflow as a trusted publisher.', '', 'Fix:', '', '1. Run locally: `smoo release trust-publisher`', `2. Ensure the npm trusted publisher uses repository \`${trustedPublisherRepository(options)}\` and workflow \`publish.yml\``, '3. Rerun the Publish workflow.', '', 'For first-ever package publishes, run `smoo release trust-publisher --bootstrap` locally.');
35
+ return lines.join('\n');
36
+ }
37
+ function trustedPublisherRepository(options) {
38
+ return options.repository ?? 'the current GitHub repository';
39
+ }
@@ -0,0 +1,49 @@
1
+ import type { ReleasePackageInfo, ReleaseTarget } from './core.js';
2
+ export type ReleaseVersionMode = 'new' | 'none';
3
+ export interface ReleaseSummary<Package extends ReleasePackageInfo = ReleasePackageInfo> {
4
+ sha: string;
5
+ dryRun: boolean;
6
+ packages: Package[];
7
+ pushed: boolean;
8
+ published: Package[];
9
+ alreadyPublished: Package[];
10
+ githubReleases: Package[];
11
+ rerunRequired: boolean;
12
+ noRelease: boolean;
13
+ }
14
+ export interface ReleaseCompletionShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
15
+ gitHead(): Promise<string>;
16
+ pushReleaseRefs(packages: Package[]): Promise<boolean>;
17
+ listNpmMissingPackages(packages: Package[]): Promise<Package[]>;
18
+ buildReleaseCandidate(packages: Package[]): Promise<void>;
19
+ publishPackage(pkg: Package, distTag: string, dryRun: boolean): Promise<void>;
20
+ listGithubMissingPackages(packages: Package[]): Promise<Package[]>;
21
+ createGithubRelease(pkg: Package, dryRun: boolean): Promise<void>;
22
+ }
23
+ export interface ReleaseRepairShell<Package extends ReleasePackageInfo = ReleasePackageInfo> extends ReleaseCompletionShell<Package> {
24
+ checkout(ref: string): Promise<void>;
25
+ withDevenvEnv<T>(runWithEnv: () => Promise<T>): Promise<T>;
26
+ beforeRepairTarget?(target: ReleaseTarget<Package>): void;
27
+ afterRepairTarget?(target: ReleaseTarget<Package>): void;
28
+ }
29
+ export interface ReleaseVersionShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
30
+ releasePackagesAtHead(): Promise<Package[]>;
31
+ releaseVersionPackages(bump: string): Promise<Package[]>;
32
+ ensureLocalReleaseTags(packages: Package[]): Promise<void>;
33
+ gitHead(): Promise<string>;
34
+ runNxReleaseVersion(packages: Package[], bump: string, dryRun: boolean): Promise<void>;
35
+ assertCleanGitTree(): Promise<void>;
36
+ }
37
+ export interface ReleaseVersionResult<Package extends ReleasePackageInfo = ReleasePackageInfo> {
38
+ mode: ReleaseVersionMode;
39
+ packages: Package[];
40
+ status: 'already-release-target' | 'dry-run' | 'new-release' | 'no-release-needed';
41
+ }
42
+ export declare function runReleaseVersion<Package extends ReleasePackageInfo>(shell: ReleaseVersionShell<Package>, options: {
43
+ bump: string;
44
+ dryRun: boolean;
45
+ }): Promise<ReleaseVersionResult<Package>>;
46
+ export declare function completeReleaseAtHead<Package extends ReleasePackageInfo>(shell: ReleaseCompletionShell<Package>, packages: Package[], dryRun: boolean, rerunRequired: boolean): Promise<ReleaseSummary<Package>>;
47
+ export declare function repairPendingTargets<Package extends ReleasePackageInfo>(shell: ReleaseRepairShell<Package>, targets: Array<ReleaseTarget<Package>>, restoreRef: string, dryRun: boolean): Promise<Array<ReleaseSummary<Package>>>;
48
+ export declare function completeRepairTargetAtHead<Package extends ReleasePackageInfo>(shell: ReleaseCompletionShell<Package>, target: ReleaseTarget<Package>, dryRun: boolean): Promise<ReleaseSummary<Package>>;
49
+ //# sourceMappingURL=orchestration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../../src/release/orchestration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ import { planPublishActions } from './publish-plan.js';
2
+ export async function runReleaseVersion(shell, options) {
3
+ if (!options.dryRun) {
4
+ const localRelease = await shell.releasePackagesAtHead();
5
+ if (localRelease.length > 0) {
6
+ await shell.ensureLocalReleaseTags(localRelease);
7
+ return { mode: 'none', packages: localRelease, status: 'already-release-target' };
8
+ }
9
+ }
10
+ const versionPackages = await shell.releaseVersionPackages(options.bump);
11
+ if (versionPackages.length === 0) {
12
+ if (options.bump !== 'auto') {
13
+ // invariant throw: the CLI resolves forced bumps from the full owned release package set.
14
+ throw new Error(`No release packages were selected for forced --bump ${options.bump}.`);
15
+ }
16
+ return { mode: 'none', packages: [], status: 'no-release-needed' };
17
+ }
18
+ const headBeforeVersioning = await shell.gitHead();
19
+ await shell.runNxReleaseVersion(versionPackages, options.bump, options.dryRun);
20
+ if (options.dryRun) {
21
+ return { mode: 'none', packages: [], status: 'dry-run' };
22
+ }
23
+ await shell.assertCleanGitTree();
24
+ const headAfterVersioning = await shell.gitHead();
25
+ const releasedPackages = await shell.releasePackagesAtHead();
26
+ await shell.ensureLocalReleaseTags(releasedPackages);
27
+ if (headAfterVersioning === headBeforeVersioning) {
28
+ if (releasedPackages.length > 0) {
29
+ return { mode: 'none', packages: releasedPackages, status: 'already-release-target' };
30
+ }
31
+ if (options.bump !== 'auto') {
32
+ throw new Error(`Nx did not create a release commit for forced --bump ${options.bump}.`);
33
+ }
34
+ return { mode: 'none', packages: [], status: 'no-release-needed' };
35
+ }
36
+ if (releasedPackages.length === 0) {
37
+ throw new Error('Nx created a release commit without current package release tags at HEAD.');
38
+ }
39
+ return { mode: 'new', packages: releasedPackages, status: 'new-release' };
40
+ }
41
+ export async function completeReleaseAtHead(shell, packages, dryRun, rerunRequired) {
42
+ const npmMissingPackages = await shell.listNpmMissingPackages(packages);
43
+ const githubMissingPackages = dryRun ? packages : await shell.listGithubMissingPackages(packages);
44
+ return completePlannedRelease(shell, {
45
+ sha: await shell.gitHead(),
46
+ dryRun,
47
+ packages,
48
+ pushed: dryRun ? false : await shell.pushReleaseRefs(packages),
49
+ npmMissingPackages,
50
+ githubMissingPackages,
51
+ rerunRequired,
52
+ });
53
+ }
54
+ export async function repairPendingTargets(shell, targets, restoreRef, dryRun) {
55
+ const summaries = [];
56
+ try {
57
+ for (const target of targets) {
58
+ await shell.checkout(target.sha);
59
+ if (target.packages.length === 0) {
60
+ throw new Error(`Release commit ${target.sha} has no release packages after checkout.`);
61
+ }
62
+ shell.beforeRepairTarget?.(target);
63
+ try {
64
+ summaries.push(await shell.withDevenvEnv(() => completeRepairTargetAtHead(shell, target, dryRun)));
65
+ }
66
+ finally {
67
+ shell.afterRepairTarget?.(target);
68
+ }
69
+ }
70
+ }
71
+ finally {
72
+ await shell.checkout(restoreRef);
73
+ }
74
+ return summaries;
75
+ }
76
+ export async function completeRepairTargetAtHead(shell, target, dryRun) {
77
+ return completePlannedRelease(shell, {
78
+ sha: await shell.gitHead(),
79
+ dryRun,
80
+ packages: target.packages,
81
+ pushed: dryRun ? false : await shell.pushReleaseRefs(target.packages),
82
+ npmMissingPackages: target.npmPackages,
83
+ githubMissingPackages: target.githubPackages,
84
+ rerunRequired: false,
85
+ });
86
+ }
87
+ async function completePlannedRelease(shell, input) {
88
+ const plan = planPublishActions({
89
+ releasePackages: input.packages,
90
+ npmMissingPackages: input.npmMissingPackages,
91
+ githubMissingPackages: input.githubMissingPackages,
92
+ });
93
+ if (plan.buildProjects.length > 0) {
94
+ await shell.buildReleaseCandidate(plan.publishPackages.map((action) => action.pkg));
95
+ }
96
+ for (const { pkg, distTag } of plan.publishPackages) {
97
+ await shell.publishPackage(pkg, distTag, input.dryRun);
98
+ }
99
+ for (const pkg of plan.githubReleasePackages) {
100
+ await shell.createGithubRelease(pkg, input.dryRun);
101
+ }
102
+ return {
103
+ sha: input.sha,
104
+ dryRun: input.dryRun,
105
+ packages: input.packages,
106
+ pushed: input.pushed,
107
+ published: input.dryRun ? [] : plan.publishPackages.map((action) => action.pkg),
108
+ alreadyPublished: input.packages.filter((pkg) => !input.npmMissingPackages.includes(pkg)),
109
+ githubReleases: input.dryRun ? [] : plan.githubReleasePackages,
110
+ rerunRequired: input.rerunRequired,
111
+ noRelease: false,
112
+ };
113
+ }
@@ -0,0 +1,17 @@
1
+ import { type ReleasePackageInfo } from './core.js';
2
+ export interface PublishPackageAction<Package extends ReleasePackageInfo = ReleasePackageInfo> {
3
+ pkg: Package;
4
+ distTag: string;
5
+ }
6
+ export interface PublishPlan<Package extends ReleasePackageInfo = ReleasePackageInfo> {
7
+ buildProjects: string[];
8
+ publishPackages: Array<PublishPackageAction<Package>>;
9
+ githubReleasePackages: Package[];
10
+ }
11
+ export interface PublishPlanInput<Package extends ReleasePackageInfo = ReleasePackageInfo> {
12
+ releasePackages: Package[];
13
+ npmMissingPackages: Package[];
14
+ githubMissingPackages: Package[];
15
+ }
16
+ export declare function planPublishActions<Package extends ReleasePackageInfo>(input: PublishPlanInput<Package>): PublishPlan<Package>;
17
+ //# sourceMappingURL=publish-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-plan.d.ts","sourceRoot":"","sources":["../../src/release/publish-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE1E,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAC3F,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAClF,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,qBAAqB,EAAE,OAAO,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACvF,eAAe,EAAE,OAAO,EAAE,CAAC;IAC3B,kBAAkB,EAAE,OAAO,EAAE,CAAC;IAC9B,qBAAqB,EAAE,OAAO,EAAE,CAAC;CAClC;AAED,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,kBAAkB,EACnE,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAC/B,WAAW,CAAC,OAAO,CAAC,CAWtB"}
@@ -0,0 +1,15 @@
1
+ import { npmDistTagForVersion } from './core.js';
2
+ export function planPublishActions(input) {
3
+ const npmMissingNames = packageNameSet(input.npmMissingPackages);
4
+ const githubMissingNames = packageNameSet(input.githubMissingPackages);
5
+ const npmPackages = input.releasePackages.filter((pkg) => npmMissingNames.has(pkg.name));
6
+ const githubReleasePackages = input.releasePackages.filter((pkg) => githubMissingNames.has(pkg.name));
7
+ return {
8
+ buildProjects: npmPackages.map((pkg) => pkg.projectName),
9
+ publishPackages: npmPackages.map((pkg) => ({ pkg, distTag: npmDistTagForVersion(pkg.version) })),
10
+ githubReleasePackages,
11
+ };
12
+ }
13
+ function packageNameSet(packages) {
14
+ return new Set(packages.map((pkg) => pkg.name));
15
+ }
@@ -0,0 +1,34 @@
1
+ import { type ReleasePackageInfo } from './core.js';
2
+ export interface RetagUnpublishedOptions {
3
+ tags: string[];
4
+ toRef: string;
5
+ push: boolean;
6
+ dispatch: boolean;
7
+ dryRun: boolean;
8
+ branch: string;
9
+ workflow: string;
10
+ }
11
+ export interface RetagUnpublishedTagUpdate<Package extends ReleasePackageInfo = ReleasePackageInfo> {
12
+ tag: string;
13
+ pkg: Package;
14
+ expectedRemoteObject: string | null;
15
+ }
16
+ export interface RetagUnpublishedShell<Package extends Omit<ReleasePackageInfo, 'version'> = ReleasePackageInfo> {
17
+ listReleasePackages(): Package[];
18
+ resolveRef(ref: string): Promise<string>;
19
+ resolveDispatchRef(branch: string): Promise<string | null>;
20
+ packageVersionAtRef(packagePath: string, ref: string): Promise<string | null>;
21
+ npmVersionExists(name: string, version: string): Promise<boolean>;
22
+ githubReleaseExists(tag: string): Promise<boolean>;
23
+ remoteTagObject(tag: string): Promise<string | null>;
24
+ createOrMoveTag(tag: string, ref: string): Promise<void>;
25
+ pushTags(updates: Array<RetagUnpublishedTagUpdate<Package & {
26
+ version: string;
27
+ }>>): Promise<void>;
28
+ dispatchPublishWorkflow(workflow: string, branch: string): Promise<void>;
29
+ log(message: string): void;
30
+ }
31
+ export declare function retagUnpublished<Package extends Omit<ReleasePackageInfo, 'version'>>(shell: RetagUnpublishedShell<Package>, options: RetagUnpublishedOptions): Promise<Array<RetagUnpublishedTagUpdate<Package & {
32
+ version: string;
33
+ }>>>;
34
+ //# sourceMappingURL=retag-unpublished.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retag-unpublished.d.ts","sourceRoot":"","sources":["../../src/release/retag-unpublished.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAwB,MAAM,WAAW,CAAC;AAE1E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAChG,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,OAAO,CAAC;IACb,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB,CAAC,OAAO,SAAS,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,GAAG,kBAAkB;IAC7G,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3D,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9E,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrD,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,yBAAyB,CAAC,OAAO,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gBAAgB,CAAC,OAAO,SAAS,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,EACxF,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,EACrC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAAC,CA4E1E"}
@@ -0,0 +1,77 @@
1
+ import { releasePackageForTag } from './core.js';
2
+ export async function retagUnpublished(shell, options) {
3
+ if (options.tags.length === 0) {
4
+ throw new Error('retag-unpublished requires at least one release tag.');
5
+ }
6
+ assertUniqueTags(options.tags);
7
+ const targetSha = await shell.resolveRef(options.toRef);
8
+ if (options.dispatch) {
9
+ const dispatchSha = await shell.resolveDispatchRef(options.branch);
10
+ if (!dispatchSha) {
11
+ throw new Error(`Cannot dispatch ${options.workflow}: remote branch ${options.branch} was not found.`);
12
+ }
13
+ if (dispatchSha !== targetSha) {
14
+ throw new Error(`Cannot dispatch ${options.workflow}: ${options.toRef} resolves to ${targetSha.slice(0, 12)}, but ${options.branch} resolves to ${dispatchSha.slice(0, 12)}. Push the branch first or choose a ref already at the remote branch HEAD.`);
15
+ }
16
+ }
17
+ const packages = shell.listReleasePackages();
18
+ const updates = [];
19
+ for (const tag of options.tags) {
20
+ const match = releasePackageForTag(packages, tag);
21
+ if (!match) {
22
+ throw new Error(`Release tag ${tag} does not match an owned release package.`);
23
+ }
24
+ const versionAtRef = await shell.packageVersionAtRef(match.pkg.path, options.toRef);
25
+ if (versionAtRef !== match.version) {
26
+ throw new Error(`Release tag ${tag} cannot move to ${options.toRef}: ${match.pkg.path}/package.json has version ${versionAtRef ?? 'missing'}, expected ${match.version}.`);
27
+ }
28
+ if (await shell.npmVersionExists(match.pkg.name, match.version)) {
29
+ throw new Error(`Cannot retag ${tag}: ${match.pkg.name}@${match.version} already exists on npm.`);
30
+ }
31
+ if (await shell.githubReleaseExists(tag)) {
32
+ throw new Error(`Cannot retag ${tag}: GitHub Release ${tag} already exists.`);
33
+ }
34
+ updates.push({
35
+ tag,
36
+ pkg: { ...match.pkg, version: match.version },
37
+ expectedRemoteObject: options.push ? await shell.remoteTagObject(tag) : null,
38
+ });
39
+ }
40
+ for (const update of updates) {
41
+ if (options.dryRun) {
42
+ shell.log(`Would move ${update.tag} to ${options.toRef} (${targetSha.slice(0, 12)}).`);
43
+ }
44
+ else {
45
+ await shell.createOrMoveTag(update.tag, options.toRef);
46
+ shell.log(`Moved ${update.tag} to ${options.toRef} (${targetSha.slice(0, 12)}).`);
47
+ }
48
+ }
49
+ if (options.push) {
50
+ if (options.dryRun) {
51
+ shell.log(`Would push ${updates.length} retagged release tag${updates.length === 1 ? '' : 's'}.`);
52
+ }
53
+ else {
54
+ await shell.pushTags(updates);
55
+ shell.log(`Pushed ${updates.length} retagged release tag${updates.length === 1 ? '' : 's'}.`);
56
+ }
57
+ }
58
+ if (options.dispatch) {
59
+ if (options.dryRun) {
60
+ shell.log(`Would dispatch ${options.workflow} on ${options.branch} with bump=auto.`);
61
+ }
62
+ else {
63
+ await shell.dispatchPublishWorkflow(options.workflow, options.branch);
64
+ shell.log(`Dispatched ${options.workflow} on ${options.branch} with bump=auto.`);
65
+ }
66
+ }
67
+ return updates;
68
+ }
69
+ function assertUniqueTags(tags) {
70
+ const seen = new Set();
71
+ for (const tag of tags) {
72
+ if (seen.has(tag)) {
73
+ throw new Error(`Release tag ${tag} was provided more than once.`);
74
+ }
75
+ seen.add(tag);
76
+ }
77
+ }
@@ -0,0 +1,54 @@
1
+ # git-format-staged configuration for SmoothBricks-style monorepos
2
+
3
+ formatters:
4
+ # ESLint for Astro files (run first as it only handles .astro files)
5
+ eslint:
6
+ command: "eslint-stdout '{}'"
7
+ patterns:
8
+ - '*.astro'
9
+ - '!.*' # Exclude hidden files
10
+
11
+ # Biome for JS/TS/JSX/TSX/JSON/HTML/CSS/GraphQL files
12
+ biome:
13
+ command: "biome check --files-ignore-unknown=true --use-editorconfig=true '--stdin-file-path={}' --fix"
14
+ patterns:
15
+ - '*.js'
16
+ - '*.ts'
17
+ - '*.jsx'
18
+ - '*.tsx'
19
+ - '*.json'
20
+ - '*.jsonc'
21
+ - '*.html'
22
+ - '*.css'
23
+ - '*.graphql'
24
+
25
+ # Prettier for all other files (mainly Markdown)
26
+ prettier:
27
+ command: "prettier --ignore-unknown --stdin-filepath '{}'"
28
+ patterns:
29
+ # Match all files
30
+ - '*'
31
+ # Exclude files handled by Biome
32
+ - '!*.js'
33
+ - '!*.ts'
34
+ - '!*.jsx'
35
+ - '!*.tsx'
36
+ - '!*.json'
37
+ - '!*.jsonc'
38
+ - '!*.html'
39
+ - '!*.css'
40
+ - '!*.graphql'
41
+ # Exclude files handled by Alejandra
42
+ - '!*.nix'
43
+ # Bun lockfiles are generated and should not be rewritten by Prettier
44
+ - '!bun.lock'
45
+
46
+ # Alejandra for Nix files
47
+ alejandra:
48
+ command: 'alejandra'
49
+ patterns:
50
+ - '*.nix'
51
+
52
+ settings:
53
+ update_working_tree: true
54
+ show_commands: true # Verbose output
@@ -6,4 +6,4 @@ export PATH="$TOOLING/git-hooks:$TOOLING:$PWD/node_modules/.bin:$TOOLING/direnv/
6
6
 
7
7
  set -e -o pipefail
8
8
 
9
- smoo monorepo validate-commit-msg "$1"
9
+ smoo monorepo validate-commit-msg --fix "$1"
@@ -10,10 +10,5 @@ set -e -o pipefail
10
10
  git-format-staged
11
11
 
12
12
  # Adding a workspace package is rare and easy to leave half-wired. Run the
13
- # full monorepo validator only for newly staged package manifests; --fail-fast
14
- # keeps pre-commit output focused on the first blocking setup issue.
15
- if ! git diff --cached --quiet --diff-filter=A -- \
16
- 'packages/*/package.json' \
17
- 'targets/*/package.json'; then
18
- smoo monorepo validate --fail-fast
19
- fi
13
+ # full monorepo validator only for newly staged package manifests.
14
+ smoo monorepo validate --fail-fast --only-if-new-workspace-package
@@ -15,13 +15,7 @@ runs:
15
15
  # This action is intentionally post-checkout only. Repo-local actions do not
16
16
  # exist before actions/checkout has populated the working tree.
17
17
  - name: ❄️ Install Nix
18
- uses: DeterminateSystems/nix-installer-action@v22
19
- with:
20
- extra-conf: |
21
- keep-outputs = true
22
- keep-derivations = true
23
- gc-keep-derivations = true
24
- gc-keep-outputs = true
18
+ uses: DeterminateSystems/determinate-nix-action@v3
25
19
 
26
20
  - name: 🧊 Cache Nix profiles and store NAR
27
21
  id: nix-cache
@@ -2,6 +2,8 @@ name: CI
2
2
 
3
3
  on:
4
4
  push:
5
+ branches:
6
+ - '**'
5
7
  pull_request:
6
8
 
7
9
  permissions:
@@ -16,6 +18,7 @@ defaults:
16
18
  jobs:
17
19
  main:
18
20
  runs-on: ubuntu-latest
21
+ timeout-minutes: 45
19
22
  env:
20
23
  NIX_STORE_NAR: ${{ github.workspace }}/nix-store.nar
21
24
  GH_TOKEN: ${{ github.token }}
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@smoothbricks/cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "SmoothBricks monorepo automation CLI",
6
6
  "bin": {
7
7
  "smoo": "./bin/smoo"
8
8
  },
9
+ "scripts": {
10
+ "test": "nx run cli:test"
11
+ },
9
12
  "main": "./dist/index.js",
10
13
  "module": "./dist/index.js",
11
14
  "types": "./dist/index.d.ts",
@@ -30,6 +33,11 @@
30
33
  "development": "./src/monorepo/git-config.ts",
31
34
  "import": "./dist/monorepo/git-config.js",
32
35
  "default": "./dist/monorepo/git-config.js"
36
+ },
37
+ "./nx-version-actions": {
38
+ "types": "./dist/nx-version-actions.d.cts",
39
+ "require": "./dist/nx-version-actions.cjs",
40
+ "default": "./dist/nx-version-actions.cjs"
33
41
  }
34
42
  },
35
43
  "files": [
@@ -42,19 +50,44 @@
42
50
  ],
43
51
  "dependencies": {
44
52
  "@arethetypeswrong/cli": "^0.18.2",
45
- "@smoothbricks/validation": "0.0.1",
53
+ "@smoothbricks/validation": "0.1.1",
46
54
  "commander": "^14.0.3",
47
55
  "publint": "^0.3.18",
56
+ "semver": "^7.7.4",
48
57
  "sherif": "^1.11.1",
49
58
  "tslib": "^2.8.1"
50
59
  },
60
+ "devDependencies": {
61
+ "fast-check": "^4.4.0"
62
+ },
51
63
  "nx": {
52
64
  "targets": {
53
- "lint": {}
65
+ "lint": {},
66
+ "typecheck-tests": {
67
+ "executor": "nx:run-commands",
68
+ "options": {
69
+ "command": "tsc --noEmit -p tsconfig.test.json",
70
+ "cwd": "packages/cli"
71
+ },
72
+ "dependsOn": [
73
+ "build"
74
+ ]
75
+ },
76
+ "test": {
77
+ "executor": "nx:run-commands",
78
+ "dependsOn": [
79
+ "^build"
80
+ ],
81
+ "options": {
82
+ "command": "bun test",
83
+ "cwd": "{projectRoot}"
84
+ }
85
+ }
54
86
  },
55
87
  "tags": [
56
88
  "npm:public"
57
- ]
89
+ ],
90
+ "name": "cli"
58
91
  },
59
92
  "license": "MIT",
60
93
  "publishConfig": {