pubz 0.2.2 → 0.2.4

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 (3) hide show
  1. package/README.md +221 -57
  2. package/dist/cli.js +82 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -6,113 +6,277 @@ bunx pubz
6
6
 
7
7
  `pubz` publishes multiple packages in one command, with some useful steps:
8
8
 
9
- 1. Prompts you to bump version number of packages.
10
- 2. Prompts you for where you want to publish (e.g. `npm` or private registry).
11
- 3. Prompts you to create a `git tag` and push it.
12
-
13
- # Example
9
+ 1. Discovers all publishable packages (supports monorepos)
10
+ 2. Sorts packages by dependency order
11
+ 3. Prompts you to select which packages to publish
12
+ 4. Prompts you to bump version number of packages
13
+ 5. Updates inter-package dependency versions
14
+ 6. Commits version changes
15
+ 7. Prompts you for where you want to publish (e.g. `npm` or private registry)
16
+ 8. Builds packages
17
+ 9. Publishes to npm
18
+ 10. Prompts you to create a `git tag` and push it
19
+
20
+ ## Options
21
+
22
+ | Flag | Description |
23
+ | ---------------------- | ------------------------------------------------------------------------ |
24
+ | `--dry-run` | Show what would be published without actually publishing |
25
+ | `--registry <url>` | Specify npm registry URL (default: public npm) |
26
+ | `--otp <code>` | One-time password for 2FA |
27
+ | `--skip-build` | Skip the build step |
28
+ | `--yes`, `-y` | Skip yes/no confirmation prompts (still asks for choices) |
29
+ | `--ci` | CI mode: skip all prompts, auto-accept everything (requires `--version`) |
30
+ | `--version <value>` | Version bump type (`patch`, `minor`, `major`) or explicit version |
31
+ | `-h`, `--help` | Show help message |
32
+
33
+ ## Examples
34
+
35
+ ### Interactive publish
14
36
 
15
37
  ```bash
16
38
  bunx pubz
17
39
  ```
18
40
 
