@peiyanlu/release 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.mjs +68 -39
  2. package/package.json +5 -5
package/dist/cli.mjs CHANGED
@@ -1,30 +1,30 @@
1
- import path, { join, resolve } from "node:path";
2
- import { fileURLToPath, pathToFileURL } from "node:url";
3
- import { bumpPackageVersion, canPublish, coloredStatus, eol, execAsync, getAuthenticatedUser, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLogSince, getPackageInfo, getPackageUrl, getPublishedVersion, getRemoteList, getRemoteNames, getShortStatus, gitAddAll, gitAddSync, gitAddTracked, gitBranchCurrent, gitCommitMessage, gitPushBranch, gitPushTag, gitResetHardSync, gitTagAnnotated, gitTagDeleteSync, hasWriteAccess, isGitRepo, isOtpError, isPrerelease, isValidVersion, isWorkingTreeClean, parseGitHubRepo, parseVersion, pingRegistry, publishPackage, resolveChangelogRange, resolvePublishTag } from "@peiyanlu/cli-utils";
1
+ import { bold, compareUrl, each, heading, link, list, newline, segments, small, words } from "@conventional-changelog/template";
2
+ import { bumpPackageVersion, coloredStatus, eol, execAsync, getAuthenticatedUser, getGithubReleaseUrl, getGithubUrl, getLatestTag, getLogSince, getPackageInfo, getPackageUrl, getPublishedVersion, getRemoteList, getRemoteNames, getShortStatus, gitAddAll, gitAddSync, gitAddTracked, gitBranchCurrent, gitCommitMessage, gitPushBranch, gitPushTag, gitResetHardSync, gitTagAnnotated, gitTagDeleteSync, hasWriteAccess, isGitRepo, isOtpError, isPrerelease, isValidVersion, isWorkingTreeClean, parseGitHubRepo, parseVersion, pingRegistry, publishPackage, registryArg, resolveChangelogRange, resolvePublishTag, runNpm } from "@peiyanlu/cli-utils";
4
3
  import { copyDir, createMatcher, createTempDir, editFile, readJsonFile, readJsonFileSync, writeJsonFile } from "@peiyanlu/node-utils";
5
4
  import { dim, green, red, rgb, underline, yellow } from "ansis";
6
5
  import { program } from "commander";
