@smoothbricks/cli 0.1.1 → 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.
- package/README.md +155 -30
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +91 -7
- package/dist/devenv/index.d.ts +10 -0
- package/dist/devenv/index.d.ts.map +1 -0
- package/dist/devenv/index.js +27 -0
- package/dist/lib/cli-package.d.ts +4 -0
- package/dist/lib/cli-package.d.ts.map +1 -0
- package/dist/lib/cli-package.js +15 -0
- package/dist/lib/run.d.ts +5 -0
- package/dist/lib/run.d.ts.map +1 -1
- package/dist/lib/run.js +13 -0
- package/dist/lib/workspace.d.ts +15 -1
- package/dist/lib/workspace.d.ts.map +1 -1
- package/dist/lib/workspace.js +25 -2
- package/dist/monorepo/commit-msg.d.ts +8 -1
- package/dist/monorepo/commit-msg.d.ts.map +1 -1
- package/dist/monorepo/commit-msg.js +85 -7
- package/dist/monorepo/index.d.ts +19 -2
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +104 -16
- package/dist/monorepo/managed-files.js +1 -1
- package/dist/monorepo/nx-sync.d.ts +2 -1
- package/dist/monorepo/nx-sync.d.ts.map +1 -1
- package/dist/monorepo/nx-sync.js +8 -2
- package/dist/monorepo/package-hygiene.d.ts +6 -2
- package/dist/monorepo/package-hygiene.d.ts.map +1 -1
- package/dist/monorepo/package-hygiene.js +12 -4
- package/dist/monorepo/package-policy.d.ts +22 -2
- package/dist/monorepo/package-policy.d.ts.map +1 -1
- package/dist/monorepo/package-policy.js +1167 -8
- package/dist/monorepo/packed-package.d.ts +3 -0
- package/dist/monorepo/packed-package.d.ts.map +1 -1
- package/dist/monorepo/packed-package.js +68 -36
- package/dist/monorepo/packs/index.d.ts +20 -1
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +238 -19
- package/dist/monorepo/publish-workflow.d.ts +0 -4
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +5 -12
- package/dist/monorepo/tool-validation.d.ts +22 -0
- package/dist/monorepo/tool-validation.d.ts.map +1 -0
- package/dist/monorepo/tool-validation.js +399 -0
- package/dist/nx/index.d.ts +24 -0
- package/dist/nx/index.d.ts.map +1 -0
- package/dist/nx/index.js +94 -0
- package/dist/release/bootstrap-npm-packages.d.ts +19 -0
- package/dist/release/bootstrap-npm-packages.d.ts.map +1 -0
- package/dist/release/bootstrap-npm-packages.js +58 -0
- package/dist/release/candidates.d.ts +11 -0
- package/dist/release/candidates.d.ts.map +1 -0
- package/dist/release/candidates.js +181 -0
- package/dist/release/core.d.ts +1 -0
- package/dist/release/core.d.ts.map +1 -1
- package/dist/release/github-release.js +2 -2
- package/dist/release/index.d.ts +25 -0
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +247 -49
- package/dist/release/npm-auth.d.ts +0 -1
- package/dist/release/npm-auth.d.ts.map +1 -1
- package/dist/release/npm-auth.js +4 -16
- package/dist/release/orchestration.d.ts +2 -1
- package/dist/release/orchestration.d.ts.map +1 -1
- package/dist/release/orchestration.js +9 -1
- package/dist/release/publish-plan.js +1 -1
- package/managed/raw/git-format-staged.yml +54 -0
- package/managed/raw/tooling/git-hooks/commit-msg.sh +1 -1
- package/managed/templates/github/actions/setup-devenv/action.yml +1 -7
- package/managed/templates/github/workflows/ci.yml +1 -0
- package/package.json +15 -3
- package/src/cli.ts +134 -20
- package/src/devenv/index.test.ts +49 -0
- package/src/devenv/index.ts +38 -0
- package/src/lib/cli-package.ts +18 -0
- package/src/lib/run.ts +19 -0
- package/src/lib/workspace.ts +41 -2
- package/src/monorepo/__tests__/publish-workflow.test.ts +16 -9
- package/src/monorepo/commit-msg.test.ts +45 -0
- package/src/monorepo/commit-msg.ts +107 -7
- package/src/monorepo/index.ts +142 -16
- package/src/monorepo/managed-files.ts +1 -1
- package/src/monorepo/nx-sync.ts +9 -2
- package/src/monorepo/package-hygiene.test.ts +34 -0
- package/src/monorepo/package-hygiene.ts +26 -4
- package/src/monorepo/package-policy.test.ts +902 -0
- package/src/monorepo/package-policy.ts +1393 -7
- package/src/monorepo/packed-package.ts +89 -37
- package/src/monorepo/packs/index.test.ts +189 -0
- package/src/monorepo/packs/index.ts +311 -20
- package/src/monorepo/publish-workflow.ts +8 -16
- package/src/monorepo/setup-test-tracing.test.ts +120 -0
- package/src/monorepo/tool-validation.test.ts +261 -0
- package/src/monorepo/tool-validation.ts +462 -0
- package/src/nx/index.test.ts +64 -0
- package/src/nx/index.ts +119 -0
- package/src/release/__tests__/bootstrap-npm-packages.test.ts +127 -0
- package/src/release/__tests__/candidates.test.ts +217 -0
- package/src/release/__tests__/core-properties.test.ts +4 -4
- package/src/release/__tests__/core-scenarios.test.ts +15 -5
- package/src/release/__tests__/core.test.ts +2 -2
- package/src/release/__tests__/fixture-repo.test.ts +22 -13
- package/src/release/__tests__/github-release.test.ts +13 -8
- package/src/release/__tests__/helpers/fixture-repo.ts +1 -0
- package/src/release/__tests__/npm-auth.test.ts +12 -21
- package/src/release/__tests__/orchestration.test.ts +51 -7
- package/src/release/__tests__/publish-plan.test.ts +9 -3
- package/src/release/__tests__/retag-unpublished.test.ts +1 -1
- package/src/release/__tests__/trust-publisher.test.ts +133 -0
- package/src/release/bootstrap-npm-packages.ts +88 -0
- package/src/release/candidates.ts +225 -0
- package/src/release/core.ts +1 -0
- package/src/release/github-release.ts +2 -2
- package/src/release/index.ts +346 -56
- package/src/release/npm-auth.ts +4 -33
- package/src/release/orchestration.ts +12 -2
- package/src/release/publish-plan.ts +1 -1
- package/managed/raw/.git-format-staged.yml +0 -47
package/dist/release/index.js
CHANGED
|
@@ -5,10 +5,12 @@ import { createInterface } from 'node:readline/promises';
|
|
|
5
5
|
import { Writable } from 'node:stream';
|
|
6
6
|
import { $ } from 'bun';
|
|
7
7
|
import { withDevenvEnv } from '../lib/devenv.js';
|
|
8
|
-
import { isRecord, stringProperty } from '../lib/json.js';
|
|
9
|
-
import { decode, run, runStatus } from '../lib/run.js';
|
|
8
|
+
import { isRecord, readJsonObject, stringProperty } from '../lib/json.js';
|
|
9
|
+
import { decode, run, runResult, runStatus } from '../lib/run.js';
|
|
10
10
|
import { listReleasePackages, readPackageJson, repositoryInfo } from '../lib/workspace.js';
|
|
11
11
|
import { readPackedPackageJson, validatePackedWorkspaceDependencies } from '../monorepo/packed-manifest.js';
|
|
12
|
+
import { bootstrapNpmPackages, NPM_BOOTSTRAP_DIST_TAG, NPM_BOOTSTRAP_VERSION, } from './bootstrap-npm-packages.js';
|
|
13
|
+
import { autoReleaseCandidatePackages } from './candidates.js';
|
|
12
14
|
import { collectOwnedReleaseTagRecords, pendingReleaseTargets, releaseTag, } from './core.js';
|
|
13
15
|
import { createOrUpdateGithubRelease, renderNxProjectChangelogContents } from './github-release.js';
|
|
14
16
|
import { publishWithAuthDiagnostics } from './npm-auth.js';
|
|
@@ -17,12 +19,12 @@ import { retagUnpublished } from './retag-unpublished.js';
|
|
|
17
19
|
export async function releaseVersion(root, options) {
|
|
18
20
|
const bump = releaseBumpArg(options.bump);
|
|
19
21
|
const packages = releasePackages(root);
|
|
20
|
-
const projects = releasePackageProjects(packages);
|
|
21
22
|
const result = await runReleaseVersion({
|
|
22
23
|
releasePackagesAtHead: () => releasePackagesAtHead(root, packages),
|
|
24
|
+
releaseVersionPackages: (releaseBump) => releaseVersionPackages(root, packages, releaseBump),
|
|
23
25
|
ensureLocalReleaseTags: (releasePackages) => ensureLocalReleaseTags(root, releasePackages),
|
|
24
26
|
gitHead: () => gitHead(root),
|
|
25
|
-
runNxReleaseVersion: (releaseBump, dryRun) => runNxReleaseVersion(root,
|
|
27
|
+
runNxReleaseVersion: (releasePackages, releaseBump, dryRun) => runNxReleaseVersion(root, releasePackageProjects(releasePackages), releaseBump, dryRun),
|
|
26
28
|
assertCleanGitTree: () => assertCleanGitTree(root),
|
|
27
29
|
}, { bump, dryRun: options.dryRun === true });
|
|
28
30
|
if (result.status === 'already-release-target') {
|
|
@@ -76,56 +78,107 @@ export async function releaseRepairPending(root, options) {
|
|
|
76
78
|
export async function releaseTrustPublisher(root, options) {
|
|
77
79
|
const repository = githubRepositoryFromRootPackage(root);
|
|
78
80
|
const workflow = 'publish.yml';
|
|
79
|
-
|
|
81
|
+
await configureTrustedPublishers({
|
|
82
|
+
repository,
|
|
83
|
+
workflow,
|
|
84
|
+
listReleasePackages: () => listReleasePackages(root),
|
|
85
|
+
packageExists: (name) => npmPackageExists(root, name),
|
|
86
|
+
bootstrapNpmPackages: (bootstrapOptions) => bootstrapNpmPackages({
|
|
87
|
+
listReleasePackages: () => listReleasePackages(root),
|
|
88
|
+
packageExists: (name) => npmPackageExists(root, name),
|
|
89
|
+
login: () => runLatestNpm(root, ['login', '--auth-type=web']),
|
|
90
|
+
publishPlaceholder: (pkg, env) => publishPlaceholderPackage(root, pkg, env),
|
|
91
|
+
promptOtp: (packageName) => promptForNpmOtp(packageName),
|
|
92
|
+
log: (message) => console.log(message),
|
|
93
|
+
}, bootstrapOptions),
|
|
94
|
+
login: () => runLatestNpm(root, ['login', '--auth-type=web']),
|
|
95
|
+
trustPublisher: (pkg, dryRun, env) => {
|
|
96
|
+
const args = ['trust', 'github', pkg.name, '--file', workflow, '--repo', repository, '--yes'];
|
|
97
|
+
if (dryRun) {
|
|
98
|
+
args.push('--dry-run');
|
|
99
|
+
}
|
|
100
|
+
return runLatestNpmTrust(root, args, env);
|
|
101
|
+
},
|
|
102
|
+
promptOtp: (packageName) => promptForNpmOtp(packageName),
|
|
103
|
+
log: (message) => console.log(message),
|
|
104
|
+
error: (message) => console.error(message),
|
|
105
|
+
}, options);
|
|
106
|
+
}
|
|
107
|
+
export async function configureTrustedPublishers(shell, options) {
|
|
108
|
+
const packages = shell.listReleasePackages();
|
|
80
109
|
if (packages.length === 0) {
|
|
81
110
|
throw new Error('No owned release packages found.');
|
|
82
111
|
}
|
|
112
|
+
let bootstrapLoggedIn = false;
|
|
113
|
+
if (options.bootstrap) {
|
|
114
|
+
const bootstrapped = await shell.bootstrapNpmPackages({
|
|
115
|
+
dryRun: options.dryRun === true,
|
|
116
|
+
skipLogin: options.skipLogin === true,
|
|
117
|
+
otp: options.bootstrapOtp,
|
|
118
|
+
packages: [],
|
|
119
|
+
});
|
|
120
|
+
bootstrapLoggedIn = bootstrapped.length > 0 && !options.dryRun && !options.skipLogin;
|
|
121
|
+
}
|
|
83
122
|
if (!options.dryRun) {
|
|
84
|
-
const packageStates = await Promise.all(packages.map(async (pkg) => ((await
|
|
123
|
+
const packageStates = await Promise.all(packages.map(async (pkg) => ((await shell.packageExists(pkg.name)) ? null : pkg.name)));
|
|
85
124
|
const missingPackages = packageStates.filter((name) => name !== null);
|
|
86
125
|
if (missingPackages.length > 0) {
|
|
87
126
|
throw new Error('npm trusted publishing can only be configured after packages exist on the registry. ' +
|
|
88
|
-
'
|
|
127
|
+
'Run smoo release trust-publisher --bootstrap locally. ' +
|
|
89
128
|
`Missing packages: ${missingPackages.join(', ')}`);
|
|
90
129
|
}
|
|
91
130
|
}
|
|
92
|
-
if (!options.dryRun && !options.skipLogin) {
|
|
93
|
-
await
|
|
131
|
+
if (!options.dryRun && !options.skipLogin && !bootstrapLoggedIn) {
|
|
132
|
+
await shell.login();
|
|
94
133
|
}
|
|
95
134
|
const failedPackages = [];
|
|
96
135
|
for (const pkg of packages) {
|
|
97
|
-
|
|
98
|
-
const args = ['trust', 'github', pkg.name, '--file', workflow, '--repo', repository, '--yes'];
|
|
99
|
-
if (options.dryRun) {
|
|
100
|
-
args.push('--dry-run');
|
|
101
|
-
}
|
|
136
|
+
shell.log(`${pkg.name}: trusting GitHub Actions ${shell.repository}/${shell.workflow}`);
|
|
102
137
|
while (true) {
|
|
103
|
-
const otp = options.dryRun ? undefined : (options.otp ?? (await
|
|
138
|
+
const otp = options.dryRun ? undefined : (options.otp ?? (await shell.promptOtp(pkg.name)));
|
|
104
139
|
try {
|
|
105
|
-
await
|
|
140
|
+
const result = await shell.trustPublisher(pkg, options.dryRun === true, otp ? { NPM_CONFIG_OTP: otp } : undefined);
|
|
141
|
+
if (result === 'already-configured') {
|
|
142
|
+
shell.log(`${pkg.name}: npm trusted publisher is already configured; skipping.`);
|
|
143
|
+
}
|
|
106
144
|
break;
|
|
107
145
|
}
|
|
108
146
|
catch (error) {
|
|
109
|
-
|
|
110
|
-
|
|
147
|
+
shell.error(`${pkg.name}: npm trusted publisher setup failed.`);
|
|
148
|
+
shell.error(error instanceof Error ? error.message : String(error));
|
|
111
149
|
if (!options.dryRun) {
|
|
112
|
-
|
|
150
|
+
shell.error('npm OTP codes are single-use. Generate a fresh OTP before retrying this package.');
|
|
113
151
|
}
|
|
114
152
|
if (options.otp || options.dryRun) {
|
|
115
153
|
failedPackages.push(pkg.name);
|
|
116
154
|
break;
|
|
117
155
|
}
|
|
118
|
-
|
|
156
|
+
shell.error('Retrying this package. Press Ctrl-C to stop.');
|
|
119
157
|
}
|
|
120
158
|
}
|
|
121
159
|
}
|
|
122
160
|
if (failedPackages.length > 0) {
|
|
123
|
-
|
|
161
|
+
shell.error(`Trusted publishing was not configured for: ${failedPackages.join(', ')}`);
|
|
124
162
|
if (options.otp) {
|
|
125
|
-
|
|
163
|
+
shell.error('Rerun smoo release trust-publisher without --otp to enter a fresh OTP for each failed package.');
|
|
126
164
|
}
|
|
127
165
|
}
|
|
128
166
|
}
|
|
167
|
+
export async function releaseBootstrapNpmPackages(root, options) {
|
|
168
|
+
await bootstrapNpmPackages({
|
|
169
|
+
listReleasePackages: () => listReleasePackages(root),
|
|
170
|
+
packageExists: (name) => npmPackageExists(root, name),
|
|
171
|
+
login: () => runLatestNpm(root, ['login', '--auth-type=web']),
|
|
172
|
+
publishPlaceholder: (pkg, env) => publishPlaceholderPackage(root, pkg, env),
|
|
173
|
+
promptOtp: (packageName) => promptForNpmOtp(packageName),
|
|
174
|
+
log: (message) => console.log(message),
|
|
175
|
+
}, {
|
|
176
|
+
dryRun: options.dryRun === true,
|
|
177
|
+
skipLogin: options.skipLogin === true,
|
|
178
|
+
otp: options.otp,
|
|
179
|
+
packages: options.packages ?? [],
|
|
180
|
+
});
|
|
181
|
+
}
|
|
129
182
|
export async function releaseRetagUnpublished(root, options) {
|
|
130
183
|
const toRef = options.to ?? 'HEAD';
|
|
131
184
|
const dispatch = options.dispatch === true;
|
|
@@ -159,15 +212,14 @@ async function listUnpublishedPackages(root, packages) {
|
|
|
159
212
|
const states = await Promise.all(packages.map(async (pkg) => ({ pkg, published: await npmVersionExists(root, pkg.name, pkg.version) })));
|
|
160
213
|
return states.filter((state) => !state.published).map((state) => state.pkg);
|
|
161
214
|
}
|
|
162
|
-
async function publishPackedPackage(root, pkg, tag, dryRun
|
|
215
|
+
async function publishPackedPackage(root, pkg, tag, dryRun) {
|
|
163
216
|
const tempDir = await mkdtemp(join(tmpdir(), 'smoo-publish-'));
|
|
164
217
|
const tarball = join(tempDir, `${safeTarballPrefix(pkg.name)}-${pkg.version}.tgz`);
|
|
165
218
|
try {
|
|
166
219
|
console.log(`${pkg.name}@${pkg.version}: packing with bun pm pack`);
|
|
167
220
|
await run('bun', ['pm', 'pack', '--filename', tarball, '--ignore-scripts', '--quiet'], join(root, pkg.path));
|
|
168
221
|
await assertPackedWorkspaceDependencies(root, tarball, pkg);
|
|
169
|
-
// npm CLI owns authentication here: trusted publishing OIDC when configured
|
|
170
|
-
// or the temporary NODE_AUTH_TOKEN bootstrap path below before trust exists.
|
|
222
|
+
// npm CLI owns authentication here: trusted publishing OIDC when configured.
|
|
171
223
|
// Bun still produces the tarball so workspace:* dependencies are resolved the
|
|
172
224
|
// same way smoo validates packed packages before release.
|
|
173
225
|
const args = ['publish', tarball, '--access', 'public', '--tag', tag, '--provenance'];
|
|
@@ -175,7 +227,7 @@ async function publishPackedPackage(root, pkg, tag, dryRun, useBootstrapToken) {
|
|
|
175
227
|
args.push('--dry-run');
|
|
176
228
|
}
|
|
177
229
|
await publishWithAuthDiagnostics(pkg, {
|
|
178
|
-
publish: () => runLatestNpmPublish(root, args
|
|
230
|
+
publish: () => runLatestNpmPublish(root, args),
|
|
179
231
|
versionExists: () => npmVersionExists(root, pkg.name, pkg.version),
|
|
180
232
|
log: (message) => console.log(message),
|
|
181
233
|
error: (message) => console.error(message),
|
|
@@ -186,7 +238,6 @@ async function publishPackedPackage(root, pkg, tag, dryRun, useBootstrapToken) {
|
|
|
186
238
|
}
|
|
187
239
|
},
|
|
188
240
|
}, {
|
|
189
|
-
useBootstrapToken,
|
|
190
241
|
tokenPresent: npmAuthTokenPresent(),
|
|
191
242
|
repository: githubRepositoryFromRootPackage(root),
|
|
192
243
|
});
|
|
@@ -198,6 +249,24 @@ async function publishPackedPackage(root, pkg, tag, dryRun, useBootstrapToken) {
|
|
|
198
249
|
function npmAuthTokenPresent() {
|
|
199
250
|
return Boolean(process.env.NODE_AUTH_TOKEN || process.env.NPM_TOKEN || process.env.NPM_CONFIG_USERCONFIG);
|
|
200
251
|
}
|
|
252
|
+
async function publishPlaceholderPackage(root, pkg, env) {
|
|
253
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'smoo-npm-bootstrap-'));
|
|
254
|
+
try {
|
|
255
|
+
await writeFile(join(tempDir, 'package.json'), `${JSON.stringify({
|
|
256
|
+
name: pkg.name,
|
|
257
|
+
version: NPM_BOOTSTRAP_VERSION,
|
|
258
|
+
description: `Bootstrap placeholder for ${pkg.name}. Real releases are published by SmoothBricks CI.`,
|
|
259
|
+
license: stringProperty(pkg.json, 'license') ?? 'UNLICENSED',
|
|
260
|
+
repository: pkg.json.repository,
|
|
261
|
+
publishConfig: { access: 'public' },
|
|
262
|
+
}, null, 2)}\n`);
|
|
263
|
+
await writeFile(join(tempDir, 'README.md'), `# ${pkg.name}\n\nThis is a bootstrap placeholder. Real package versions are published by SmoothBricks release automation.\n`);
|
|
264
|
+
await runLatestNpm(root, ['publish', tempDir, '--access', 'public', '--tag', NPM_BOOTSTRAP_DIST_TAG], env);
|
|
265
|
+
}
|
|
266
|
+
finally {
|
|
267
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
201
270
|
function safeTarballPrefix(name) {
|
|
202
271
|
return name.replace(/^@/, '').replace(/[^a-zA-Z0-9._-]+/g, '-');
|
|
203
272
|
}
|
|
@@ -216,7 +285,20 @@ function releasePackages(root) {
|
|
|
216
285
|
return packages;
|
|
217
286
|
}
|
|
218
287
|
function releasePackageProjects(packages) {
|
|
219
|
-
return packages.map((pkg) => pkg.
|
|
288
|
+
return packages.map((pkg) => pkg.projectName).join(',');
|
|
289
|
+
}
|
|
290
|
+
async function releaseVersionPackages(root, packages, bump) {
|
|
291
|
+
if (bump !== 'auto') {
|
|
292
|
+
return packages;
|
|
293
|
+
}
|
|
294
|
+
return autoReleaseCandidatePackages({
|
|
295
|
+
gitRefExists: (ref) => gitRefExists(root, ref),
|
|
296
|
+
packageChangedFilesSince: (ref, packagePath) => packageChangedFilesSince(root, ref, packagePath),
|
|
297
|
+
packageJsonAtRef: (ref, packagePath) => packageJsonAtRef(root, ref, packagePath),
|
|
298
|
+
currentPackageJson: (packagePath) => currentPackageJson(root, packagePath),
|
|
299
|
+
packageBuildInputPatterns: (projectName, packagePath) => packageBuildInputPatterns(root, projectName, packagePath),
|
|
300
|
+
packageHasHistory: (packagePath) => packageHasHistory(root, packagePath),
|
|
301
|
+
}, packages);
|
|
220
302
|
}
|
|
221
303
|
async function runNxReleaseVersion(root, projects, bump, dryRun) {
|
|
222
304
|
// Nx owns local release mutation: package versions, bun.lock updates, the
|
|
@@ -355,7 +437,10 @@ function releaseCompletionShell(root) {
|
|
|
355
437
|
buildReleaseCandidate: (packages) => buildReleaseCandidate(root, packages),
|
|
356
438
|
publishPackage: async (pkg, distTag, dryRun) => {
|
|
357
439
|
const packageExists = dryRun ? true : await npmPackageExists(root, pkg.name);
|
|
358
|
-
|
|
440
|
+
if (!packageExists) {
|
|
441
|
+
throw new Error(missingNpmPackagePublishGuidance(pkg));
|
|
442
|
+
}
|
|
443
|
+
await publishPackedPackage(root, pkg, distTag, dryRun);
|
|
359
444
|
},
|
|
360
445
|
listGithubMissingPackages: (packages) => listMissingGithubReleasePackages(root, packages),
|
|
361
446
|
createGithubRelease: (pkg, dryRun) => createGithubRelease(root, pkg, dryRun),
|
|
@@ -538,6 +623,125 @@ async function gitRefExists(root, ref) {
|
|
|
538
623
|
const result = await $ `git rev-parse --verify ${ref}`.cwd(root).quiet().nothrow();
|
|
539
624
|
return result.exitCode === 0;
|
|
540
625
|
}
|
|
626
|
+
async function packageChangedFilesSince(root, ref, packagePath) {
|
|
627
|
+
const result = await $ `git diff --name-only ${`${ref}..HEAD`} -- ${packagePath}`.cwd(root).quiet().nothrow();
|
|
628
|
+
if (result.exitCode !== 0) {
|
|
629
|
+
throw new Error(`Unable to inspect package changes under ${packagePath}.`);
|
|
630
|
+
}
|
|
631
|
+
const packagePrefix = `${packagePath}/`;
|
|
632
|
+
return decode(result.stdout)
|
|
633
|
+
.split('\n')
|
|
634
|
+
.map((path) => path.trim())
|
|
635
|
+
.filter(Boolean)
|
|
636
|
+
.map((path) => (path.startsWith(packagePrefix) ? path.slice(packagePrefix.length) : path));
|
|
637
|
+
}
|
|
638
|
+
async function packageJsonAtRef(root, ref, packagePath) {
|
|
639
|
+
const result = await $ `git show ${`${ref}:${packagePath}/package.json`}`.cwd(root).quiet().nothrow();
|
|
640
|
+
if (result.exitCode !== 0) {
|
|
641
|
+
return null;
|
|
642
|
+
}
|
|
643
|
+
try {
|
|
644
|
+
const parsed = JSON.parse(decode(result.stdout));
|
|
645
|
+
return isRecord(parsed) ? parsed : null;
|
|
646
|
+
}
|
|
647
|
+
catch {
|
|
648
|
+
return null;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
async function currentPackageJson(root, packagePath) {
|
|
652
|
+
return readPackageJson(join(root, packagePath, 'package.json'))?.json ?? null;
|
|
653
|
+
}
|
|
654
|
+
async function packageBuildInputPatterns(root, projectName, _packagePath) {
|
|
655
|
+
const project = await nxProjectJson(root, projectName);
|
|
656
|
+
const nxJson = readJsonObject(join(root, 'nx.json')) ?? {};
|
|
657
|
+
return resolveBuildInputPatterns(project, nxJson);
|
|
658
|
+
}
|
|
659
|
+
async function nxProjectJson(root, projectName) {
|
|
660
|
+
const result = await $ `nx show project ${projectName} --json`.cwd(root).quiet();
|
|
661
|
+
const parsed = JSON.parse(decode(result.stdout));
|
|
662
|
+
if (!isRecord(parsed)) {
|
|
663
|
+
throw new Error(`Unable to inspect Nx project ${projectName}.`);
|
|
664
|
+
}
|
|
665
|
+
return parsed;
|
|
666
|
+
}
|
|
667
|
+
function resolveBuildInputPatterns(project, nxJson) {
|
|
668
|
+
const targets = recordProperty(project, 'targets');
|
|
669
|
+
if (!targets) {
|
|
670
|
+
return [];
|
|
671
|
+
}
|
|
672
|
+
return normalizeInputPatterns(collectBuildInputs(targets), nxJson);
|
|
673
|
+
}
|
|
674
|
+
function collectBuildInputs(targets) {
|
|
675
|
+
const build = recordProperty(targets, 'build');
|
|
676
|
+
if (!build) {
|
|
677
|
+
return ['production'];
|
|
678
|
+
}
|
|
679
|
+
const directInputs = stringArrayProperty(build, 'inputs');
|
|
680
|
+
if (directInputs.length > 0) {
|
|
681
|
+
return directInputs;
|
|
682
|
+
}
|
|
683
|
+
const inputs = [];
|
|
684
|
+
for (const dependency of stringArrayProperty(build, 'dependsOn')) {
|
|
685
|
+
if (dependency.startsWith('^')) {
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
const targetName = dependency.includes(':') ? dependency.split(':')[1] : dependency;
|
|
689
|
+
if (!targetName) {
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
inputs.push(...stringArrayProperty(recordProperty(targets, targetName), 'inputs'));
|
|
693
|
+
}
|
|
694
|
+
return inputs.length > 0 ? inputs : ['production'];
|
|
695
|
+
}
|
|
696
|
+
function normalizeInputPatterns(inputs, nxJson) {
|
|
697
|
+
const patterns = [];
|
|
698
|
+
const seen = new Set();
|
|
699
|
+
for (const input of inputs) {
|
|
700
|
+
for (const pattern of expandInputPattern(input, nxJson, seen)) {
|
|
701
|
+
patterns.push(pattern);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
return patterns;
|
|
705
|
+
}
|
|
706
|
+
function expandInputPattern(input, nxJson, seen) {
|
|
707
|
+
if (seen.has(input)) {
|
|
708
|
+
return [];
|
|
709
|
+
}
|
|
710
|
+
seen.add(input);
|
|
711
|
+
if (!input.includes('{')) {
|
|
712
|
+
const namedInputs = recordProperty(nxJson, 'namedInputs');
|
|
713
|
+
const namedInput = namedInputs?.[input];
|
|
714
|
+
if (Array.isArray(namedInput)) {
|
|
715
|
+
return namedInput.flatMap((entry) => (typeof entry === 'string' ? expandInputPattern(entry, nxJson, seen) : []));
|
|
716
|
+
}
|
|
717
|
+
return [];
|
|
718
|
+
}
|
|
719
|
+
const excluded = input.startsWith('!');
|
|
720
|
+
const rawInput = excluded ? input.slice(1) : input;
|
|
721
|
+
if (!rawInput.startsWith('{projectRoot}/')) {
|
|
722
|
+
return [];
|
|
723
|
+
}
|
|
724
|
+
const packageRelative = rawInput.slice('{projectRoot}/'.length);
|
|
725
|
+
return [`${excluded ? '!' : ''}${packageRelative}`];
|
|
726
|
+
}
|
|
727
|
+
function recordProperty(record, key) {
|
|
728
|
+
if (!record) {
|
|
729
|
+
return null;
|
|
730
|
+
}
|
|
731
|
+
const value = record[key];
|
|
732
|
+
return isRecord(value) ? value : null;
|
|
733
|
+
}
|
|
734
|
+
function stringArrayProperty(record, key) {
|
|
735
|
+
const value = record?.[key];
|
|
736
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === 'string') : [];
|
|
737
|
+
}
|
|
738
|
+
async function packageHasHistory(root, packagePath) {
|
|
739
|
+
const result = await $ `git log --format=%H -- ${packagePath}`.cwd(root).quiet().nothrow();
|
|
740
|
+
if (result.exitCode !== 0) {
|
|
741
|
+
throw new Error(`Unable to inspect package history under ${packagePath}.`);
|
|
742
|
+
}
|
|
743
|
+
return decode(result.stdout).trim().length > 0;
|
|
744
|
+
}
|
|
541
745
|
async function gitIsAncestor(root, ancestor, descendant) {
|
|
542
746
|
const result = await $ `git merge-base --is-ancestor ${ancestor} ${descendant}`.cwd(root).quiet().nothrow();
|
|
543
747
|
return result.exitCode === 0;
|
|
@@ -712,28 +916,22 @@ function githubRepositoryFromUrl(url) {
|
|
|
712
916
|
async function runLatestNpm(root, npmArgs, env) {
|
|
713
917
|
await run('nix', ['shell', 'nixpkgs#nodejs_latest', '-c', 'npm', ...npmArgs], root, env);
|
|
714
918
|
}
|
|
715
|
-
async function
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
|
-
const token = process.env.NODE_AUTH_TOKEN || process.env.NPM_TOKEN;
|
|
721
|
-
if (!token || process.env.NPM_CONFIG_USERCONFIG) {
|
|
722
|
-
if (!token && !process.env.NPM_CONFIG_USERCONFIG) {
|
|
723
|
-
throw new Error('First publish for a package requires NODE_AUTH_TOKEN or NPM_TOKEN until trusted publishing exists.');
|
|
724
|
-
}
|
|
725
|
-
await runLatestNpm(root, npmArgs);
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
const tempDir = await mkdtemp(join(tmpdir(), 'smoo-npm-auth-'));
|
|
729
|
-
const npmrc = join(tempDir, '.npmrc');
|
|
730
|
-
try {
|
|
731
|
-
await writeFile(npmrc, `registry=https://registry.npmjs.org/\n//registry.npmjs.org/:_authToken=${token}\n`);
|
|
732
|
-
await runLatestNpm(root, npmArgs, { NPM_CONFIG_USERCONFIG: npmrc });
|
|
919
|
+
async function runLatestNpmTrust(root, npmArgs, env) {
|
|
920
|
+
const result = await runResult('nix', ['shell', 'nixpkgs#nodejs_latest', '-c', 'npm', ...npmArgs], root, env);
|
|
921
|
+
if (result.exitCode === 0) {
|
|
922
|
+
return 'configured';
|
|
733
923
|
}
|
|
734
|
-
|
|
735
|
-
|
|
924
|
+
const output = `${result.stdout}\n${result.stderr}`;
|
|
925
|
+
if (/\bE409\b|\b409 Conflict\b/.test(output)) {
|
|
926
|
+
return 'already-configured';
|
|
736
927
|
}
|
|
928
|
+
throw new Error(`nix shell nixpkgs#nodejs_latest -c npm ${npmArgs.join(' ')} failed with exit code ${result.exitCode}`);
|
|
929
|
+
}
|
|
930
|
+
async function runLatestNpmPublish(root, npmArgs) {
|
|
931
|
+
await runLatestNpm(root, npmArgs, { NODE_AUTH_TOKEN: '', NPM_TOKEN: '' });
|
|
932
|
+
}
|
|
933
|
+
function missingNpmPackagePublishGuidance(pkg) {
|
|
934
|
+
return `${pkg.name} does not exist on npm yet. Run smoo release trust-publisher --bootstrap locally before rerunning the Publish workflow.`;
|
|
737
935
|
}
|
|
738
936
|
async function promptForNpmOtp(packageName) {
|
|
739
937
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
@@ -1 +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,
|
|
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"}
|
package/dist/release/npm-auth.js
CHANGED
|
@@ -10,40 +10,28 @@ export async function publishWithAuthDiagnostics(pkg, shell, options) {
|
|
|
10
10
|
}
|
|
11
11
|
shell.error(npmPublishAuthFailureMessage(pkg, options));
|
|
12
12
|
await shell.appendSummary(npmPublishAuthFailureMarkdown(pkg, options));
|
|
13
|
-
throw new Error(`${packageVersion}: npm publish authentication failed. Run smoo release trust-publisher
|
|
13
|
+
throw new Error(`${packageVersion}: npm publish authentication failed. Run smoo release trust-publisher; see the warning banner above for details.`, { cause: error });
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
export function npmPublishAuthFailureMessage(pkg, options) {
|
|
17
17
|
const packageVersion = `${pkg.name}@${pkg.version}`;
|
|
18
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
|
|
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
20
|
'',
|
|
21
21
|
`🚨 npm publish authentication failed for ${packageVersion}`,
|
|
22
22
|
'',
|
|
23
23
|
];
|
|
24
|
-
if (options.useBootstrapToken) {
|
|
25
|
-
lines.push('smoo expected a temporary npm automation token because this package does not exist on npm yet.', options.tokenPresent
|
|
26
|
-
? 'NODE_AUTH_TOKEN/NPM_TOKEN is set, but npm still rejected the bootstrap publish. Check that the token is valid, has publish rights for this scope, and is available to this workflow.'
|
|
27
|
-
: 'NODE_AUTH_TOKEN/NPM_TOKEN is not set. Add a temporary NPM_TOKEN repository secret and rerun the Publish workflow.', '', 'After the first successful publish, run:', ' smoo release trust-publisher', '', 'Then remove the temporary bootstrap token path for future releases.');
|
|
28
|
-
return lines.join('\n');
|
|
29
|
-
}
|
|
30
24
|
lines.push('smoo expected npm trusted publishing/OIDC because this package already exists on npm.', options.tokenPresent
|
|
31
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.'
|
|
32
|
-
: '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,
|
|
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.');
|
|
33
27
|
return lines.join('\n');
|
|
34
28
|
}
|
|
35
29
|
export function npmPublishAuthFailureMarkdown(pkg, options) {
|
|
36
30
|
const packageVersion = `${pkg.name}@${pkg.version}`;
|
|
37
31
|
const lines = ['## 🚨 npm Publish Authentication Failed', '', `Package: \`${packageVersion}\``, ''];
|
|
38
|
-
if (options.useBootstrapToken) {
|
|
39
|
-
lines.push('smoo expected a temporary npm automation token because this package does not exist on npm yet.', '', options.tokenPresent
|
|
40
|
-
? '`NODE_AUTH_TOKEN`/`NPM_TOKEN` is set, but npm still rejected the bootstrap publish. Check that the token is valid, has publish rights for this scope, and is available to this workflow.'
|
|
41
|
-
: '`NODE_AUTH_TOKEN`/`NPM_TOKEN` is not set. Add a temporary `NPM_TOKEN` repository secret and rerun the Publish workflow.', '', 'After the first successful publish, run `smoo release trust-publisher`, then remove the temporary bootstrap token path for future releases.');
|
|
42
|
-
return lines.join('\n');
|
|
43
|
-
}
|
|
44
32
|
lines.push('smoo expected npm trusted publishing/OIDC because this package already exists on npm.', '', options.tokenPresent
|
|
45
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.'
|
|
46
|
-
: '`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,
|
|
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.');
|
|
47
35
|
return lines.join('\n');
|
|
48
36
|
}
|
|
49
37
|
function trustedPublisherRepository(options) {
|
|
@@ -28,9 +28,10 @@ export interface ReleaseRepairShell<Package extends ReleasePackageInfo = Release
|
|
|
28
28
|
}
|
|
29
29
|
export interface ReleaseVersionShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
|
|
30
30
|
releasePackagesAtHead(): Promise<Package[]>;
|
|
31
|
+
releaseVersionPackages(bump: string): Promise<Package[]>;
|
|
31
32
|
ensureLocalReleaseTags(packages: Package[]): Promise<void>;
|
|
32
33
|
gitHead(): Promise<string>;
|
|
33
|
-
runNxReleaseVersion(bump: string, dryRun: boolean): Promise<void>;
|
|
34
|
+
runNxReleaseVersion(packages: Package[], bump: string, dryRun: boolean): Promise<void>;
|
|
34
35
|
assertCleanGitTree(): Promise<void>;
|
|
35
36
|
}
|
|
36
37
|
export interface ReleaseVersionResult<Package extends ReleasePackageInfo = ReleasePackageInfo> {
|
|
@@ -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,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,IAAI,CAAC,CAAC;CACnE;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,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../../src/release/orchestration.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,16 @@ export async function runReleaseVersion(shell, options) {
|
|
|
7
7
|
return { mode: 'none', packages: localRelease, status: 'already-release-target' };
|
|
8
8
|
}
|
|
9
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
|
+
}
|
|
10
18
|
const headBeforeVersioning = await shell.gitHead();
|
|
11
|
-
await shell.runNxReleaseVersion(options.bump, options.dryRun);
|
|
19
|
+
await shell.runNxReleaseVersion(versionPackages, options.bump, options.dryRun);
|
|
12
20
|
if (options.dryRun) {
|
|
13
21
|
return { mode: 'none', packages: [], status: 'dry-run' };
|
|
14
22
|
}
|
|
@@ -5,7 +5,7 @@ export function planPublishActions(input) {
|
|
|
5
5
|
const npmPackages = input.releasePackages.filter((pkg) => npmMissingNames.has(pkg.name));
|
|
6
6
|
const githubReleasePackages = input.releasePackages.filter((pkg) => githubMissingNames.has(pkg.name));
|
|
7
7
|
return {
|
|
8
|
-
buildProjects: npmPackages.map((pkg) => pkg.
|
|
8
|
+
buildProjects: npmPackages.map((pkg) => pkg.projectName),
|
|
9
9
|
publishPackages: npmPackages.map((pkg) => ({ pkg, distTag: npmDistTagForVersion(pkg.version) })),
|
|
10
10
|
githubReleasePackages,
|
|
11
11
|
};
|
|
@@ -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
|
|
@@ -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-
|
|
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
|