@peiyanlu/release 0.0.6 → 0.0.7

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 CHANGED
@@ -65,6 +65,18 @@ pnpm release minor --ci
65
65
  | `--show-changelog` | 打印生成的 Changelog 并退出 |
66
66
  | `--ci` | 启用 CI 模式:禁用交互提示,缺少必要参数时直接失败;GitHub Actions 等 CI/CD 环境中默认启用 |
67
67
 
68
+ ### Prepare 相关参数
69
+
70
+ | 参数 | 说明 |
71
+ |-------------|--------------------------|
72
+ | `--prepare` | 仅仅变更版本、提交代码、创建 Tag、推送到远程 |
73
+
74
+ ```bash
75
+ pnpm release minor --prepare --ci --package pkg-a
76
+ ```
77
+
78
+ > 后续可以通过 tag 进行 npm 发布和创建 GitHub release
79
+
68
80
  ### Monorepo / CI 相关参数
69
81
 
70
82
  | 参数 | 说明 |
@@ -72,7 +84,7 @@ pnpm release minor --ci
72
84
  | `-p, --package <pkg>` | 指定要发布的子包名称(仅用于 Monorepo 的 CI 场景) |
73
85
 
74
86
  ```bash
75
- pnpm release minor --ci --package test-a
87
+ pnpm release minor --ci --package pkg-a
76
88
  ```
77
89
 
78
90
  ### npm 发布相关参数
@@ -268,6 +280,36 @@ GitHub Release 可基于 Git Tag 自动创建,并支持附带:
268
280
 
269
281
  工具默认配置偏向于 **单仓库(Single Repo)** 项目,但是可以通过配置使其支持 **Monorepo**
270
282
 
283
+ ## 流程拆分
284
+
285
+ ### 本地准备 Release(仅创建 Tag)
286
+
287
+ 在本地完成版本确认与变更准备:
288
+
289
+ - 确定下一个版本
290
+ - 更新 `package.json` / `CHANGELOG`
291
+ - 创建发布提交
292
+ - 创建并推送 git 标签
293
+
294
+ ### CI/CD 自动发布(由 Tag 触发)
295
+
296
+ 当 Tag 推送到远端后,CI/CD 自动执行:
297
+
298
+ - 发布到 npm
299
+ - 创建 GItHub release
300
+
301
+ ```ts
302
+ // publishCI.ts
303
+ import { publishTagToNpm } from '@peiyanlu/release'
304
+
305
+
306
+ await publishTagToNpm({
307
+ gitTag: '1.0.16',
308
+ getPkgDir: () => '.',
309
+ defaultPackage: '.',
310
+ })
311
+ ```
312
+
271
313
  ## Dry Run
272
314
 