7
6
  import { createReadStream, createWriteStream, existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
7
+ import { join, resolve } from "node:path";
8
8
  import { cancel, confirm, group, intro, isCancel, log, outro, select, tasks, text } from "@clack/prompts";
9
- import { castArray, isEmptyObject, isFunction, isPlainObject, isUndefined, isZero, mapObject, omit, partition, unset } from "@peiyanlu/ts-utils";
9
+ import { castArray, isBoolean, isEmptyObject, isFunction, isNotEmpty, isNumber, isPlainObject, isUndefined, isZero, omit, partition, unset } from "@peiyanlu/ts-utils";
10
10
  import { publint } from "publint";
11
11
  import { formatMessage } from "publint/utils";
12
12
  import { inc, neq } from "semver";
13
+ import { pathToFileURL } from "node:url";
13
14
  import { inspect } from "node:util";
14
15
  import { ConventionalChangelog } from "conventional-changelog";
15
16
  import createPreset from "conventional-changelog-conventionalcommits";
16
17
  import { Bumper } from "conventional-recommended-bump";
17
18
  import { writeFile } from "node:fs/promises";
18
19
  import { finished } from "node:stream/promises";
19
- import { bold, compareUrl, each, heading, link, list, newline, segments, small, words } from "@conventional-changelog/template";
20
20
  import { Octokit } from "@octokit/rest";
21
21
  import { contentType } from "mime-types";
22
22
  import open from "open";
23
23
  import { glob } from "tinyglobby";
24
- //#region node_modules/.pnpm/tsdown@0.22.13_publint@0.3.21_typescript@6.0.3/node_modules/tsdown/esm-shims.js
25
- const getFilename = () => fileURLToPath(import.meta.url);
26
- const getDirname = () => path.dirname(getFilename());
27
- const __dirname = /* @__PURE__ */ getDirname();
24
+ //#region package.json
25
+ var name = "@peiyanlu/release";
26
+ var version = "1.2.0";
27
+ var description = "Release project tool.";
28
28
  //#endregion
29
29
  //#region src/config.ts
30
30
  const findConfigFile = (cwd = process.cwd()) => {
@@ -1033,16 +1033,33 @@ Read full docs **[here](${homepage})**.`;
1033
1033
  };
1034
1034
  //#endregion
1035
1035
  //#region src/npm/publish.ts
1036
+ const canPublish = async (registry, cwd) => {
1037
+ const res = await runNpm([
1038
+ "publish",
1039
+ "--dry-run",
1040
+ "--access",
1041
+ "public",
1042
+ ...registryArg(registry)
1043
+ ], {
1044
+ error: "throw",
1045
+ cwd
1046
+ }).catch((err) => err);
1047
+ const allowedErr = (err) => {
1048
+ return [/previously published versions/i, /cannot publish over/i].some((reg) => reg.test(err.message));
1049
+ };
1050
+ if (!(res instanceof Error) || allowedErr(res)) return true;
1051
+ throw res;
1052
+ };
1036
1053
  const npmCheck = async (ctx, config) => {
1037
- const { pkg: { name, current, publishConfig: { registry } } } = ctx;
1038
- const { npm: { skipChecks } } = config;
1054
+ const { pkg: { name, current, publishConfig: { registry } }, selectedPkg } = ctx;
1055
+ const { npm: { skipChecks }, getPkgDir } = config;
1039
1056
  const tag = await resolvePublishTag(name, current);
1040
1057
  Object.assign(ctx.npm, { tag });
1041
1058
  if (skipChecks) return "";
1042
1059
  const [pinged, username] = await Promise.all([
1043
1060
  pingRegistry(registry),
1044
1061
  getAuthenticatedUser(registry),
1045
- canPublish(registry)
1062
+ canPublish(registry, getPkgDir(selectedPkg))
1046
1063
  ]);
1047
1064
  if (!pinged) throw new Error(MSG.ERROR.NPM_REGISTRY(registry));
1048
1065
  if (!username) throw new Error(MSG.ERROR.NPM_AUTH);
@@ -1100,7 +1117,7 @@ var Action = class {
1100
1117
  taskEnd(MSG.OUTRO(ctx.dryRun));
1101
1118
  }
1102
1119
  async handlePrepareRelease(cmdArgs, options) {
1103
- const { ctx, config } = await this.createContext(cmdArgs, options, true);
1120
+ const { ctx, config } = await this.createContext(cmdArgs, options);
1104
1121
  await this.checkTask(ctx, config);
1105
1122
  await this.bumpTask(ctx, config);
1106
1123
  await this.changelogTask(ctx, config);
@@ -1108,27 +1125,12 @@ var Action = class {
1108
1125
  if (ctx.dryRun) gitRollback(ctx);
1109
1126
  taskEnd(MSG.OUTRO_PREPARE(ctx.dryRun));
1110
1127
  }
1111
- async createContext(cmdArgs, options, prepare = false) {
1112
- const { version: cVersion, name: cName } = readJsonFileSync(join(__dirname, "../package.json"));
1113
- const { otp, package: defPkg, releaseCount, ...others } = options;
1114
- const { showChangelog, showRelease, ci, dryRun, onlyChangelog } = mapObject(others, (k, v) => [k, Boolean(v)]);
1115
- process.env["dryRun"] = String(dryRun);
1116
- const { configFile, config: local } = await resolveConfig(process.cwd());
1117
- const config = mergeConfig(createDefaultConfig(ci ? true : void 0), local);
1118
- info(MSG.INFO.TOOL(cName, cVersion));
1128
+ async createContext(cmdArgs, options) {
1129
+ const { configFile, config } = await this.createConfig(options);
1130
+ info(MSG.INFO.TOOL(name, version));
1119
1131
  info(MSG.INFO.CONFIG(configFile));
1120
- {
1121
- const { requireCleanWorkingTree, skipGit, skipNpm, skipGithub, isMonorepo, includeHidden } = mapObject(others, (k, v) => [k, Boolean(v)]);
1122
- const count = Number(releaseCount);
1123
- config.changelog.releaseCount = isNaN(count) ? 0 : count;
1124
- config.changelog.includeHidden = includeHidden;
1125
- config.git.requireCleanWorkingTree = requireCleanWorkingTree;
1126
- config.skipGit = skipGit;
1127
- config.skipNpm = skipNpm;
1128
- config.skipGithub = skipGithub;
1129
- config.isMonorepo = isMonorepo;
1130
- }
1131
1132
  console.log();
1133
+ const { otp, package: defPkg, prepare, showChangelog, showRelease, ci, dryRun, onlyChangelog } = options;
1132
1134
  intro(prepare ? MSG.INTRO_PREPARE(dryRun) : MSG.INTRO(dryRun));
1133
1135
  const { isMonorepo, packages, getPkgDir, skipNpm } = config;
1134
1136
  if (isMonorepo) {
@@ -1153,7 +1155,7 @@ var Action = class {
1153
1155
  const nextVersion = inc(pkgVersion, cmdArgs) ?? "";
1154
1156
  const ctx = mergeConfig(createDefaultContext(), {
1155
1157
  selectedPkg,
1156
- configFileExists: Object.keys(local).length > 0,
1158
+ configFileExists: isNotEmpty(configFile),
1157
1159
  dryRun,
1158
1160
  showRelease,
1159
1161
  showChangelog,
@@ -1189,6 +1191,34 @@ var Action = class {
1189
1191
  config
1190
1192
  };
1191
1193
  }
1194
+ async createConfig(options) {
1195
+ const { ci, requireCleanWorkingTree, skipGit, skipNpm, skipGithub, isMonorepo, includeHidden, releaseCount } = options;
1196
+ const toFalse = (value) => {
1197
+ return isBoolean(value) && !value ? value : void 0;
1198
+ };
1199
+ const toNumber = (value) => {
1200
+ return isNumber(value) ? value : void 0;
1201
+ };
1202
+ const defaultConfig = createDefaultConfig(ci ? true : void 0);
1203
+ const { configFile, config: local } = await this.resolveUserConfig(process.cwd());
1204
+ return {
1205
+ configFile,
1206
+ config: mergeConfig(mergeConfig(defaultConfig, local), {
1207
+ changelog: {
1208
+ releaseCount: toNumber(releaseCount),
1209
+ includeHidden
1210
+ },
1211
+ git: { requireCleanWorkingTree: toFalse(requireCleanWorkingTree) },
1212
+ skipGit,
1213
+ skipNpm,
1214
+ skipGithub,
1215
+ isMonorepo
1216
+ })
1217
+ };
1218
+ }
1219
+ async resolveUserConfig(cwd = process.cwd()) {
1220
+ return resolveConfig(cwd);
1221
+ }
1192
1222
  async printChangelog(ctx, config) {
1193
1223
  const { showChangelog, selectedPkg, noGit, isIncrement } = ctx;
1194
1224
  const { isMonorepo, getPkgDir, changelog: { tagPrefix, releaseCount, includeHidden, transformTypes } } = config;
@@ -1370,13 +1400,12 @@ var Action = class {
1370
1400
  };
1371
1401
  //#endregion
1372
1402
  //#region src/cli.ts
1373
- const pkg = readJsonFileSync(join(__dirname, "..", "package.json"));
1374
- 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("-m, --is-monorepo", "Mono-repo project", false).option("-p, --package <pkg>", "Specify package name (Mono-repo 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).option("-r, --release-count <count>", "Release count for release.", (value) => Number(value), 1).option("--include-hidden", "Include hidden commit types in the changelog.", false).option("--only-changelog", "Only update the changelog.", false).option("-C, --no-require-clean-working-tree", "Allow releasing with uncommitted changes.", true).option("--skip-git", "Skip all Git-related checks and operations.", false).option("--skip-npm", "Skip all npm-related checks and operations.", false).option("--skip-github", "Skip all GitHub-related checks and operations.", false).helpOption("-h, --help", "Display help information.").action(async (releaseType, options) => {
1403
+ program.name("release").description(description).version(version, "-v, --version", "Print the tool version and exit.").usage("[release-type] [options]").argument("[release-type]", "Version bump type: patch | minor | major").enablePositionalOptions().option("-n, --dry-run", "Run in dry mode", false).option("-p, --package <pkg>", "Specify package name (Mono-repo 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).option("--only-changelog", "Only update the changelog.", false).option("-r, --release-count <count>", "Release count for release.", (val) => Number(val)).option("--include-hidden", "Include hidden commit types in the changelog.").option("-C, --no-require-clean-working-tree", "Allow releasing with uncommitted changes.").option("--skip-git", "Skip all Git-related checks and operations.").option("--skip-npm", "Skip all npm-related checks and operations.").option("--skip-github", "Skip all GitHub-related checks and operations.").option("-m, --is-monorepo", "Mono-repo project").helpOption("-h, --help", "Display help information.").action(async (releaseType, options) => {
1375
1404
  const { prepare } = options;
1376
1405
  const action = new Action();
1377
1406
  prepare ? await action.handlePrepareRelease(releaseType, options) : await action.handleRelease(releaseType, options);
1378
1407
  });
1379
- program.command("init").description("Create a release configuration file").option("-f, --force", "Overwrite existing config file", false).option("-m, --monorepo", "Mono-repo project", false).option("-a, --add", "Automatically stage the config file.", false).action((options) => {
1408
+ program.command("init").description("Create a release configuration file").option("-f, --force", "Overwrite existing config file", false).option("-m, --monorepo", "Mono-repo project", false).option("-a, --add", "Automatically stage the config file.", false).action(async (options) => {
1380
1409
  const { force = false, monorepo = false, add = false } = options;
1381
1410
  const cwd = process.cwd();
1382
1411
  const { type } = readJsonFileSync(join(cwd, "package.json"));
@@ -1390,15 +1419,15 @@ program.command("init").description("Create a release configuration file").optio
1390
1419
  }
1391
1420
  const monoConfigToString = () => `{
1392
1421
  isMonorepo: true,
1393
- packages: [ 'demo-a', 'demo-b' ],
1422
+ packages: [],
1394
1423
  getPkgDir: (pkg) => \`packages/\${ pkg }\`,
1395
1424
  toTag: (pkg, version) => \`\${ pkg }@\${ version }\`,
1396
1425
  changelog: {
1397
1426
  tagPrefix: (pkg) => \`\${ pkg }@\`,
1398
1427
  },
1399
1428
  }`;
1400
- const content = [`import { defineConfig } from '@peiyanlu/release'`, `export default defineConfig(${monorepo ? monoConfigToString() : "{}"})`].join(eol(2));
1401
- writeFileSync(configFile, content, "utf-8");
1429
+ const content = [`import { defineConfig } from '@peiyanlu/release'`, `export default defineConfig(${monorepo ? monoConfigToString() : "{}"})`].join(eol(3));
1430
+ writeFileSync(configFile, content + newline(), "utf-8");
1402
1431
  console.log(`Wrote to ${underline(dim(configFile))}`);
1403
1432
  if (add) gitAddSync([infile]);
1404
1433
  console.log(`\n${content}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peiyanlu/release",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Release project tool.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -23,9 +23,9 @@
23
23
  "@clack/prompts": "^1.7.0",
24
24
  "@conventional-changelog/template": "^1.2.1",
25
25
  "@octokit/rest": "^22.0.1",
26
- "@peiyanlu/cli-utils": "^0.0.14",
27
- "@peiyanlu/node-utils": "^0.0.2",
28
- "@peiyanlu/ts-utils": "^0.0.11",
26
+ "@peiyanlu/cli-utils": "^0.0.15",
27
+ "@peiyanlu/node-utils": "^0.0.3",
28
+ "@peiyanlu/ts-utils": "^0.0.12",
29
29
  "ansis": "^4.3.1",
30
30
  "commander": "^15.0.0",
31
31
  "conventional-changelog": "^8.1.0",
@@ -34,7 +34,7 @@
34
34
  "mime-types": "^3.0.2",
35
35
  "minimatch": "^10.2.5",
36
36
  "open": "^11.0.0",
37
- "publint": "^0.3.21",
37
+ "publint": "^0.3.22",
38
38
  "semver": "^7.8.5",
39
39
  "tinyglobby": "^0.2.17"
40
40
  },