@peiyanlu/release 2.0.0 → 2.1.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.
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { createWriteStream, existsSync, readFileSync } from "node:fs";
2
- import { dirname, isAbsolute, join, parse, resolve } from "node:path";
3
- import { pathToFileURL } from "node:url";
4
- import { eol, execAsync, getAuthenticatedUser, getGithubUrl, getPublishedVersion, gitAdd, gitBranch, gitBranchCurrent, gitCheckout, gitCheckoutBranch, gitCheckoutBranchForce, gitCommitAmendNoEdit, gitCommitMessage, gitConfigGet, gitConfigSet, gitDiff, gitFetch, gitLog, gitLsRemote, gitPush, gitPushBranch, gitRevParse, gitTag, hasWriteAccess, isGitRepo, isPrerelease, isValidVersion, isWorkingTreeClean, parseGitHubRepo, pingRegistry, runGit } from "@peiyanlu/cli-utils";
5
- import { copyDir, createMatcher, createTempDir, editFile, normalizePath, readJsonFile, writeJsonFile } from "@peiyanlu/node-utils";
6
- import { assert, dedent, equals, isBlankString, isBoolean, isEmpty, isEmptyObject, isFunction, isIndex, isNotEmpty, isNull, isString, isUndefined, isZero, newline, omit, onceAsync, partition, sleep, throwError, tryCall, tryCallSync, unset } from "@peiyanlu/ts-utils";
2
+ import path, { dirname, isAbsolute, join, parse, resolve } from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { eol, execAsync, getGithubUrl, gitAdd, gitBranch, gitBranchCurrent, gitCheckout, gitCheckoutBranch, gitCheckoutBranchForce, gitCommitAmendNoEdit, gitCommitMessage, gitConfigGet, gitConfigSet, gitDiff, gitFetch, gitLog, gitLsRemote, gitPush, gitPushBranch, gitRevParse, gitTag, isPrerelease, isValidVersion, runGit } from "@peiyanlu/cli-utils";
5
+ import { copyDir, createMatcher, createTempDir, editFile, normalizePath, readJsonFile, readJsonFileSync, writeJsonFile } from "@peiyanlu/node-utils";
6
+ import { dedent, equals, isBlankString, isBoolean, isEmpty, isEmptyObject, isFunction, isIndex, isNotEmpty, isNull, isString, isUndefined, isZero, newline, omit, onceAsync, partition, sleep, throwError, tryCall, tryCallSync, unset } from "@peiyanlu/ts-utils";
7
7
  import { ConventionalChangelog } from "conventional-changelog";
8
8
  import createPreset from "conventional-changelog-conventionalcommits";
9
9
  import { Bumper } from "conventional-recommended-bump";
@@ -19,7 +19,7 @@ import { context } from "@actions/github";
19
19
  import { getBooleanInput, getInput } from "@actions/core";
20
20
  import { cancel, confirm, group, intro, isCancel, log, note, outro, select, text } from "@clack/prompts";
21
21
  import { blue, blueBright, cyan, cyanBright, dim, green, greenBright, magenta, magentaBright, red, redBright, yellow } from "ansis";
22
- //#region src/config/index.ts
22
+ // src/config/index.ts
23
23
  const defineConfig = (config) => config;
24
24
  const loadJavaScriptFile = async (file) => {
25
25
  const { href } = pathToFileURL(file);
@@ -49,8 +49,7 @@ const loadConfig = async (cwd = process.cwd()) => {
49
49
  config: await loadJavaScriptFile(file)
50
50
  };
51
51
  };
52
- //#endregion
53
- //#region src/core/changelog/committype.ts
52
+ // src/core/changelog/committype.ts
54
53
  const defaultTypes = [
55
54
  {
56
55
  type: "feat",
@@ -148,8 +147,7 @@ const defaultTypes = [
148
147
  effect: "hidden"
149
148
  }
150
149
  ];
151
- //#endregion
152
- //#region src/core/changelog/templates.ts
150
+ // src/core/changelog/templates.ts
153
151
  const isLikelyHash = (value) => /^[0-9a-f]{7,40}$/i.test(value);
154
152
  function headerPartial(context) {
155
153
  const { isPatch, linkCompare, version, title, date, previousTag } = context;
@@ -169,8 +167,7 @@ function template(context) {
169
167
  return each([line1, line2], (t) => t, newline$1());
170
168
  })), newline$1(2)), each(commitGroups, (group) => segments(group.title && heading(3, group.title), list(group.commits, (commit) => commitPartial(context, commit))), newline$1(2)), footerPartial(context));
171
169
  }
172
- //#endregion
173
- //#region src/core/changelog/changelog.ts
170
+ // src/core/changelog/changelog.ts
174
171
  const versionHeaderRegex = /^#+ (?:<small>)?\[?([^[\]()\s]*\d+\.\d+\.\d+[^[\]()\s]*)]?(?:<\/small>)?/m;
