pubz 0.7.3 → 0.7.5
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/dist/cli.js +175 -111
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -47,24 +47,92 @@ function frameLine(text = "") {
|
|
|
47
47
|
|
|
48
48
|
// src/discovery.ts
|
|
49
49
|
import { readFile, readdir as readdir2, stat as stat2 } from "node:fs/promises";
|
|
50
|
-
import { join as
|
|
50
|
+
import { join as join3, resolve } from "node:path";
|
|
51
|
+
|
|
52
|
+
// src/config.ts
|
|
53
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
54
|
+
import { join } from "node:path";
|
|
55
|
+
|
|
56
|
+
// src/log.ts
|
|
57
|
+
var verboseEnabled = false;
|
|
58
|
+
function setVerbose(enabled) {
|
|
59
|
+
verboseEnabled = enabled;
|
|
60
|
+
}
|
|
61
|
+
function debug(...args) {
|
|
62
|
+
if (verboseEnabled) {
|
|
63
|
+
console.error("[debug]", ...args);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/config.ts
|
|
68
|
+
var CONFIG_FILENAME = ".pubz";
|
|
69
|
+
var VALID_KEYS = new Set(["skip-build", "skip-publish", "always-publish", "registry"]);
|
|
70
|
+
function loadConfig(cwd) {
|
|
71
|
+
const configPath = join(cwd, CONFIG_FILENAME);
|
|
72
|
+
if (!existsSync(configPath)) {
|
|
73
|
+
debug(`No ${CONFIG_FILENAME} found at ${configPath}`);
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
const content = readFileSync(configPath, "utf-8");
|
|
77
|
+
const config = {};
|
|
78
|
+
for (const rawLine of content.split(`
|
|
79
|
+
`)) {
|
|
80
|
+
const line = rawLine.trim();
|
|
81
|
+
if (!line || line.startsWith("#"))
|
|
82
|
+
continue;
|
|
83
|
+
const eqIndex = line.indexOf("=");
|
|
84
|
+
let key;
|
|
85
|
+
let value;
|
|
86
|
+
if (eqIndex === -1) {
|
|
87
|
+
key = line;
|
|
88
|
+
} else {
|
|
89
|
+
key = line.slice(0, eqIndex).trim();
|
|
90
|
+
value = line.slice(eqIndex + 1).trim();
|
|
91
|
+
}
|
|
92
|
+
if (!VALID_KEYS.has(key)) {
|
|
93
|
+
debug(`Ignoring unknown config key: ${key}`);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (key === "registry") {
|
|
97
|
+
config.registry = value ?? "";
|
|
98
|
+
} else {
|
|
99
|
+
const boolKey = key;
|
|
100
|
+
if (value === undefined || value === "true") {
|
|
101
|
+
config[boolKey] = true;
|
|
102
|
+
} else if (value === "false") {
|
|
103
|
+
config[boolKey] = false;
|
|
104
|
+
} else {
|
|
105
|
+
debug(`Invalid boolean value for ${key}: ${value}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
debug(`Loaded ${CONFIG_FILENAME}: ${JSON.stringify(config)}`);
|
|
110
|
+
return config;
|
|
111
|
+
}
|
|
51
112
|
|
|
52
113
|
// src/glob.ts
|
|
53
114
|
import { readdir, stat } from "node:fs/promises";
|
|
54
|
-
import { join } from "node:path";
|
|
115
|
+
import { join as join2 } from "node:path";
|
|
55
116
|
async function glob(pattern, cwd) {
|
|
56
117
|
const results = [];
|
|
118
|
+
const isGlob = /\/\*\*?$/.test(pattern);
|
|
57
119
|
const basePattern = pattern.replace(/\/\*\*?$/, "");
|
|
58
120
|
const isRecursive = pattern.endsWith("/**");
|
|
59
|
-
const basePath =
|
|
121
|
+
const basePath = join2(cwd, basePattern);
|
|
122
|
+
if (!isGlob) {
|
|
123
|
+
try {
|
|
124
|
+
await stat(join2(basePath, "package.json"));
|
|
125
|
+
return [basePattern];
|
|
126
|
+
} catch {}
|
|
127
|
+
}
|
|
60
128
|
try {
|
|
61
129
|
const entries = await readdir(basePath, { withFileTypes: true });
|
|
62
130
|
for (const entry of entries) {
|
|
63
131
|
if (entry.isDirectory()) {
|
|
64
|
-
const entryPath =
|
|
65
|
-
const fullPath =
|
|
132
|
+
const entryPath = join2(basePattern, entry.name);
|
|
133
|
+
const fullPath = join2(cwd, entryPath);
|
|
66
134
|
try {
|
|
67
|
-
await stat(
|
|
135
|
+
await stat(join2(fullPath, "package.json"));
|
|
68
136
|
results.push(entryPath);
|
|
69
137
|
} catch {
|
|
70
138
|
if (isRecursive) {
|
|
@@ -80,7 +148,7 @@ async function glob(pattern, cwd) {
|
|
|
80
148
|
|
|
81
149
|
// src/discovery.ts
|
|
82
150
|
async function findRootPackageJson(cwd) {
|
|
83
|
-
const packageJsonPath =
|
|
151
|
+
const packageJsonPath = join3(cwd, "package.json");
|
|
84
152
|
try {
|
|
85
153
|
await stat2(packageJsonPath);
|
|
86
154
|
return packageJsonPath;
|
|
@@ -116,10 +184,10 @@ async function discoverPackages(cwd) {
|
|
|
116
184
|
packageDirs.push(...matches);
|
|
117
185
|
}
|
|
118
186
|
} else {
|
|
119
|
-
const packagesDir =
|
|
187
|
+
const packagesDir = join3(cwd, "packages");
|
|
120
188
|
try {
|
|
121
189
|
const entries = await readdir2(packagesDir, { withFileTypes: true });
|
|
122
|
-
packageDirs = entries.filter((entry) => entry.isDirectory()).map((entry) =>
|
|
190
|
+
packageDirs = entries.filter((entry) => entry.isDirectory()).map((entry) => join3("packages", entry.name));
|
|
123
191
|
} catch {
|
|
124
192
|
if (!rootPackageJson.private) {
|
|
125
193
|
return [
|
|
@@ -137,7 +205,7 @@ async function discoverPackages(cwd) {
|
|
|
137
205
|
}
|
|
138
206
|
for (const dir of packageDirs) {
|
|
139
207
|
const pkgPath = resolve(cwd, dir);
|
|
140
|
-
const pkgJsonPath =
|
|
208
|
+
const pkgJsonPath = join3(pkgPath, "package.json");
|
|
141
209
|
try {
|
|
142
210
|
const pkgJson = await readPackageJson(pkgJsonPath);
|
|
143
211
|
packageNames.add(pkgJson.name);
|
|
@@ -150,13 +218,16 @@ async function discoverPackages(cwd) {
|
|
|
150
218
|
return packages;
|
|
151
219
|
}
|
|
152
220
|
async function packageFromPath(path, packageJsonPath, packageJson, localDependencies) {
|
|
221
|
+
const pkgConfig = loadConfig(path);
|
|
153
222
|
return {
|
|
154
223
|
name: packageJson.name,
|
|
155
224
|
version: packageJson.version,
|
|
156
225
|
path,
|
|
157
226
|
packageJsonPath,
|
|
158
227
|
isPrivate: packageJson.private === true,
|
|
159
|
-
localDependencies
|
|
228
|
+
localDependencies,
|
|
229
|
+
skipPublish: pkgConfig["skip-publish"],
|
|
230
|
+
alwaysPublish: pkgConfig["always-publish"]
|
|
160
231
|
};
|
|
161
232
|
}
|
|
162
233
|
function findLocalDependencies(pkg, packageNames) {
|
|
@@ -338,19 +409,6 @@ async function multiSelect(message, options, allSelectedByDefault = true) {
|
|
|
338
409
|
// src/auth.ts
|
|
339
410
|
import { spawn } from "node:child_process";
|
|
340
411
|
import { homedir } from "node:os";
|
|
341
|
-
|
|
342
|
-
// src/log.ts
|
|
343
|
-
var verboseEnabled = false;
|
|
344
|
-
function setVerbose(enabled) {
|
|
345
|
-
verboseEnabled = enabled;
|
|
346
|
-
}
|
|
347
|
-
function debug(...args) {
|
|
348
|
-
if (verboseEnabled) {
|
|
349
|
-
console.error("[debug]", ...args);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// src/auth.ts
|
|
354
412
|
async function checkNpmAuth(registry) {
|
|
355
413
|
return new Promise((resolve2) => {
|
|
356
414
|
const proc = spawn("npm", ["whoami", "--registry", registry], {
|
|
@@ -397,10 +455,10 @@ async function npmLogin(registry) {
|
|
|
397
455
|
import { spawn as spawn2 } from "node:child_process";
|
|
398
456
|
import { readFile as readFile2, stat as stat3 } from "node:fs/promises";
|
|
399
457
|
import { homedir as homedir2 } from "node:os";
|
|
400
|
-
import { join as
|
|
458
|
+
import { join as join4 } from "node:path";
|
|
401
459
|
var DIM_ON = "\x1B[90m";
|
|
402
460
|
var DIM_OFF = "\x1B[39m";
|
|
403
|
-
function run(command, args, cwd) {
|
|
461
|
+
function run(command, args, cwd, options) {
|
|
404
462
|
return new Promise((resolve2) => {
|
|
405
463
|
const proc = spawn2(command, args, {
|
|
406
464
|
cwd,
|
|
@@ -409,17 +467,29 @@ function run(command, args, cwd) {
|
|
|
409
467
|
let output = "";
|
|
410
468
|
proc.stdout?.on("data", (data) => {
|
|
411
469
|
output += data.toString();
|
|
412
|
-
|
|
470
|
+
if (!options?.silent)
|
|
471
|
+
process.stdout.write(DIM_ON + data.toString() + DIM_OFF);
|
|
413
472
|
});
|
|
414
473
|
proc.stderr?.on("data", (data) => {
|
|
415
474
|
output += data.toString();
|
|
416
|
-
|
|
475
|
+
if (!options?.silent)
|
|
476
|
+
process.stderr.write(DIM_ON + data.toString() + DIM_OFF);
|
|
417
477
|
});
|
|
418
478
|
proc.on("close", (code) => {
|
|
419
479
|
resolve2({ code: code ?? 1, output });
|
|
420
480
|
});
|
|
421
481
|
});
|
|
422
482
|
}
|
|
483
|
+
function runStdout(command, args, cwd) {
|
|
484
|
+
return new Promise((resolve2) => {
|
|
485
|
+
const proc = spawn2(command, args, { cwd, stdio: ["inherit", "pipe", "ignore"] });
|
|
486
|
+
let stdout = "";
|
|
487
|
+
proc.stdout?.on("data", (data) => {
|
|
488
|
+
stdout += data.toString();
|
|
489
|
+
});
|
|
490
|
+
proc.on("close", () => resolve2(stdout));
|
|
491
|
+
});
|
|
492
|
+
}
|
|
423
493
|
function runInteractive(command, args, cwd) {
|
|
424
494
|
return new Promise((resolve2) => {
|
|
425
495
|
const proc = spawn2(command, args, {
|
|
@@ -466,7 +536,7 @@ async function verifyBuild(pkg) {
|
|
|
466
536
|
filesToCheck.push("./dist/index.js");
|
|
467
537
|
}
|
|
468
538
|
for (const file of filesToCheck) {
|
|
469
|
-
const filePath =
|
|
539
|
+
const filePath = join4(pkg.path, file);
|
|
470
540
|
try {
|
|
471
541
|
await stat3(filePath);
|
|
472
542
|
} catch {
|
|
@@ -479,6 +549,10 @@ function isOtpError(output) {
|
|
|
479
549
|
return output.includes("EOTP") || output.includes("one-time password");
|
|
480
550
|
}
|
|
481
551
|
var NPM_COMMAND = process.env.PUBZ_NPM_COMMAND ?? "npm";
|
|
552
|
+
async function isVersionPublished(packageName, version, registry) {
|
|
553
|
+
const result = await runStdout(NPM_COMMAND, ["view", `${packageName}@${version}`, "version", "--registry", registry], homedir2());
|
|
554
|
+
return result.trim() === version;
|
|
555
|
+
}
|
|
482
556
|
async function publishPackage(pkg, registry, context, dryRun) {
|
|
483
557
|
if (dryRun) {
|
|
484
558
|
return { success: true };
|
|
@@ -510,8 +584,8 @@ async function publishPackage(pkg, registry, context, dryRun) {
|
|
|
510
584
|
return { success: true };
|
|
511
585
|
}
|
|
512
586
|
async function hasUncommittedChanges(cwd) {
|
|
513
|
-
const
|
|
514
|
-
const output =
|
|
587
|
+
const stdout = await runStdout("git", ["status", "--porcelain"], cwd);
|
|
588
|
+
const output = stdout.trim();
|
|
515
589
|
if (!output) {
|
|
516
590
|
return { hasChanges: false, files: [] };
|
|
517
591
|
}
|
|
@@ -524,8 +598,8 @@ async function commitVersionBump(version, cwd, dryRun) {
|
|
|
524
598
|
if (dryRun) {
|
|
525
599
|
return { success: true };
|
|
526
600
|
}
|
|
527
|
-
const
|
|
528
|
-
if (!
|
|
601
|
+
const statusOutput = await runStdout("git", ["status", "--porcelain"], cwd);
|
|
602
|
+
if (!statusOutput.trim()) {
|
|
529
603
|
return { success: true };
|
|
530
604
|
}
|
|
531
605
|
const addResult = await run("git", ["add", "-A"], cwd);
|
|
@@ -543,11 +617,15 @@ async function createGitTag(version, cwd, dryRun) {
|
|
|
543
617
|
if (dryRun) {
|
|
544
618
|
return { success: true };
|
|
545
619
|
}
|
|
620
|
+
const existing = await runStdout("git", ["tag", "-l", tagName], cwd);
|
|
621
|
+
if (existing.trim() === tagName) {
|
|
622
|
+
return { success: true };
|
|
623
|
+
}
|
|
546
624
|
const tagResult = await run("git", ["tag", tagName], cwd);
|
|
547
625
|
if (tagResult.code !== 0) {
|
|
548
626
|
return {
|
|
549
627
|
success: false,
|
|
550
|
-
error: `Failed to create tag ${tagName}
|
|
628
|
+
error: `Failed to create tag ${tagName}`
|
|
551
629
|
};
|
|
552
630
|
}
|
|
553
631
|
return { success: true };
|
|
@@ -574,12 +652,12 @@ import { spawn as spawn4 } from "node:child_process";
|
|
|
574
652
|
// src/claude.ts
|
|
575
653
|
import { spawn as spawn3 } from "node:child_process";
|
|
576
654
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
577
|
-
import { join as
|
|
655
|
+
import { join as join5 } from "node:path";
|
|
578
656
|
async function resolveCredentials() {
|
|
579
657
|
const home = process.env.HOME ?? "";
|
|
580
658
|
if (!process.env.CLAUDE_CODE_OAUTH_TOKEN) {
|
|
581
659
|
try {
|
|
582
|
-
const tokenFile =
|
|
660
|
+
const tokenFile = join5(home, ".claude", "agent-oauth-token");
|
|
583
661
|
const token = (await readFile3(tokenFile, "utf-8")).trim();
|
|
584
662
|
if (token) {
|
|
585
663
|
process.env.CLAUDE_CODE_OAUTH_TOKEN = token;
|
|
@@ -619,7 +697,7 @@ async function resolveCredentials() {
|
|
|
619
697
|
}
|
|
620
698
|
if (!process.env.CLAUDE_CODE_OAUTH_TOKEN) {
|
|
621
699
|
try {
|
|
622
|
-
const raw = await readFile3(
|
|
700
|
+
const raw = await readFile3(join5(home, ".claude.json"), "utf-8");
|
|
623
701
|
const creds = JSON.parse(raw);
|
|
624
702
|
const accessToken = creds?.claudeAiOauth?.accessToken;
|
|
625
703
|
if (typeof accessToken === "string" && accessToken.length > 0) {
|
|
@@ -794,6 +872,12 @@ async function createGitHubRelease(version, body, cwd, dryRun) {
|
|
|
794
872
|
console.log(`[DRY RUN] Would create GitHub release for ${tagName}`);
|
|
795
873
|
return { success: true };
|
|
796
874
|
}
|
|
875
|
+
const existing = await runSilent(GH_COMMAND, ["release", "view", tagName], cwd);
|
|
876
|
+
if (existing.code === 0) {
|
|
877
|
+
const url2 = existing.output.trim().split(`
|
|
878
|
+
`).find((l) => l.startsWith("https://"))?.trim();
|
|
879
|
+
return { success: true, url: url2 };
|
|
880
|
+
}
|
|
797
881
|
const result = await runSilent(GH_COMMAND, ["release", "create", tagName, "--title", tagName, "--notes", body], cwd);
|
|
798
882
|
if (result.code !== 0) {
|
|
799
883
|
return {
|
|
@@ -805,54 +889,6 @@ async function createGitHubRelease(version, body, cwd, dryRun) {
|
|
|
805
889
|
return { success: true, url };
|
|
806
890
|
}
|
|
807
891
|
|
|
808
|
-
// src/config.ts
|
|
809
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
810
|
-
import { join as join5 } from "node:path";
|
|
811
|
-
var CONFIG_FILENAME = ".pubz";
|
|
812
|
-
var VALID_KEYS = new Set(["skip-build", "skip-publish", "registry"]);
|
|
813
|
-
function loadConfig(cwd) {
|
|
814
|
-
const configPath = join5(cwd, CONFIG_FILENAME);
|
|
815
|
-
if (!existsSync(configPath)) {
|
|
816
|
-
debug(`No ${CONFIG_FILENAME} found at ${configPath}`);
|
|
817
|
-
return {};
|
|
818
|
-
}
|
|
819
|
-
const content = readFileSync(configPath, "utf-8");
|
|
820
|
-
const config = {};
|
|
821
|
-
for (const rawLine of content.split(`
|
|
822
|
-
`)) {
|
|
823
|
-
const line = rawLine.trim();
|
|
824
|
-
if (!line || line.startsWith("#"))
|
|
825
|
-
continue;
|
|
826
|
-
const eqIndex = line.indexOf("=");
|
|
827
|
-
let key;
|
|
828
|
-
let value;
|
|
829
|
-
if (eqIndex === -1) {
|
|
830
|
-
key = line;
|
|
831
|
-
} else {
|
|
832
|
-
key = line.slice(0, eqIndex).trim();
|
|
833
|
-
value = line.slice(eqIndex + 1).trim();
|
|
834
|
-
}
|
|
835
|
-
if (!VALID_KEYS.has(key)) {
|
|
836
|
-
debug(`Ignoring unknown config key: ${key}`);
|
|
837
|
-
continue;
|
|
838
|
-
}
|
|
839
|
-
if (key === "registry") {
|
|
840
|
-
config.registry = value ?? "";
|
|
841
|
-
} else {
|
|
842
|
-
const boolKey = key;
|
|
843
|
-
if (value === undefined || value === "true") {
|
|
844
|
-
config[boolKey] = true;
|
|
845
|
-
} else if (value === "false") {
|
|
846
|
-
config[boolKey] = false;
|
|
847
|
-
} else {
|
|
848
|
-
debug(`Invalid boolean value for ${key}: ${value}`);
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
debug(`Loaded ${CONFIG_FILENAME}: ${JSON.stringify(config)}`);
|
|
853
|
-
return config;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
892
|
// src/version.ts
|
|
857
893
|
import { readFile as readFile4, writeFile } from "node:fs/promises";
|
|
858
894
|
async function transformWorkspaceProtocolForPublish(packages, newVersion, dryRun) {
|
|
@@ -1149,13 +1185,20 @@ async function main() {
|
|
|
1149
1185
|
process.exit(1);
|
|
1150
1186
|
}
|
|
1151
1187
|
let packages = await discoverPackages(cwd);
|
|
1152
|
-
const publishablePackages = packages.filter((p) =>
|
|
1188
|
+
const publishablePackages = packages.filter((p) => {
|
|
1189
|
+
if (p.alwaysPublish)
|
|
1190
|
+
return true;
|
|
1191
|
+
if (p.isPrivate)
|
|
1192
|
+
return p.skipPublish || options.skipPublish;
|
|
1193
|
+
return true;
|
|
1194
|
+
});
|
|
1153
1195
|
if (publishablePackages.length === 0) {
|
|
1154
1196
|
console.log(yellow("No publishable packages found."));
|
|
1155
1197
|
console.log("");
|
|
1156
1198
|
console.log(muted("Make sure your packages:"));
|
|
1157
1199
|
console.log(muted(' - Have a package.json with a "name" field'));
|
|
1158
1200
|
console.log(muted(' - Do not have "private": true (or use --skip-publish for private packages)'));
|
|
1201
|
+
console.log(muted(' - Do not have "skip-publish" in a per-package .pubz file'));
|
|
1159
1202
|
console.log("");
|
|
1160
1203
|
process.exit(1);
|
|
1161
1204
|
}
|
|
@@ -1230,29 +1273,38 @@ async function main() {
|
|
|
1230
1273
|
console.log("");
|
|
1231
1274
|
}
|
|
1232
1275
|
if (didBump) {
|
|
1233
|
-
|
|
1234
|
-
if (
|
|
1235
|
-
|
|
1276
|
+
const onDiskVersion = JSON.parse(readFileSync2(packages[0].packageJsonPath, "utf-8")).version;
|
|
1277
|
+
if (onDiskVersion === newVersion) {
|
|
1278
|
+
console.log(dim(`⏭ Version already set to ${newVersion}, skipping bump`));
|
|
1279
|
+
console.log("");
|
|
1280
|
+
for (const pkg of packages) {
|
|
1281
|
+
pkg.version = newVersion;
|
|
1282
|
+
}
|
|
1236
1283
|
} else {
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1284
|
+
frameHeader("\uD83D\uDD16 Version");
|
|
1285
|
+
if (options.version && ["patch", "minor", "major"].includes(options.version)) {
|
|
1286
|
+
frameLine(`Bumping (${options.version}): ${yellow(currentVersion)} → ${green(newVersion)}`);
|
|
1287
|
+
} else {
|
|
1288
|
+
frameLine(`${yellow(currentVersion)} → ${green(newVersion)}`);
|
|
1289
|
+
}
|
|
1290
|
+
frameLine(dim("Updating all packages..."));
|
|
1291
|
+
for (const pkg of packages) {
|
|
1292
|
+
await updatePackageVersion(pkg, newVersion, options.dryRun);
|
|
1293
|
+
}
|
|
1294
|
+
await updateLocalDependencyVersions(packages, newVersion, options.dryRun);
|
|
1295
|
+
for (const pkg of packages) {
|
|
1296
|
+
pkg.version = newVersion;
|
|
1297
|
+
}
|
|
1298
|
+
const commitResult = await commitVersionBump(newVersion, cwd, options.dryRun);
|
|
1299
|
+
if (!commitResult.success) {
|
|
1300
|
+
frameFooter();
|
|
1301
|
+
console.error(red(bold("Failed to commit version bump:")) + ` ${commitResult.error}`);
|
|
1302
|
+
closePrompt();
|
|
1303
|
+
process.exit(1);
|
|
1304
|
+
}
|
|
1249
1305
|
frameFooter();
|
|
1250
|
-
console.
|
|
1251
|
-
closePrompt();
|
|
1252
|
-
process.exit(1);
|
|
1306
|
+
console.log("");
|
|
1253
1307
|
}
|
|
1254
|
-
frameFooter();
|
|
1255
|
-
console.log("");
|
|
1256
1308
|
}
|
|
1257
1309
|
if (!options.skipBuild) {
|
|
1258
1310
|
frameHeader("\uD83C\uDFD7️ Build");
|
|
@@ -1283,7 +1335,14 @@ async function main() {
|
|
|
1283
1335
|
process.exit(1);
|
|
1284
1336
|
}
|
|
1285
1337
|
}
|
|
1286
|
-
|
|
1338
|
+
const packagesToPublish = packages.filter((p) => {
|
|
1339
|
+
if (p.alwaysPublish)
|
|
1340
|
+
return true;
|
|
1341
|
+
if (p.skipPublish || options.skipPublish)
|
|
1342
|
+
return false;
|
|
1343
|
+
return true;
|
|
1344
|
+
});
|
|
1345
|
+
if (packagesToPublish.length === 0) {
|
|
1287
1346
|
console.log(yellow(bold("⏭️ Skipping npm publish")) + dim(" — use without --skip-publish to publish to npm"));
|
|
1288
1347
|
console.log("");
|
|
1289
1348
|
} else {
|
|
@@ -1308,7 +1367,7 @@ async function main() {
|
|
|
1308
1367
|
console.log(`Publishing to ${cyan(registry)}:`);
|
|
1309
1368
|
}
|
|
1310
1369
|
console.log("");
|
|
1311
|
-
for (const pkg of
|
|
1370
|
+
for (const pkg of packagesToPublish) {
|
|
1312
1371
|
console.log(` ${dim("•")} ${cyan(pkg.name)}${dim("@")}${yellow(newVersion)}`);
|
|
1313
1372
|
}
|
|
1314
1373
|
console.log("");
|
|
@@ -1352,7 +1411,7 @@ async function main() {
|
|
|
1352
1411
|
}
|
|
1353
1412
|
}
|
|
1354
1413
|
frameLine(dim("Preparing packages..."));
|
|
1355
|
-
const workspaceTransforms = await transformWorkspaceProtocolForPublish(
|
|
1414
|
+
const workspaceTransforms = await transformWorkspaceProtocolForPublish(packagesToPublish, newVersion, options.dryRun);
|
|
1356
1415
|
const publishContext = {
|
|
1357
1416
|
otp: options.otp,
|
|
1358
1417
|
useBrowserAuth: !options.ci,
|
|
@@ -1363,10 +1422,15 @@ async function main() {
|
|
|
1363
1422
|
let failedPackageName = "";
|
|
1364
1423
|
let failedError = "";
|
|
1365
1424
|
try {
|
|
1366
|
-
for (const pkg of
|
|
1425
|
+
for (const pkg of packagesToPublish) {
|
|
1367
1426
|
if (options.dryRun) {
|
|
1368
1427
|
frameLine(` ${dim("[dry run]")} ${cyan(pkg.name)}${dim("@")}${yellow(newVersion)}`);
|
|
1369
1428
|
} else {
|
|
1429
|
+
const alreadyPublished = await isVersionPublished(pkg.name, newVersion, registry);
|
|
1430
|
+
if (alreadyPublished) {
|
|
1431
|
+
frameLine(` ${dim("⏭")} ${cyan(pkg.name)}${dim("@")}${yellow(newVersion)} ${dim("already published, skipping")}`);
|
|
1432
|
+
continue;
|
|
1433
|
+
}
|
|
1370
1434
|
frameLine(dim(` Publishing ${pkg.name}...`));
|
|
1371
1435
|
}
|
|
1372
1436
|
const result = await publishPackage(pkg, registry, publishContext, options.dryRun);
|
|
@@ -1400,7 +1464,7 @@ async function main() {
|
|
|
1400
1464
|
console.log("");
|
|
1401
1465
|
}
|
|
1402
1466
|
}
|
|
1403
|
-
if (
|
|
1467
|
+
if (packagesToPublish.length > 0) {
|
|
1404
1468
|
console.log("✅ " + green(bold(`Published v${newVersion}!`)));
|
|
1405
1469
|
console.log("");
|
|
1406
1470
|
}
|