41
+ ### Preview changes (dry run)
42
+
43
+ ```bash
44
+ bunx pubz --dry-run
45
+ ```
46
+
47
+ ### Quick publish with confirmations auto-accepted
48
+
49
+ ```bash
50
+ bunx pubz --yes
51
+ ```
52
+
53
+ ### Publish to GitHub Packages
54
+
55
+ ```bash
56
+ bunx pubz --registry https://npm.pkg.github.com
57
+ ```
58
+
59
+ ### CI mode with version bump
60
+
61
+ ```bash
62
+ bunx pubz --ci --version patch
63
+ bunx pubz --ci --version minor
64
+ bunx pubz --ci --version major
65
+ ```
66
+
67
+ ### CI mode with explicit version
68
+
69
+ ```bash
70
+ bunx pubz --ci --version 1.2.3
71
+ ```
72
+
73
+ ## GitHub Actions
74
+
75
+ Here's an example workflow for publishing with `pubz`, using an input selector for patch/minor/major version bump.
76
+
77
+ ### Using NPM_TOKEN (classic)
78
+
79
+ ```yaml
80
+ name: Publish
81
+
82
+ on:
83
+ workflow_dispatch:
84
+ inputs:
85
+ version:
86
+ description: 'Version bump type or explicit version'
87
+ required: true
88
+ type: choice
89
+ options:
90
+ - patch
91
+ - minor
92
+ - major
93
+
94
+ jobs:
95
+ publish:
96
+ runs-on: ubuntu-latest
97
+ steps:
98
+ - uses: actions/checkout@v4
99
+
100
+ - uses: oven-sh/setup-bun@v2
101
+
102
+ - run: bun install
103
+
104
+ - name: Configure git
105
+ run: |
106
+ git config user.name "github-actions[bot]"
107
+ git config user.email "github-actions[bot]@users.noreply.github.com"
108
+
109
+ - name: Configure npm
110
+ run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
111
+
112
+ - name: Publish
113
+ run: bunx pubz --ci --version ${{ inputs.version }}
114
+
115
+ - name: Push changes
116
+ run: git push && git push --tags
117
+ ```
118
+
119
+ ### Using OIDC Trusted Publishing (recommended)
120
+
121
+ Trusted publishing uses OpenID Connect to authenticate with npm without storing long-lived tokens. First, configure your package on npmjs.com:
122
+
123
+ 1. Go to your package → Settings → Trusted Publishers
124
+ 2. Add your GitHub repository and workflow file name
125
+
126
+ ```yaml
127
+ name: Publish
128
+
129
+ on:
130
+ workflow_dispatch:
131
+ inputs:
132
+ version:
133
+ description: 'Version bump type or explicit version'
134
+ required: true
135
+ type: choice
136
+ options:
137
+ - patch
138
+ - minor
139
+ - major
140
+
141
+ jobs:
142
+ publish:
143
+ runs-on: ubuntu-latest
144
+ permissions:
145
+ contents: write
146
+ id-token: write
147
+ steps:
148
+ - uses: actions/checkout@v4
149
+
150
+ - uses: oven-sh/setup-bun@v2
151
+
152
+ - uses: actions/setup-node@v4
153
+ with:
154
+ registry-url: 'https://registry.npmjs.org'
155
+
156
+ - run: bun install
157
+
158
+ - name: Configure git
159
+ run: |
160
+ git config user.name "github-actions[bot]"
161
+ git config user.email "github-actions[bot]@users.noreply.github.com"
162
+
163
+ - name: Publish
164
+ run: bunx pubz --ci --version ${{ inputs.version }}
165
+
166
+ - name: Push changes
167
+ run: git push && git push --tags
168
+ ```
169
+
170
+ ## Example Output
171
+
19
172
  ```bash
173
+ bunx pubz
174
+ ```
175
+
176
+ ```
20
177
  pubz - npm package publisher
21
- =============================
178
+ ══════════════════════════════
22
179
 
23
180
  Discovering packages...
24
181
 
25
182
  Found 1 publishable package(s):
26
183
 
27
- - pubz@0.1.0
184
+ pubz@0.2.2
28
185
 
29
186
  Step 1: Version Management
30
- --------------------------
187
+ ──────────────────────────────
188
+
189
+ Current version: 0.2.2
190
+
191
+ ? Bump version before publishing? [Y/n]
192
+ ? Select version bump type:
31
193
 
32
- Current version: 0.1.0
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
33
208
 
34
- Bump version before publishing? [y/N] n
35
- Select publish target:
209
+ ? Select publish target:
36
210
 
37
211
  > 1) Public npm registry (https://registry.npmjs.org)
38
212
  2) GitHub Packages (https://npm.pkg.github.com)
39
213
 
40
- Enter choice [1-2] (default: 1): 1
214
+ Enter choice [1-2] (default: 1):
41
215
 
42
216
  Publishing to: https://registry.npmjs.org
43
217
 
44
218
  Step 2: Building Packages
45
- -------------------------
219
+ ──────────────────────────────
46
220
 
47
221
  Running build...
48
222
 
49
223
  $ bun build src/cli.ts --outdir dist --target node
50
- Bundled 6 modules in 4ms
224
+ Bundled 7 modules in 7ms
225
+
226
+ cli.js 28.65 KB (entry point)
51
227
 
52
- cli.js 20.0 KB (entry point)
53
228
 
54
229
  Build completed successfully
55
230
 
56
231
  Verifying builds...
57
232
 
58
- pubz build verified
233
+ pubz build verified
59
234
 
60
235
  Step 3: Publishing to npm
61
- -------------------------
236
+ ──────────────────────────────
62
237
 
63
238
  About to publish the following packages:
64
239
 
65
- pubz@0.1.0
240
+ pubz@0.2.3
66
241
 
67
242
  Registry: https://registry.npmjs.org
68
243
 
69
- Continue? [y/N] y
244
+ ? Continue? [Y/n]
70
245
 
71
246
  Publishing packages...
72
247
 
73
- Publishing pubz@0.1.0...
74
- bun publish v1.3.2 (b131639c)
75
-
76
- packed 0.70KB package.json
77
- packed 322B README.md
78
- packed 20.0KB dist/cli.js
79
-
80
- Total files: 3
81
- Shasum: 0494617a65c8a92d8a2c43d115dea0f94919102f
82
- Integrity: sha512-KLEM/H7EOadzz[...]c1up2JcHW9gcQ==
83
- Unpacked size: 21.1KB
84
- Packed size: 5.73KB
85
- Tag: latest
86
- Access: public
87
- Registry: https://registry.npmjs.org
88
-
89
- + pubz@0.1.0
248
+ Publishing pubz@0.2.3...
249
+ npm notice
250
+ npm notice 📦 pubz@0.2.3
251
+ npm notice Tarball Contents
252
+ npm notice 717B package.json
253
+ npm notice 2.3kB README.md
254
+ npm notice 28.7kB dist/cli.js
255
+ npm notice Tarball Details
256
+ npm notice name: pubz
257
+ npm notice version: 0.2.3
258
+ npm notice filename: pubz-0.2.3.tgz
259
+ npm notice package size: 8.3 kB
260
+ npm notice unpacked size: 31.6 kB
261
+ npm notice shasum: b8cd25d62b05d5cd6a4ecc8ff6ef6e522e7b2aa5
262
+ npm notice integrity: sha512-jihTMvUxMeXNX[...]2+gtHJexETkWA==
263
+ npm notice total files: 3
264
+ npm notice
265
+ + pubz@0.2.3
90
266
  pubz published successfully
91
267
 
92
- ==================================
268
+ ══════════════════════════════
93
269
  Publishing complete!
94
270
 
95
- Published version: 0.1.0
96
-
97
- Create a git tag for v0.1.0? [y/N] y
271
+ Published version: 0.2.3
98
272
 
99
- A .npmrc
100
- M README.md
101
- M package.json
102
- M src/cli.ts
103
- M src/publish.ts
104
- M src/types.ts
105
- Uncommitted changes detected. Committing...
106
- error: pathspec 'release' did not match any file(s) known to git
107
- error: pathspec 'v0.1.0' did not match any file(s) known to git
108
- Changes committed
109
- Tag v0.1.0 created
110
- Push tag to origin? [y/N] y
111
- fatal: 'origin' does not appear to be a git repository
112
- fatal: Could not read from remote repository.
273
+ ? Create a git tag for v0.2.3? [Y/n]
113
274
 
114
- Please make sure you have the correct access rights
115
- and the repository exists.
275
+ Tag v0.2.3 created
276
+ ? Push tag to origin? [Y/n]
277
+ To github.com:mm-zacharydavison/pubz.git
278
+ * [new tag] v0.2.3 -> v0.2.3
279
+ Tag v0.2.3 pushed to origin
116
280
 
117
281
  Done!
118
- ```
282
+ ```
package/dist/cli.js CHANGED
@@ -386,7 +386,7 @@ async function publishPackage(pkg, registry, otp, dryRun) {
386
386
  if (otp) {
387
387
  args.push("--otp", otp);
388
388
  }
389
- const result = await run("bun", args, pkg.path);
389
+ const result = await run("npm", args, pkg.path);
390
390
  if (result.code !== 0) {
391
391
  return { success: false, error: `Failed to publish ${pkg.name}` };
392
392
  }
@@ -539,13 +539,17 @@ Options:
539
539
  --registry <url> Specify npm registry URL (default: public npm)
540
540
  --otp <code> One-time password for 2FA
541
541
  --skip-build Skip the build step
542
- --yes, -y Skip confirmation prompts (use defaults)
542
+ --yes, -y Skip yes/no confirmation prompts (still asks for choices)
543
+ --ci CI mode: skip all prompts, auto-accept everything
544
+ --version <value> Version bump type (patch|minor|major) or explicit version (required with --ci)
543
545
  -h, --help Show this help message
544
546
 
545
547
  Examples:
546
548
  pubz # Interactive publish
547
549
  pubz --dry-run # Preview what would happen
548
550
  pubz --registry https://npm.pkg.github.com # Publish to GitHub Packages
551
+ pubz --ci --version patch # CI mode with patch bump
552
+ pubz --ci --version 1.2.3 # CI mode with explicit version
549
553
  `);
