@deot/dev-releaser 2.9.9 → 2.9.10
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.cjs +520 -591
- package/dist/index.js +496 -571
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -1,597 +1,526 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let chalk = require("chalk");
|
|
25
|
+
chalk = __toESM(chalk);
|
|
26
|
+
let _deot_dev_shared = require("@deot/dev-shared");
|
|
27
|
+
let node_path = require("node:path");
|
|
28
|
+
node_path = __toESM(node_path);
|
|
29
|
+
let node_module = require("node:module");
|
|
30
|
+
let fs_extra = require("fs-extra");
|
|
31
|
+
fs_extra = __toESM(fs_extra);
|
|
32
|
+
let conventional_commits_parser = require("conventional-commits-parser");
|
|
33
|
+
let semver = require("semver");
|
|
34
|
+
semver = __toESM(semver);
|
|
35
|
+
let _inquirer_prompts = require("@inquirer/prompts");
|
|
36
|
+
//#region packages/releaser/src/release.ts
|
|
37
|
+
var require$ = (0, node_module.createRequire)(process.cwd());
|
|
38
|
+
var HASH = "-hash-";
|
|
39
|
+
var SUFFIX = "🐒💨🙊";
|
|
40
|
+
var reBreaking = new RegExp(`(${{ noteKeywords: ["BREAKING CHANGE", "Breaking Change"] }.noteKeywords.join(")|(")})`);
|
|
41
|
+
var commitParser = new conventional_commits_parser.CommitParser();
|
|
42
|
+
var Release = class {
|
|
43
|
+
packageDir;
|
|
44
|
+
packageName;
|
|
45
|
+
packageFolderName;
|
|
46
|
+
packageOptions;
|
|
47
|
+
packageRelation;
|
|
48
|
+
config;
|
|
49
|
+
changeLog;
|
|
50
|
+
version;
|
|
51
|
+
commits;
|
|
52
|
+
commandOptions;
|
|
53
|
+
constructor(config, commandOptions) {
|
|
54
|
+
const { packageDir, packageRelation } = _deot_dev_shared.Locals.impl();
|
|
55
|
+
if (typeof config === "string") {
|
|
56
|
+
const packageFolderName = config;
|
|
57
|
+
config = {
|
|
58
|
+
dir: node_path.resolve(packageDir, packageFolderName),
|
|
59
|
+
name: packageFolderName
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
this.packageDir = config.dir;
|
|
63
|
+
this.packageName = _deot_dev_shared.Locals.getPackageName(config.name);
|
|
64
|
+
this.packageFolderName = config.name;
|
|
65
|
+
this.packageOptions = require$(`${this.packageDir}/package.json`);
|
|
66
|
+
this.packageRelation = packageRelation[this.packageName] || [];
|
|
67
|
+
this.config = config;
|
|
68
|
+
this.commits = [];
|
|
69
|
+
this.changeLog = "";
|
|
70
|
+
this.version = "";
|
|
71
|
+
this.commandOptions = commandOptions;
|
|
72
|
+
}
|
|
73
|
+
async parseCommits() {
|
|
74
|
+
const { workspace } = _deot_dev_shared.Locals.impl();
|
|
75
|
+
const { packageFolderName, commandOptions } = this;
|
|
76
|
+
const [latestTag] = await this.getTags();
|
|
77
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`Last Release Tag`) + `: ${latestTag || "<none>"}`);
|
|
78
|
+
const params = [
|
|
79
|
+
"--no-pager",
|
|
80
|
+
"log",
|
|
81
|
+
`${latestTag}..HEAD`,
|
|
82
|
+
`--format=%B%n${HASH}%n%H${SUFFIX}`
|
|
83
|
+
];
|
|
84
|
+
let { stdout } = await _deot_dev_shared.Shell.exec("git", params);
|
|
85
|
+
let skipGetLog = false;
|
|
86
|
+
if (latestTag) {
|
|
87
|
+
const log1 = await _deot_dev_shared.Shell.exec("git", ["rev-parse", latestTag]);
|
|
88
|
+
const log2 = await _deot_dev_shared.Shell.exec("git", [
|
|
89
|
+
"--no-pager",
|
|
90
|
+
"log",
|
|
91
|
+
"-1",
|
|
92
|
+
"--format=%H"
|
|
93
|
+
]);
|
|
94
|
+
if (log1.stdout === log2.stdout) skipGetLog = true;
|
|
95
|
+
}
|
|
96
|
+
if (!skipGetLog && !stdout) {
|
|
97
|
+
if (latestTag) params.splice(2, 1, `${latestTag}`);
|
|
98
|
+
else params.splice(2, 1, "HEAD");
|
|
99
|
+
({stdout} = await _deot_dev_shared.Shell.exec("git", params));
|
|
100
|
+
}
|
|
101
|
+
const allowTypes = [
|
|
102
|
+
"feat",
|
|
103
|
+
`fix`,
|
|
104
|
+
`break change`,
|
|
105
|
+
`style`,
|
|
106
|
+
`perf`,
|
|
107
|
+
`types`,
|
|
108
|
+
`refactor`,
|
|
109
|
+
`chore`
|
|
110
|
+
];
|
|
111
|
+
const rePlugin = new RegExp(`^(${allowTypes.join("|")})${workspace ? `\\(([,\\w-]+(,))?${packageFolderName}((,)[,\\w-]+)?\\)` : "(\\(.+\\))?"}: .*`, "i");
|
|
112
|
+
const reAll = workspace && new RegExp(`^(${allowTypes.join("|")})\\(\\*\\): .*`, "i");
|
|
113
|
+
const allCommits = commandOptions.commits || stdout.split(SUFFIX);
|
|
114
|
+
const commits = allCommits.filter((commit) => {
|
|
115
|
+
const chunk = commit.trim();
|
|
116
|
+
return chunk && (rePlugin.test(chunk) || reAll && reAll.test(chunk));
|
|
117
|
+
}).map((commit) => {
|
|
118
|
+
const node = commitParser.parse(commit);
|
|
119
|
+
const body = node.body || node.footer;
|
|
120
|
+
if (!node.type) node.type = commitParser.parse(node.header?.replace(/\(.+\)!?:/, ":") || "").type;
|
|
121
|
+
if (!node.hash) node.hash = commit.split(HASH).pop()?.trim();
|
|
122
|
+
node.breaking = reBreaking.test(body) || /!:/.test(node.header);
|
|
123
|
+
node.effect = false;
|
|
124
|
+
node.custom = false;
|
|
125
|
+
return node;
|
|
126
|
+
});
|
|
127
|
+
if (!commits.length) _deot_dev_shared.Logger.log(chalk.default.red(`No Commits Found.`));
|
|
128
|
+
else _deot_dev_shared.Logger.log(chalk.default.yellow(`Found `) + chalk.default.bold(`${allCommits.length}`) + ` Commits, ` + chalk.default.bold(`${commits.length}`) + " Commits Valid");
|
|
129
|
+
const { skipUpdatePackage } = commandOptions;
|
|
130
|
+
if (commits.length && skipUpdatePackage) {
|
|
131
|
+
let skip = false;
|
|
132
|
+
if (typeof skipUpdatePackage === "boolean" && skipUpdatePackage) skip = await (0, _inquirer_prompts.confirm)({
|
|
133
|
+
message: `Skip Update(${this.packageName}@${this.packageOptions.version}):`,
|
|
134
|
+
default: true
|
|
135
|
+
});
|
|
136
|
+
else if (typeof skipUpdatePackage === "string" && (skipUpdatePackage === "*" || skipUpdatePackage.split(",").includes(this.packageName))) skip = true;
|
|
137
|
+
if (skip) {
|
|
138
|
+
_deot_dev_shared.Logger.log(chalk.default.red(`Skipping Update\n`));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
await this.updateVersion();
|
|
143
|
+
await this.updateCommits(commits);
|
|
144
|
+
const { forceUpdatePackage } = commandOptions;
|
|
145
|
+
if (!commits.length && forceUpdatePackage) {
|
|
146
|
+
let force = false;
|
|
147
|
+
if (typeof forceUpdatePackage === "boolean" && forceUpdatePackage) force = await (0, _inquirer_prompts.confirm)({
|
|
148
|
+
message: `Force Update(${this.packageName}@${this.packageOptions.version}):`,
|
|
149
|
+
default: true
|
|
150
|
+
});
|
|
151
|
+
else if (typeof forceUpdatePackage === "string" && (forceUpdatePackage === "*" || forceUpdatePackage.split(",").includes(this.packageName))) force = true;
|
|
152
|
+
if (force) {
|
|
153
|
+
const versionChanged = `\`${this.packageOptions.version}\` -> \`${this.version}\``;
|
|
154
|
+
this.commits = [{
|
|
155
|
+
type: "chore",
|
|
156
|
+
header: `chore(${this.packageFolderName || "release"}): force-publish ${versionChanged}`,
|
|
157
|
+
hash: "",
|
|
158
|
+
effect: false,
|
|
159
|
+
breaking: false,
|
|
160
|
+
custom: true
|
|
161
|
+
}];
|
|
162
|
+
this.changeLog = `### Force Update Package\n\n- ${versionChanged}`.trim();
|
|
24
163
|
}
|
|
25
164
|
}
|
|
26
165
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
166
|
+
async getTags() {
|
|
167
|
+
const { packageName } = this;
|
|
168
|
+
const params = [
|
|
169
|
+
"tag",
|
|
170
|
+
"--list",
|
|
171
|
+
`'${packageName}@*'`,
|
|
172
|
+
"--sort",
|
|
173
|
+
"-v:refname"
|
|
174
|
+
];
|
|
175
|
+
const { stdout } = await _deot_dev_shared.Shell.exec("git", params);
|
|
176
|
+
return stdout.split("\n");
|
|
177
|
+
}
|
|
178
|
+
rebuildChangeLog(commits) {
|
|
179
|
+
const { packageDir } = this;
|
|
180
|
+
const { homepage, workspace } = _deot_dev_shared.Locals.impl();
|
|
181
|
+
const logPath = node_path.resolve(packageDir, "./CHANGELOG.md");
|
|
182
|
+
const logFile = fs_extra.default.existsSync(logPath) ? fs_extra.default.readFileSync(logPath, "utf-8") : "";
|
|
183
|
+
const notes = {
|
|
184
|
+
breaking: [],
|
|
185
|
+
features: [],
|
|
186
|
+
fixes: [],
|
|
187
|
+
updates: []
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* (close #1) -> issues
|
|
191
|
+
* close (#1) -> issues
|
|
192
|
+
* (#1) -> pull request
|
|
193
|
+
*
|
|
194
|
+
* JS支持后行断言
|
|
195
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Assertions
|
|
196
|
+
*/
|
|
197
|
+
const closeRegxp = /\(?(closes? )\(?#((\d+))\)/gi;
|
|
198
|
+
const pullRegxp = /(?<!closes? )\((#(\d+))\)/gi;
|
|
199
|
+
for (const commit of commits) {
|
|
200
|
+
const { effect, breaking, hash, header, type } = commit;
|
|
201
|
+
/**
|
|
202
|
+
* 确保当log一样时,commit hash判断log是不一致的
|
|
203
|
+
* close: commit下自行提交(log可能会相同)需添加ref
|
|
204
|
+
* pr: 由github pr生成一条提交记录(唯一的, 无需添加ref)
|
|
205
|
+
*/
|
|
206
|
+
const ref = !hash || pullRegxp.test(header) ? "" : ` ([${hash?.substring(0, 7)}](${homepage}/commit/${hash}))`;
|
|
207
|
+
let message = header?.trim();
|
|
208
|
+
if (workspace && !effect) message = message.replace(/\(.+\)!?:/, ":");
|
|
209
|
+
message = message.replace(pullRegxp, `[$1](${homepage}/pull/$2)`).replace(closeRegxp, `[$1$2](${homepage}/issues/$2)`) + ref;
|
|
210
|
+
if (breaking) notes.breaking.push(message);
|
|
211
|
+
else if (type === "fix") notes.fixes.push(message);
|
|
212
|
+
else if (type === "feat") notes.features.push(message);
|
|
213
|
+
else notes.updates.push(message);
|
|
214
|
+
}
|
|
215
|
+
Object.keys(notes).forEach((i) => {
|
|
216
|
+
notes[i] = notes[i].filter((j) => {
|
|
217
|
+
return !logFile.includes(j);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
const parts = [
|
|
221
|
+
notes.breaking.length ? `### Breaking Changes\n\n- ${notes.breaking.join("\n- ")}`.trim() : "",
|
|
222
|
+
notes.fixes.length ? `### Bugfixes\n\n- ${notes.fixes.join("\n- ")}`.trim() : "",
|
|
223
|
+
notes.features.length ? `### Features\n\n- ${notes.features.join("\n- ")}`.trim() : "",
|
|
224
|
+
notes.updates.length ? `### Updates\n\n- ${notes.updates.join("\n- ")}`.trim() : ""
|
|
225
|
+
].filter(Boolean);
|
|
226
|
+
const newLog = parts.join("\n\n");
|
|
227
|
+
return !parts.length || logFile.includes(newLog) ? "" : newLog;
|
|
228
|
+
}
|
|
229
|
+
async updateVersion() {
|
|
230
|
+
const { packageOptions, commits, commandOptions } = this;
|
|
231
|
+
const { version } = packageOptions;
|
|
232
|
+
let newVersion = "";
|
|
233
|
+
if (commandOptions.customVersion) {
|
|
234
|
+
newVersion = commandOptions.customVersion;
|
|
235
|
+
if (!/\d+.\d+.\d+/.test(newVersion) || version === newVersion) newVersion = await (0, _inquirer_prompts.input)({
|
|
236
|
+
message: `Custom Update Version(${this.packageName}@${version}):`,
|
|
237
|
+
default: "",
|
|
238
|
+
validate: (answer) => {
|
|
239
|
+
if (!/\d+.\d+.\d+/.test(answer)) return "Version Should Be Like x.x.x";
|
|
240
|
+
if (answer === version) return "Version Should Be Diff Than Before";
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
} else {
|
|
245
|
+
const intersection = [
|
|
246
|
+
commandOptions.major && "major",
|
|
247
|
+
commandOptions.minor && "minor",
|
|
248
|
+
commandOptions.patch && "patch"
|
|
249
|
+
].filter((i) => !!i);
|
|
250
|
+
if (intersection.length) newVersion = semver.default.inc(version, intersection[0]) || "";
|
|
251
|
+
else {
|
|
252
|
+
const types = new Set(commits.map(({ type }) => type));
|
|
253
|
+
const level = commits.some((commit) => !!commit.breaking) ? "major" : types.has("feat") ? "minor" : "patch";
|
|
254
|
+
newVersion = semver.default.inc(version, level) || "";
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
this.version = newVersion;
|
|
258
|
+
}
|
|
259
|
+
isChanged() {
|
|
260
|
+
return !!this.commits.length;
|
|
261
|
+
}
|
|
262
|
+
async updateCommits(commits, source) {
|
|
263
|
+
if (!commits.length) return;
|
|
264
|
+
const { packageName } = this;
|
|
265
|
+
const olds = this.commits.map((i) => JSON.stringify({
|
|
266
|
+
...i,
|
|
267
|
+
effect: false
|
|
268
|
+
}));
|
|
269
|
+
const newCommits = commits.filter((i) => {
|
|
270
|
+
return !olds.includes(JSON.stringify({
|
|
271
|
+
...i,
|
|
272
|
+
effect: false
|
|
273
|
+
}));
|
|
274
|
+
}).map((j) => {
|
|
275
|
+
return {
|
|
276
|
+
...j,
|
|
277
|
+
effect: !!source
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
if (newCommits.length && this.commits.length) this.commits = this.commits.filter((i) => !i.custom);
|
|
281
|
+
const commits$ = this.commits.concat(newCommits);
|
|
282
|
+
if (source) _deot_dev_shared.Logger.log(chalk.default.magenta(`MERGE COMMITS: `) + chalk.default.bold(`${commits.length}`) + " Commits. merge " + chalk.default.yellow(source) + " into " + chalk.default.green(packageName));
|
|
283
|
+
else _deot_dev_shared.Logger.log(``);
|
|
284
|
+
const changeLog = this.rebuildChangeLog(commits$);
|
|
285
|
+
if (changeLog) {
|
|
286
|
+
this.commits = commits$;
|
|
287
|
+
this.changeLog = changeLog;
|
|
288
|
+
} else if (commits.length) _deot_dev_shared.Logger.log(chalk.default.red(`${commits.length} Commits Already Exists.`));
|
|
289
|
+
}
|
|
290
|
+
async updatePackageOptions(relationVerisons = {}) {
|
|
291
|
+
if (!this.isChanged()) return;
|
|
292
|
+
const { packageDir, packageOptions, commandOptions } = this;
|
|
293
|
+
const { dependencies, devDependencies } = packageOptions;
|
|
294
|
+
const newVersion = this.version;
|
|
295
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`New Version: `) + `${newVersion}`);
|
|
296
|
+
packageOptions.version = newVersion;
|
|
297
|
+
if (Object.keys(this.packageRelation).length) for (const packageName$ in relationVerisons) {
|
|
298
|
+
const newVersion$ = relationVerisons[packageName$];
|
|
299
|
+
if (dependencies?.[packageName$]) dependencies[packageName$] = newVersion$;
|
|
300
|
+
if (devDependencies?.[packageName$]) devDependencies[packageName$] = newVersion$;
|
|
301
|
+
}
|
|
302
|
+
if (commandOptions.dryRun) {
|
|
303
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`Skipping package.json Update`));
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`Updating `) + "package.json");
|
|
307
|
+
fs_extra.default.outputFileSync(`${packageDir}/package.json`, JSON.stringify(packageOptions, null, 2));
|
|
308
|
+
}
|
|
309
|
+
async updateChangelog() {
|
|
310
|
+
if (!this.isChanged()) return;
|
|
311
|
+
const { packageName, packageDir, packageOptions, commandOptions } = this;
|
|
312
|
+
const title = `# ${packageName} ChangeLog`;
|
|
313
|
+
const [date] = (/* @__PURE__ */ new Date()).toISOString().split("T");
|
|
314
|
+
const logPath = node_path.resolve(packageDir, "./CHANGELOG.md");
|
|
315
|
+
const logFile = fs_extra.default.existsSync(logPath) ? fs_extra.default.readFileSync(logPath, "utf-8") : "";
|
|
316
|
+
const oldNotes = logFile.startsWith(title) ? logFile.slice(title.length).trim() : logFile;
|
|
317
|
+
const newLog = [
|
|
318
|
+
`## v${packageOptions.version}`,
|
|
319
|
+
`_${date}_`,
|
|
320
|
+
this.changeLog
|
|
321
|
+
].filter(Boolean).join("\n\n");
|
|
322
|
+
if (commandOptions.dryRun) {
|
|
323
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`New ChangeLog:`) + `\n${newLog}`);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`Updating `) + `CHANGELOG.md`);
|
|
327
|
+
let content = [
|
|
328
|
+
title,
|
|
329
|
+
newLog,
|
|
330
|
+
oldNotes
|
|
331
|
+
].filter(Boolean).join("\n\n");
|
|
332
|
+
if (!content.endsWith("\n")) content += "\n";
|
|
333
|
+
fs_extra.default.writeFileSync(logPath, content, "utf-8");
|
|
334
|
+
}
|
|
335
|
+
async test() {
|
|
336
|
+
if (!this.isChanged()) return;
|
|
337
|
+
const { commandOptions } = this;
|
|
338
|
+
if (commandOptions.dryRun) {
|
|
339
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow("Skipping Test"));
|
|
340
|
+
return;
|
|
341
|
+
} else _deot_dev_shared.Logger.log(chalk.default.yellow("Test..."));
|
|
342
|
+
await _deot_dev_shared.Shell.exec(`npm run test -- --package-name ${this.packageName}${commandOptions.coverage ? "" : " --no-coverage"}`);
|
|
343
|
+
}
|
|
344
|
+
async build() {
|
|
345
|
+
if (!this.isChanged()) return;
|
|
346
|
+
const { commandOptions } = this;
|
|
347
|
+
if (commandOptions.dryRun) {
|
|
348
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow("Skipping Build"));
|
|
349
|
+
return;
|
|
350
|
+
} else _deot_dev_shared.Logger.log(chalk.default.yellow("Build..."));
|
|
351
|
+
await _deot_dev_shared.Shell.exec(`npm run build -- --package-name ${this.packageName}`);
|
|
352
|
+
}
|
|
353
|
+
async publish() {
|
|
354
|
+
const { commandOptions } = this;
|
|
355
|
+
if (!this.isChanged() || !commandOptions.publish) return;
|
|
356
|
+
const { packageDir, packageName } = this;
|
|
357
|
+
_deot_dev_shared.Logger.log(chalk.default.magenta(`PUBLISH: `) + packageName);
|
|
358
|
+
if (commandOptions.dryRun) {
|
|
359
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`Skipping Publish`));
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
_deot_dev_shared.Logger.log(chalk.default.cyan(`\n Publishing to NPM`));
|
|
363
|
+
await _deot_dev_shared.Shell.spawn("npm", [
|
|
364
|
+
"publish",
|
|
365
|
+
"--no-git-checks",
|
|
366
|
+
"--access",
|
|
367
|
+
"public"
|
|
368
|
+
], { cwd: packageDir });
|
|
369
|
+
}
|
|
370
|
+
async tag() {
|
|
371
|
+
const { commandOptions } = this;
|
|
372
|
+
if (!this.isChanged() || !commandOptions.tag) return;
|
|
373
|
+
const { packageDir, packageName, packageOptions } = this;
|
|
374
|
+
_deot_dev_shared.Logger.log(chalk.default.magenta(`TAG: `) + packageName);
|
|
375
|
+
if (commandOptions.dryRun) {
|
|
376
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`Skipping Git Tag`));
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
const tagName = `${packageName}@${packageOptions.version}`;
|
|
380
|
+
_deot_dev_shared.Logger.log(chalk.default.blue(`\n Tagging`) + chalk.default.grey(`${tagName}`));
|
|
381
|
+
await _deot_dev_shared.Shell.spawn("git", ["tag", tagName], { cwd: packageDir });
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* 清理tags,仅保留最后一个tag. 相当于tags仅用于记录commit开始的位置
|
|
385
|
+
* git push以后执行。即时删除失败了,也不会产生不必要的影响
|
|
386
|
+
*/
|
|
387
|
+
async cleanTagsAndKeepLastTag() {
|
|
388
|
+
const { commandOptions } = this;
|
|
389
|
+
if (!commandOptions.keepLastTag) return;
|
|
390
|
+
let tags = await this.getTags();
|
|
391
|
+
tags = tags.slice(1).filter((i) => !!i).reverse();
|
|
392
|
+
if (!tags.length) return;
|
|
393
|
+
const { packageName } = this;
|
|
394
|
+
_deot_dev_shared.Logger.log(chalk.default.magenta(`CLEAN TAGS: `) + packageName);
|
|
395
|
+
if (commandOptions.dryRun) {
|
|
396
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow(`Skipping Tags Clean`));
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
await tags.reduce((preProcess, tag) => {
|
|
400
|
+
preProcess = preProcess.then(() => _deot_dev_shared.Shell.spawn("git", [
|
|
401
|
+
"push",
|
|
402
|
+
"origin",
|
|
403
|
+
"--delete",
|
|
404
|
+
tag
|
|
405
|
+
])).then(() => _deot_dev_shared.Shell.spawn("git", [
|
|
406
|
+
"tag",
|
|
407
|
+
"--delete",
|
|
408
|
+
tag
|
|
409
|
+
]));
|
|
410
|
+
return preProcess;
|
|
411
|
+
}, Promise.resolve());
|
|
412
|
+
}
|
|
413
|
+
async process() {
|
|
414
|
+
const { workspace } = _deot_dev_shared.Locals.impl();
|
|
415
|
+
const { packageName, packageDir, packageFolderName } = this;
|
|
416
|
+
if (!packageDir || !fs_extra.default.pathExists(packageDir)) throw new RangeError(`Could not find directory for package: ${packageFolderName}`);
|
|
417
|
+
_deot_dev_shared.Logger.log(chalk.default.cyan(`Releasing ${packageName}`) + " from " + chalk.default.grey(`${workspace}/${packageFolderName}`));
|
|
418
|
+
await this.parseCommits();
|
|
419
|
+
return this;
|
|
420
|
+
}
|
|
39
421
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class Release {
|
|
43
|
-
packageDir;
|
|
44
|
-
packageName;
|
|
45
|
-
packageFolderName;
|
|
46
|
-
packageOptions;
|
|
47
|
-
packageRelation;
|
|
48
|
-
config;
|
|
49
|
-
changeLog;
|
|
50
|
-
version;
|
|
51
|
-
commits;
|
|
52
|
-
commandOptions;
|
|
53
|
-
constructor(config, commandOptions) {
|
|
54
|
-
const { packageDir, packageRelation } = devShared.Locals.impl();
|
|
55
|
-
if (typeof config === "string") {
|
|
56
|
-
const packageFolderName = config;
|
|
57
|
-
const packageDir$ = path__namespace.resolve(packageDir, packageFolderName);
|
|
58
|
-
config = {
|
|
59
|
-
dir: packageDir$,
|
|
60
|
-
name: packageFolderName
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
this.packageDir = config.dir;
|
|
64
|
-
this.packageName = devShared.Locals.getPackageName(config.name);
|
|
65
|
-
this.packageFolderName = config.name;
|
|
66
|
-
this.packageOptions = require$(`${this.packageDir}/package.json`);
|
|
67
|
-
this.packageRelation = packageRelation[this.packageName] || [];
|
|
68
|
-
this.config = config;
|
|
69
|
-
this.commits = [];
|
|
70
|
-
this.changeLog = "";
|
|
71
|
-
this.version = "";
|
|
72
|
-
this.commandOptions = commandOptions;
|
|
73
|
-
}
|
|
74
|
-
async parseCommits() {
|
|
75
|
-
const { workspace } = devShared.Locals.impl();
|
|
76
|
-
const { packageFolderName, commandOptions } = this;
|
|
77
|
-
const [latestTag] = await this.getTags();
|
|
78
|
-
devShared.Logger.log(chalk.yellow(`Last Release Tag`) + `: ${latestTag || "<none>"}`);
|
|
79
|
-
const params = ["--no-pager", "log", `${latestTag}..HEAD`, `--format=%B%n${HASH}%n%H${SUFFIX}`];
|
|
80
|
-
let {
|
|
81
|
-
stdout
|
|
82
|
-
} = await devShared.Shell.exec("git", params);
|
|
83
|
-
let skipGetLog = false;
|
|
84
|
-
if (latestTag) {
|
|
85
|
-
const log1 = await devShared.Shell.exec("git", ["rev-parse", latestTag]);
|
|
86
|
-
const log2 = await devShared.Shell.exec("git", ["--no-pager", "log", "-1", "--format=%H"]);
|
|
87
|
-
if (log1.stdout === log2.stdout) {
|
|
88
|
-
skipGetLog = true;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (!skipGetLog && !stdout) {
|
|
92
|
-
if (latestTag) {
|
|
93
|
-
params.splice(2, 1, `${latestTag}`);
|
|
94
|
-
} else {
|
|
95
|
-
params.splice(2, 1, "HEAD");
|
|
96
|
-
}
|
|
97
|
-
({ stdout } = await devShared.Shell.exec("git", params));
|
|
98
|
-
}
|
|
99
|
-
const allowTypes = ["feat", `fix`, `break change`, `style`, `perf`, `types`, `refactor`, `chore`];
|
|
100
|
-
const rePlugin = new RegExp(`^(${allowTypes.join("|")})${workspace ? `\\(([,\\w-]+(,))?${packageFolderName}((,)[,\\w-]+)?\\)` : "(\\(.+\\))?"}: .*`, "i");
|
|
101
|
-
const reAll = workspace && new RegExp(`^(${allowTypes.join("|")})\\(\\*\\): .*`, "i");
|
|
102
|
-
const allCommits = commandOptions.commits || stdout.split(SUFFIX);
|
|
103
|
-
const commits = allCommits.filter((commit) => {
|
|
104
|
-
const chunk = commit.trim();
|
|
105
|
-
return chunk && (rePlugin.test(chunk) || reAll && reAll.test(chunk));
|
|
106
|
-
}).map((commit) => {
|
|
107
|
-
const node = commitParser.parse(commit);
|
|
108
|
-
const body = node.body || node.footer;
|
|
109
|
-
if (!node.type) node.type = commitParser.parse(node.header?.replace(/\(.+\)!?:/, ":") || "").type;
|
|
110
|
-
if (!node.hash) node.hash = commit.split(HASH).pop()?.trim();
|
|
111
|
-
node.breaking = reBreaking.test(body) || /!:/.test(node.header);
|
|
112
|
-
node.effect = false;
|
|
113
|
-
node.custom = false;
|
|
114
|
-
return node;
|
|
115
|
-
});
|
|
116
|
-
if (!commits.length) {
|
|
117
|
-
devShared.Logger.log(chalk.red(`No Commits Found.`));
|
|
118
|
-
} else {
|
|
119
|
-
devShared.Logger.log(
|
|
120
|
-
chalk.yellow(`Found `) + chalk.bold(`${allCommits.length}`) + ` Commits, ` + chalk.bold(`${commits.length}`) + " Commits Valid"
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
const { skipUpdatePackage } = commandOptions;
|
|
124
|
-
if (commits.length && skipUpdatePackage) {
|
|
125
|
-
let skip = false;
|
|
126
|
-
if (typeof skipUpdatePackage === "boolean" && skipUpdatePackage) {
|
|
127
|
-
skip = await prompts.confirm({
|
|
128
|
-
message: `Skip Update(${this.packageName}@${this.packageOptions.version}):`,
|
|
129
|
-
default: true
|
|
130
|
-
});
|
|
131
|
-
} else if (typeof skipUpdatePackage === "string" && (skipUpdatePackage === "*" || skipUpdatePackage.split(",").includes(this.packageName))) {
|
|
132
|
-
skip = true;
|
|
133
|
-
}
|
|
134
|
-
if (skip) {
|
|
135
|
-
devShared.Logger.log(chalk.red(`Skipping Update
|
|
136
|
-
`));
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
await this.updateVersion();
|
|
141
|
-
await this.updateCommits(commits);
|
|
142
|
-
const { forceUpdatePackage } = commandOptions;
|
|
143
|
-
if (!commits.length && forceUpdatePackage) {
|
|
144
|
-
let force = false;
|
|
145
|
-
if (typeof forceUpdatePackage === "boolean" && forceUpdatePackage) {
|
|
146
|
-
force = await prompts.confirm({
|
|
147
|
-
message: `Force Update(${this.packageName}@${this.packageOptions.version}):`,
|
|
148
|
-
default: true
|
|
149
|
-
});
|
|
150
|
-
} else if (typeof forceUpdatePackage === "string" && (forceUpdatePackage === "*" || forceUpdatePackage.split(",").includes(this.packageName))) {
|
|
151
|
-
force = true;
|
|
152
|
-
}
|
|
153
|
-
if (force) {
|
|
154
|
-
const oldVersion = this.packageOptions.version;
|
|
155
|
-
const versionChanged = `\`${oldVersion}\` -> \`${this.version}\``;
|
|
156
|
-
this.commits = [
|
|
157
|
-
{
|
|
158
|
-
type: "chore",
|
|
159
|
-
header: `chore(${this.packageFolderName || "release"}): force-publish ${versionChanged}`,
|
|
160
|
-
hash: "",
|
|
161
|
-
effect: false,
|
|
162
|
-
breaking: false,
|
|
163
|
-
custom: true
|
|
164
|
-
}
|
|
165
|
-
];
|
|
166
|
-
this.changeLog = `### Force Update Package
|
|
167
|
-
|
|
168
|
-
- ${versionChanged}`.trim();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
async getTags() {
|
|
173
|
-
const { packageName } = this;
|
|
174
|
-
const params = ["tag", "--list", `'${packageName}@*'`, "--sort", "-v:refname"];
|
|
175
|
-
const { stdout } = await devShared.Shell.exec("git", params);
|
|
176
|
-
return stdout.split("\n");
|
|
177
|
-
}
|
|
178
|
-
rebuildChangeLog(commits) {
|
|
179
|
-
const { packageDir } = this;
|
|
180
|
-
const { homepage, workspace } = devShared.Locals.impl();
|
|
181
|
-
const logPath = path__namespace.resolve(packageDir, "./CHANGELOG.md");
|
|
182
|
-
const logFile = fs.existsSync(logPath) ? fs.readFileSync(logPath, "utf-8") : "";
|
|
183
|
-
const notes = {
|
|
184
|
-
breaking: [],
|
|
185
|
-
features: [],
|
|
186
|
-
fixes: [],
|
|
187
|
-
updates: []
|
|
188
|
-
};
|
|
189
|
-
const closeRegxp = /\(?(closes? )\(?#((\d+))\)/ig;
|
|
190
|
-
const pullRegxp = /(?<!closes? )\((#(\d+))\)/ig;
|
|
191
|
-
for (const commit of commits) {
|
|
192
|
-
const { effect, breaking, hash, header, type } = commit;
|
|
193
|
-
const ref = !hash || pullRegxp.test(header) ? "" : ` ([${hash?.substring(0, 7)}](${homepage}/commit/${hash}))`;
|
|
194
|
-
let message = header?.trim();
|
|
195
|
-
if (workspace && !effect) {
|
|
196
|
-
message = message.replace(/\(.+\)!?:/, ":");
|
|
197
|
-
}
|
|
198
|
-
message = message.replace(pullRegxp, `[$1](${homepage}/pull/$2)`).replace(closeRegxp, `[$1$2](${homepage}/issues/$2)`) + ref;
|
|
199
|
-
if (breaking) {
|
|
200
|
-
notes.breaking.push(message);
|
|
201
|
-
} else if (type === "fix") {
|
|
202
|
-
notes.fixes.push(message);
|
|
203
|
-
} else if (type === "feat") {
|
|
204
|
-
notes.features.push(message);
|
|
205
|
-
} else {
|
|
206
|
-
notes.updates.push(message);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
Object.keys(notes).forEach((i) => {
|
|
210
|
-
notes[i] = notes[i].filter((j) => {
|
|
211
|
-
return !logFile.includes(j);
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
const parts = [
|
|
215
|
-
notes.breaking.length ? `### Breaking Changes
|
|
216
|
-
|
|
217
|
-
- ${notes.breaking.join("\n- ")}`.trim() : "",
|
|
218
|
-
notes.fixes.length ? `### Bugfixes
|
|
219
|
-
|
|
220
|
-
- ${notes.fixes.join("\n- ")}`.trim() : "",
|
|
221
|
-
notes.features.length ? `### Features
|
|
222
|
-
|
|
223
|
-
- ${notes.features.join("\n- ")}`.trim() : "",
|
|
224
|
-
notes.updates.length ? `### Updates
|
|
225
|
-
|
|
226
|
-
- ${notes.updates.join("\n- ")}`.trim() : ""
|
|
227
|
-
].filter(Boolean);
|
|
228
|
-
const newLog = parts.join("\n\n");
|
|
229
|
-
return !parts.length || logFile.includes(newLog) ? "" : newLog;
|
|
230
|
-
}
|
|
231
|
-
async updateVersion() {
|
|
232
|
-
const { packageOptions, commits, commandOptions } = this;
|
|
233
|
-
const { version } = packageOptions;
|
|
234
|
-
let newVersion = "";
|
|
235
|
-
if (commandOptions.customVersion) {
|
|
236
|
-
newVersion = commandOptions.customVersion;
|
|
237
|
-
if (!/\d+.\d+.\d+/.test(newVersion) || version === newVersion) {
|
|
238
|
-
newVersion = await prompts.input(
|
|
239
|
-
{
|
|
240
|
-
message: `Custom Update Version(${this.packageName}@${version}):`,
|
|
241
|
-
default: "",
|
|
242
|
-
validate: (answer) => {
|
|
243
|
-
if (!/\d+.\d+.\d+/.test(answer)) {
|
|
244
|
-
return "Version Should Be Like x.x.x";
|
|
245
|
-
}
|
|
246
|
-
if (answer === version) {
|
|
247
|
-
return "Version Should Be Diff Than Before";
|
|
248
|
-
}
|
|
249
|
-
return true;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
const intersection = [
|
|
256
|
-
commandOptions.major && "major",
|
|
257
|
-
commandOptions.minor && "minor",
|
|
258
|
-
commandOptions.patch && "patch"
|
|
259
|
-
].filter((i) => !!i);
|
|
260
|
-
if (intersection.length) {
|
|
261
|
-
newVersion = semver.inc(version, intersection[0]) || "";
|
|
262
|
-
} else {
|
|
263
|
-
const types = new Set(commits.map(({
|
|
264
|
-
type
|
|
265
|
-
}) => type));
|
|
266
|
-
const breaking = commits.some((commit) => !!commit.breaking);
|
|
267
|
-
const level = breaking ? "major" : types.has("feat") ? "minor" : "patch";
|
|
268
|
-
newVersion = semver.inc(version, level) || "";
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
this.version = newVersion;
|
|
272
|
-
}
|
|
273
|
-
isChanged() {
|
|
274
|
-
return !!this.commits.length;
|
|
275
|
-
}
|
|
276
|
-
async updateCommits(commits, source) {
|
|
277
|
-
if (!commits.length) return;
|
|
278
|
-
const { packageName } = this;
|
|
279
|
-
const olds = this.commits.map((i) => JSON.stringify({ ...i, effect: false }));
|
|
280
|
-
const newCommits = commits.filter((i) => {
|
|
281
|
-
return !olds.includes(JSON.stringify({ ...i, effect: false }));
|
|
282
|
-
}).map((j) => {
|
|
283
|
-
return {
|
|
284
|
-
...j,
|
|
285
|
-
effect: !!source
|
|
286
|
-
};
|
|
287
|
-
});
|
|
288
|
-
if (newCommits.length && this.commits.length) {
|
|
289
|
-
this.commits = this.commits.filter((i) => !i.custom);
|
|
290
|
-
}
|
|
291
|
-
const commits$ = this.commits.concat(newCommits);
|
|
292
|
-
if (source) {
|
|
293
|
-
devShared.Logger.log(
|
|
294
|
-
chalk.magenta(`MERGE COMMITS: `) + chalk.bold(`${commits.length}`) + ` Commits. merge ` + chalk.yellow(source) + " into " + chalk.green(packageName)
|
|
295
|
-
);
|
|
296
|
-
} else {
|
|
297
|
-
devShared.Logger.log(``);
|
|
298
|
-
}
|
|
299
|
-
const changeLog = this.rebuildChangeLog(commits$);
|
|
300
|
-
if (changeLog) {
|
|
301
|
-
this.commits = commits$;
|
|
302
|
-
this.changeLog = changeLog;
|
|
303
|
-
} else if (commits.length) {
|
|
304
|
-
devShared.Logger.log(chalk.red(`${commits.length} Commits Already Exists.`));
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
async updatePackageOptions(relationVerisons = {}) {
|
|
308
|
-
if (!this.isChanged()) return;
|
|
309
|
-
const { packageDir, packageOptions, commandOptions } = this;
|
|
310
|
-
const { dependencies, devDependencies } = packageOptions;
|
|
311
|
-
const newVersion = this.version;
|
|
312
|
-
devShared.Logger.log(chalk.yellow(`New Version: `) + `${newVersion}`);
|
|
313
|
-
packageOptions.version = newVersion;
|
|
314
|
-
if (Object.keys(this.packageRelation).length) {
|
|
315
|
-
for (const packageName$ in relationVerisons) {
|
|
316
|
-
const newVersion$ = relationVerisons[packageName$];
|
|
317
|
-
if (dependencies?.[packageName$]) {
|
|
318
|
-
dependencies[packageName$] = newVersion$;
|
|
319
|
-
}
|
|
320
|
-
if (devDependencies?.[packageName$]) {
|
|
321
|
-
devDependencies[packageName$] = newVersion$;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (commandOptions.dryRun) {
|
|
326
|
-
devShared.Logger.log(chalk.yellow(`Skipping package.json Update`));
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
devShared.Logger.log(chalk.yellow(`Updating `) + "package.json");
|
|
330
|
-
fs.outputFileSync(`${packageDir}/package.json`, JSON.stringify(packageOptions, null, 2));
|
|
331
|
-
}
|
|
332
|
-
async updateChangelog() {
|
|
333
|
-
if (!this.isChanged()) return;
|
|
334
|
-
const { packageName, packageDir, packageOptions, commandOptions } = this;
|
|
335
|
-
const title = `# ${packageName} ChangeLog`;
|
|
336
|
-
const [date] = (/* @__PURE__ */ new Date()).toISOString().split("T");
|
|
337
|
-
const logPath = path__namespace.resolve(packageDir, "./CHANGELOG.md");
|
|
338
|
-
const logFile = fs.existsSync(logPath) ? fs.readFileSync(logPath, "utf-8") : "";
|
|
339
|
-
const oldNotes = logFile.startsWith(title) ? logFile.slice(title.length).trim() : logFile;
|
|
340
|
-
const parts = [
|
|
341
|
-
`## v${packageOptions.version}`,
|
|
342
|
-
`_${date}_`,
|
|
343
|
-
this.changeLog
|
|
344
|
-
].filter(Boolean);
|
|
345
|
-
const newLog = parts.join("\n\n");
|
|
346
|
-
if (commandOptions.dryRun) {
|
|
347
|
-
devShared.Logger.log(chalk.yellow(`New ChangeLog:`) + `
|
|
348
|
-
${newLog}`);
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
devShared.Logger.log(chalk.yellow(`Updating `) + `CHANGELOG.md`);
|
|
352
|
-
let content = [title, newLog, oldNotes].filter(Boolean).join("\n\n");
|
|
353
|
-
if (!content.endsWith("\n")) content += "\n";
|
|
354
|
-
fs.writeFileSync(logPath, content, "utf-8");
|
|
355
|
-
}
|
|
356
|
-
async test() {
|
|
357
|
-
if (!this.isChanged()) return;
|
|
358
|
-
const { commandOptions } = this;
|
|
359
|
-
if (commandOptions.dryRun) {
|
|
360
|
-
devShared.Logger.log(chalk.yellow("Skipping Test"));
|
|
361
|
-
return;
|
|
362
|
-
} else {
|
|
363
|
-
devShared.Logger.log(chalk.yellow("Test..."));
|
|
364
|
-
}
|
|
365
|
-
await devShared.Shell.exec(`npm run test -- --package-name ${this.packageName}${commandOptions.coverage ? "" : " --no-coverage"}`);
|
|
366
|
-
}
|
|
367
|
-
async build() {
|
|
368
|
-
if (!this.isChanged()) return;
|
|
369
|
-
const { commandOptions } = this;
|
|
370
|
-
if (commandOptions.dryRun) {
|
|
371
|
-
devShared.Logger.log(chalk.yellow("Skipping Build"));
|
|
372
|
-
return;
|
|
373
|
-
} else {
|
|
374
|
-
devShared.Logger.log(chalk.yellow("Build..."));
|
|
375
|
-
}
|
|
376
|
-
await devShared.Shell.exec(`npm run build -- --package-name ${this.packageName}`);
|
|
377
|
-
}
|
|
378
|
-
async publish() {
|
|
379
|
-
const { commandOptions } = this;
|
|
380
|
-
if (!this.isChanged() || !commandOptions.publish) return;
|
|
381
|
-
const { packageDir, packageName } = this;
|
|
382
|
-
devShared.Logger.log(chalk.magenta(`PUBLISH: `) + packageName);
|
|
383
|
-
if (commandOptions.dryRun) {
|
|
384
|
-
devShared.Logger.log(chalk.yellow(`Skipping Publish`));
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
devShared.Logger.log(chalk.cyan(`
|
|
388
|
-
Publishing to NPM`));
|
|
389
|
-
await devShared.Shell.spawn(
|
|
390
|
-
"npm",
|
|
391
|
-
["publish", "--no-git-checks", "--access", "public"],
|
|
392
|
-
{
|
|
393
|
-
cwd: packageDir
|
|
394
|
-
}
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
async tag() {
|
|
398
|
-
const { commandOptions } = this;
|
|
399
|
-
if (!this.isChanged() || !commandOptions.tag) return;
|
|
400
|
-
const { packageDir, packageName, packageOptions } = this;
|
|
401
|
-
devShared.Logger.log(chalk.magenta(`TAG: `) + packageName);
|
|
402
|
-
if (commandOptions.dryRun) {
|
|
403
|
-
devShared.Logger.log(chalk.yellow(`Skipping Git Tag`));
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
const tagName = `${packageName}@${packageOptions.version}`;
|
|
407
|
-
devShared.Logger.log(chalk.blue(`
|
|
408
|
-
Tagging`) + chalk.grey(`${tagName}`));
|
|
409
|
-
await devShared.Shell.spawn(
|
|
410
|
-
"git",
|
|
411
|
-
["tag", tagName],
|
|
412
|
-
{
|
|
413
|
-
cwd: packageDir
|
|
414
|
-
}
|
|
415
|
-
);
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* 清理tags,仅保留最后一个tag. 相当于tags仅用于记录commit开始的位置
|
|
419
|
-
* git push以后执行。即时删除失败了,也不会产生不必要的影响
|
|
420
|
-
*/
|
|
421
|
-
async cleanTagsAndKeepLastTag() {
|
|
422
|
-
const { commandOptions } = this;
|
|
423
|
-
if (!commandOptions.keepLastTag) return;
|
|
424
|
-
let tags = await this.getTags();
|
|
425
|
-
tags = tags.slice(1).filter((i) => !!i).reverse();
|
|
426
|
-
if (!tags.length) return;
|
|
427
|
-
const { packageName } = this;
|
|
428
|
-
devShared.Logger.log(chalk.magenta(`CLEAN TAGS: `) + packageName);
|
|
429
|
-
if (commandOptions.dryRun) {
|
|
430
|
-
devShared.Logger.log(chalk.yellow(`Skipping Tags Clean`));
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
await tags.reduce(
|
|
434
|
-
(preProcess, tag) => {
|
|
435
|
-
preProcess = preProcess.then(() => devShared.Shell.spawn("git", ["push", "origin", "--delete", tag])).then(() => devShared.Shell.spawn("git", ["tag", "--delete", tag]));
|
|
436
|
-
return preProcess;
|
|
437
|
-
},
|
|
438
|
-
Promise.resolve()
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
async process() {
|
|
442
|
-
const { workspace } = devShared.Locals.impl();
|
|
443
|
-
const { packageName, packageDir, packageFolderName } = this;
|
|
444
|
-
if (!packageDir || !fs.pathExists(packageDir)) {
|
|
445
|
-
throw new RangeError(`Could not find directory for package: ${packageFolderName}`);
|
|
446
|
-
}
|
|
447
|
-
devShared.Logger.log(chalk.cyan(`Releasing ${packageName}`) + " from " + chalk.grey(`${workspace}/${packageFolderName}`));
|
|
448
|
-
await this.parseCommits();
|
|
449
|
-
return this;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
const release = (options, commandOptions) => {
|
|
453
|
-
return new Release(options, commandOptions);
|
|
422
|
+
var release = (options, commandOptions) => {
|
|
423
|
+
return new Release(options, commandOptions);
|
|
454
424
|
};
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
devShared.Logger.log(chalk.magenta(`PUSH: `) + "Nothing Chanaged.");
|
|
557
|
-
} else if (!options.push) {
|
|
558
|
-
devShared.Logger.log(chalk.magenta(`PUSH: `) + "Push Disabled.");
|
|
559
|
-
} else if (options.dryRun) {
|
|
560
|
-
devShared.Logger.log(chalk.magenta(`PUSH: `) + "Skipping Git Push");
|
|
561
|
-
} else {
|
|
562
|
-
devShared.Logger.log(chalk.yellow("Git Pull/Push..."));
|
|
563
|
-
await devShared.Shell.spawn("git", ["pull", "--rebase"]);
|
|
564
|
-
await devShared.Shell.spawn("git", ["push"]);
|
|
565
|
-
await devShared.Shell.spawn("git", ["push", "--tags"]);
|
|
566
|
-
}
|
|
567
|
-
devShared.Logger.log(chalk.blue(`
|
|
568
|
-
---------------------
|
|
569
|
-
`));
|
|
570
|
-
await inputs.reduce(
|
|
571
|
-
(preProcess, packageFolderName) => {
|
|
572
|
-
const instance = instances[packageFolderName];
|
|
573
|
-
preProcess = preProcess.then(() => instance.cleanTagsAndKeepLastTag());
|
|
574
|
-
return preProcess;
|
|
575
|
-
},
|
|
576
|
-
Promise.resolve()
|
|
577
|
-
);
|
|
578
|
-
devShared.Logger.log(chalk.magenta(`FINISH: `) + chalk.green(`Release Successed.`));
|
|
579
|
-
if (options.dryRun) {
|
|
580
|
-
devShared.Logger.log(
|
|
581
|
-
chalk.green("NO DRY RUN WAY: ") + chalk.grey(`npm run release -- --no-dry-run
|
|
582
|
-
`)
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
}, {
|
|
586
|
-
onError: (e) => {
|
|
587
|
-
if (typeof e === "number" && e === 1) {
|
|
588
|
-
devShared.Logger.error("发布失败");
|
|
589
|
-
} else {
|
|
590
|
-
devShared.Logger.error(e);
|
|
591
|
-
}
|
|
592
|
-
devShared.Logger.log(chalk.magenta(`FINISH: `) + chalk.red(`Release Failed.`));
|
|
593
|
-
process.exit(1);
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
|
|
425
|
+
//#endregion
|
|
426
|
+
//#region packages/releaser/src/index.ts
|
|
427
|
+
var run = (options) => _deot_dev_shared.Utils.autoCatch(async () => {
|
|
428
|
+
options = {
|
|
429
|
+
coverage: true,
|
|
430
|
+
dryRun: true,
|
|
431
|
+
tag: true,
|
|
432
|
+
publish: true,
|
|
433
|
+
commit: true,
|
|
434
|
+
push: true,
|
|
435
|
+
keepLastTag: false,
|
|
436
|
+
...options
|
|
437
|
+
};
|
|
438
|
+
const locals = _deot_dev_shared.Locals.impl();
|
|
439
|
+
options.forceUpdateName = _deot_dev_shared.Locals.getRealPackageName(options.forceUpdateName);
|
|
440
|
+
options.skipUpdateName = _deot_dev_shared.Locals.getRealPackageName(options.skipUpdateName);
|
|
441
|
+
if (options.dryRun) _deot_dev_shared.Logger.log(chalk.default.magenta(`DRY RUN: `) + "No files will be modified.", options);
|
|
442
|
+
let inputs = [];
|
|
443
|
+
if (locals.workspace) inputs = locals.normalizePackageFolderNames;
|
|
444
|
+
else inputs = [""];
|
|
445
|
+
const instances = {};
|
|
446
|
+
await inputs.reduce((preProcess, packageFolderName) => {
|
|
447
|
+
preProcess = preProcess.then(() => release(packageFolderName, options).process()).then((instance) => {
|
|
448
|
+
instances[packageFolderName] = instance;
|
|
449
|
+
});
|
|
450
|
+
return preProcess;
|
|
451
|
+
}, Promise.resolve());
|
|
452
|
+
_deot_dev_shared.Logger.log(chalk.default.blue(`---------------------\n`));
|
|
453
|
+
let message = `chore(release): publish\n\n`;
|
|
454
|
+
const relationVerisons = {};
|
|
455
|
+
await inputs.reduce((preProcess, packageFolderName) => {
|
|
456
|
+
const instance = instances[packageFolderName];
|
|
457
|
+
instance.packageRelation.forEach((i) => {
|
|
458
|
+
const instance$ = instances[_deot_dev_shared.Locals.getPackageFolderName(i)];
|
|
459
|
+
if (instance$.commits.length > 0) instance.updateCommits(instance$.commits, instance$.packageName);
|
|
460
|
+
});
|
|
461
|
+
if (instance.commits.length) preProcess = preProcess.then(() => _deot_dev_shared.Logger.log(chalk.default.magenta(`CHANGED: `) + instance.packageName)).then(() => instance.test()).then(() => instance.build()).then(() => instance.updatePackageOptions(relationVerisons)).then(() => instance.updateChangelog()).then(() => {
|
|
462
|
+
message += `- ${instance.packageName}@${instance.packageOptions.version}\n`;
|
|
463
|
+
relationVerisons[instance.packageName] = `^${instance.packageOptions.version}`;
|
|
464
|
+
});
|
|
465
|
+
return preProcess;
|
|
466
|
+
}, Promise.resolve());
|
|
467
|
+
_deot_dev_shared.Logger.log(chalk.default.blue(`\n---------------------\n`));
|
|
468
|
+
const isChanged = Object.keys(relationVerisons).length;
|
|
469
|
+
if (!isChanged) _deot_dev_shared.Logger.log(chalk.default.magenta(`COMMIT: `) + "Nothing Chanaged Found.");
|
|
470
|
+
else if (!options.commit) _deot_dev_shared.Logger.log(chalk.default.magenta(`COMMIT: `) + "Disabled.");
|
|
471
|
+
else if (options.dryRun) _deot_dev_shared.Logger.log(chalk.default.magenta(`COMMIT: `) + chalk.default.yellow(`Skipping Git Commit`) + `\n${message}`);
|
|
472
|
+
else {
|
|
473
|
+
_deot_dev_shared.Logger.log(chalk.default.magenta(`CHANGED: `) + `pnpm-lock.yaml`);
|
|
474
|
+
await _deot_dev_shared.Shell.spawn("npx", [
|
|
475
|
+
"pnpm",
|
|
476
|
+
"install",
|
|
477
|
+
"--lockfile-only"
|
|
478
|
+
]);
|
|
479
|
+
_deot_dev_shared.Logger.log(chalk.default.magenta(`COMMIT: `) + `CHANGELOG.md, package.json, pnpm-lock.yaml`);
|
|
480
|
+
await _deot_dev_shared.Shell.spawn("git", ["add", process.cwd()]);
|
|
481
|
+
await _deot_dev_shared.Shell.spawn("git", [
|
|
482
|
+
"commit",
|
|
483
|
+
"--m",
|
|
484
|
+
`'${message}'`
|
|
485
|
+
]);
|
|
486
|
+
}
|
|
487
|
+
if ((options.keepLastTag || options.push) && !options.dryRun) {
|
|
488
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow("Git Fetch..."));
|
|
489
|
+
await _deot_dev_shared.Shell.spawn("git", [
|
|
490
|
+
"fetch",
|
|
491
|
+
"--prune",
|
|
492
|
+
"--prune-tags"
|
|
493
|
+
]);
|
|
494
|
+
}
|
|
495
|
+
_deot_dev_shared.Logger.log(chalk.default.blue(`\n---------------------\n`));
|
|
496
|
+
await inputs.reduce((preProcess, packageFolderName) => {
|
|
497
|
+
const instance = instances[packageFolderName];
|
|
498
|
+
preProcess = preProcess.then(() => instance.publish()).then(() => instance.tag());
|
|
499
|
+
return preProcess;
|
|
500
|
+
}, Promise.resolve());
|
|
501
|
+
_deot_dev_shared.Logger.log(chalk.default.blue(`\n---------------------\n`));
|
|
502
|
+
if (!isChanged) _deot_dev_shared.Logger.log(chalk.default.magenta(`PUSH: `) + "Nothing Chanaged.");
|
|
503
|
+
else if (!options.push) _deot_dev_shared.Logger.log(chalk.default.magenta(`PUSH: `) + "Push Disabled.");
|
|
504
|
+
else if (options.dryRun) _deot_dev_shared.Logger.log(chalk.default.magenta(`PUSH: `) + "Skipping Git Push");
|
|
505
|
+
else {
|
|
506
|
+
_deot_dev_shared.Logger.log(chalk.default.yellow("Git Pull/Push..."));
|
|
507
|
+
await _deot_dev_shared.Shell.spawn("git", ["pull", "--rebase"]);
|
|
508
|
+
await _deot_dev_shared.Shell.spawn("git", ["push"]);
|
|
509
|
+
await _deot_dev_shared.Shell.spawn("git", ["push", "--tags"]);
|
|
510
|
+
}
|
|
511
|
+
_deot_dev_shared.Logger.log(chalk.default.blue(`\n---------------------\n`));
|
|
512
|
+
await inputs.reduce((preProcess, packageFolderName) => {
|
|
513
|
+
const instance = instances[packageFolderName];
|
|
514
|
+
preProcess = preProcess.then(() => instance.cleanTagsAndKeepLastTag());
|
|
515
|
+
return preProcess;
|
|
516
|
+
}, Promise.resolve());
|
|
517
|
+
_deot_dev_shared.Logger.log(chalk.default.magenta(`FINISH: `) + chalk.default.green(`Release Successed.`));
|
|
518
|
+
if (options.dryRun) _deot_dev_shared.Logger.log(chalk.default.green("NO DRY RUN WAY: ") + chalk.default.grey(`npm run release -- --no-dry-run\n`));
|
|
519
|
+
}, { onError: (e) => {
|
|
520
|
+
if (typeof e === "number" && e === 1) _deot_dev_shared.Logger.error("发布失败");
|
|
521
|
+
else _deot_dev_shared.Logger.error(e);
|
|
522
|
+
_deot_dev_shared.Logger.log(chalk.default.magenta(`FINISH: `) + chalk.default.red(`Release Failed.`));
|
|
523
|
+
process.exit(1);
|
|
524
|
+
} });
|
|
525
|
+
//#endregion
|
|
597
526
|
exports.run = run;
|