273
315
  ```bash
package/dist/cli.mjs CHANGED
@@ -1,14 +1,14 @@
1
1
  import path, { join, resolve } from "node:path";
2
2
  import { fileURLToPath, pathToFileURL } from "node:url";
3
- import { bumpPackageVersion, coloredChangeset, eol, execAsync, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLog, getPackageInfo, getPackageUrl, getPublishedVersion, getRemote, getStatus, gitAddAll, gitAddTracked, gitCommit, gitTagAnnotated, hasWriteAccess, isGitRepo, isWorkingDirClean, parseGitHubRepo, pingRegistry, publishPackage, pushBranch, pushTag, readJsonFile, resolveChangelogRange } from "@peiyanlu/cli-utils";
3
+ import { bumpPackageVersion, coloredChangeset, eol, execAsync, getAllRemotes, getAuthenticatedUser, getCurrentBranch, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLog, getPackageInfo, getPackageUrl, getPublishedVersion, getRemote, getStatus, gitAddAll, gitAddTracked, gitCommit, gitTagAnnotated, hasWriteAccess, isGitRepo, isPrerelease, isValid, isWorkingDirClean, parseGitHubRepo, parseVersion, pingRegistry, publishPackage, pushBranch, pushTag, readJsonFile, resolveChangelogRange } from "@peiyanlu/cli-utils";
4
4
  import { dim, green, red, rgb, underline, yellow } from "ansis";
5
5
  import { program } from "commander";
6
6
  import { createReadStream, createWriteStream, existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
7
7
  import { cancel, confirm, group, intro, isCancel, log, outro, select, tasks, text } from "@clack/prompts";
8
8
  import { publint } from "publint";
9
9
  import { formatMessage } from "publint/utils";
10
- import { coerce, inc, lt, neq, parse, prerelease, valid } from "semver";
11
- import { castArray, isPlainObject, isUndefined } from "@peiyanlu/ts-utils";
10
+ import { inc, lt, neq } from "semver";
11
+ import { castArray, isFunction, isPlainObject, isUndefined } from "@peiyanlu/ts-utils";
12
12
  import { spawnSync } from "node:child_process";
13
13
  import { inspect } from "node:util";
14
14
  import { ConventionalChangelog } from "conventional-changelog";
@@ -55,7 +55,6 @@ const resolveConfig = async (cwd) => {
55
55
  config: await loadConfig(configFile)
56
56
  };
57
57
  };
58
- const isFunction = (v) => typeof v === "function";
59
58
  const mergeConfig = (defaults, overrides) => {
60
59
  if (!overrides) return structuredClone(defaults);
61
60
  if (Object.keys(defaults).length === 0) return structuredClone(overrides);
@@ -78,8 +77,9 @@ const n = (b) => b ? "(dry run)" : "";
78
77
  const t = () => green(`${Math.floor(process.uptime())}s`);
79
78
  const MSG = {
80
79
  INTRO: (dryRun) => `🚀 Starting release ${n(dryRun)}`,
80
+ INTRO_PREPARE: (dryRun) => `🚀 Starting prepare release ${n(dryRun)}`,
81
81
  OUTRO: (dryRun) => `🎉 Release finished successfully in ${t()} ${n(dryRun)}`,
82
- OUTRO_PREPARE: (dryRun) => `🎉 PrepareRelease finished successfully in ${t()} ${n(dryRun)}`,
82
+ OUTRO_PREPARE: (dryRun) => `🎉 Prepare release finished successfully in ${t()} ${n(dryRun)}`,
83
83
  LOG: {
84
84
  SHOW_VERSION: (version) => `🎉 Released ${green(version)}`,
85
85
  SHOW_CHANGELOG: "🎉 Changelog collected",
@@ -298,34 +298,6 @@ const formatTemplate = async (ctx, config) => {
298
298
  Object.assign(ctx.github, { releaseName });
299
299
  };
300
300
 
301
- //#endregion
302
- //#region src/version/bump.ts
303
- const isPreRelease = (version) => {
304
- return Boolean(prerelease(version));
305
- };
306
- const isValid = (version) => {
307
- return Boolean(valid(version));
308
- };
309
- const parseVersion = (raw) => {
310
- const next = isValid(raw) ? raw : coerce(raw)?.toString();
311
- if (!next) return {};
312
- const { prerelease: prerelease$1 } = parse(next);
313
- const toPreRelease = Boolean(prerelease$1.length);
314
- const [preId, preBase] = prerelease$1.map(String);
315
- return {
316
- next,
317
- toPreRelease,
318
- preId,
319
- preBase
320
- };
321
- };
322
- const getCIVersion = (current) => {
323
- return inc(current, Release.PATCH);
324
- };
325
- const isNeq = (current, next) => {
326
- return neq(current, next);
327
- };
328
-
329
301
  //#endregion
330
302
  //#region src/version/prompts.ts
331
303
  let Release = /* @__PURE__ */ function(Release$1) {
@@ -779,7 +751,7 @@ const getReleaseByTagSafe = async (octokit, options) => {
779
751
  }
780
752
  };
781
753
  const createCRelease = async (octokit, options) => {
782
- const { owner, repo, tag, name, body, draft, prerelease: prerelease$1, generateReleaseNotes, makeLatest, targetCommitish, discussionCategoryName } = options;
754
+ const { owner, repo, tag, name, body, draft, prerelease, generateReleaseNotes, makeLatest, targetCommitish, discussionCategoryName } = options;
783
755
  const { data } = await octokit.repos.createRelease({
784
756
  owner,
785
757
  repo,
@@ -787,7 +759,7 @@ const createCRelease = async (octokit, options) => {
787
759
  name,
788
760
  body,
789
761
  draft,
790
- prerelease: prerelease$1,
762
+ prerelease,
791
763
  generate_release_notes: generateReleaseNotes,
792
764
  make_latest: makeLatest,
793
765
  target_commitish: targetCommitish,
@@ -796,7 +768,7 @@ const createCRelease = async (octokit, options) => {
796
768
  return data;
797
769
  };
798
770
  const updateCRelease = async (octokit, options) => {
799
- const { owner, repo, tag, name, body, draft, prerelease: prerelease$1, generateReleaseNotes, makeLatest, targetCommitish, discussionCategoryName, releaseId } = options;
771
+ const { owner, repo, tag, name, body, draft, prerelease, generateReleaseNotes, makeLatest, targetCommitish, discussionCategoryName, releaseId } = options;
800
772
  const { data } = await octokit.repos.updateRelease({
801
773
  owner,
802
774
  repo,
@@ -805,7 +777,7 @@ const updateCRelease = async (octokit, options) => {
805
777
  name,
806
778
  body,
807
779
  draft,
808
- prerelease: prerelease$1,
780
+ prerelease,
809
781
  generate_release_notes: generateReleaseNotes,
810
782
  make_latest: makeLatest,
811
783
  target_commitish: targetCommitish,
@@ -842,13 +814,13 @@ const uploadAssets = async (octokit, options) => {
842
814
  }));
843
815
  };
844
816
  const createWebRelease = async (options) => {
845
- const { owner, repo, tag, title, body, prerelease: prerelease$1 } = options;
817
+ const { owner, repo, tag, title, body, prerelease } = options;
846
818
  const url = new URL(`${getGithubUrl(owner, repo)}/releases/new`);
847
819
  Object.entries({
848
820
  tag,
849
821
  title,
850
822
  body,
851
- prerelease: prerelease$1
823
+ prerelease
852
824
  }).forEach(([key, value]) => {
853
825
  url.searchParams.set(key, value);
854
826
  });
@@ -891,7 +863,7 @@ const githubCheck = async (ctx, config) => {
891
863
  const createRelease = async (ctx, config) => {
892
864
  const { pkg: { name, toPreRelease }, git: { currentTag }, isCI, dryRun } = ctx;
893
865
  const { github: { isWeb, token, owner, repo, changelog, releaseName } } = ctx;
894
- const { github: { release, assets, prerelease: prerelease$1, autoGenerate, draft } } = config;
866
+ const { github: { release, assets, prerelease, autoGenerate, draft } } = config;
895
867
  if (!release || dryRun) return;
896
868
  const octokit = new Octokit({ auth: token });
897
869
  if (isWeb) await createWebRelease({
@@ -900,7 +872,7 @@ const createRelease = async (ctx, config) => {
900
872
  tag: currentTag,
901
873
  title: releaseName,
902
874
  body: truncateBody(changelog),
903
- prerelease: String(toPreRelease || prerelease$1)
875
+ prerelease: String(toPreRelease || prerelease)
904
876
  });
905
877
  else if (isCI) {
906
878
  const res = await createCReleaseByTag(octokit, {
@@ -910,7 +882,7 @@ const createRelease = async (ctx, config) => {
910
882
  name: releaseName,
911
883
  body: autoGenerate ? "" : truncateBody(changelog),
912
884
  draft,
913
- prerelease: toPreRelease || prerelease$1,
885
+ prerelease: toPreRelease || prerelease,
914
886
  generateReleaseNotes: autoGenerate,
915
887
  makeLatest: "true"
916
888
  });
@@ -963,8 +935,8 @@ const runNpmOptPrompts = async (ctx, config) => {
963
935
  //#endregion
964
936
  //#region src/npm/publish.ts
965
937
  const resolvePublishTag = async (pkgName, version) => {
966
- const { toPreRelease, preId } = parseVersion(version);
967
- if (toPreRelease) return preId || "next";
938
+ const { isPrerelease: isPrerelease$1, preId } = parseVersion(version);
939
+ if (isPrerelease$1) return preId || "next";
968
940
  const active = await getPublishedVersion(pkgName);
969
941
  if (!active) return "latest";
970
942
  return lt(version, active) ? "previous" : "latest";
@@ -1018,7 +990,7 @@ var Action = class {
1018
990
  taskEnd(MSG.OUTRO(ctx.dryRun));
1019
991
  }
1020
992
  async handlePrepareRelease(cmdArgs, options) {
1021
- const { ctx, config } = await this.createContext(cmdArgs, options);
993
+ const { ctx, config } = await this.createContext(cmdArgs, options, true);
1022
994
  await this.checkTask(ctx, config);
1023
995
  await this.bumpTask(ctx, config);
1024
996
  await this.changelogTask(ctx, config);
@@ -1026,7 +998,7 @@ var Action = class {
1026
998
  if (ctx.dryRun) gitRollback(ctx);
1027
999
  taskEnd(MSG.OUTRO_PREPARE(ctx.dryRun));
1028
1000
  }
1029
- async createContext(cmdArgs, options) {
1001
+ async createContext(cmdArgs, options, prepare = false) {
1030
1002
  const { version: cVersion, name: cName } = readJsonFile(join(__dirname, "../package.json"));
1031
1003
  const { otp, package: defPkg, ...others } = options;
1032
1004
  const { showChangelog, showRelease, ci, dryRun } = Object.fromEntries(Object.entries(others).map(([k, v]) => [k, Boolean(v)]));
@@ -1036,7 +1008,7 @@ var Action = class {
1036
1008
  info(MSG.INFO.TOOL(cName, cVersion));
1037
1009
  info(MSG.INFO.CONFIG(configPath));
1038
1010
  console.log();
1039
- intro(MSG.INTRO(dryRun));
1011
+ intro(prepare ? MSG.INTRO_PREPARE(dryRun) : MSG.INTRO(dryRun));
1040
1012
  const { isMonorepo, packages, getPkgDir } = config;
1041
1013
  if (isMonorepo) {
1042
1014
  if (ci) {
@@ -1077,7 +1049,7 @@ var Action = class {
1077
1049
  pkg: {
1078
1050
  name: pkgName,
1079
1051
  isPrivate: pkgPrivate,
1080
- fromPreRelease: isPreRelease(pkgVersion),
1052
+ fromPreRelease: isPrerelease(pkgVersion),
1081
1053
  current: pkgVersion,
1082
1054
  next: nextVersion,
1083
1055
  toPreRelease: false,
@@ -1135,10 +1107,15 @@ var Action = class {
1135
1107
  return !next$1 && isIncrement$1;
1136
1108
  };
1137
1109
  if (need(ctx)) {
1138
- const next$1 = (isCI ? getCIVersion(current) : void 0) || await runVersionPrompts(ctx, config);
1139
- ctx.isIncrement = isNeq(current, next$1);
1140
- const parsed = parseVersion(next$1);
1141
- Object.assign(ctx.pkg, { ...parsed });
1110
+ const nextVersion = (isCI ? inc(current, "patch") : void 0) || await runVersionPrompts(ctx, config);
1111
+ ctx.isIncrement = neq(current, nextVersion);
1112
+ const { version: next$1, isPrerelease: toPreRelease, preId, preBase } = parseVersion(nextVersion);
1113
+ Object.assign(ctx.pkg, {
1114
+ next: next$1,
1115
+ toPreRelease,
1116
+ preId,
1117
+ preBase
1118
+ });
1142
1119
  }
1143
1120
  const { pkg: { next }, isIncrement } = ctx;
1144
1121
  if (showRelease) taskEnd(MSG.LOG.SHOW_VERSION(next));
@@ -1243,14 +1220,10 @@ var Action = class {
1243
1220
  //#endregion
1244
1221
  //#region src/cli.ts
1245
1222
  const pkg = readJsonFile(join(__dirname, "..", "package.json"));
1246
- function withCommonOptions(cmd) {
1247
- return cmd.version(pkg.version, "-v, --version", "Print the tool version and exit.").usage("[release-type] [options]").argument("[release-type]", "Version bump type: patch | minor | major").option("-n, --dry-run", "Run in dry mode", false).option("-p, --package <pkg>", "Specify package name (CI only).", "").option("--otp <code>", "One-time password for npm publish.", "").option("--ci", "Enable CI mode.", false).option("--show-changelog", "Print changelog and exit.", false).option("--show-release", "Print release version and exit.", false).helpOption("-h, --help", "Display help information.");
1248
- }
1249
- withCommonOptions(program.name("release").description(pkg.description)).action(async (releaseType, options) => {
1250
- await new Action().handleRelease(releaseType, options);
1251
- });
1252
- withCommonOptions(program.command("prepare").description("Prepare a release (bump version, commit, tag)")).action(async (releaseType, options) => {
1253
- await new Action().handlePrepareRelease(releaseType, options);
1223
+ program.name("release").description(pkg.description).version(pkg.version, "-v, --version", "Print the tool version and exit.").usage("[release-type] [options]").argument("[release-type]", "Version bump type: patch | minor | major").option("-n, --dry-run", "Run in dry mode", false).option("-p, --package <pkg>", "Specify package name (CI only).", "").option("--otp <code>", "One-time password for npm publish.", "").option("--prepare", "Prepare a release.", false).option("--ci", "Enable CI mode.", false).option("--show-changelog", "Print changelog and exit.", false).option("--show-release", "Print release version and exit.", false).helpOption("-h, --help", "Display help information.").action(async (releaseType, options) => {
1224
+ const { prepare } = options;
1225
+ const action = new Action();
1226
+ prepare ? await action.handlePrepareRelease(releaseType, options) : await action.handleRelease(releaseType, options);
1254
1227
  });
1255
1228
  program.command("init").description("Create a release configuration file").option("-f, --force", "Overwrite existing config file", false).option("-m, --monorepo", "Mono-repo project", false).action((options) => {
1256
1229
  const { force = false, monorepo = false } = options;
@@ -1258,9 +1231,10 @@ program.command("init").description("Create a release configuration file").optio
1258
1231
  const { type } = readJsonFile(join(cwd, "package.json"));
1259
1232
  const isESM = type === "module";
1260
1233
  const isTS = existsSync(join(cwd, "tsconfig.json"));
1261
- const configPath = join(cwd, `release.config.${isESM ? "" : "m"}${isTS ? "ts" : "js"}`);
1234
+ const infile = `release.config.${isESM ? "" : "m"}${isTS ? "ts" : "js"}`;
1235
+ const configPath = join(cwd, infile);
1262
1236
  if (existsSync(configPath) && !force) {
1263
- console.error(`${red`Error:`} ${yellow`release.config.ts`} already exists.\nUse ${green`--force`} to overwrite.`);
1237
+ console.error(`${red`Error:`} ${yellow(infile)} already exists.\nUse ${green`--force`} to overwrite.`);
1264
1238
  process.exit(1);
1265
1239
  }
1266
1240
  const monoConfigToString = () => `{
@@ -1270,10 +1244,8 @@ program.command("init").description("Create a release configuration file").optio
1270
1244
  toTag: (pkg, version) => \`\${ pkg }@\${ version }\`,
1271
1245
  tagPrefix: (pkg) => \`\${ pkg }@\`,
1272
1246
  }`;
1273
- writeFileSync(configPath, `import { defineConfig } from '@peiyanlu/release'
1274
-
1275
- export default defineConfig(${monorepo ? monoConfigToString() : "{}"})`, "utf-8");
1276
- console.log(`${green`✔ release.config.ts`} created successfully`);
1247
+ writeFileSync(configPath, [`import { defineConfig } from '@peiyanlu/release'`, `export default defineConfig(${monorepo ? monoConfigToString() : "{}"})`].join(eol(2)), "utf-8");
1248
+ console.log(`${green`✔`} ${infile} created successfully`);
1277
1249
  });