550
554
  }
551
555
  function parseArgs(args) {
@@ -554,7 +558,9 @@ function parseArgs(args) {
554
558
  registry: "",
555
559
  otp: "",
556
560
  skipBuild: false,
557
- skipPrompts: false,
561
+ skipConfirms: false,
562
+ ci: false,
563
+ version: "",
558
564
  help: false
559
565
  };
560
566
  for (let i = 0;i < args.length; i++) {
@@ -574,7 +580,13 @@ function parseArgs(args) {
574
580
  break;
575
581
  case "--yes":
576
582
  case "-y":
577
- options.skipPrompts = true;
583
+ options.skipConfirms = true;
584
+ break;
585
+ case "--ci":
586
+ options.ci = true;
587
+ break;
588
+ case "--version":
589
+ options.version = args[++i] || "";
578
590
  break;
579
591
  case "-h":
580
592
  case "--help":
@@ -590,6 +602,18 @@ async function main() {
590
602
  printUsage();
591
603
  process.exit(0);
592
604
  }
605
+ if (options.ci && !options.version) {
606
+ console.error(red(bold("Error:")) + " --ci requires --version to be specified");
607
+ console.log("");
608
+ console.log(muted("Examples:"));
609
+ console.log(muted(" pubz --ci --version patch"));
610
+ console.log(muted(" pubz --ci --version minor"));
611
+ console.log(muted(" pubz --ci --version major"));
612
+ console.log(muted(" pubz --ci --version 1.2.3"));
613
+ process.exit(1);
614
+ }
615
+ const skipConfirms = options.skipConfirms || options.ci;
616
+ const skipAllPrompts = options.ci;
593
617
  const cwd = process.cwd();
594
618
  if (options.dryRun) {
595
619
  console.log(yellow(bold("DRY RUN MODE")) + dim(" - No actual changes will be made"));
@@ -634,7 +658,7 @@ async function main() {
634
658
  console.log(` ${dim("•")} ${cyan(pkg.name)}${dim("@")}${yellow(pkg.version)}${deps}`);
635
659
  }
636
660
  console.log("");
637
- if (packages.length > 1 && !options.skipPrompts) {
661
+ if (packages.length > 1 && !skipAllPrompts) {
638
662
  const selectedPackages = await multiSelect("Select packages to publish:", packages.map((pkg) => ({
639
663
  label: `${pkg.name}@${pkg.version}`,
640
664
  value: pkg
@@ -654,8 +678,35 @@ async function main() {
654
678
  console.log(`Current version: ${yellow(currentVersion)}`);
655
679
  console.log("");
656
680
  let newVersion = currentVersion;
657
- if (!options.skipPrompts) {
658
- const shouldBump = await confirm("Bump version before publishing?");
681
+ if (options.version) {
682
+ const bumpTypes = ["patch", "minor", "major"];
683
+ const isBumpType = bumpTypes.includes(options.version);
684
+ if (isBumpType) {
685
+ newVersion = bumpVersion(currentVersion, options.version);
686
+ console.log(`Bumping version (${options.version}): ${yellow(currentVersion)} → ${green(newVersion)}`);
687
+ } else {
688
+ newVersion = options.version;
689
+ console.log(`Using explicit version: ${green(newVersion)}`);
690
+ }
691
+ console.log("");
692
+ console.log(`Updating version to ${green(newVersion)} in all packages...`);
693
+ console.log("");
694
+ for (const pkg of packages) {
695
+ await updatePackageVersion(pkg, newVersion, options.dryRun);
696
+ }
697
+ await updateLocalDependencyVersions(packages, newVersion, options.dryRun);
698
+ for (const pkg of packages) {
699
+ pkg.version = newVersion;
700
+ }
701
+ const commitResult = await commitVersionBump(newVersion, cwd, options.dryRun);
702
+ if (!commitResult.success) {
703
+ console.error(red(bold("Failed to commit version bump:")) + ` ${commitResult.error}`);
704
+ closePrompt();
705
+ process.exit(1);
706
+ }
707
+ console.log("");
708
+ } else if (!skipAllPrompts) {
709
+ const shouldBump = skipConfirms || await confirm("Bump version before publishing?");
659
710
  if (shouldBump) {
660
711
  const bumpType = await select("Select version bump type:", [
661
712
  {
@@ -692,7 +743,7 @@ async function main() {
692
743
  }
693
744
  }
694
745
  let registry = options.registry;
695
- if (!registry && !options.skipPrompts) {
746
+ if (!registry && !skipAllPrompts) {
696
747
  registry = await select("Select publish target:", [
697
748
  {
698
749
  label: "Public npm registry (https://registry.npmjs.org)",
@@ -758,7 +809,7 @@ async function main() {
758
809
  console.log("");
759
810
  console.log(`Registry: ${cyan(registry)}`);
760
811
  console.log("");
761
- if (!options.skipPrompts) {
812
+ if (!skipConfirms) {
762
813
  const shouldContinue = await confirm("Continue?");
763
814
  if (!shouldContinue) {
764
815
  console.log(yellow("Publish cancelled."));
@@ -786,22 +837,35 @@ async function main() {
786
837
  console.log("");
787
838
  console.log(`Published version: ${green(bold(newVersion))}`);
788
839
  console.log("");
789
- if (!options.dryRun && !options.skipPrompts) {
790
- const shouldTag = await confirm(`Create a git tag for ${cyan(`v${newVersion}`)}?`);
791
- if (shouldTag) {
840
+ if (!options.dryRun) {
841
+ if (options.ci) {
792
842
  console.log("");
843
+ console.log(cyan("Creating git tag..."));
793
844
  const tagResult = await createGitTag(newVersion, cwd, options.dryRun);
794
845
  if (tagResult.success) {
795
- const shouldPush = await confirm("Push tag to origin?");
796
- if (shouldPush) {
797
- await pushGitTag(newVersion, cwd, options.dryRun);
798
- } else {
799
- console.log(`Tag created locally. Push manually with: ${dim(`git push origin v${newVersion}`)}`);
800
- }
846
+ console.log(cyan("Pushing tag to origin..."));
847
+ await pushGitTag(newVersion, cwd, options.dryRun);
801
848
  } else {
802
849
  console.error(red(tagResult.error ?? "Failed to create git tag"));
803
850
  }
804
851
  console.log("");
852
+ } else if (!skipConfirms) {
853
+ const shouldTag = await confirm(`Create a git tag for ${cyan(`v${newVersion}`)}?`);
854
+ if (shouldTag) {
855
+ console.log("");
856
+ const tagResult = await createGitTag(newVersion, cwd, options.dryRun);
857
+ if (tagResult.success) {
858
+ const shouldPush = await confirm("Push tag to origin?");
859
+ if (shouldPush) {
860
+ await pushGitTag(newVersion, cwd, options.dryRun);
861
+ } else {
862
+ console.log(`Tag created locally. Push manually with: ${dim(`git push origin v${newVersion}`)}`);
863
+ }
864
+ } else {
865
+ console.error(red(tagResult.error ?? "Failed to create git tag"));
866
+ }
867
+ console.log("");
868
+ }
805
869
  }
806
870
  }
807
871
  console.log(green(bold("Done!")));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pubz",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Interactive CLI for publishing npm packages (single or monorepo)",
5
5
  "type": "module",
6
6
  "bin": {