175
172
  const tagsRegex = /\/([^/)]*)\.\.\.([^/)]*)\)/;
176
173
  const decodeTag = (tag) => {
@@ -284,12 +281,10 @@ var Changelog = class {
284
281
  return content.trimEnd();
285
282
  }
286
283
  };
287
- //#endregion
288
- //#region src/core/hosting/hosting.ts
284
+ // src/core/hosting/hosting.ts
289
285
  /** Git 仓库托管服务的基类 */
290
286
  var GitRepositoryHosting = class {};
291
- //#endregion
292
- //#region src/core/manifest/manifest.ts
287
+ // src/core/manifest/manifest.ts
293
288
  var ProjectManifest = class {
294
289
  filepath;
295
290
  static Filename;
@@ -303,8 +298,7 @@ var ProjectManifest = class {
303
298
  return prerelease(version);
304
299
  }
305
300
  };
306
- //#endregion
307
- //#region src/core/manifest/packageJson.ts
301
+ // src/core/manifest/packageJson.ts
308
302
  var PackageJsonManifest = class extends ProjectManifest {
309
303
  static Filename = "package.json";
310
304
  contents;
@@ -346,8 +340,7 @@ var PackageJsonManifest = class extends ProjectManifest {
346
340
  }
347
341
  contentsMutex;
348
342
  };
349
- //#endregion
350
- //#region src/core/manifest/composed.ts
343
+ // src/core/manifest/composed.ts
351
344
  var ComposedProjectManifest = class extends ProjectManifest {
352
345
  mainManifest;
353
346
  subManifests;
@@ -383,8 +376,7 @@ var ComposedProjectManifest = class extends ProjectManifest {
383
376
  return update;
384
377
  }
385
378
  };