1278
1250
  program.parse(process.argv);
1279
1251
  program.on("command:*", () => {
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { log } from "@clack/prompts";
2
1
  import { DeepPartial, DeepRequired } from "@peiyanlu/ts-utils";
3
2
  import { ConventionalChangelog } from "conventional-changelog";
3
+ import { log } from "@clack/prompts";
4
4
 
5
5
  //#region src/types.d.ts
6
6
 
package/dist/index.mjs CHANGED
@@ -1,8 +1,7 @@
1
- import { eol, getPackageInfo, getPublishedVersion, publishPackage } from "@peiyanlu/cli-utils";
2
- import { coerce, lt, parse, valid } from "semver";
3
- import { dim, green, underline, yellow } from "ansis";
4
- import { log } from "@clack/prompts";
5
- import { isPlainObject } from "@peiyanlu/ts-utils";
1
+ import { eol, getPackageInfo, getPublishedVersion, parseVersion, publishPackage } from "@peiyanlu/cli-utils";
2
+ import { blue, cyan, dim, green, magenta, red, underline, yellow } from "ansis";
3
+ import { lt } from "semver";
4
+ import { isFunction, isPlainObject } from "@peiyanlu/ts-utils";
6
5
  import { createWriteStream, existsSync, readFileSync } from "node:fs";
7
6
  import { join } from "node:path";
8
7
  import { ConventionalChangelog } from "conventional-changelog";
@@ -15,8 +14,9 @@ const n = (b) => b ? "(dry run)" : "";
15
14
  const t = () => green(`${Math.floor(process.uptime())}s`);
16
15
  const MSG = {
17
16
  INTRO: (dryRun) => `🚀 Starting release ${n(dryRun)}`,
17
+ INTRO_PREPARE: (dryRun) => `🚀 Starting prepare release ${n(dryRun)}`,
18
18
  OUTRO: (dryRun) => `🎉 Release finished successfully in ${t()} ${n(dryRun)}`,
19
- OUTRO_PREPARE: (dryRun) => `🎉 PrepareRelease finished successfully in ${t()} ${n(dryRun)}`,
19
+ OUTRO_PREPARE: (dryRun) => `🎉 Prepare release finished successfully in ${t()} ${n(dryRun)}`,
20
20
  LOG: {
21
21
  SHOW_VERSION: (version) => `🎉 Released ${green(version)}`,
22
22
  SHOW_CHANGELOG: "🎉 Changelog collected",
@@ -93,30 +93,11 @@ const MSG = {
93
93
  }
94
94
  };
95
95
 
96
- //#endregion
97
- //#region src/version/bump.ts
98
- const isValid = (version) => {
99
- return Boolean(valid(version));
100
- };
101
- const parseVersion = (raw) => {
102
- const next = isValid(raw) ? raw : coerce(raw)?.toString();
103
- if (!next) return {};
104
- const { prerelease } = parse(next);
105
- const toPreRelease = Boolean(prerelease.length);
106
- const [preId, preBase] = prerelease.map(String);
107
- return {
108
- next,
109
- toPreRelease,
110
- preId,
111
- preBase
112
- };
113
- };
114
-
115
96
  //#endregion
116
97
  //#region src/npm/publish.ts
117
98
  const resolvePublishTag = async (pkgName, version) => {
118
- const { toPreRelease, preId } = parseVersion(version);
119
- if (toPreRelease) return preId || "next";
99
+ const { isPrerelease, preId } = parseVersion(version);
100
+ if (isPrerelease) return preId || "next";
120
101
  const active = await getPublishedVersion(pkgName);
121
102
  if (!active) return "latest";
122
103
  return lt(version, active) ? "previous" : "latest";
@@ -127,7 +108,6 @@ const resolvePublishTag = async (pkgName, version) => {
127
108
  function defineConfig(config) {
128
109
  return config;
129
110
  }
130
- const isFunction = (v) => typeof v === "function";
131
111
  const mergeConfig = (defaults, overrides) => {
132
112
  if (!overrides) return structuredClone(defaults);
133
113
  if (Object.keys(defaults).length === 0) return structuredClone(overrides);
@@ -327,35 +307,35 @@ const publishTagToNpm = async (options) => {
327
307
  const { gitTag, defaultPackage, tagSeparator = "@", getPkgDir = () => ".", provenance } = options;
328
308
  const tag = process.argv.slice(2)[0] || gitTag;
329
309
  if (!tag) throw new Error(`❌ No git tag specified.`);
330
- console.log(`\n📦 Start publishing from git tag: ${tag}`);
310
+ console.log(`\n📦 Start publishing from git tag: ${cyan(tag)}`);
331
311
  let pkgName = defaultPackage;
332
312
  let version;
333
313
  if (tag.includes(tagSeparator)) {
334
314
  [pkgName, version] = tag.split(tagSeparator);
335
- console.log(`🔍 Parsed tag → package: "${pkgName}", version: "${version}"`);
315
+ console.log(`🔍 Parsed tag → package: "${yellow(pkgName)}", version: "${green(version)}"`);
336
316
  } else {
337
317
  version = tag;
338
- console.log(`🔍 Parsed tag → version only: "${version}"`);
318
+ console.log(`🔍 Parsed tag → version only: "${green(version)}"`);
339
319
  }
340
320
  if (version.startsWith("v")) {
341
321
  version = version.slice(1);
342
322
  console.log(`✂️ Normalized version (strip v): ${version}`);
343
323
  }
344
324
  if (!pkgName) throw new Error(`❌ Package name should be specified in tag "${tag}" when defaultPackage is not set`);
345
- console.log(`📁 Resolving package info for "${pkgName}"...`);
325
+ console.log(`📁 Resolving package info for "${magenta(pkgName)}"...`);
346
326
  const { pkg, pkgDir } = getPackageInfo(pkgName, getPkgDir);
347
- console.log(`📄 package.json → name: ${pkg.name}, version: ${pkg.version}`);
348
- console.log(`📂 Package directory: ${pkgDir}`);
327
+ console.log(`📄 package.json → name: ${yellow(pkg.name)}, version: ${green(pkg.version)}`);
328
+ console.log(`📂 Package directory: ${underline(pkgDir)}`);
349
329
  if (pkg.version !== version) throw new Error(`❌ Package version from tag "${version}" mismatches with current version "${pkg.version}"`);
350
330
  const publishTag = await resolvePublishTag(pkg.name, version);
351
- console.log(`🏷 Resolved npm dist-tag: "${publishTag}" (version ${version})`);
352
- console.log(`🚀 Publishing "${pkg.name}@${version}" to npm...`);
331
+ console.log(`🏷 Resolved npm dist-tag: "${blue(publishTag)}" (version ${green(version)})`);
332
+ console.log(`🚀 Publishing "${red`${pkg.name}@${version}`}" to npm...`);
353
333
  await publishPackage({
354
334
  tag: publishTag,
355
335
  args: provenance ? ["--provenance"] : [],
356
336
  cwd: pkgDir
357
337
  });
358
- console.log(`✅ Successfully published ${pkg.name}@${version} with dist-tag "${publishTag}"\n`);
338
+ console.log(`🎉 Successfully published ${red`${pkg.name}@${version}`} with dist-tag "${blue(publishTag)}"\n`);
359
339
  };
360
340
 
361
341
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peiyanlu/release",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Release project tool.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,11 +17,19 @@
17
17
  },
18
18
  "./package.json": "./package.json"
19
19
  },
20
+ "scripts": {
21
+ "dev": "tsdown -w",
22
+ "build": "tsdown",
23
+ "prepublish": "tsdown",
24
+ "release": "node index.js",
25
+ "test": "vitest run",
26
+ "test:cov": "vitest run --coverage"
27
+ },
20
28
  "dependencies": {
21
29
  "@clack/prompts": "^0.11.0",
22
30
  "@octokit/rest": "^22.0.1",
23
- "@peiyanlu/cli-utils": "^0.0.6",
24
- "@peiyanlu/ts-utils": "^0.0.4",
31
+ "@peiyanlu/cli-utils": "^0.0.7",
32
+ "@peiyanlu/ts-utils": "^0.0.5",
25
33
  "ansis": "^4.2.0",
26
34
  "commander": "^14.0.2",
27
35
  "conventional-changelog": "^7.1.1",
@@ -66,13 +74,5 @@
66
74
  "bugs": {
67
75
  "url": "https://github.com/peiyanlu/release/issues"
68
76
  },
69
- "homepage": "https://github.com/peiyanlu/release#readme",
70
- "scripts": {
71
- "dev": "tsdown -w",
72
- "build": "tsdown",
73
- "prepublish": "tsdown",
74
- "release": "node index.js",
75
- "test": "vitest run",
76
- "test:cov": "vitest run --coverage"
77
- }
78
- }
77
+ "homepage": "https://github.com/peiyanlu/release#readme"
78
+ }