@peiyanlu/release 0.0.1 → 0.0.2
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.mjs +98 -176
- package/dist/index.d.cts +2 -4
- package/dist/index.d.mts +2 -4
- package/package.json +4 -6
package/dist/cli.mjs
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { execAsync, isGitRepo, readJsonFile } from "@peiyanlu/cli-utils";
|
|
2
|
-
import { blue, dim, gray, green, red, rgb, yellow } from "ansis";
|
|
3
|
-
import { program } from "commander";
|
|
4
1
|
import path, { dirname, join, resolve } from "node:path";
|
|
5
2
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
|
+
import { eol, execAsync, isGitRepo, parseGitHubRepo, readJsonFile, runGit, runNpm } from "@peiyanlu/cli-utils";
|
|
4
|
+
import { blue, dim, gray, green, red, rgb, underline, yellow } from "ansis";
|
|
5
|
+
import { program } from "commander";
|
|
6
6
|
import { cancel, confirm, group, intro, isCancel, log, outro, select, tasks, text } from "@clack/prompts";
|
|
7
|
-
import { inspect, styleText } from "node:util";
|
|
8
7
|
import { clean, coerce, gt, gte, inc, parse, prerelease, valid } from "semver";
|
|
9
8
|
import { createReadStream, existsSync, statSync } from "node:fs";
|
|
10
|
-
import { EOL } from "node:os";
|
|
11
9
|
import { readFile, writeFile } from "node:fs/promises";
|
|
12
10
|
import { Octokit } from "@octokit/rest";
|
|
13
11
|
import { contentType } from "mime-types";
|
|
14
12
|
import open from "open";
|
|
15
13
|
import { glob } from "tinyglobby";
|
|
16
|
-
import {
|
|
14
|
+
import { inspect, styleText } from "node:util";
|
|
15
|
+
import { castArray, isUndefined } from "@peiyanlu/ts-utils";
|
|
17
16
|
|
|
18
|
-
//#region node_modules/.pnpm/tsdown@0.18.
|
|
17
|
+
//#region node_modules/.pnpm/tsdown@0.18.4_typescript@5.9.3/node_modules/tsdown/esm-shims.js
|
|
19
18
|
const getFilename = () => fileURLToPath(import.meta.url);
|
|
20
19
|
const getDirname = () => path.dirname(getFilename());
|
|
21
20
|
const __dirname$1 = /* @__PURE__ */ getDirname();
|
|
@@ -66,57 +65,17 @@ const mergeConfig = (defaults, overrides) => {
|
|
|
66
65
|
return result;
|
|
67
66
|
};
|
|
68
67
|
|
|
69
|
-
//#endregion
|
|
70
|
-
//#region src/utils.ts
|
|
71
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
72
|
-
const __dirname = dirname(__filename);
|
|
73
|
-
function joinUrl(input) {
|
|
74
|
-
const temps = Array.isArray(input) ? input : [...arguments];
|
|
75
|
-
if (temps.length === 0) return "";
|
|
76
|
-
const result = [];
|
|
77
|
-
const parts = [...temps];
|
|
78
|
-
/** 协议正则 */
|
|
79
|
-
const PROTOCOL_RE = /^[^/:]+:\/*$/;
|
|
80
|
-
const FILE_PROTOCOL_RE = /^file:\/\/\//;
|
|
81
|
-
if (PROTOCOL_RE.test(parts[0]) && parts.length > 1) {
|
|
82
|
-
parts[1] = parts[0] + parts[1];
|
|
83
|
-
parts.shift();
|
|
84
|
-
}
|
|
85
|
-
if (FILE_PROTOCOL_RE.test(parts[0])) parts[0] = parts[0].replace(/^([^/:]+):\/*/, "$1:///");
|
|
86
|
-
else parts[0] = parts[0].replace(/^([^/:]+):\/*/, "$1://");
|
|
87
|
-
parts.forEach((part, index) => {
|
|
88
|
-
if (!part) return;
|
|
89
|
-
let segment = part;
|
|
90
|
-
if (index > 0) segment = segment.replace(/^\/+/, "");
|
|
91
|
-
if (index < parts.length - 1) segment = segment.replace(/\/+$/, "");
|
|
92
|
-
else segment = segment.replace(/\/+$/, "/");
|
|
93
|
-
result.push(segment);
|
|
94
|
-
});
|
|
95
|
-
let url = result.join("/");
|
|
96
|
-
url = url.replace(/\/(\?|&|#[^!])/g, "$1");
|
|
97
|
-
const [base, ...queryParts] = url.split("?");
|
|
98
|
-
url = base + (queryParts.length ? "?" + queryParts.join("&") : "");
|
|
99
|
-
return url;
|
|
100
|
-
}
|
|
101
|
-
const isUndefined = (val) => {
|
|
102
|
-
return void 0 === val;
|
|
103
|
-
};
|
|
104
|
-
const eol = (n$1 = 1) => EOL.repeat(n$1);
|
|
105
|
-
const underline = (text$1) => {
|
|
106
|
-
return styleText(["dim", "underline"], text$1);
|
|
107
|
-
};
|
|
108
|
-
const castArray = (arr) => {
|
|
109
|
-
return Array.isArray(arr) ? arr : [arr];
|
|
110
|
-
};
|
|
111
|
-
|
|
112
68
|
//#endregion
|
|
113
69
|
//#region src/messages.ts
|
|
114
70
|
const n = (b) => {
|
|
115
|
-
return b ? "
|
|
71
|
+
return b ? "(dry run)" : "";
|
|
72
|
+
};
|
|
73
|
+
const t = () => {
|
|
74
|
+
return green(Math.floor(process.uptime()));
|
|
116
75
|
};
|
|
117
76
|
const MSG = {
|
|
118
|
-
INTRO: (pkgName, dryRun) => `🚀 Starting release ${yellow(pkgName)}${n(dryRun)}`,
|
|
119
|
-
OUTRO: (dryRun) => `🎉 Release finished successfully${n(dryRun)}`,
|
|
77
|
+
INTRO: (pkgName, dryRun) => `🚀 Starting release ${yellow(pkgName)} ${n(dryRun)}`,
|
|
78
|
+
OUTRO: (dryRun) => `🎉 Release finished successfully in ${t()}s ${n(dryRun)} `,
|
|
120
79
|
LOG: {
|
|
121
80
|
SHOW_VERSION: (version) => `🎉 Released ${green(version)}`,
|
|
122
81
|
SHOW_CHANGELOG: "🎉 Changelog collected",
|
|
@@ -126,11 +85,11 @@ const MSG = {
|
|
|
126
85
|
CHECK: {
|
|
127
86
|
GIT: {
|
|
128
87
|
CHECKING: "Checking Git repository",
|
|
129
|
-
CHECKED: (name, url) => `Git remote resolved: ${dim(name)} → ${underline(url)}`
|
|
88
|
+
CHECKED: (name, url) => `Git remote resolved: ${dim(name)} → ${underline(dim(url))}`
|
|
130
89
|
},
|
|
131
90
|
NPM: {
|
|
132
91
|
CHECKING: "Checking npm registry",
|
|
133
|
-
CHECKED: (registry, msg$1) => `NPM registry: ${underline(registry)}${msg$1 ? ` ${msg$1}` : ""}`
|
|
92
|
+
CHECKED: (registry, msg$1) => `NPM registry: ${underline(dim(registry))}${msg$1 ? ` ${msg$1}` : ""}`
|
|
134
93
|
}
|
|
135
94
|
},
|
|
136
95
|
TASK: {
|
|
@@ -154,11 +113,11 @@ const MSG = {
|
|
|
154
113
|
PROMPT: {
|
|
155
114
|
SELECT_VERSION: "Select version bump:",
|
|
156
115
|
INPUT_VERSION: "Enter custom version:",
|
|
157
|
-
NPM_PUBLISH: (pkg$1) => `Publish to npm ${underline(`(${pkg$1})`)}?`,
|
|
116
|
+
NPM_PUBLISH: (pkg$1) => `Publish to npm ${underline(dim`(${pkg$1})`)}?`,
|
|
158
117
|
NPM_OTP: "Enter npm one-time password (OTP):",
|
|
159
|
-
GITHUB_RELEASE: (title) => `Create a new GitHub release ${underline(`(${title})`)}?`,
|
|
160
|
-
GIT_COMMIT: (msg$1) => `Create git commit ${underline(`(${msg$1})`)}?`,
|
|
161
|
-
GIT_TAG: (msg$1) => `Create git tag ${underline(`(${msg$1})`)}?`,
|
|
118
|
+
GITHUB_RELEASE: (title) => `Create a new GitHub release ${underline(dim`(${title})`)}?`,
|
|
119
|
+
GIT_COMMIT: (msg$1) => `Create git commit ${underline(dim`(${msg$1})`)}?`,
|
|
120
|
+
GIT_TAG: (msg$1) => `Create git tag ${underline(dim`(${msg$1})`)}?`,
|
|
162
121
|
GIT_PUSH: "Push commits and tags to remote?"
|
|
163
122
|
},
|
|
164
123
|
ERROR: {
|
|
@@ -168,7 +127,7 @@ const MSG = {
|
|
|
168
127
|
GITHUB_TOKEN: (tokenRef) => `[github] Missing GitHub token. Please set ${yellow(tokenRef ?? "GITHUB_TOKEN")}`,
|
|
169
128
|
GITHUB_AUTH: "[github] Invalid GitHub token or insufficient permissions",
|
|
170
129
|
GITHUB_USER: "[github] User does not have permission to create releases",
|
|
171
|
-
NPM_REGISTRY: (registry) => `[npm] Unable to reach npm registry ${underline(registry)}`,
|
|
130
|
+
NPM_REGISTRY: (registry) => `[npm] Unable to reach npm registry ${underline(dim(registry))}`,
|
|
172
131
|
NPM_AUTH: `[npm] Not authenticated with npm. Please run ${yellow("npm login")} and try again.`,
|
|
173
132
|
NPM_USER: (user, name) => `[npm] User ${dim(user)} is not a collaborator of ${dim(name)}.`
|
|
174
133
|
}
|
|
@@ -340,10 +299,7 @@ const runVersionPrompts = async (ctx, config) => {
|
|
|
340
299
|
const parsed = parseVersion(next);
|
|
341
300
|
Object.assign(ctx.pkg, { ...parsed });
|
|
342
301
|
ctx.isIncrement = gte(next, current);
|
|
343
|
-
log.message(gray`
|
|
344
|
-
from ${dim(current)}
|
|
345
|
-
to ${diff(current, next)}
|
|
346
|
-
`);
|
|
302
|
+
log.message(gray`from ${dim(current)}${eol()} to ${diff(current, next)}`);
|
|
347
303
|
return { next };
|
|
348
304
|
};
|
|
349
305
|
|
|
@@ -353,12 +309,11 @@ const createDefaultContext = () => {
|
|
|
353
309
|
return {
|
|
354
310
|
ci: false,
|
|
355
311
|
release: false,
|
|
356
|
-
noNpm: false,
|
|
357
312
|
dryRun: false,
|
|
358
313
|
changelog: false,
|
|
359
314
|
increment: "",
|
|
360
315
|
isIncrement: false,
|
|
361
|
-
|
|
316
|
+
configFileExists: false,
|
|
362
317
|
pkg: {
|
|
363
318
|
current: "",
|
|
364
319
|
next: "",
|
|
@@ -368,8 +323,7 @@ const createDefaultContext = () => {
|
|
|
368
323
|
toPreRelease: false,
|
|
369
324
|
publishConfig: {
|
|
370
325
|
access: "public",
|
|
371
|
-
registry: "https://registry.npmjs.org"
|
|
372
|
-
publicPath: ""
|
|
326
|
+
registry: "https://registry.npmjs.org"
|
|
373
327
|
},
|
|
374
328
|
preId: PreId.BETA,
|
|
375
329
|
preBase: "0"
|
|
@@ -440,64 +394,61 @@ const createDefaultConfig = (isCI) => {
|
|
|
440
394
|
};
|
|
441
395
|
|
|
442
396
|
//#endregion
|
|
443
|
-
//#region src/
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const dim$1 = (text$1) => styleText(["dim"], text$1);
|
|
449
|
-
const red$1 = (text$1) => styleText(["red"], text$1);
|
|
450
|
-
if (dryRun) {
|
|
451
|
-
console.log(`${dim$1("[dry-run]")} ${fullCmd}`);
|
|
452
|
-
return resolve$1(void 0);
|
|
453
|
-
}
|
|
454
|
-
const child = spawn(cmd, args, { ...others });
|
|
455
|
-
let stdout = "";
|
|
456
|
-
child.stdout?.setEncoding("utf-8");
|
|
457
|
-
child.stdout?.on("data", (data) => stdout += trim ? data.trim() : data);
|
|
458
|
-
let stderr = "";
|
|
459
|
-
child.stderr?.setEncoding("utf-8");
|
|
460
|
-
child.stderr?.on("data", (data) => stderr += trim ? data.trim() : data);
|
|
461
|
-
child.on("close", (code) => {
|
|
462
|
-
if (stderr) {
|
|
463
|
-
const err = `${red$1("spawnAsync")} ${dim$1(fullCmd)} ${stderr}`;
|
|
464
|
-
switch (error) {
|
|
465
|
-
case "log":
|
|
466
|
-
console.error(err);
|
|
467
|
-
break;
|
|
468
|
-
case "throw": throw new Error(err);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
resolve$1(0 === code ? stdout : void 0);
|
|
472
|
-
});
|
|
473
|
-
});
|
|
397
|
+
//#region src/utils.ts
|
|
398
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
399
|
+
const __dirname = dirname(__filename);
|
|
400
|
+
const info = (msg$1) => {
|
|
401
|
+
console.log(`${rgb(33, 91, 184)(`ℹ`)} ${gray(msg$1)}`);
|
|
474
402
|
};
|
|
475
|
-
const
|
|
476
|
-
return
|
|
403
|
+
const success = (msg$1, dryRun) => {
|
|
404
|
+
return `${(dryRun ? rgb(123, 115, 66) : green)("✔")} ${msg$1}`;
|
|
405
|
+
};
|
|
406
|
+
const runLifeCycleHook = async (hooks, key, dryRun) => {
|
|
407
|
+
const handler = hooks[key];
|
|
408
|
+
if (typeof handler === "function") {
|
|
409
|
+
if (!dryRun) await handler();
|
|
410
|
+
log.success(success(`${dim`run`} ${inspect(handler)}`, dryRun));
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
return Promise.allSettled(castArray(handler).filter(Boolean).map(async (hook) => {
|
|
414
|
+
if (!dryRun) await execAsync(hook, { shell: true }).catch(console.error);
|
|
415
|
+
log.success(success(hook.replace("echo", dim("echo")), dryRun));
|
|
416
|
+
}));
|
|
417
|
+
};
|
|
418
|
+
const format = (str, ctx) => {
|
|
419
|
+
const { pkg: { next } } = ctx;
|
|
420
|
+
return str.replace("${version}", next);
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/git/commit.ts
|
|
425
|
+
const runGitProxy = (...args) => {
|
|
426
|
+
if (process.env["dryRun"]) log.message(`${dim("$")} ${gray(["git", ...args[0]].join(" "))}`);
|
|
427
|
+
return runGit(...args);
|
|
477
428
|
};
|
|
478
429
|
const getBranchName = () => {
|
|
479
|
-
return
|
|
430
|
+
return runGitProxy([
|
|
480
431
|
"rev-parse",
|
|
481
432
|
"--abbrev-ref",
|
|
482
433
|
"HEAD"
|
|
483
434
|
]);
|
|
484
435
|
};
|
|
485
436
|
const getRemoteForBranch = (branch) => {
|
|
486
|
-
return
|
|
437
|
+
return runGitProxy([
|
|
487
438
|
"config",
|
|
488
439
|
"--get",
|
|
489
440
|
`branch.${branch}.remote`
|
|
490
441
|
]);
|
|
491
442
|
};
|
|
492
443
|
const getStatus = () => {
|
|
493
|
-
return
|
|
444
|
+
return runGitProxy([
|
|
494
445
|
"status",
|
|
495
446
|
"--short",
|
|
496
447
|
"--untracked-files=no"
|
|
497
|
-
], false);
|
|
448
|
+
], { trim: false });
|
|
498
449
|
};
|
|
499
450
|
const gitRestore = () => {
|
|
500
|
-
return
|
|
451
|
+
return runGitProxy(["restore", "."]);
|
|
501
452
|
};
|
|
502
453
|
const coloredChangeset = (log$1) => {
|
|
503
454
|
const colorStatusChar = (ch) => {
|
|
@@ -520,23 +471,19 @@ const getRemote = async () => {
|
|
|
520
471
|
const remoteName = branch && await getRemoteForBranch(branch) || "origin";
|
|
521
472
|
return {
|
|
522
473
|
remoteName,
|
|
523
|
-
remoteUrl: await
|
|
474
|
+
remoteUrl: await runGitProxy([
|
|
524
475
|
"remote",
|
|
525
476
|
"get-url",
|
|
526
477
|
remoteName
|
|
527
|
-
]).catch((_) =>
|
|
478
|
+
]).catch((_) => runGitProxy([
|
|
528
479
|
"config",
|
|
529
480
|
"--get",
|
|
530
481
|
`remote.${remoteName}.url`
|
|
531
482
|
]))
|
|
532
483
|
};
|
|
533
484
|
};
|
|
534
|
-
const parseGitHubRepo = (url) => {
|
|
535
|
-
const match = url.trim().match(/github(?:\.com)?[:/](.+?)\/(.+?)(\/.+?)?(\.git)?$/);
|
|
536
|
-
return match ? match.slice(1, 3) : [];
|
|
537
|
-
};
|
|
538
485
|
const getLatestTag = async (match = "*", exclude = "*-beta.*") => {
|
|
539
|
-
return
|
|
486
|
+
return runGitProxy([
|
|
540
487
|
"describe",
|
|
541
488
|
"--tags",
|
|
542
489
|
"--abbrev=0",
|
|
@@ -545,11 +492,11 @@ const getLatestTag = async (match = "*", exclude = "*-beta.*") => {
|
|
|
545
492
|
]);
|
|
546
493
|
};
|
|
547
494
|
const getPreviousTag = async (current) => {
|
|
548
|
-
return
|
|
495
|
+
return runGitProxy([
|
|
549
496
|
"describe",
|
|
550
497
|
"--tags",
|
|
551
498
|
"--abbrev=0",
|
|
552
|
-
`${await
|
|
499
|
+
`${await runGitProxy([
|
|
553
500
|
"rev-list",
|
|
554
501
|
"--tags",
|
|
555
502
|
current || "--skip=1",
|
|
@@ -577,7 +524,7 @@ const getLog = async (print, isIncrement) => {
|
|
|
577
524
|
const cmd = ["log", `--pretty=format:${print ? "* %s (%h)" : "%s %h %H"}`];
|
|
578
525
|
const { from, to } = await resolveChangelogRange(isIncrement);
|
|
579
526
|
if (from) cmd.push(`${from}...${to}`);
|
|
580
|
-
return
|
|
527
|
+
return runGitProxy(cmd, { trim: false });
|
|
581
528
|
};
|
|
582
529
|
const normalizeTag = (tag) => clean(tag) ?? tag;
|
|
583
530
|
const resolveTag$1 = async (ctx, config) => {
|
|
@@ -602,10 +549,10 @@ const gitCheck = async (ctx, config) => {
|
|
|
602
549
|
parseGithubUrl(ctx);
|
|
603
550
|
};
|
|
604
551
|
const hasUpstreamBranch = async () => {
|
|
605
|
-
const branch = await
|
|
552
|
+
const branch = await runGitProxy([
|
|
606
553
|
"for-each-ref",
|
|
607
554
|
"--format=%(upstream:short)",
|
|
608
|
-
await
|
|
555
|
+
await runGitProxy(["symbolic-ref", "HEAD"])
|
|
609
556
|
]);
|
|
610
557
|
return Boolean(branch);
|
|
611
558
|
};
|
|
@@ -624,22 +571,18 @@ const getUpstreamArgs = async (remoteName) => {
|
|
|
624
571
|
if (remoteName) return [remoteName];
|
|
625
572
|
return [];
|
|
626
573
|
};
|
|
627
|
-
const format = (str, ctx) => {
|
|
628
|
-
const { pkg: { next } } = ctx;
|
|
629
|
-
return str.replace("${version}", next);
|
|
630
|
-
};
|
|
631
574
|
const commitAndTag = async (ctx, config) => {
|
|
632
575
|
const { git: { currentTag, remoteName }, dryRun } = ctx;
|
|
633
576
|
const { git: { commit, tag, push, tagMessage, commitMessage } } = config;
|
|
634
577
|
if (!commit) return;
|
|
635
578
|
const args = dryRun ? ["--dry-run"] : [];
|
|
636
|
-
await
|
|
579
|
+
await runGitProxy([
|
|
637
580
|
"add",
|
|
638
581
|
".",
|
|
639
582
|
"--all",
|
|
640
583
|
...args
|
|
641
584
|
]);
|
|
642
|
-
await
|
|
585
|
+
await runGitProxy([
|
|
643
586
|
"commit",
|
|
644
587
|
"--message",
|
|
645
588
|
format(commitMessage, ctx),
|
|
@@ -647,7 +590,7 @@ const commitAndTag = async (ctx, config) => {
|
|
|
647
590
|
]);
|
|
648
591
|
if (!dryRun) Object.assign(ctx.git, { isCommitted: true });
|
|
649
592
|
if (tag) {
|
|
650
|
-
await
|
|
593
|
+
await runGitProxy([
|
|
651
594
|
"tag",
|
|
652
595
|
"--annotate",
|
|
653
596
|
"--message",
|
|
@@ -657,7 +600,7 @@ const commitAndTag = async (ctx, config) => {
|
|
|
657
600
|
]);
|
|
658
601
|
if (!dryRun) Object.assign(ctx.git, { isTagged: true });
|
|
659
602
|
}
|
|
660
|
-
if (push) await
|
|
603
|
+
if (push) await runGitProxy([
|
|
661
604
|
"push",
|
|
662
605
|
...await getUpstreamArgs(remoteName),
|
|
663
606
|
"--follow-tags",
|
|
@@ -667,12 +610,12 @@ const commitAndTag = async (ctx, config) => {
|
|
|
667
610
|
const gitRollback = async (ctx) => {
|
|
668
611
|
const { git: { currentTag, isCommitted, isTagged } } = ctx;
|
|
669
612
|
await gitRestore();
|
|
670
|
-
if (isTagged) await
|
|
613
|
+
if (isTagged) await runGitProxy([
|
|
671
614
|
"tag",
|
|
672
615
|
"--delete",
|
|
673
616
|
currentTag
|
|
674
617
|
]);
|
|
675
|
-
await
|
|
618
|
+
await runGitProxy([
|
|
676
619
|
"reset",
|
|
677
620
|
"--hard",
|
|
678
621
|
isCommitted ? "HEAD~1" : "HEAD"
|
|
@@ -930,19 +873,18 @@ const renderChangelog = async (ctx, sections) => {
|
|
|
930
873
|
const { pkg: { next: to }, github: { owner, repo }, git: { latestTag } } = ctx;
|
|
931
874
|
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
932
875
|
const github = getGithubUrl(owner, repo);
|
|
933
|
-
const eol$1 = (n$1) => EOL.repeat(n$1);
|
|
934
876
|
let md;
|
|
935
|
-
if (!latestTag) md = `## ${to} (${date})${eol
|
|
936
|
-
else md = `## [${to}](${github}/compare/${latestTag}...${to}) (${date})${eol
|
|
877
|
+
if (!latestTag) md = `## ${to} (${date})${eol(2)}`;
|
|
878
|
+
else md = `## [${to}](${github}/compare/${latestTag}...${to}) (${date})${eol(2)}`;
|
|
937
879
|
for (const [type, items] of Object.entries(sections)) {
|
|
938
880
|
if (!items.length) continue;
|
|
939
|
-
md += `### ${findType(type)}${eol
|
|
940
|
-
for (const [desc, hash, fullHash] of items) md += `* **${type}** ${desc} [${hash}](${github}/commit/${fullHash})${eol
|
|
941
|
-
md += eol
|
|
881
|
+
md += `### ${findType(type)}${eol(2)}`;
|
|
882
|
+
for (const [desc, hash, fullHash] of items) md += `* **${type}** ${desc} [${hash}](${github}/commit/${fullHash})${eol(1)}`;
|
|
883
|
+
md += eol(2);
|
|
942
884
|
}
|
|
943
885
|
if (latestTag) {
|
|
944
886
|
md += `**Full Changelog**: ${github}/compare/${latestTag}...${to}`;
|
|
945
|
-
md += eol
|
|
887
|
+
md += eol(3);
|
|
946
888
|
}
|
|
947
889
|
return md;
|
|
948
890
|
};
|
|
@@ -958,7 +900,7 @@ const updateChangelog = async (newContent) => {
|
|
|
958
900
|
const file = "CHANGELOG.md";
|
|
959
901
|
const title = `# Changelog${eol(3)}`;
|
|
960
902
|
await writeFile(file, `${(existsSync(file) && await readFile(file, "utf-8") || title).replace(/* @__PURE__ */ new RegExp(`^${title}`), `${title}${newContent}`).trim()}${eol()}`);
|
|
961
|
-
await
|
|
903
|
+
await runGitProxy(["add", file]);
|
|
962
904
|
};
|
|
963
905
|
|
|
964
906
|
//#endregion
|
|
@@ -1059,23 +1001,24 @@ const runNpmOptPrompts = async (ctx, config) => {
|
|
|
1059
1001
|
|
|
1060
1002
|
//#endregion
|
|
1061
1003
|
//#region src/npm/publish.ts
|
|
1004
|
+
const runNpmProxy = (...args) => {
|
|
1005
|
+
if (process.env["dryRun"]) log.message(`${dim("$")} ${gray(["npm", ...args[0]].join(" "))}`);
|
|
1006
|
+
return runNpm(...args);
|
|
1007
|
+
};
|
|
1062
1008
|
const DEFAULT_TAG = "latest";
|
|
1063
1009
|
const DEFAULT_TAG_PRERELEASE = "next";
|
|
1064
|
-
const runNpm = (args) => {
|
|
1065
|
-
return execAsync(["npm", ...args].join(" "));
|
|
1066
|
-
};
|
|
1067
1010
|
const getRegistry = (publishConfig = {}) => {
|
|
1068
1011
|
return (publishConfig.registry ? [publishConfig.registry] : Object.keys(publishConfig).filter((key) => key.endsWith("registry")).map((key) => publishConfig[key]))[0];
|
|
1069
1012
|
};
|
|
1070
1013
|
const isRegistryUp = async (registry) => {
|
|
1071
|
-
return void 0 !== await
|
|
1014
|
+
return void 0 !== await runNpmProxy(["ping", ...registry ? [`--registry ${registry}`] : []]);
|
|
1072
1015
|
};
|
|
1073
1016
|
const isAuthenticated = (registry) => {
|
|
1074
|
-
return
|
|
1017
|
+
return runNpmProxy(["whoami", ...registry ? [`--registry ${registry}`] : []]);
|
|
1075
1018
|
};
|
|
1076
1019
|
const getLatestRegistryVersion = (name, tag, registry) => {
|
|
1077
1020
|
const registryArg = registry ? [`--registry ${registry}`] : [];
|
|
1078
|
-
return
|
|
1021
|
+
return runNpmProxy([
|
|
1079
1022
|
"show",
|
|
1080
1023
|
`${name}@${tag}`,
|
|
1081
1024
|
"version",
|
|
@@ -1083,7 +1026,7 @@ const getLatestRegistryVersion = (name, tag, registry) => {
|
|
|
1083
1026
|
]);
|
|
1084
1027
|
};
|
|
1085
1028
|
const getRegistryTags = async (name, registry) => {
|
|
1086
|
-
const res = await
|
|
1029
|
+
const res = await runNpmProxy([
|
|
1087
1030
|
"view",
|
|
1088
1031
|
name,
|
|
1089
1032
|
"dist-tags",
|
|
@@ -1094,7 +1037,7 @@ const getRegistryTags = async (name, registry) => {
|
|
|
1094
1037
|
};
|
|
1095
1038
|
const bump = (version, allowSameVersion, args = []) => {
|
|
1096
1039
|
allowSameVersion && args.push(`--allow-same-version`);
|
|
1097
|
-
return
|
|
1040
|
+
return runNpmProxy([
|
|
1098
1041
|
"version",
|
|
1099
1042
|
version,
|
|
1100
1043
|
"--no-git-tag-version",
|
|
@@ -1113,10 +1056,10 @@ const resolveTag = async (ctx, config) => {
|
|
|
1113
1056
|
else return tag || preId || await guessPreReleaseTag(name);
|
|
1114
1057
|
};
|
|
1115
1058
|
const isCollaborator = async (ctx) => {
|
|
1116
|
-
const { name, publishConfig } = ctx
|
|
1059
|
+
const { pkg: { name, publishConfig }, npm: { username } } = ctx;
|
|
1117
1060
|
const registry = getRegistry(publishConfig);
|
|
1118
1061
|
const registryArg = registry ? [`--registry ${registry}`] : [];
|
|
1119
|
-
let npmVersion = await
|
|
1062
|
+
let npmVersion = await runNpmProxy(["--version"]);
|
|
1120
1063
|
let accessCommand;
|
|
1121
1064
|
if (gt(npmVersion, "9.0.0")) accessCommand = [
|
|
1122
1065
|
"access",
|
|
@@ -1125,24 +1068,20 @@ const isCollaborator = async (ctx) => {
|
|
|
1125
1068
|
"--json"
|
|
1126
1069
|
];
|
|
1127
1070
|
else accessCommand = ["access", "ls-collaborators"];
|
|
1128
|
-
const res = await
|
|
1071
|
+
const res = await runNpmProxy([
|
|
1129
1072
|
...accessCommand,
|
|
1130
1073
|
name,
|
|
1131
1074
|
...registryArg
|
|
1132
1075
|
]);
|
|
1133
1076
|
if (res) {
|
|
1134
|
-
const permissions = JSON.parse(res ?? "{}")[
|
|
1077
|
+
const permissions = JSON.parse(res ?? "{}")[username];
|
|
1135
1078
|
return permissions && permissions.includes("write");
|
|
1136
1079
|
}
|
|
1137
|
-
log.error(`Unable to verify if user ${
|
|
1080
|
+
log.error(`Unable to verify if user ${username} is a collaborator for ${name}.`);
|
|
1138
1081
|
};
|
|
1139
1082
|
const getPackageUrl = (ctx) => {
|
|
1140
|
-
const { name } = ctx
|
|
1141
|
-
return
|
|
1142
|
-
"https://www.npmjs.com",
|
|
1143
|
-
"/package",
|
|
1144
|
-
name
|
|
1145
|
-
]);
|
|
1083
|
+
const { pkg: { name, next } } = ctx;
|
|
1084
|
+
return `https://www.npmjs.com/package/${name}/v/${next}`;
|
|
1146
1085
|
};
|
|
1147
1086
|
const npmCheck = async (ctx, config) => {
|
|
1148
1087
|
const { pkg: { name, publishConfig }, npm: { username } } = ctx;
|
|
@@ -1171,39 +1110,22 @@ const publishNpm = async (ctx, config) => {
|
|
|
1171
1110
|
if (tag) args.push("--tag", tag);
|
|
1172
1111
|
if (otp) args.push("--otp", otp);
|
|
1173
1112
|
if (dryRun) args.push("--dry-run");
|
|
1174
|
-
return
|
|
1113
|
+
return runNpmProxy(args);
|
|
1175
1114
|
};
|
|
1176
1115
|
|
|
1177
1116
|
//#endregion
|
|
1178
1117
|
//#region src/action.ts
|
|
1179
|
-
const info = (msg$1) => {
|
|
1180
|
-
console.log(`${rgb(33, 91, 184)(`ℹ`)} ${gray(msg$1)}`);
|
|
1181
|
-
};
|
|
1182
|
-
const success = (msg$1, dryRun) => {
|
|
1183
|
-
return `${(dryRun ? rgb(123, 115, 66) : green)("✔")} ${msg$1}`;
|
|
1184
|
-
};
|
|
1185
|
-
const runLifeCycleHook = async (hooks, key, dryRun) => {
|
|
1186
|
-
const handler = hooks[key];
|
|
1187
|
-
if (typeof handler === "function") {
|
|
1188
|
-
if (!dryRun) await handler();
|
|
1189
|
-
log.success(success(`${dim`run`} ${inspect(handler)}`, dryRun));
|
|
1190
|
-
return;
|
|
1191
|
-
}
|
|
1192
|
-
return Promise.allSettled(castArray(handler).map(async (hook) => {
|
|
1193
|
-
if (!dryRun) await execAsync(hook).catch(console.error);
|
|
1194
|
-
handler && log.success(success(hook.replace("echo", dim("echo")), dryRun));
|
|
1195
|
-
}));
|
|
1196
|
-
};
|
|
1197
1118
|
var Action = class {
|
|
1198
1119
|
async handle(cmdArgs, options) {
|
|
1199
1120
|
const { version: cVersion, name: cName } = readJsonFile(join(__dirname$1, "../package.json"));
|
|
1200
1121
|
info(`${cName} ${dim(`v${cVersion}`)} `);
|
|
1201
1122
|
const { otp, ...others } = options;
|
|
1202
1123
|
const { showChangelog, showRelease, ci, dryRun } = Object.fromEntries(Object.entries(others).map(([k, v]) => [k, Boolean(v)]));
|
|
1124
|
+
process.env["dryRun"] = String(dryRun);
|
|
1203
1125
|
const { version: pkgVersion, private: pkgPrivate, name: pkgName, publishConfig = {} } = readJsonFile("package.json");
|
|
1204
1126
|
const nextVersion = inc(pkgVersion, cmdArgs) ?? "";
|
|
1205
1127
|
const local = await resolveConfig(process.cwd(), (path$1) => {
|
|
1206
|
-
info(`config file: ${underline(path$1)}`);
|
|
1128
|
+
info(`config file: ${underline(dim(path$1))}`);
|
|
1207
1129
|
});
|
|
1208
1130
|
const config = mergeConfig(createDefaultConfig(ci ? true : void 0), local);
|
|
1209
1131
|
const ctx = mergeConfig(createDefaultContext(), {
|
|
@@ -1340,7 +1262,7 @@ var Action = class {
|
|
|
1340
1262
|
|
|
1341
1263
|
//#endregion
|
|
1342
1264
|
//#region src/cli.ts
|
|
1343
|
-
const pkg = readJsonFile(join(__dirname, "..", "package.json"));
|
|
1265
|
+
const pkg = readJsonFile(join(__dirname$1, "..", "package.json"));
|
|
1344
1266
|
program.name(pkg.name).description(pkg.description).version(pkg.version, "-v, --version", "Output the current version.").usage("[ARGUMENT] [OPTION]...").argument("[argument]", "patch|minor|major").option("-n, --dry-run", "Report actions that would be performed without writing out results.", false).option("--ci", "CI mode", false).option("--otp", "npm publish otp", "").option("--show-changelog", "Skip npm publish", false).option("--show-release", "Skip github release", false).action(async (argName, options) => {
|
|
1345
1267
|
await new Action().handle(argName, options);
|
|
1346
1268
|
}).helpOption("-h, --help", "Output usage information.").parse(process.argv);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DeepPartial, DeepRequired } from "@peiyanlu/ts-utils";
|
|
2
|
+
|
|
1
3
|
//#region src/types.d.ts
|
|
2
4
|
|
|
3
5
|
type HookTiming = 'before' | 'after';
|
|
@@ -29,10 +31,6 @@ interface ReleaseConfig {
|
|
|
29
31
|
assets: string[];
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
|
-
type Primitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
33
|
-
type Builtin = Primitive | Date | RegExp | Error | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any>;
|
|
34
|
-
type DeepRequired<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepRequired<U>[] : T extends Array<infer U> ? Array<DeepRequired<U>> : { [K in keyof T]-?: DeepRequired<T[K]> };
|
|
35
|
-
type DeepPartial<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepPartial<U>[] : T extends Array<infer U> ? Array<DeepPartial<U>> : { [K in keyof T]?: DeepPartial<T[K]> };
|
|
36
34
|
//#endregion
|
|
37
35
|
//#region src/config.d.ts
|
|
38
36
|
type UserConfig = DeepPartial<ReleaseConfig>;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DeepPartial, DeepRequired } from "@peiyanlu/ts-utils";
|
|
2
|
+
|
|
1
3
|
//#region src/types.d.ts
|
|
2
4
|
|
|
3
5
|
type HookTiming = 'before' | 'after';
|
|
@@ -29,10 +31,6 @@ interface ReleaseConfig {
|
|
|
29
31
|
assets: string[];
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
|
-
type Primitive = string | number | boolean | bigint | symbol | null | undefined;
|
|
33
|
-
type Builtin = Primitive | Date | RegExp | Error | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any>;
|
|
34
|
-
type DeepRequired<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepRequired<U>[] : T extends Array<infer U> ? Array<DeepRequired<U>> : { [K in keyof T]-?: DeepRequired<T[K]> };
|
|
35
|
-
type DeepPartial<T> = T extends Builtin ? T : T extends ((...args: any[]) => any) ? T : T extends readonly (infer U)[] ? DeepPartial<U>[] : T extends Array<infer U> ? Array<DeepPartial<U>> : { [K in keyof T]?: DeepPartial<T[K]> };
|
|
36
34
|
//#endregion
|
|
37
35
|
//#region src/config.d.ts
|
|
38
36
|
type UserConfig = DeepPartial<ReleaseConfig>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peiyanlu/release",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Release project tool.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
"bin": {
|
|
9
9
|
"release": "index.js"
|
|
10
10
|
},
|
|
11
|
-
"main": "dist/index.cjs",
|
|
12
|
-
"types": "dist/index.d.cts",
|
|
13
11
|
"exports": {
|
|
14
12
|
".": {
|
|
15
13
|
"import": {
|
|
@@ -32,8 +30,8 @@
|
|
|
32
30
|
"dependencies": {
|
|
33
31
|
"@clack/prompts": "^0.11.0",
|
|
34
32
|
"@octokit/rest": "^22.0.1",
|
|
35
|
-
"@peiyanlu/cli-utils": "^0.0.
|
|
36
|
-
"@peiyanlu/ts-utils": "^0.0.
|
|
33
|
+
"@peiyanlu/cli-utils": "^0.0.3",
|
|
34
|
+
"@peiyanlu/ts-utils": "^0.0.3",
|
|
37
35
|
"ansis": "^4.2.0",
|
|
38
36
|
"commander": "^14.0.2",
|
|
39
37
|
"mime-types": "^3.0.2",
|
|
@@ -46,7 +44,7 @@
|
|
|
46
44
|
"@types/mime-types": "^3.0.1",
|
|
47
45
|
"@types/node": "^24.10.3",
|
|
48
46
|
"@vitest/coverage-v8": "^4.0.15",
|
|
49
|
-
"tsdown": "^0.18.
|
|
47
|
+
"tsdown": "^0.18.4",
|
|
50
48
|
"typescript": "^5.9.3",
|
|
51
49
|
"vitest": "^4.0.15"
|
|
52
50
|
},
|