386
- //#endregion
387
- //#region src/core/utils.ts
379
+ // src/core/utils.ts
388
380
  const nonPreReleaseTypes = [
389
381
  "patch",
390
382
  "minor",
@@ -477,16 +469,18 @@ const readTextSync = (path) => {
477
469
  return readFileSync(path).toString("utf8");
478
470
  };
479
471
  const parseHostedGitUrl = (url) => {
480
- const [domain = "", prefix = "", owner = "", repo = ""] = [...(url.trim().match(/((?:github|gitlab|bitbucket|gitee|codeberg|sourceforge|git\.sr|\d+\.\d+\.\d+\.\d+:\d+)\.?(?:com|org|net|ht)?)[:\/](~)?([^/]+)\/(.+?)(?:[#/?](?:.+?)?)?(?:\.git)?$/) ?? []).slice(1)];
472
+ const [host = "", hostname = "", port = "", prefix = "", owner = "", repo = ""] = [...(url.trim().match(/(((?:github|gitlab|bitbucket|gitee|codeberg|sourceforge|git\.sr|\d+\.\d+\.\d+\.\d+)\.?(?:com|org|net|ht)?)(?::(\d+))?)[:\/](~)?([^/]+)\/(.+?)(?:[#/?](?:.+?)?)?(?:\.git)?$/) ?? []).slice(1)];
481
473
  return {
482
- host: domain ? `http${url.includes("https://") ? "s" : ""}://${domain}` : "",
474
+ origin: hostname ? `http${url.includes("https://") ? "s" : ""}://${host}` : "",
475
+ host,
476
+ hostname,
477
+ port,
483
478
  prefix,
484
479
  owner,
485
480
  repo
486
481
  };
487
482
  };
488
- //#endregion
489
- //#region src/core/project/project.ts
483
+ // src/core/project/project.ts
490
484
  const DEFAULT_TAG_PREFIX = "v";
491
485
  const DEFAULT_CHANGELOG_FILE = "CHANGELOG.md";
492
486
  const DEFAULT_PUBLISH_TAG = "latest";
@@ -535,11 +529,7 @@ var Project = class {
535
529
  const version = await manifest.getVersion();
536
530
  const tag = this.toTag(tagPrefix, version);
537
531
  if (verify) {
538
- const isTagExists = await gitRevParse(["--verify", tag]);
539
- if (isTagExists) {
540
- console.log("isTagExists:", isTagExists);
541
- return [];
542
- }
532
+ if (await gitRevParse(["--verify", tag])) return [];
543
533
  }
544
534
  return [tag];
545
535
  }
@@ -742,8 +732,7 @@ var Project = class {
742
732
  return true;
743
733
  }
744
734
  };
745
- //#endregion
746
- //#region src/core/project/monorepo.ts
735
+ // src/core/project/monorepo.ts
747
736
  var MonorepoProject = class extends Project {
748
737
  mode;
749
738
  async getCommitMessage() {
@@ -992,8 +981,7 @@ var MonorepoProject = class extends Project {
992
981
  return allFirst;
993
982
  }
994
983
  };
995
- //#endregion
996
- //#region src/core/project/packageJson.ts
984
+ // src/core/project/packageJson.ts
997
985
  var PackageJsonProject = class extends Project {
998
986
  constructor(options = {}) {
999
987
  const { path = PackageJsonManifest.Filename } = options;
@@ -1005,12 +993,8 @@ var PackageJsonProject = class extends Project {
1005
993
  publish(_options) {
1006
994
  throwError("Publishing a package.json project is not supported");
1007
995
  }
1008
- publishCheck(_options) {
1009
- throwError("Publishing a package.json project is not supported");
1010
- }
1011
996
  };
1012
- //#endregion
1013
- //#region src/core/project/packageJsonMonorepo.ts
997
+ // src/core/project/packageJsonMonorepo.ts
1014
998
  /**
1015
999
  * 基于 package.json 的单体仓库项目。
1016
1000
  */
@@ -1031,12 +1015,8 @@ var PackageJsonMonorepoProject = class extends MonorepoProject {
1031
1015
  publish(_options) {
1032
1016
  throwError("Publishing a package.json monorepo project is not supported");
1033
1017
  }
1034
- publishCheck(_options) {
1035
- throwError("Publishing a package.json monorepo project is not supported");
1036
- }
1037
1018
  };
1038
- //#endregion
1039
- //#region src/core/logger.ts
1019
+ // src/core/logger.ts
1040
1020
  const defaultPrinter = ({ dryRun, stage, message }) => {
1041
1021
  console.log(`${dryRun ? `[dry-run]` : ""}[${stage}]:`, message);
1042
1022
  };
@@ -1116,8 +1096,7 @@ var Logger = class {
1116
1096
  return color;
1117
1097
  }
1118
1098
  };
1119
- //#endregion
1120
- //#region src/core/releaser.ts
1099
+ // src/core/releaser.ts
1121
1100
  var Releaser = class {
1122
1101
  options;
1123
1102
  project;
@@ -1195,7 +1174,7 @@ var Releaser = class {
1195
1174
  logger.info("Skipping checkout.");
1196
1175
  return;
1197
1176
  }
1198
- logger.info(`Checking out branch ${headBranch}...`);
1177
+ logger.info(`Checking out branch "${headBranch}"...`);
1199
1178
  this.state.headBranch = headBranch;
1200
1179
  this.state.baseBranch = await this.getBaseBranch();
1201
1180
  if (fetch) {
@@ -1210,10 +1189,10 @@ var Releaser = class {
1210
1189
  ]);
1211
1190
  }
1212
1191
  if (force) {
1213
- logger.verbose(`Force checking out branch ${headBranch}...`);
1192
+ logger.verbose(`Force checking out branch "${headBranch}"...`);
1214
1193
  if (!dryRun) await gitCheckoutBranchForce(headBranch);
1215
1194
  } else {
1216
- logger.verbose(`Checking out branch ${headBranch}...`);
1195
+ logger.verbose(`Checking out branch "${headBranch}"...`);
1217
1196
  if (!dryRun) await gitCheckoutBranch(headBranch);
1218
1197
  }
1219
1198
  });
@@ -1489,8 +1468,7 @@ var Releaser = class {
1489
1468
  return gitBranchCurrent();
1490
1469
  }
1491
1470
  };
1492
- //#endregion
1493
- //#region src/hosting-github/github.ts
1471
+ // src/hosting-github/github.ts
1494
1472
  var GithubHosting = class extends GitRepositoryHosting {
1495
1473
  options;
1496
1474
  octokit;
@@ -1607,13 +1585,6 @@ var GithubHosting = class extends GitRepositoryHosting {
1607
1585
  });
1608
1586
  }
1609
1587
  }
1610
- async releaseCheck(options = {}) {
1611
- const { logger } = options;
1612
- logger?.verbose("Checking GitHub repository configuration...");
1613
- const remoteUrl = await gitConfigGet("remote.origin.url");
1614
- const useGithub = isNotEmpty(parseGitHubRepo(remoteUrl));
1615
- assert(useGithub, "Git remote \"origin\" is not a GitHub repository");
1616
- }
1617
1588
  async getRepositoryId(project) {
1618
1589
  let { options: { owner, repo } } = this;
1619
1590
  const i = project.getHostedGitInfo();
@@ -1672,8 +1643,7 @@ var GithubHosting = class extends GitRepositoryHosting {
1672
1643
  };
1673
1644
  }
1674
1645
  };
1675
- //#endregion
1676
- //#region src/project-github-action/publish.ts
1646
+ // src/project-github-action/publish.ts
1677
1647
  const runBuildCommands = async (commands, options, cwd) => {
1678
1648
  const { dryRun, env = process.env, logger } = options;
1679
1649
  for (const command of commands) {
@@ -1773,8 +1743,7 @@ const publish = async (project, options = {}) => {
1773
1743
  if (shouldRestoreBranch) await gitCheckout([originalBranch]);
1774
1744
  }
1775
1745
  };
1776
- //#endregion
1777
- //#region src/project-github-action/project.ts
1746
+ // src/project-github-action/project.ts
1778
1747
  /** Node.js GitHub Actions 项目,将版本引用发布到 Git 分支和标签 */
1779
1748
  var NodeGithubActionProject = class extends PackageJsonProject {
1780
1749
  /**
@@ -1798,13 +1767,6 @@ var NodeGithubActionProject = class extends PackageJsonProject {
1798
1767
  ...options
1799
1768
  });
1800
1769
  }
1801
- async publishCheck(options) {
1802
- const { logger } = options;
1803
- logger?.verbose("Checking GitHub repository configuration...");
1804
- const remoteUrl = await gitConfigGet("remote.origin.url");
1805
- const useGithub = isNotEmpty(parseGitHubRepo(remoteUrl));
1806
- assert(useGithub, "Git remote \"origin\" is not a GitHub repository");
1807
- }
1808
1770
  constructor(options = {}) {
1809
1771
  super(options);
1810
1772
  }
@@ -1817,25 +1779,7 @@ var NodeGithubActionProject = class extends PackageJsonProject {
1817
1779
  ]), false);
1818
1780
  }
1819
1781
  };
1820
- //#endregion
1821
- //#region src/project-npm/check.ts
1822
- const check$1 = async (project, options = {}) => {
1823
- const { logger } = options;
1824
- logger?.verbose("Checking npm registry...");
1825
- const pinged = await pingRegistry();
1826
- assert(pinged, "Unable to connect to the npm registry");
1827
- logger?.verbose("Checking npm authentication...");
1828
- const username = await getAuthenticatedUser();
1829
- assert(username, "Not authenticated with npm");
1830
- const name = await project.manifest.getName();
1831
- if (await getPublishedVersion(name)) {
1832
- logger?.verbose(`Checking npm write access for "${name}"...`);
1833
- const hasAccess = await hasWriteAccess(name, username);
1834
- assert(hasAccess, `No write access to npm package "${name}"`);
1835
- }
1836
- };
1837
- //#endregion
1838
- //#region src/project-npm/cleanup.ts
1782
+ // src/project-npm/cleanup.ts
1839
1783
  const PUBLISH_CONFIG_FIELDS$1 = [
1840
1784
  "bin",
1841
1785
  "main",
@@ -1938,8 +1882,7 @@ const cleanReadme$1 = async (dir, homepage) => {
1938
1882
  Read full docs **[here](${homepage})**.`;
1939
1883
  });
1940
1884
  };
1941
- //#endregion
1942
- //#region src/project-npm/publish.ts
1885
+ // src/project-npm/publish.ts
1943
1886
  const publish$2 = async (project, options = {}) => {
1944
1887
  const { manifest, manifest: { projectDir } } = project;
1945
1888
  const { access, tag, otp, env = process.env, dryRun, logger, cleanPublish } = options;
@@ -1965,8 +1908,8 @@ const publish$2 = async (project, options = {}) => {
1965
1908
  if (shouldCleanReadme) {
1966
1909
  const info = await project.getHostedGitInfo();
1967
1910
  if (!Object.values(info).every(isEmpty)) {
1968
- const { host, prefix, owner, repo } = info;
1969
- await cleanReadme$1(temp.path, `${host}/${prefix}${owner}/${repo}#readme`);
1911
+ const { origin, prefix, owner, repo } = info;
1912
+ await cleanReadme$1(temp.path, `${origin}/${prefix}${owner}/${repo}#readme`);
1970
1913
  }
1971
1914
  }
1972
1915
  logger?.verbose(`Publishing "${await manifest.getName()}" with command: npm ${args.join(" ")}`);
@@ -1985,19 +1928,14 @@ const publish$2 = async (project, options = {}) => {
1985
1928
  });
1986
1929
  }
1987
1930
  };
1988
- //#endregion
1989
- //#region src/project-npm/project.ts
1931
+ // src/project-npm/project.ts
1990
1932
  /** 一个基于 npm 的项目,使用 package.json 进行配置 */
1991
1933
  var NpmProject = class extends PackageJsonProject {
1992
1934
  async publish(options = {}) {
1993
1935
  await publish$2(this, { ...options });
1994
1936
  }
1995
- async publishCheck(options = {}) {
1996
- await check$1(this, options);
1997
- }
1998
1937
  };
1999
- //#endregion
2000
- //#region src/project-npm/workspacesProject.ts
1938
+ // src/project-npm/workspacesProject.ts
2001
1939
  const getPackagesGlobPatterns$1 = async (manifest) => {
2002
1940
  const workspaces = (await manifest).workspaces;
2003
1941
  return Array.isArray(workspaces) ? workspaces : workspaces?.packages ?? [];
@@ -2038,29 +1976,8 @@ var NpmWorkspacesProject = class extends PackageJsonMonorepoProject {
2038
1976
  });
2039
1977
  }
2040
1978
  }
2041
- async publishCheck(options = {}) {
2042
- await check$1(this, options);
2043
- }
2044
- };
2045
- //#endregion
2046
- //#region src/project-pnpm/check.ts
2047
- const check = async (project, options = {}) => {
2048
- const { logger } = options;
2049
- logger?.verbose("Checking npm registry...");
2050
- const pinged = await pingRegistry();
2051
- assert(pinged, "Unable to connect to the npm registry");
2052
- logger?.verbose("Checking npm authentication...");
2053
- const username = await getAuthenticatedUser();
2054
- assert(username, "Not authenticated with npm");
2055
- const name = await project.manifest.getName();
2056
- if (await getPublishedVersion(name)) {
2057
- logger?.verbose(`Checking npm write access for "${name}"...`);
2058
- const hasAccess = await hasWriteAccess(name, username);
2059
- assert(hasAccess, `No write access to npm package "${name}"`);
2060
- }
2061
1979
  };
2062
- //#endregion
2063
- //#region src/project-pnpm/cleanup.ts
1980
+ // src/project-pnpm/cleanup.ts
2064
1981
  const PUBLISH_CONFIG_FIELDS = [
2065
1982
  "bin",
2066
1983
  "main",
@@ -2163,8 +2080,7 @@ const cleanReadme = async (dir, homepage) => {
2163
2080
  Read full docs **[here](${homepage})**.`;
2164
2081
  });
2165
2082
  };
2166
- //#endregion
2167
- //#region src/project-pnpm/publish.ts
2083
+ // src/project-pnpm/publish.ts
2168
2084
  const publish$1 = async (project, options = {}) => {
2169
2085
  const { manifest, manifest: { projectDir } } = project;
2170
2086
  const { access, tag, otp, env = process.env, dryRun, logger, gitChecks, cleanPublish } = options;
@@ -2191,8 +2107,8 @@ const publish$1 = async (project, options = {}) => {
2191
2107
  if (shouldCleanReadme) {
2192
2108
  const info = await project.getHostedGitInfo();
2193
2109
  if (!Object.values(info).every(isEmpty)) {
2194
- const { host, prefix, owner, repo } = info;
2195
- await cleanReadme(temp.path, `${host}/${prefix}${owner}/${repo}#readme`);
2110
+ const { origin, prefix, owner, repo } = info;
2111
+ await cleanReadme(temp.path, `${origin}/${prefix}${owner}/${repo}#readme`);
2196
2112
  }
2197
2113
  }
2198
2114
  logger?.verbose(`Publishing "${await manifest.getName()}" with command: pnpm ${args.join(" ")}`);
@@ -2211,19 +2127,14 @@ const publish$1 = async (project, options = {}) => {
2211
2127
  });
2212
2128
  }
2213
2129
  };
2214
- //#endregion
2215
- //#region src/project-pnpm/project.ts
2130
+ // src/project-pnpm/project.ts
2216
2131
  /** 一个基于 pnpm 的项目,使用 package.json 进行配置 */
2217
2132
  var PnpmProject = class extends PackageJsonProject {
2218
2133
  async publish(options = {}) {
2219
2134
  await publish$1(this, { ...options });
2220
2135
  }
2221
- async publishCheck(options = {}) {
2222
- await check(this, options);
2223
- }
2224
2136
  };
2225
- //#endregion
2226
- //#region src/project-pnpm/workspacesProject.ts
2137
+ // src/project-pnpm/workspacesProject.ts
2227
2138
  const getPackagesGlobPatterns = async (filepath) => {
2228
2139
  const { packages = [] } = parse$1(readFileSync(filepath, "utf8"));
2229
2140
  return packages;
@@ -2266,12 +2177,8 @@ var PnpmWorkspacesProject = class extends PackageJsonMonorepoProject {
2266
2177
  });
2267
2178
  }
2268
2179
  }
