@varlet/release 0.4.4 → 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/README.md +163 -161
- package/README.zh-CN.md +163 -161
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +19 -0
- package/dist/index.d.ts +39 -26
- package/dist/index.js +278 -299
- package/package.json +37 -35
- package/bin/index.js +0 -47
- package/dist/index.cjs +0 -409
- package/dist/index.d.cts +0 -41
package/dist/index.js
CHANGED
|
@@ -1,301 +1,293 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { confirm, select } from "@
|
|
4
|
-
import
|
|
5
|
-
import { glob } from "glob";
|
|
6
|
-
import { createSpinner as createSpinner2 } from "nanospinner";
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { styleText } from "node:util";
|
|
3
|
+
import { cancel, confirm, isCancel, select, spinner } from "@clack/prompts";
|
|
4
|
+
import fse from "fs-extra";
|
|
7
5
|
import { logger } from "rslog";
|
|
8
6
|
import semver from "semver";
|
|
9
|
-
import { x
|
|
10
|
-
|
|
11
|
-
// src/changelog.ts
|
|
12
|
-
import { resolve as resolvePath } from "path";
|
|
7
|
+
import { x } from "tinyexec";
|
|
13
8
|
import conventionalChangelog from "conventional-changelog";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function changelog({
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
commit.subject = commit.subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => {
|
|
69
|
-
if (username.includes("/")) {
|
|
70
|
-
return `@${username}`;
|
|
71
|
-
}
|
|
72
|
-
return `[@${username}](${context.host}/${username})`;
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
commit.references = commit.references.filter((reference) => {
|
|
77
|
-
if (issues.indexOf(reference.issue) === -1) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
81
|
-
});
|
|
82
|
-
return commit;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
} = {}) {
|
|
86
|
-
const s = createSpinner("Generating changelog").start();
|
|
87
|
-
return new Promise((resolve2) => {
|
|
88
|
-
conventionalChangelog(
|
|
89
|
-
{
|
|
90
|
-
preset,
|
|
91
|
-
releaseCount
|
|
92
|
-
},
|
|
93
|
-
void 0,
|
|
94
|
-
void 0,
|
|
95
|
-
void 0,
|
|
96
|
-
writerOpts
|
|
97
|
-
).pipe(createWriteStream(resolvePath(process.cwd(), file))).on("close", () => {
|
|
98
|
-
s.success({ text: "Changelog generated success!" });
|
|
99
|
-
resolve2();
|
|
100
|
-
});
|
|
101
|
-
});
|
|
9
|
+
|
|
10
|
+
//#region src/changelog.ts
|
|
11
|
+
const { createWriteStream } = fse;
|
|
12
|
+
function changelog({ releaseCount = 0, file = "CHANGELOG.md", preset = "angular", writerOpts = { transform(commit, context) {
|
|
13
|
+
let discard = true;
|
|
14
|
+
const issues = [];
|
|
15
|
+
commit.notes.forEach((note) => {
|
|
16
|
+
note.title = "BREAKING CHANGES";
|
|
17
|
+
discard = false;
|
|
18
|
+
});
|
|
19
|
+
if (commit.type === "feat") commit.type = "Features";
|
|
20
|
+
else if (commit.type === "fix") commit.type = "Bug Fixes";
|
|
21
|
+
else if (commit.type === "perf") commit.type = "Performance Improvements";
|
|
22
|
+
else if (commit.type === "revert" || commit.revert) commit.type = "Reverts";
|
|
23
|
+
else if (commit.type === "refactor") commit.type = "Code Refactoring";
|
|
24
|
+
else if (discard) return false;
|
|
25
|
+
else if (commit.type === "docs") commit.type = "Documentation";
|
|
26
|
+
else if (commit.type === "style") commit.type = "Styles";
|
|
27
|
+
else if (commit.type === "test") commit.type = "Tests";
|
|
28
|
+
else if (commit.type === "build") commit.type = "Build System";
|
|
29
|
+
else if (commit.type === "ci") commit.type = "Continuous Integration";
|
|
30
|
+
if (commit.scope === "*") commit.scope = "";
|
|
31
|
+
if (typeof commit.hash === "string") commit.shortHash = commit.hash.substring(0, 7);
|
|
32
|
+
if (typeof commit.subject === "string") {
|
|
33
|
+
let url = context.repository ? `${context.host}/${context.owner}/${context.repository}` : context.repoUrl;
|
|
34
|
+
if (url) {
|
|
35
|
+
url = `${url}/issues/`;
|
|
36
|
+
commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
|
|
37
|
+
issues.push(issue);
|
|
38
|
+
return `[#${issue}](${url}${issue})`;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (context.host) commit.subject = commit.subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => {
|
|
42
|
+
if (username.includes("/")) return `@${username}`;
|
|
43
|
+
return `[@${username}](${context.host}/${username})`;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
commit.references = commit.references.filter((reference) => {
|
|
47
|
+
if (issues.indexOf(reference.issue) === -1) return true;
|
|
48
|
+
return false;
|
|
49
|
+
});
|
|
50
|
+
return commit;
|
|
51
|
+
} } } = {}) {
|
|
52
|
+
const s = spinner();
|
|
53
|
+
s.start("Generating changelog");
|
|
54
|
+
return new Promise((resolve$1) => {
|
|
55
|
+
conventionalChangelog({
|
|
56
|
+
preset,
|
|
57
|
+
releaseCount
|
|
58
|
+
}, void 0, void 0, void 0, writerOpts).pipe(createWriteStream(resolve(process.cwd(), file))).on("close", () => {
|
|
59
|
+
s.stop("Changelog generated successfully!");
|
|
60
|
+
resolve$1();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
102
63
|
}
|
|
103
64
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/release.ts
|
|
67
|
+
const cwd = process.cwd();
|
|
68
|
+
const { writeFileSync, readJSONSync, existsSync, readdirSync } = fse;
|
|
69
|
+
const releaseTypes = [
|
|
70
|
+
"patch",
|
|
71
|
+
"minor",
|
|
72
|
+
"major",
|
|
73
|
+
"prepatch",
|
|
74
|
+
"preminor",
|
|
75
|
+
"premajor"
|
|
76
|
+
];
|
|
77
|
+
const BACK_HINT = "Back to previous step";
|
|
109
78
|
async function isWorktreeEmpty() {
|
|
110
|
-
|
|
111
|
-
return !ret.stdout;
|
|
79
|
+
return !(await x("git", ["status", "--porcelain"])).stdout;
|
|
112
80
|
}
|
|
113
81
|
async function isSameVersion(version) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
82
|
+
const s = spinner();
|
|
83
|
+
s.start("Check remote version...");
|
|
84
|
+
const packageJsones = getPackageJsons();
|
|
85
|
+
const packageJson = packageJsones.find((packageJson) => !packageJson.config.private) || packageJsones[0];
|
|
86
|
+
if (packageJson) {
|
|
87
|
+
const { config } = packageJson;
|
|
88
|
+
try {
|
|
89
|
+
await x("npm", [
|
|
90
|
+
"view",
|
|
91
|
+
`${config.name}@${version ?? config.version}`,
|
|
92
|
+
"version"
|
|
93
|
+
], { throwOnError: true });
|
|
94
|
+
s.cancel();
|
|
95
|
+
logger.warn(`The npm package has a same remote version ${version ?? config.version}.`);
|
|
96
|
+
return true;
|
|
97
|
+
} catch {
|
|
98
|
+
s.stop();
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
132
102
|
}
|
|
133
103
|
async function publish({ preRelease, checkRemoteVersion, npmTag }) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
104
|
+
const s = spinner();
|
|
105
|
+
s.start("Publishing all packages");
|
|
106
|
+
const args = [
|
|
107
|
+
"-r",
|
|
108
|
+
"publish",
|
|
109
|
+
"--no-git-checks",
|
|
110
|
+
"--access",
|
|
111
|
+
"public"
|
|
112
|
+
];
|
|
113
|
+
if (checkRemoteVersion && await isSameVersion()) {
|
|
114
|
+
logger.error("publishing automatically skipped.");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (preRelease) args.push("--tag", "alpha");
|
|
118
|
+
else if (npmTag) args.push("--tag", npmTag);
|
|
119
|
+
try {
|
|
120
|
+
const ret = await x("pnpm", args, { throwOnError: true });
|
|
121
|
+
s.stop("Publish all packages successfully");
|
|
122
|
+
ret.stdout && logger.log(ret.stdout);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
s.cancel("Publish all packages failed");
|
|
125
|
+
throw error?.output?.stderr ?? error;
|
|
126
|
+
}
|
|
148
127
|
}
|
|
149
128
|
async function pushGit(version, remote = "origin", skipGitTag = false) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
129
|
+
const s = spinner();
|
|
130
|
+
s.start("Pushing to remote git repository");
|
|
131
|
+
await x("git", ["add", "."], { throwOnError: true });
|
|
132
|
+
await x("git", [
|
|
133
|
+
"commit",
|
|
134
|
+
"-m",
|
|
135
|
+
`v${version}`
|
|
136
|
+
], { throwOnError: true });
|
|
137
|
+
if (!skipGitTag) {
|
|
138
|
+
await x("git", ["tag", `v${version}`], { throwOnError: true });
|
|
139
|
+
await x("git", [
|
|
140
|
+
"push",
|
|
141
|
+
remote,
|
|
142
|
+
`v${version}`
|
|
143
|
+
], { throwOnError: true });
|
|
144
|
+
}
|
|
145
|
+
const ret = await x("git", ["push"], { throwOnError: true });
|
|
146
|
+
s.stop("Push remote repository successfully");
|
|
147
|
+
ret.stdout && logger.log(ret.stdout);
|
|
148
|
+
}
|
|
149
|
+
function getAllPackageJsons() {
|
|
150
|
+
const result = [resolve(cwd, "package.json")];
|
|
151
|
+
const packagesDir = resolve(cwd, "packages");
|
|
152
|
+
if (existsSync(packagesDir)) for (const name of readdirSync(packagesDir)) {
|
|
153
|
+
const pkgPath = resolve(packagesDir, name, "package.json");
|
|
154
|
+
if (existsSync(pkgPath)) result.push(pkgPath);
|
|
155
|
+
}
|
|
156
|
+
return result;
|
|
170
157
|
}
|
|
171
158
|
function getPackageJsons() {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
};
|
|
179
|
-
});
|
|
159
|
+
return getAllPackageJsons().map((path) => {
|
|
160
|
+
return {
|
|
161
|
+
config: readJSONSync(path),
|
|
162
|
+
filePath: path
|
|
163
|
+
};
|
|
164
|
+
});
|
|
180
165
|
}
|
|
181
166
|
function updateVersion(version) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
});
|
|
167
|
+
getPackageJsons().forEach(({ config, filePath }) => {
|
|
168
|
+
config.version = version;
|
|
169
|
+
writeFileSync(filePath, JSON.stringify(config, null, 2));
|
|
170
|
+
});
|
|
187
171
|
}
|
|
188
172
|
async function confirmRegistry() {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
173
|
+
const registry = (await x("npm", [
|
|
174
|
+
"config",
|
|
175
|
+
"get",
|
|
176
|
+
"registry"
|
|
177
|
+
])).stdout;
|
|
178
|
+
const ret = await confirm({ message: `Current registry is: ${registry}` });
|
|
179
|
+
if (isCancel(ret)) {
|
|
180
|
+
cancel("Operation cancelled.");
|
|
181
|
+
process.exit(0);
|
|
182
|
+
}
|
|
183
|
+
return ret;
|
|
194
184
|
}
|
|
195
185
|
async function confirmVersion(currentVersion, expectVersion) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
186
|
+
const ret = await select({
|
|
187
|
+
message: "Version confirm",
|
|
188
|
+
options: [`All packages version ${currentVersion} -> ${expectVersion}`, BACK_HINT].map((value) => ({
|
|
189
|
+
label: value,
|
|
190
|
+
value
|
|
191
|
+
}))
|
|
192
|
+
});
|
|
193
|
+
if (isCancel(ret)) {
|
|
194
|
+
cancel("Operation cancelled.");
|
|
195
|
+
process.exit(0);
|
|
196
|
+
}
|
|
197
|
+
return ret;
|
|
204
198
|
}
|
|
205
199
|
async function confirmRefs(remote = "origin") {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
200
|
+
const { stdout } = await x("git", ["remote", "-v"]);
|
|
201
|
+
const reg = new RegExp(`${remote}\t(.*) \\(push`);
|
|
202
|
+
const repo = stdout.match(reg)?.[1];
|
|
203
|
+
const { stdout: branch } = await x("git", ["branch", "--show-current"]);
|
|
204
|
+
const ret = await confirm({ message: `Current refs ${repo}:refs/for/${styleText("blue", branch)}` });
|
|
205
|
+
if (isCancel(ret)) {
|
|
206
|
+
cancel("Operation cancelled.");
|
|
207
|
+
process.exit(0);
|
|
208
|
+
}
|
|
209
|
+
return ret;
|
|
214
210
|
}
|
|
215
211
|
async function getReleaseType() {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
212
|
+
const releaseType = await select({
|
|
213
|
+
message: "Please select release type",
|
|
214
|
+
options: releaseTypes.map((type) => ({
|
|
215
|
+
label: type,
|
|
216
|
+
value: type
|
|
217
|
+
}))
|
|
218
|
+
});
|
|
219
|
+
if (isCancel(releaseType)) {
|
|
220
|
+
cancel("Operation cancelled.");
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
return releaseType;
|
|
221
224
|
}
|
|
222
225
|
async function getReleaseVersion(currentVersion) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
226
|
+
let isPreRelease = false;
|
|
227
|
+
let expectVersion = "";
|
|
228
|
+
let confirmVersionRet = "";
|
|
229
|
+
do {
|
|
230
|
+
const type = await getReleaseType();
|
|
231
|
+
isPreRelease = type.startsWith("pre");
|
|
232
|
+
expectVersion = semver.inc(currentVersion, type, `alpha.${Date.now()}`);
|
|
233
|
+
expectVersion = isPreRelease ? expectVersion.slice(0, -2) : expectVersion;
|
|
234
|
+
confirmVersionRet = await confirmVersion(currentVersion, expectVersion);
|
|
235
|
+
} while (confirmVersionRet === BACK_HINT);
|
|
236
|
+
return {
|
|
237
|
+
isPreRelease,
|
|
238
|
+
expectVersion
|
|
239
|
+
};
|
|
234
240
|
}
|
|
235
241
|
async function release(options) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
} catch {
|
|
277
|
-
}
|
|
278
|
-
try {
|
|
279
|
-
await exec("git", ["restore", "package.json"], {
|
|
280
|
-
throwOnError: true
|
|
281
|
-
});
|
|
282
|
-
} catch {
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
} catch (error) {
|
|
286
|
-
logger.error(error.toString());
|
|
287
|
-
process.exit(1);
|
|
288
|
-
}
|
|
242
|
+
try {
|
|
243
|
+
const currentVersion = readJSONSync(resolve(cwd, "package.json")).version;
|
|
244
|
+
if (!currentVersion) {
|
|
245
|
+
logger.error("Your package is missing the version field");
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (!await isWorktreeEmpty()) {
|
|
249
|
+
logger.error("Git worktree is not empty, please commit changed");
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (!await confirmRefs(options.remote)) return;
|
|
253
|
+
if (!options.skipNpmPublish && !await confirmRegistry()) return;
|
|
254
|
+
const { isPreRelease, expectVersion } = await getReleaseVersion(currentVersion);
|
|
255
|
+
if (options.checkRemoteVersion && await isSameVersion(expectVersion)) {
|
|
256
|
+
logger.error("Please check remote version.");
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
updateVersion(expectVersion);
|
|
260
|
+
if (options.task) await options.task(expectVersion, currentVersion);
|
|
261
|
+
if (!options.skipNpmPublish) await publish({
|
|
262
|
+
preRelease: isPreRelease,
|
|
263
|
+
npmTag: options.npmTag
|
|
264
|
+
});
|
|
265
|
+
if (!isPreRelease) {
|
|
266
|
+
if (!options.skipChangelog) await changelog();
|
|
267
|
+
await pushGit(expectVersion, options.remote, options.skipGitTag);
|
|
268
|
+
}
|
|
269
|
+
logger.success(`Release version ${expectVersion} successfully!`);
|
|
270
|
+
if (isPreRelease) {
|
|
271
|
+
try {
|
|
272
|
+
await x("git", ["restore", "**/package.json"], { throwOnError: true });
|
|
273
|
+
} catch {}
|
|
274
|
+
try {
|
|
275
|
+
await x("git", ["restore", "package.json"], { throwOnError: true });
|
|
276
|
+
} catch {}
|
|
277
|
+
}
|
|
278
|
+
} catch (error) {
|
|
279
|
+
logger.error(error);
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
289
282
|
}
|
|
290
283
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
var WARNING_MESSAGE = `The rules for commit messages are as follows
|
|
284
|
+
//#endregion
|
|
285
|
+
//#region src/commitLint.ts
|
|
286
|
+
const { readFileSync } = fse;
|
|
287
|
+
const COMMIT_MESSAGE_RE = /^(revert|fix|feat|docs|perf|test|types|style|build|chore|release|refactor|merge|wip)(\(.+\))?!?: (.|\n)+/;
|
|
288
|
+
const ERROR_MESSAGE = "Commit message invalid.";
|
|
289
|
+
const WARNING_MESSAGE = `\
|
|
290
|
+
The rules for commit messages are as follows
|
|
299
291
|
|
|
300
292
|
Example:
|
|
301
293
|
|
|
@@ -325,40 +317,27 @@ Allowed types:
|
|
|
325
317
|
- wip
|
|
326
318
|
|
|
327
319
|
Commit message reference: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y
|
|
328
|
-
|
|
320
|
+
参考阮一峰Commit message编写指南: https://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html`;
|
|
329
321
|
function isVersionCommitMessage(message) {
|
|
330
|
-
|
|
322
|
+
return Boolean(message.startsWith("v") && semver.valid(message.slice(1)));
|
|
331
323
|
}
|
|
332
324
|
function getCommitMessage(commitMessagePath) {
|
|
333
|
-
|
|
325
|
+
return readFileSync(commitMessagePath, "utf-8").trim();
|
|
334
326
|
}
|
|
335
327
|
function commitLint(options) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if (!isVersionCommitMessage(commitMessage) && !isValidCommitMessage) {
|
|
349
|
-
logger2.error(errorMessage);
|
|
350
|
-
logger2.warn(warningMessage);
|
|
351
|
-
process.exit(1);
|
|
352
|
-
}
|
|
328
|
+
const { commitMessagePath, commitMessageRe = COMMIT_MESSAGE_RE, errorMessage = ERROR_MESSAGE, warningMessage = WARNING_MESSAGE } = options;
|
|
329
|
+
if (!commitMessagePath) {
|
|
330
|
+
logger.error("commitMessagePath is required");
|
|
331
|
+
process.exit(1);
|
|
332
|
+
}
|
|
333
|
+
const commitMessage = getCommitMessage(commitMessagePath);
|
|
334
|
+
const isValidCommitMessage = new RegExp(commitMessageRe).test(commitMessage);
|
|
335
|
+
if (!isVersionCommitMessage(commitMessage) && !isValidCommitMessage) {
|
|
336
|
+
logger.error(errorMessage);
|
|
337
|
+
logger.warn(warningMessage);
|
|
338
|
+
process.exit(1);
|
|
339
|
+
}
|
|
353
340
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
commitLint,
|
|
358
|
-
getCommitMessage,
|
|
359
|
-
isSameVersion,
|
|
360
|
-
isVersionCommitMessage,
|
|
361
|
-
publish,
|
|
362
|
-
release,
|
|
363
|
-
updateVersion
|
|
364
|
-
};
|
|
341
|
+
|
|
342
|
+
//#endregion
|
|
343
|
+
export { COMMIT_MESSAGE_RE, changelog, commitLint, getAllPackageJsons, getCommitMessage, isSameVersion, isVersionCommitMessage, publish, release, updateVersion };
|