pubz 0.3.0 → 0.4.1
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 +67 -53
- package/dist/cli.js +208 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# `pubz`
|
|
2
2
|
|
|
3
|
+
<img width="1024" height="1024" alt="image" src="https://github.com/user-attachments/assets/11ffa33c-e895-4a7d-b2c3-dfadde8dd124" />
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
3
7
|
```bash
|
|
4
8
|
bunx pubz
|
|
5
9
|
```
|
|
@@ -14,8 +18,10 @@ bunx pubz
|
|
|
14
18
|
6. Commits version changes
|
|
15
19
|
7. Prompts you for where you want to publish (e.g. `npm` or private registry)
|
|
16
20
|
8. Builds packages
|
|
17
|
-
9.
|
|
18
|
-
10.
|
|
21
|
+
9. Transforms `workspace:` definitions to hard version numbers (so `npm` can be used for publishing with OIDC support).
|
|
22
|
+
10. Publishes to npm
|
|
23
|
+
11. Prompts you to create a `git tag` and push it
|
|
24
|
+
12. Generates a changelog and creates a GitHub Release
|
|
19
25
|
|
|
20
26
|
## Options
|
|
21
27
|
|
|
@@ -181,49 +187,35 @@ Discovering packages...
|
|
|
181
187
|
|
|
182
188
|
Found 1 publishable package(s):
|
|
183
189
|
|
|
184
|
-
• pubz@0.
|
|
190
|
+
• pubz@0.4.0
|
|
185
191
|
|
|
186
192
|
Step 1: Version Management
|
|
187
193
|
──────────────────────────────
|
|
188
194
|
|
|
189
|
-
Current version: 0.
|
|
190
|
-
|
|
191
|
-
? Bump version before publishing? [Y/n]
|
|
192
|
-
? Select version bump type:
|
|
193
|
-
|
|
194
|
-
> 1) patch (0.2.2 -> 0.2.3)
|
|
195
|
-
2) minor (0.2.2 -> 0.3.0)
|
|
196
|
-
3) major (0.2.2 -> 1.0.0)
|
|
197
|
-
|
|
198
|
-
Enter choice [1-3] (default: 1): 1
|
|
199
|
-
|
|
200
|
-
Updating version to 0.2.3 in all packages...
|
|
201
|
-
|
|
202
|
-
Updated pubz: 0.2.2 -> 0.2.3
|
|
203
|
-
M package.json
|
|
204
|
-
Committing version bump...
|
|
205
|
-
[main 945e1a3] chore: release v0.2.3
|
|
206
|
-
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
207
|
-
Changes committed
|
|
195
|
+
Current version: 0.4.0
|
|
208
196
|
|
|
197
|
+
? Bump version before publishing? [Y/n] n
|
|
209
198
|
? Select publish target:
|
|
210
199
|
|
|
211
200
|
> 1) Public npm registry (https://registry.npmjs.org)
|
|
212
201
|
2) GitHub Packages (https://npm.pkg.github.com)
|
|
213
202
|
|
|
214
|
-
Enter choice [1-2] (default: 1):
|
|
203
|
+
Enter choice [1-2] (default: 1):
|
|
215
204
|
|
|
216
205
|
Publishing to: https://registry.npmjs.org
|
|
217
206
|
|
|
207
|
+
Verifying npm authentication...
|
|
208
|
+
Authenticated as zdavison
|
|
209
|
+
|
|
218
210
|
Step 2: Building Packages
|
|
219
211
|
──────────────────────────────
|
|
220
212
|
|
|
221
213
|
Running build...
|
|
222
214
|
|
|
223
215
|
$ bun build src/cli.ts --outdir dist --target node
|
|
224
|
-
Bundled
|
|
216
|
+
Bundled 10 modules in 5ms
|
|
225
217
|
|
|
226
|
-
cli.js
|
|
218
|
+
cli.js 41.27 KB (entry point)
|
|
227
219
|
|
|
228
220
|
|
|
229
221
|
Build completed successfully
|
|
@@ -237,46 +229,68 @@ Step 3: Publishing to npm
|
|
|
237
229
|
|
|
238
230
|
About to publish the following packages:
|
|
239
231
|
|
|
240
|
-
• pubz@0.
|
|
232
|
+
• pubz@0.4.0
|
|
241
233
|
|
|
242
234
|
Registry: https://registry.npmjs.org
|
|
243
235
|
|
|
244
|
-
? Continue? [Y/n]
|
|
236
|
+
? Continue? [Y/n]
|
|
237
|
+
|
|
238
|
+
Preparing packages for publish...
|
|
245
239
|
|
|
246
240
|
Publishing packages...
|
|
247
241
|
|
|
248
|
-
Publishing pubz@0.
|
|
249
|
-
npm notice
|
|
250
|
-
npm notice 📦 pubz@0.
|
|
251
|
-
npm notice Tarball Contents
|
|
252
|
-
npm notice
|
|
253
|
-
npm notice
|
|
254
|
-
npm notice
|
|
255
|
-
npm notice Tarball Details
|
|
256
|
-
npm notice name: pubz
|
|
257
|
-
npm notice version: 0.
|
|
258
|
-
npm notice filename: pubz-0.
|
|
259
|
-
npm notice package size:
|
|
260
|
-
npm notice unpacked size:
|
|
261
|
-
npm notice shasum:
|
|
262
|
-
npm notice integrity: sha512-
|
|
263
|
-
npm notice total files: 3
|
|
264
|
-
npm notice
|
|
265
|
-
|
|
242
|
+
Publishing pubz@0.4.0...
|
|
243
|
+
npm notice
|
|
244
|
+
npm notice 📦 pubz@0.4.0
|
|
245
|
+
npm notice === Tarball Contents ===
|
|
246
|
+
npm notice 7.1kB README.md
|
|
247
|
+
npm notice 41.3kB dist/cli.js
|
|
248
|
+
npm notice 697B package.json
|
|
249
|
+
npm notice === Tarball Details ===
|
|
250
|
+
npm notice name: pubz
|
|
251
|
+
npm notice version: 0.4.0
|
|
252
|
+
npm notice filename: pubz-0.4.0.tgz
|
|
253
|
+
npm notice package size: 12.0 kB
|
|
254
|
+
npm notice unpacked size: 49.1 kB
|
|
255
|
+
npm notice shasum: 3026a7936458dcaa84030a0ce2e206b9f74aa65d
|
|
256
|
+
npm notice integrity: sha512-6vKMOsC7sZa87[...]w8KNx1fD45u/A==
|
|
257
|
+
npm notice total files: 3
|
|
258
|
+
npm notice
|
|
259
|
+
npm notice Publishing to https://registry.npmjs.org/ with tag latest and public access
|
|
260
|
+
Authenticate your account at:
|
|
261
|
+
https://www.npmjs.com/auth/cli/c47d9bee-2a1e-4adf-9aab-63d15acfade2
|
|
262
|
+
Press ENTER to open in the browser...
|
|
263
|
+
|
|
264
|
+
+ pubz@0.4.0
|
|
266
265
|
pubz published successfully
|
|
267
266
|
|
|
268
267
|
══════════════════════════════
|
|
269
268
|
Publishing complete!
|
|
270
269
|
|
|
271
|
-
Published version: 0.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
270
|
+
Published version: 0.4.0
|
|
271
|
+
|
|
272
|
+
Changes since v0.2.12:
|
|
273
|
+
5553c95 Fix ENTER to open browser not working.
|
|
274
|
+
9aaddff Fix tag/push/release branch when using --yes.
|
|
275
|
+
0ce3ab8 Generate changlog and attach it to release page / print it out during publish.
|
|
276
|
+
5a29ca4 Merge branch 'main' of github.com:mm-zacharydavison/pubz
|
|
277
|
+
b4c47fc Clean up README.md formatting
|
|
278
|
+
2da403c Update README.md
|
|
279
|
+
88a4211 Update README with image and usage instructions
|
|
280
|
+
8a8148a Update README.md
|
|
281
|
+
2b45d21 Transform 'workspace:' definitions on publish, and restore them before any commit.
|
|
282
|
+
|
|
283
|
+
? Create a git tag for v0.4.0? [Y/n]
|
|
284
|
+
|
|
285
|
+
Tag v0.4.0 created
|
|
286
|
+
? Push tag to origin? [Y/n]
|
|
287
|
+
remote: This repository moved. Please use the new location:
|
|
288
|
+
remote: git@github.com:zdavison/pubz.git
|
|
277
289
|
To github.com:mm-zacharydavison/pubz.git
|
|
278
|
-
* [new tag] v0.
|
|
279
|
-
Tag v0.
|
|
290
|
+
* [new tag] v0.4.0 -> v0.4.0
|
|
291
|
+
Tag v0.4.0 pushed to origin
|
|
292
|
+
? Create a GitHub release? [Y/n]
|
|
293
|
+
Release created: https://github.com/zdavison/pubz/releases/tag/v0.4.0
|
|
280
294
|
|
|
281
295
|
Done!
|
|
282
296
|
```
|
package/dist/cli.js
CHANGED
|
@@ -195,6 +195,9 @@ function prompt(question) {
|
|
|
195
195
|
function closePrompt() {
|
|
196
196
|
rl.close();
|
|
197
197
|
}
|
|
198
|
+
function pausePrompt() {
|
|
199
|
+
rl.close();
|
|
200
|
+
}
|
|
198
201
|
function resetPrompt() {
|
|
199
202
|
rl.close();
|
|
200
203
|
rl = readline.createInterface({
|
|
@@ -317,10 +320,25 @@ async function multiSelect(message, options, allSelectedByDefault = true) {
|
|
|
317
320
|
|
|
318
321
|
// src/auth.ts
|
|
319
322
|
import { spawn } from "node:child_process";
|
|
323
|
+
import { homedir } from "node:os";
|
|
324
|
+
|
|
325
|
+
// src/log.ts
|
|
326
|
+
var verboseEnabled = false;
|
|
327
|
+
function setVerbose(enabled) {
|
|
328
|
+
verboseEnabled = enabled;
|
|
329
|
+
}
|
|
330
|
+
function debug(...args) {
|
|
331
|
+
if (verboseEnabled) {
|
|
332
|
+
console.error("[debug]", ...args);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/auth.ts
|
|
320
337
|
async function checkNpmAuth(registry) {
|
|
321
338
|
return new Promise((resolve2) => {
|
|
322
339
|
const proc = spawn("npm", ["whoami", "--registry", registry], {
|
|
323
|
-
stdio: ["
|
|
340
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
341
|
+
cwd: homedir()
|
|
324
342
|
});
|
|
325
343
|
let stdout = "";
|
|
326
344
|
let stderr = "";
|
|
@@ -334,6 +352,7 @@ async function checkNpmAuth(registry) {
|
|
|
334
352
|
if (code === 0 && stdout.trim()) {
|
|
335
353
|
resolve2({ authenticated: true, username: stdout.trim() });
|
|
336
354
|
} else {
|
|
355
|
+
debug(`npm whoami failed: code=${code}, stdout=${JSON.stringify(stdout)}, stderr=${JSON.stringify(stderr)}`);
|
|
337
356
|
resolve2({ authenticated: false });
|
|
338
357
|
}
|
|
339
358
|
});
|
|
@@ -341,10 +360,13 @@ async function checkNpmAuth(registry) {
|
|
|
341
360
|
}
|
|
342
361
|
async function npmLogin(registry) {
|
|
343
362
|
return new Promise((resolve2) => {
|
|
363
|
+
debug(`spawning: npm login --registry ${registry}`);
|
|
344
364
|
const proc = spawn("npm", ["login", "--registry", registry], {
|
|
345
|
-
stdio: "inherit"
|
|
365
|
+
stdio: "inherit",
|
|
366
|
+
cwd: homedir()
|
|
346
367
|
});
|
|
347
368
|
proc.on("close", (code) => {
|
|
369
|
+
debug(`npm login exited: code=${code}`);
|
|
348
370
|
if (code === 0) {
|
|
349
371
|
resolve2({ success: true });
|
|
350
372
|
} else {
|
|
@@ -357,6 +379,7 @@ async function npmLogin(registry) {
|
|
|
357
379
|
// src/publish.ts
|
|
358
380
|
import { spawn as spawn2 } from "node:child_process";
|
|
359
381
|
import { readFile as readFile2, stat as stat3 } from "node:fs/promises";
|
|
382
|
+
import { homedir as homedir2 } from "node:os";
|
|
360
383
|
import { join as join3 } from "node:path";
|
|
361
384
|
function run(command, args, cwd) {
|
|
362
385
|
return new Promise((resolve2) => {
|
|
@@ -455,7 +478,9 @@ async function publishPackage(pkg, registry, context, dryRun) {
|
|
|
455
478
|
let result;
|
|
456
479
|
if (context.useBrowserAuth) {
|
|
457
480
|
args.push("--auth-type", "web");
|
|
458
|
-
|
|
481
|
+
args.push(pkg.path);
|
|
482
|
+
context.onInteractiveStart?.();
|
|
483
|
+
const interactiveResult = await runInteractive(NPM_COMMAND, args, homedir2());
|
|
459
484
|
result = { code: interactiveResult.code, output: "" };
|
|
460
485
|
context.onInteractiveComplete?.();
|
|
461
486
|
} else {
|
|
@@ -535,6 +560,118 @@ async function pushGitTag(version, cwd, dryRun) {
|
|
|
535
560
|
return { success: true };
|
|
536
561
|
}
|
|
537
562
|
|
|
563
|
+
// src/changelog.ts
|
|
564
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
565
|
+
function parseGitRemoteUrl(remoteUrl) {
|
|
566
|
+
const sshMatch = remoteUrl.match(/^git@([^:]+):(.+?)(?:\.git)?$/);
|
|
567
|
+
if (sshMatch) {
|
|
568
|
+
return `https://${sshMatch[1]}/${sshMatch[2]}`;
|
|
569
|
+
}
|
|
570
|
+
const httpsMatch = remoteUrl.match(/^https?:\/\/([^/]+)\/(.+?)(?:\.git)?$/);
|
|
571
|
+
if (httpsMatch) {
|
|
572
|
+
return `https://${httpsMatch[1]}/${httpsMatch[2]}`;
|
|
573
|
+
}
|
|
574
|
+
return null;
|
|
575
|
+
}
|
|
576
|
+
function runSilent(command, args, cwd) {
|
|
577
|
+
return new Promise((resolve2) => {
|
|
578
|
+
const proc = spawn3(command, args, {
|
|
579
|
+
cwd,
|
|
580
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
581
|
+
});
|
|
582
|
+
let output = "";
|
|
583
|
+
proc.stdout?.on("data", (data) => {
|
|
584
|
+
output += data.toString();
|
|
585
|
+
});
|
|
586
|
+
proc.stderr?.on("data", (data) => {
|
|
587
|
+
output += data.toString();
|
|
588
|
+
});
|
|
589
|
+
proc.on("close", (code) => {
|
|
590
|
+
resolve2({ code: code ?? 1, output });
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
async function getPreviousTag(cwd) {
|
|
595
|
+
const result = await runSilent("git", ["tag", "--sort=-version:refname"], cwd);
|
|
596
|
+
if (result.code !== 0)
|
|
597
|
+
return null;
|
|
598
|
+
const tags = result.output.trim().split(`
|
|
599
|
+
`).filter((t) => t.length > 0);
|
|
600
|
+
return tags[0] ?? null;
|
|
601
|
+
}
|
|
602
|
+
async function getRepoUrl(cwd) {
|
|
603
|
+
const result = await runSilent("git", ["remote", "get-url", "origin"], cwd);
|
|
604
|
+
if (result.code !== 0)
|
|
605
|
+
return null;
|
|
606
|
+
return parseGitRemoteUrl(result.output.trim());
|
|
607
|
+
}
|
|
608
|
+
async function getCommitsSince(ref, cwd) {
|
|
609
|
+
const result = await runSilent("git", ["log", `${ref}..HEAD`, "--oneline", "--no-decorate"], cwd);
|
|
610
|
+
if (result.code !== 0)
|
|
611
|
+
return [];
|
|
612
|
+
return result.output.trim().split(`
|
|
613
|
+
`).filter((line) => line.length > 0).map((line) => {
|
|
614
|
+
const spaceIdx = line.indexOf(" ");
|
|
615
|
+
return {
|
|
616
|
+
sha: line.slice(0, spaceIdx),
|
|
617
|
+
message: line.slice(spaceIdx + 1)
|
|
618
|
+
};
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
function isReleaseCommit(message) {
|
|
622
|
+
return /^chore: release v/.test(message);
|
|
623
|
+
}
|
|
624
|
+
function formatChangelogTerminal(commits) {
|
|
625
|
+
const filtered = commits.filter((c) => !isReleaseCommit(c.message));
|
|
626
|
+
if (filtered.length === 0)
|
|
627
|
+
return "";
|
|
628
|
+
return filtered.map((c) => ` ${dim(c.sha)} ${c.message}`).join(`
|
|
629
|
+
`);
|
|
630
|
+
}
|
|
631
|
+
function formatChangelogMarkdown(commits, repoUrl) {
|
|
632
|
+
const filtered = commits.filter((c) => !isReleaseCommit(c.message));
|
|
633
|
+
if (filtered.length === 0)
|
|
634
|
+
return "";
|
|
635
|
+
return filtered.map((c) => {
|
|
636
|
+
const shaRef = repoUrl ? `[\`${c.sha}\`](${repoUrl}/commit/${c.sha})` : `\`${c.sha}\``;
|
|
637
|
+
return `- ${shaRef} ${c.message}`;
|
|
638
|
+
}).join(`
|
|
639
|
+
`);
|
|
640
|
+
}
|
|
641
|
+
async function fetchTags(cwd) {
|
|
642
|
+
await runSilent("git", ["fetch", "--tags"], cwd);
|
|
643
|
+
}
|
|
644
|
+
async function generateChangelog(cwd) {
|
|
645
|
+
await fetchTags(cwd);
|
|
646
|
+
const [previousTag, repoUrl] = await Promise.all([
|
|
647
|
+
getPreviousTag(cwd),
|
|
648
|
+
getRepoUrl(cwd)
|
|
649
|
+
]);
|
|
650
|
+
if (!previousTag) {
|
|
651
|
+
return { commits: [], terminal: "", markdown: "", previousTag: null, repoUrl };
|
|
652
|
+
}
|
|
653
|
+
const commits = await getCommitsSince(previousTag, cwd);
|
|
654
|
+
const terminal = formatChangelogTerminal(commits);
|
|
655
|
+
const markdown = formatChangelogMarkdown(commits, repoUrl);
|
|
656
|
+
return { commits, terminal, markdown, previousTag, repoUrl };
|
|
657
|
+
}
|
|
658
|
+
async function createGitHubRelease(version, body, cwd, dryRun) {
|
|
659
|
+
const tagName = `v${version}`;
|
|
660
|
+
if (dryRun) {
|
|
661
|
+
console.log(`[DRY RUN] Would create GitHub release for ${tagName}`);
|
|
662
|
+
return { success: true };
|
|
663
|
+
}
|
|
664
|
+
const result = await runSilent("gh", ["release", "create", tagName, "--title", tagName, "--notes", body], cwd);
|
|
665
|
+
if (result.code !== 0) {
|
|
666
|
+
return {
|
|
667
|
+
success: false,
|
|
668
|
+
error: result.output.trim() || `Failed to create GitHub release for ${tagName}`
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
const url = result.output.trim();
|
|
672
|
+
return { success: true, url };
|
|
673
|
+
}
|
|
674
|
+
|
|
538
675
|
// src/version.ts
|
|
539
676
|
import { readFile as readFile3, writeFile } from "node:fs/promises";
|
|
540
677
|
async function transformWorkspaceProtocolForPublish(packages, newVersion, dryRun) {
|
|
@@ -605,6 +742,9 @@ async function restoreWorkspaceProtocol(transforms) {
|
|
|
605
742
|
console.log(` Restored workspace references in ${byPath.size} package(s)`);
|
|
606
743
|
}
|
|
607
744
|
}
|
|
745
|
+
function isValidVersion(version) {
|
|
746
|
+
return /^\d+\.\d+\.\d+(-.+)?$/.test(version);
|
|
747
|
+
}
|
|
608
748
|
function bumpVersion(version, type) {
|
|
609
749
|
if (type === "none")
|
|
610
750
|
return version;
|
|
@@ -702,6 +842,7 @@ Options:
|
|
|
702
842
|
--yes, -y Skip yes/no confirmation prompts (still asks for choices)
|
|
703
843
|
--ci CI mode: skip all prompts, auto-accept everything
|
|
704
844
|
--version <value> Version bump type (patch|minor|major) or explicit version (required with --ci)
|
|
845
|
+
--verbose Show debug logging
|
|
705
846
|
-h, --help Show this help message
|
|
706
847
|
|
|
707
848
|
Examples:
|
|
@@ -721,6 +862,7 @@ function parseArgs(args) {
|
|
|
721
862
|
skipConfirms: false,
|
|
722
863
|
ci: false,
|
|
723
864
|
version: "",
|
|
865
|
+
verbose: false,
|
|
724
866
|
help: false
|
|
725
867
|
};
|
|
726
868
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -748,6 +890,9 @@ function parseArgs(args) {
|
|
|
748
890
|
case "--version":
|
|
749
891
|
options.version = args[++i] || "";
|
|
750
892
|
break;
|
|
893
|
+
case "--verbose":
|
|
894
|
+
options.verbose = true;
|
|
895
|
+
break;
|
|
751
896
|
case "-h":
|
|
752
897
|
case "--help":
|
|
753
898
|
options.help = true;
|
|
@@ -762,6 +907,7 @@ async function main() {
|
|
|
762
907
|
process.exit(0);
|
|
763
908
|
}
|
|
764
909
|
const options = parseArgs(process.argv.slice(2));
|
|
910
|
+
setVerbose(options.verbose);
|
|
765
911
|
if (options.help) {
|
|
766
912
|
printUsage();
|
|
767
913
|
process.exit(0);
|
|
@@ -849,7 +995,13 @@ async function main() {
|
|
|
849
995
|
newVersion = bumpVersion(currentVersion, options.version);
|
|
850
996
|
console.log(`Bumping version (${options.version}): ${yellow(currentVersion)} → ${green(newVersion)}`);
|
|
851
997
|
} else {
|
|
852
|
-
|
|
998
|
+
const cleaned = options.version.startsWith("v") ? options.version.slice(1) : options.version;
|
|
999
|
+
if (!isValidVersion(cleaned)) {
|
|
1000
|
+
console.error(red(bold("Error:")) + ` Invalid version "${options.version}". Expected format: major.minor.patch (e.g. 1.2.3, 1.2.3-beta)`);
|
|
1001
|
+
closePrompt();
|
|
1002
|
+
process.exit(1);
|
|
1003
|
+
}
|
|
1004
|
+
newVersion = cleaned;
|
|
853
1005
|
console.log(`Using explicit version: ${green(newVersion)}`);
|
|
854
1006
|
}
|
|
855
1007
|
console.log("");
|
|
@@ -872,7 +1024,7 @@ async function main() {
|
|
|
872
1024
|
} else if (!skipAllPrompts) {
|
|
873
1025
|
const shouldBump = skipConfirms || await confirm("Bump version before publishing?");
|
|
874
1026
|
if (shouldBump) {
|
|
875
|
-
const
|
|
1027
|
+
const bumpChoice = await select("Select version bump type:", [
|
|
876
1028
|
{
|
|
877
1029
|
label: `patch (${previewBump(currentVersion, "patch")})`,
|
|
878
1030
|
value: "patch"
|
|
@@ -884,9 +1036,27 @@ async function main() {
|
|
|
884
1036
|
{
|
|
885
1037
|
label: `major (${previewBump(currentVersion, "major")})`,
|
|
886
1038
|
value: "major"
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
label: "custom version",
|
|
1042
|
+
value: "custom"
|
|
887
1043
|
}
|
|
888
1044
|
]);
|
|
889
|
-
|
|
1045
|
+
if (bumpChoice === "custom") {
|
|
1046
|
+
let customVersion = "";
|
|
1047
|
+
while (!customVersion) {
|
|
1048
|
+
const input = await prompt(` Enter version: `);
|
|
1049
|
+
const cleaned = input.startsWith("v") ? input.slice(1) : input;
|
|
1050
|
+
if (isValidVersion(cleaned)) {
|
|
1051
|
+
customVersion = cleaned;
|
|
1052
|
+
} else {
|
|
1053
|
+
console.log(yellow(" Invalid version. Expected format: major.minor.patch (e.g. 1.2.3, 1.2.3-beta)"));
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
newVersion = customVersion;
|
|
1057
|
+
} else {
|
|
1058
|
+
newVersion = bumpVersion(currentVersion, bumpChoice);
|
|
1059
|
+
}
|
|
890
1060
|
console.log("");
|
|
891
1061
|
console.log(`Updating version to ${green(newVersion)} in all packages...`);
|
|
892
1062
|
console.log("");
|
|
@@ -930,7 +1100,9 @@ async function main() {
|
|
|
930
1100
|
console.log("");
|
|
931
1101
|
console.log(yellow("Not logged in to npm.") + " Starting login...");
|
|
932
1102
|
console.log("");
|
|
1103
|
+
pausePrompt();
|
|
933
1104
|
const loginResult = await npmLogin(registry);
|
|
1105
|
+
resetPrompt();
|
|
934
1106
|
if (!loginResult.success) {
|
|
935
1107
|
console.error(red(bold("Login failed:")) + ` ${loginResult.error}`);
|
|
936
1108
|
closePrompt();
|
|
@@ -1014,6 +1186,7 @@ async function main() {
|
|
|
1014
1186
|
const publishContext = {
|
|
1015
1187
|
otp: options.otp,
|
|
1016
1188
|
useBrowserAuth: !options.ci,
|
|
1189
|
+
onInteractiveStart: pausePrompt,
|
|
1017
1190
|
onInteractiveComplete: resetPrompt
|
|
1018
1191
|
};
|
|
1019
1192
|
let publishFailed = false;
|
|
@@ -1052,27 +1225,52 @@ async function main() {
|
|
|
1052
1225
|
console.log("");
|
|
1053
1226
|
console.log(`Published version: ${green(bold(newVersion))}`);
|
|
1054
1227
|
console.log("");
|
|
1228
|
+
const changelog = await generateChangelog(cwd);
|
|
1229
|
+
if (changelog.terminal) {
|
|
1230
|
+
console.log(bold("Changes since ") + cyan(changelog.previousTag ?? "initial") + bold(":"));
|
|
1231
|
+
console.log(changelog.terminal);
|
|
1232
|
+
console.log("");
|
|
1233
|
+
}
|
|
1055
1234
|
if (!options.dryRun) {
|
|
1056
1235
|
if (options.ci) {
|
|
1057
|
-
console.log("");
|
|
1058
1236
|
console.log(cyan("Creating git tag..."));
|
|
1059
1237
|
const tagResult = await createGitTag(newVersion, cwd, options.dryRun);
|
|
1060
1238
|
if (tagResult.success) {
|
|
1061
1239
|
console.log(cyan("Pushing tag to origin..."));
|
|
1062
1240
|
await pushGitTag(newVersion, cwd, options.dryRun);
|
|
1241
|
+
if (changelog.markdown) {
|
|
1242
|
+
console.log(cyan("Creating GitHub release..."));
|
|
1243
|
+
const releaseResult = await createGitHubRelease(newVersion, changelog.markdown, cwd, options.dryRun);
|
|
1244
|
+
if (releaseResult.success && releaseResult.url) {
|
|
1245
|
+
console.log(` Release created: ${cyan(releaseResult.url)}`);
|
|
1246
|
+
} else if (!releaseResult.success) {
|
|
1247
|
+
console.error(yellow(releaseResult.error ?? "Failed to create GitHub release"));
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1063
1250
|
} else {
|
|
1064
1251
|
console.error(red(tagResult.error ?? "Failed to create git tag"));
|
|
1065
1252
|
}
|
|
1066
1253
|
console.log("");
|
|
1067
|
-
} else
|
|
1068
|
-
const shouldTag = await confirm(`Create a git tag for ${cyan(`v${newVersion}`)}?`);
|
|
1254
|
+
} else {
|
|
1255
|
+
const shouldTag = skipConfirms || await confirm(`Create a git tag for ${cyan(`v${newVersion}`)}?`);
|
|
1069
1256
|
if (shouldTag) {
|
|
1070
1257
|
console.log("");
|
|
1071
1258
|
const tagResult = await createGitTag(newVersion, cwd, options.dryRun);
|
|
1072
1259
|
if (tagResult.success) {
|
|
1073
|
-
const shouldPush = await confirm("Push tag to origin?");
|
|
1260
|
+
const shouldPush = skipConfirms || await confirm("Push tag to origin?");
|
|
1074
1261
|
if (shouldPush) {
|
|
1075
1262
|
await pushGitTag(newVersion, cwd, options.dryRun);
|
|
1263
|
+
if (changelog.markdown) {
|
|
1264
|
+
const shouldRelease = skipConfirms || await confirm("Create a GitHub release?");
|
|
1265
|
+
if (shouldRelease) {
|
|
1266
|
+
const releaseResult = await createGitHubRelease(newVersion, changelog.markdown, cwd, options.dryRun);
|
|
1267
|
+
if (releaseResult.success && releaseResult.url) {
|
|
1268
|
+
console.log(` Release created: ${cyan(releaseResult.url)}`);
|
|
1269
|
+
} else if (!releaseResult.success) {
|
|
1270
|
+
console.error(yellow(releaseResult.error ?? "Failed to create GitHub release"));
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1076
1274
|
} else {
|
|
1077
1275
|
console.log(`Tag created locally. Push manually with: ${dim(`git push origin v${newVersion}`)}`);
|
|
1078
1276
|
}
|