2269
- async publishCheck(options = {}) {
2270
- await check$1(this, options);
2271
- }
2272
2180
  };
2273
- //#endregion
2274
- //#region src/releaser-github-action/comment.ts
2181
+ // src/releaser-github-action/comment.ts
2275
2182
  const ALLOWED_AUTHOR_ASSOCIATIONS = [
2276
2183
  "OWNER",
2277
2184
  "COLLABORATOR",
@@ -2323,16 +2230,20 @@ function parseSetPreambleComment(comment) {
2323
2230
  }
2324
2231
  return null;
2325
2232
  }
2326
- //#endregion
2327
- //#region src/releaser-github-action/conditions.ts
2233
+ // src/releaser-github-action/conditions.ts
2328
2234
  const ifReleaseCommit = async (releaser) => {
2329
2235
  const { project, options: { dryRun } } = releaser;
2330
2236
  const logger = releaser.logger.createChild("if-release-commit");
2331
2237
  if (!(await gitLog(["-1", "--pretty=%B"]))?.startsWith("chore(release):")) {
2332
- logger.verbose("Skipping non-release commit.");
2238
+ logger.verbose("Current commit is not a release commit.");
2333
2239
  return false;
2334
2240
  }
2335
- logger.verbose("Checking existing release tags...");
2241
+ const authorName = await gitLog(["-1", "--pretty=%an"]);
2242
+ if (!authorName?.startsWith("github-actions[bot]")) {
2243
+ logger.info(`Release commit author "${authorName ?? "unknown"}" is not "github-actions[bot]".`);
2244
+ process.exit(0);
2245
+ }
2246
+ logger.verbose("Checking for existing release tags...");
2336
2247
  if (!dryRun) await gitFetch(["--tags"]);
2337
2248
  const tags = await project.getTags();
2338
2249
  const canRelease = tags.length > 0;
@@ -2362,8 +2273,7 @@ const ifCommandComment = () => {
2362
2273
  }
2363
2274
  return false;
2364
2275
  };
