@peiyanlu/release 0.0.16 → 1.0.0
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 +34 -20
- package/dist/index.d.mts +14 -8
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import path, { join, resolve } from "node:path";
|
|
2
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, gitAddTracked, gitBranchCurrent, gitCommitMessage, gitPushBranch, gitPushTag, gitResetHardSync, gitTagAnnotated, gitTagDeleteSync, hasWriteAccess, isGitRepo, isOtpError, isPrerelease, isValidVersion, isWorkingTreeClean, parseGitHubRepo, parseVersion, pingRegistry, publishPackage, readJsonFile, resolveChangelogRange, resolvePublishTag } from "@peiyanlu/cli-utils";
|
|
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, readJsonFile, resolveChangelogRange, resolvePublishTag } 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
|
-
import { castArray, isFunction, isPlainObject, isUndefined, isZero } from "@peiyanlu/ts-utils";
|
|
8
|
+
import { castArray, isFunction, isPlainObject, isUndefined, isZero, mapObjectValues } from "@peiyanlu/ts-utils";
|
|
9
9
|
import { publint } from "publint";
|
|
10
10
|
import { formatMessage } from "publint/utils";
|
|
11
11
|
import { inc, neq } from "semver";
|
|
@@ -129,7 +129,7 @@ const MSG = {
|
|
|
129
129
|
GIT_PUSH: "Push commits and tags to remote?"
|
|
130
130
|
},
|
|
131
131
|
ERROR: {
|
|
132
|
-
GIT_WORKDIR: `[git] Working
|
|
132
|
+
GIT_WORKDIR: `[git] Working tree must be clean`,
|
|
133
133
|
GIT_REGISTRY: (name) => `[git] Repository not found for ${dim(name)}`,
|
|
134
134
|
GIT_REMOTE: (name) => `[git] Remote "${dim(name)}" not found`,
|
|
135
135
|
GITHUB_TAG_EXIT: (tag) => `[github] Release for tag "${tag}" already exists and is not a draft`,
|
|
@@ -155,8 +155,8 @@ const MSG = {
|
|
|
155
155
|
//#region src/git/commit.ts
|
|
156
156
|
const gitCheck = async (ctx, config) => {
|
|
157
157
|
const { pkg: { name } } = ctx;
|
|
158
|
-
const { git: { requireRepository, requireRemote,
|
|
159
|
-
if (
|
|
158
|
+
const { git: { requireRepository, requireRemote, requireCleanWorkingTree }, skipGit, skipGithub } = config;
|
|
159
|
+
if (skipGit) {
|
|
160
160
|
ctx.noGit = true;
|
|
161
161
|
ctx.noGitHub = true;
|
|
162
162
|
return;
|
|
@@ -167,8 +167,8 @@ const gitCheck = async (ctx, config) => {
|
|
|
167
167
|
ctx.noGitHub = true;
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
170
|
-
if (
|
|
171
|
-
if (
|
|
170
|
+
if (requireCleanWorkingTree && !await isWorkingTreeClean()) throw new Error(MSG.ERROR.GIT_WORKDIR);
|
|
171
|
+
if (skipGithub) {
|
|
172
172
|
ctx.noGitHub = true;
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
@@ -438,9 +438,9 @@ const createDefaultConfig = (isCI) => {
|
|
|
438
438
|
},
|
|
439
439
|
releaseCount: 1
|
|
440
440
|
},
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
441
|
+
skipGit: false,
|
|
442
|
+
skipNpm: false,
|
|
443
|
+
skipGithub: false,
|
|
444
444
|
git: {
|
|
445
445
|
commit: isCI,
|
|
446
446
|
tag: isCI,
|
|
@@ -453,7 +453,7 @@ const createDefaultConfig = (isCI) => {
|
|
|
453
453
|
addUntrackedFiles: false,
|
|
454
454
|
requireRemote: true,
|
|
455
455
|
requireRepository: true,
|
|
456
|
-
|
|
456
|
+
requireCleanWorkingTree: true
|
|
457
457
|
},
|
|
458
458
|
npm: {
|
|
459
459
|
publish: isCI,
|
|
@@ -980,16 +980,26 @@ var Action = class {
|
|
|
980
980
|
}
|
|
981
981
|
async createContext(cmdArgs, options, prepare = false) {
|
|
982
982
|
const { version: cVersion, name: cName } = readJsonFile(join(__dirname, "../package.json"));
|
|
983
|
-
const { otp, package: defPkg, ...others } = options;
|
|
984
|
-
const { showChangelog, showRelease, ci, dryRun } =
|
|
983
|
+
const { otp, package: defPkg, releaseCount, ...others } = options;
|
|
984
|
+
const { showChangelog, showRelease, ci, dryRun } = mapObjectValues(others, (v) => Boolean(v));
|
|
985
985
|
process.env["dryRun"] = String(dryRun);
|
|
986
986
|
const { configFile, config: local } = await resolveConfig(process.cwd());
|
|
987
987
|
const config = mergeConfig(createDefaultConfig(ci ? true : void 0), local);
|
|
988
988
|
info(MSG.INFO.TOOL(cName, cVersion));
|
|
989
989
|
info(MSG.INFO.CONFIG(configFile));
|
|
990
|
+
{
|
|
991
|
+
const { requireCleanWorkingTree, skipGit, skipNpm, skipGithub, isMonorepo } = mapObjectValues(others, (v) => Boolean(v));
|
|
992
|
+
const count = Number(releaseCount);
|
|
993
|
+
config.changelog.releaseCount = isNaN(count) ? 0 : count;
|
|
994
|
+
config.git.requireCleanWorkingTree = requireCleanWorkingTree;
|
|
995
|
+
config.skipGit = skipGit;
|
|
996
|
+
config.skipNpm = skipNpm;
|
|
997
|
+
config.skipGithub = skipGithub;
|
|
998
|
+
config.isMonorepo = isMonorepo;
|
|
999
|
+
}
|
|
990
1000
|
console.log();
|
|
991
1001
|
intro(prepare ? MSG.INTRO_PREPARE(dryRun) : MSG.INTRO(dryRun));
|
|
992
|
-
const { isMonorepo, packages, getPkgDir,
|
|
1002
|
+
const { isMonorepo, packages, getPkgDir, skipNpm } = config;
|
|
993
1003
|
if (isMonorepo) {
|
|
994
1004
|
if (ci) {
|
|
995
1005
|
if (!defPkg) abortTask(MSG.ABORT.MONOREPO_CI_NO_PACKAGE);
|
|
@@ -1035,7 +1045,7 @@ var Action = class {
|
|
|
1035
1045
|
toPreRelease: false,
|
|
1036
1046
|
publishConfig: { ...publishConfig }
|
|
1037
1047
|
},
|
|
1038
|
-
noNpm: pkgPrivate ||
|
|
1048
|
+
noNpm: pkgPrivate || skipNpm
|
|
1039
1049
|
});
|
|
1040
1050
|
const { messages } = await publint({ pkgDir });
|
|
1041
1051
|
for (const message of messages) {
|
|
@@ -1210,13 +1220,13 @@ var Action = class {
|
|
|
1210
1220
|
//#endregion
|
|
1211
1221
|
//#region src/cli.ts
|
|
1212
1222
|
const pkg = readJsonFile(join(__dirname, "..", "package.json"));
|
|
1213
|
-
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) => {
|
|
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 (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("-C, --no-require-clean-working-tree", "Allow releasing with uncommitted changes.", true).option("-m, --is-monorepo", "Mono-repo project", false).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) => {
|
|
1214
1224
|
const { prepare } = options;
|
|
1215
1225
|
const action = new Action();
|
|
1216
1226
|
prepare ? await action.handlePrepareRelease(releaseType, options) : await action.handleRelease(releaseType, options);
|
|
1217
1227
|
});
|
|
1218
|
-
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) => {
|
|
1219
|
-
const { force = false, monorepo = false } = options;
|
|
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).option("-a, --add", "Automatically stage the config file.", false).action((options) => {
|
|
1229
|
+
const { force = false, monorepo = false, add = false } = options;
|
|
1220
1230
|
const cwd = process.cwd();
|
|
1221
1231
|
const { type } = readJsonFile(join(cwd, "package.json"));
|
|
1222
1232
|
const isESM = type === "module";
|
|
@@ -1236,9 +1246,13 @@ program.command("init").description("Create a release configuration file").optio
|
|
|
1236
1246
|
tagPrefix: (pkg) => \`\${ pkg }@\`,
|
|
1237
1247
|
},
|
|
1238
1248
|
}`;
|
|
1239
|
-
|
|
1240
|
-
|
|
1249
|
+
const content = [`import { defineConfig } from '@peiyanlu/release'`, `export default defineConfig(${monorepo ? monoConfigToString() : "{}"})`].join(eol(2));
|
|
1250
|
+
writeFileSync(configFile, content, "utf-8");
|
|
1251
|
+
console.log(`Wrote to ${underline(dim(configFile))}`);
|
|
1252
|
+
if (add) gitAddSync([infile]);
|
|
1253
|
+
console.log(`\n${content}`);
|
|
1241
1254
|
});
|
|
1255
|
+
program.addHelpText("afterAll", "\nThanks for using!");
|
|
1242
1256
|
program.parse(process.argv);
|
|
1243
1257
|
program.on("command:*", () => {
|
|
1244
1258
|
console.error(`\n${red`Error`} Invalid command: ${red`%s`}`, program.args.join(" "));
|
package/dist/index.d.mts
CHANGED
|
@@ -28,15 +28,21 @@ interface ReleaseConfig {
|
|
|
28
28
|
* 影响生成的日志数量、日志标题(monorepo)。
|
|
29
29
|
*/
|
|
30
30
|
changelog: {
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* 作为 CHANGELOG 标题的 Tag 前缀,多包场景下需要 `${pkg}@`
|
|
33
|
+
*/
|
|
34
|
+
tagPrefix: ((pkg: string) => string);
|
|
35
|
+
/**
|
|
36
|
+
* 生成多少个版本的变更日志,详见 {@link Options}
|
|
37
|
+
*/
|
|
32
38
|
releaseCount: number;
|
|
33
39
|
};
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
+
/** 跳过 git、github 环境检查以及后续操作 */
|
|
41
|
+
skipGit: boolean;
|
|
42
|
+
/** 跳过 npm 环境检查以及后续操作 */
|
|
43
|
+
skipNpm: boolean;
|
|
44
|
+
/** 跳过 github 环境检查以及后续操作 */
|
|
45
|
+
skipGithub: boolean;
|
|
40
46
|
/**
|
|
41
47
|
* Git 相关配置
|
|
42
48
|
* 影响提交、打 tag、推送等本地/远程 Git 行为。
|
|
@@ -90,7 +96,7 @@ interface ReleaseConfig {
|
|
|
90
96
|
/**
|
|
91
97
|
* 是否要求工作目录保持干净(无未提交的更改)
|
|
92
98
|
*/
|
|
93
|
-
|
|
99
|
+
requireCleanWorkingTree: boolean;
|
|
94
100
|
};
|
|
95
101
|
/**
|
|
96
102
|
* NPM 发布相关配置
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peiyanlu/release",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Release project tool.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@clack/prompts": "^1.5.0",
|
|
32
32
|
"@octokit/rest": "^22.0.1",
|
|
33
33
|
"@peiyanlu/cli-utils": "^0.0.12",
|
|
34
|
-
"@peiyanlu/ts-utils": "^0.0.
|
|
34
|
+
"@peiyanlu/ts-utils": "^0.0.8",
|
|
35
35
|
"ansis": "^4.3.1",
|
|
36
36
|
"commander": "^15.0.0",
|
|
37
37
|
"conventional-changelog": "^7.2.1",
|