2365
- //#endregion
2366
- //#region src/releaser-github-action/options.ts
2276
+ // src/releaser-github-action/options.ts
2367
2277
  const omitEmpty = (object) => {
2368
2278
  const result = {};
2369
2279
  for (const [key, value] of Object.entries(object)) if (isBoolean(value) || Boolean(value)) result[key] = value;
@@ -2394,8 +2304,7 @@ const getInputSkippedSteps = () => ({
2394
2304
  bump: getOptionalBooleanInput("bump-skip"),
2395
2305
  publish: getOptionalBooleanInput("publish-skip")
2396
2306
  });
2397
- //#endregion
2398
- //#region src/releaser-github-action/releaser.ts
2307
+ // src/releaser-github-action/releaser.ts
2399
2308
  var ReleaserGithubAction = class extends Releaser {
2400
2309
  setUser(options = {}) {
2401
2310
  return super.setUser({
@@ -2456,7 +2365,7 @@ var ReleaserGithubAction = class extends Releaser {
2456
2365
  let optionsApplied = false;
2457
2366
  let preamble;
2458
2367
  const preambleByName = /* @__PURE__ */ new Map();
2459
- for (let i = comments.length, comment; i >= 0; i--) {
2368
+ for (let i = comments.length - 1, comment; i >= 0; i--) {
2460
2369
  comment = comments[i];
2461
2370
  if (!optionsApplied) {
2462
2371
  const json = parseSetOptionsComment(comment);
@@ -2552,82 +2461,11 @@ var ReleaserGithubAction = class extends Releaser {
2552
2461
  }
2553
2462
  }
2554
2463
  };
2555
- //#endregion
2556
- //#region package.json
2557
- var package_default = {
2558
- name: "@peiyanlu/release",
2559
- version: "2.0.0",
2560
- description: "Tool to automate version bumps, changelogs, and releases.",
2561
- license: "MIT",
2562
- type: "module",
2563
- "private": false,
2564
- bin: { "release": "index.js" },
2565
- exports: {
2566
- ".": {
2567
- "types": "./dist/index.d.mts",
2568
- "default": "./dist/index.mjs"
2569
- },
2570
- "./package.json": "./package.json"
2571
- },
2572
- scripts: {
2573
- "dev": "tsdown -w",
2574
- "build": "tsdown",
2575
- "prepublishOnly": "tsdown",
2576
- "release": "node index.js",
2577
- "release:dry": "node index.js -C -n",
2578
- "test": "vitest run",
2579
- "test:cov": "vitest run --coverage"
2580
- },
2581
- dependencies: {
2582
- "@actions/core": "^3.0.1",
2583
- "@actions/github": "^9.1.1",
2584
- "@clack/prompts": "^1.7.0",
2585
- "@conventional-changelog/template": "^1.2.1",
2586
- "@octokit/rest": "^22.0.1",
2587
- "@peiyanlu/cli-utils": "^0.0.15",
2588
- "@peiyanlu/node-utils": "^0.0.4",
2589
- "@peiyanlu/ts-utils": "^0.0.12",
2590
- "ansis": "^4.3.1",
2591
- "commander": "^15.0.0",
2592
- "conventional-changelog": "^8.1.0",
2593
- "conventional-changelog-conventionalcommits": "^10.2.1",
2594
- "conventional-recommended-bump": "^12.1.0",
2595
- "open": "^11.0.0",
2596
- "publint": "^0.3.22",
2597
- "semver": "^7.8.5",
2598
- "tinyglobby": "^0.2.17",
2599
- "yaml": "^2.9.0",
2600
- "handlebars": "^4.7.9"
2601
- },
2602
- devDependencies: {
2603
- "@peiyanlu/test-tools": "^0.0.7",
2604
- "@types/node": "^24.13.3",
2605
- "@types/semver": "^7.7.1",
2606
- "@vitest/coverage-v8": "^4.1.10",
2607
- "tsdown": "^0.23.1",
2608
- "typescript": "^6.0.3",
2609
- "vitest": "^4.1.10"
2610
- },
2611
- author: {
2612
- "name": "YanluPei",
2613
- "email": "peiyanlu@vip.qq.com"
2614
- },
2615
- engines: { "node": ">=20" },
2616
- keywords: ["typescript", "cli"],
2617
- files: ["dist", "template"],
2618
- publishConfig: {
2619
- "access": "public",
2620
- "registry": "https://registry.npmjs.org"
2621
- },
2622
- repository: {
2623
- "type": "git",
2624
- "url": "git+https://github.com/peiyanlu/release.git"
2625
- },
2626
- bugs: { "url": "https://github.com/peiyanlu/release/issues" },
2627
- homepage: "https://github.com/peiyanlu/release#readme"
2628
- };
2629
- //#endregion
2630
- //#region src/releaser-cli/prompts.ts
2464
+ // node_modules/.pnpm/tsdown@0.23.4_publint@0.3.25_typescript@6.0.3/node_modules/tsdown/esm-shims.js
2465
+ const getFilename = () => fileURLToPath(import.meta.url);
2466
+ const getDirname = () => path.dirname(getFilename());
2467
+ const __dirname = /* @__PURE__ */ getDirname();
2468
+ // src/releaser-cli/prompts.ts
2631
2469
  const abortTask = (msg) => {
2632
2470
  cancel(`${red("✕")} ${msg ?? "Release cancelled."}`);
2633
2471
  process.exit(0);
@@ -2656,7 +2494,8 @@ const createVersionOptions = async (project, options = {}, current, tagPrefix) =
2656
2494
  {
2657
2495
  label: "Custom",
2658
2496
  value: "custom",
2659
- hint: "Specify an exact version"
2497
+ hint: "Specify an exact version",
2498
+ bump: { firstRelease }
2660
2499
  },
2661
2500
  {
2662
2501
  label: "As-is",
@@ -2787,10 +2626,8 @@ const runBumpPrompts = async (project, options = {}) => {
2787
2626
  if (isUndefined(val) || !isValidVersion(val)) return "Invalid version.";
2788
2627
  }
2789
2628
  }));
2790
- else {
2791
- const selected = find(type);
2792
- Object.assign(promptsRes, selected?.bump);
2793
- }
2629
+ const selected = find(type);
2630
+ Object.assign(promptsRes, selected?.bump);
2794
2631
  return promptsRes;
2795
2632
  };
2796
2633
  if (project.isMonorepoMode() && project.isIndependentMode) for await (const subProject of project.getProjects()) {
@@ -2814,10 +2651,10 @@ const getCliPromptOptions = async (options = {}) => {
2814
2651
  const shouldPrompt = (v) => !ci && (isUndefined(v) || dryRun);
2815
2652
  const res = await group({
2816
2653
  commit: () => options.skipGit ? Promise.resolve(false) : shouldPrompt(options.skipGit) ? confirm({ message: question("Commit release changes?", dryRun) }) : Promise.resolve(true),
2817
- tag: () => options.skipGit ? Promise.resolve(false) : shouldPrompt(options.skipGit) ? confirm({ message: question("Create release tags?", dryRun) }) : Promise.resolve(true),
2818
- push: () => options.skipGit ? Promise.resolve(false) : shouldPrompt(options.skipGit) ? confirm({ message: question("Push release changes?", dryRun) }) : Promise.resolve(true),
2654
+ tag: ({ results: { commit } }) => !commit ? Promise.resolve(false) : shouldPrompt(options.skipGit) ? confirm({ message: question("Create release tags?", dryRun) }) : Promise.resolve(true),
2655
+ push: ({ results: { commit } }) => !commit ? Promise.resolve(false) : shouldPrompt(options.skipGit) ? confirm({ message: question("Push release changes?", dryRun) }) : Promise.resolve(true),
2819
2656
  publish: () => options.skipPublish ? Promise.resolve(false) : shouldPrompt(options.skipPublish) ? confirm({ message: question("Publish project?", dryRun) }) : Promise.resolve(true),
2820
- release: () => options.skipRelease || options.skipGit ? Promise.resolve(false) : shouldPrompt(options.skipRelease) ? confirm({ message: question("Create repository release?", dryRun) }) : Promise.resolve(true)
2657
+ release: () => options.skipRelease ? Promise.resolve(false) : shouldPrompt(options.skipRelease) ? confirm({ message: question("Create repository release?", dryRun) }) : Promise.resolve(true)
2821
2658
  }, { onCancel: () => {
2822
2659
  abortTask();
2823
2660
  } });
@@ -2832,8 +2669,8 @@ const getCliPromptOptions = async (options = {}) => {
2832
2669
  const runConfirmPrompts = async (ci = false, dryRun = false) => {
2833
2670
  if (!(ci ? true : await singlePrompt(() => confirm({ message: question(red("Confirm start workflow?"), dryRun) })))) abortTask();
2834
2671
  };
2835
- //#endregion
2836
- //#region src/releaser-cli/releaser.ts
2672
+ // src/releaser-cli/releaser.ts
2673
+ const pkgJson = readJsonFileSync(join(__dirname, "..", "package.json"));
2837
2674
  var ReleaserCli = class extends Releaser {
2838
2675
  constructor(options) {
2839
2676
  const { silent, dryRun, verbose } = options;
@@ -2880,17 +2717,22 @@ var ReleaserCli = class extends Releaser {
2880
2717
  }
2881
2718
  setCliOptions(options) {
2882
2719
  return this.enqueue(async () => {
2883
- const { ci, dryRun, releaseType: as } = options;
2720
+ const { ci, dryRun, releaseType: as, skipBump } = options;
2884
2721
  const { project, stepsOptions: { bump: bumpOpts } } = this;
2885
- const bump = await runBumpPrompts(project, {
2722
+ const version = await project.manifest.getVersion();
2723
+ const bump = skipBump ? { version } : await runBumpPrompts(project, {
2886
2724
  bump: {
2887
2725
  ...bumpOpts,
2888
2726
  as
2889
2727
  },
2890
2728
  run: options
2891
2729
  });
2892
- this.setOptions({ bump }).setSkippedSteps(await getCliPromptOptions(options));
2730
+ const skippedSteps = await getCliPromptOptions(options);
2893
2731
  await runConfirmPrompts(ci, dryRun);
2732
+ this.setOptions({ bump }).setSkippedSteps({
2733
+ bump: version === bump.version && !bump.firstRelease,
2734
+ ...skippedSteps
2735
+ });
2894
2736
  });
2895
2737
  }
2896
2738
  setLegacyOptions() {
@@ -2910,33 +2752,9 @@ var ReleaserCli = class extends Releaser {
2910
2752
  this.setOptions(legacySteps);
2911
2753
  });
2912
2754
  }
2913
- check() {
2914
- return this.enqueue(async () => {
2915
- const { project, hosting } = this;
2916
- const logger = this.logger.createChild("check");
2917
- logger.info("Checking release environment...");
2918
- if (![
2919
- "commit",
2920
- "tag",
2921
- "push"
2922
- ].every((k) => this.shouldSkip(k))) {
2923
- logger.verbose("Checking Git repository...");
2924
- const isRepo = await isGitRepo();
2925
- assert(isRepo, "Current directory is not a Git repository");
2926
- logger.verbose("Checking working tree...");
2927
- const isClean = await isWorkingTreeClean();
2928
- assert(isClean, "Git working tree is not clean");
2929
- logger.verbose("Checking remote repository...");
2930
- const hasRemote = await gitConfigGet("remote.origin.url");
2931
- assert(hasRemote, "Git remote \"origin\" is not configured");
2932
- }
2933
- if (!this.shouldSkip("publish")) await project.publishCheck({ logger });
2934
- if (!this.shouldSkip("release")) await hosting?.releaseCheck({ logger });
2935
- });
2936
- }
2937
2755
  start() {
2938
2756
  return this.enqueue(async () => {
2939
- const { name, version } = package_default;
2757
+ const { name, version } = pkgJson;
2940
2758
  console.log(`${blue`i`} ${name} v${version}\n`);
2941
2759
  intro("🚀 Starting release");
2942
2760
  });
@@ -2947,8 +2765,7 @@ var ReleaserCli = class extends Releaser {
2947
2765
  process.exit(0);
2948
2766
  }
2949
2767
  async runAction(options) {
2950
- await this.start().setLegacyOptions().setCliOptions(options).check().bump().commit().tag().push().publish().release().run();
2768
+ await this.start().setLegacyOptions().setCliOptions(options).bump().commit().tag().push().publish().release().run();
2951
2769
  }
2952
2770
  };
2953
- //#endregion
2954
2771
  export { Changelog, ChildLogger, ComposedProjectManifest, DEFAULT_CHANGELOG_FILE, DEFAULT_PRE_PUBLISH_TAG, DEFAULT_PUBLISH_TAG, DEFAULT_TAG_PREFIX, GitRepositoryHosting, GithubHosting, Logger, MonorepoProject, NodeGithubActionProject, NpmProject, NpmWorkspacesProject, Octokit, PackageJsonManifest, PackageJsonMonorepoProject, PackageJsonProject, PnpmProject, PnpmWorkspacesProject, Project, ProjectManifest, Releaser, ReleaserCli, ReleaserGithubAction, defaultTypes, defineConfig, extractLastRelease, findFile, getInputOptions, getInputSkippedSteps, headerPartial, ifCommandComment, ifReleaseCommit, loadConfig, loadJavaScriptFile, preamblePartial, publish, template };