gitverse-release 3.0.0 → 3.2.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 +38 -1
- package/dist/cli.js +95 -23
- package/dist/cli.js.map +8 -8
- package/dist/index.js +95 -23
- package/dist/index.js.map +8 -8
- package/dist/types.d.ts +20 -0
- package/dist/utils/changelog.d.ts +2 -2
- package/dist/utils/git.d.ts +7 -0
- package/dist/utils/version.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,6 +106,42 @@ git commit -m "feat: новая функция
|
|
|
106
106
|
BREAKING CHANGE: изменен формат конфигурации"
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
### Pre-Major режим (0.x.x проекты)
|
|
110
|
+
|
|
111
|
+
Для проектов в стадии разработки (версии `0.x.x`) доступен режим `preMajorMode`, который контролирует поведение BREAKING CHANGES:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"versioning": {
|
|
116
|
+
"preMajorMode": "auto" // Режим по умолчанию
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Режимы работы:**
|
|
122
|
+
|
|
123
|
+
- `"auto"` (default) - версии `< 1.0.0` → **minor bump**, `>= 1.0.0` → **major bump**
|
|
124
|
+
- `"enabled"` - BREAKING CHANGE всегда делает **minor bump** (для experimental проектов)
|
|
125
|
+
- `"disabled"` - стандартное semver поведение (BREAKING → major bump)
|
|
126
|
+
- `"2.0.0"` - порог версии (minor bump пока версия < порога)
|
|
127
|
+
|
|
128
|
+
**Примеры:**
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Режим "auto" (рекомендуется)
|
|
132
|
+
# 0.5.0 + "feat!: breaking change" → 0.6.0
|
|
133
|
+
# 1.5.0 + "feat!: breaking change" → 2.0.0
|
|
134
|
+
|
|
135
|
+
# Режим "enabled" (experimental проект)
|
|
136
|
+
# 1.5.0 + "feat!: breaking change" → 1.6.0
|
|
137
|
+
|
|
138
|
+
# Режим с порогом "2.0.0"
|
|
139
|
+
# 1.5.0 + "feat!: breaking change" → 1.6.0
|
|
140
|
+
# 2.0.0 + "feat!: breaking change" → 3.0.0
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
> **Зачем это нужно?** По спецификации semver версии `0.x.x` находятся в pre-release фазе, где minor bump уже означает breaking change. Режим `auto` автоматически применяет правильную семантику.
|
|
144
|
+
|
|
109
145
|
### Программное использование
|
|
110
146
|
|
|
111
147
|
```typescript
|
|
@@ -219,7 +255,8 @@ git commit -m "chore: обновлены зависимости"
|
|
|
219
255
|
"versioning": {
|
|
220
256
|
"tagPrefix": "v",
|
|
221
257
|
"prereleasePrefix": "beta",
|
|
222
|
-
"allowPrerelease": false
|
|
258
|
+
"allowPrerelease": false,
|
|
259
|
+
"preMajorMode": "auto"
|
|
223
260
|
},
|
|
224
261
|
"gitverse": {
|
|
225
262
|
"createRelease": true,
|
package/dist/cli.js
CHANGED
|
@@ -54,11 +54,13 @@ var DEFAULT_CONFIG = {
|
|
|
54
54
|
},
|
|
55
55
|
versioning: {
|
|
56
56
|
allowPrerelease: false,
|
|
57
|
-
|
|
57
|
+
preMajorMode: "auto",
|
|
58
|
+
prereleasePrefix: "beta",
|
|
59
|
+
tagPrefix: "v"
|
|
58
60
|
}
|
|
59
61
|
};
|
|
60
62
|
async function loadConfig(configPath) {
|
|
61
|
-
const path = configPath || ".
|
|
63
|
+
const path = configPath || ".gitversereleaserc.json";
|
|
62
64
|
const fullPath = resolve(process.cwd(), path);
|
|
63
65
|
try {
|
|
64
66
|
const content = await readFile(fullPath, "utf-8");
|
|
@@ -545,6 +547,15 @@ class v2 {
|
|
|
545
547
|
getCommits(d, g3, f2) {
|
|
546
548
|
return this.client.get(`/repos/${d}/${g3}/pulls/${f2}/commits`);
|
|
547
549
|
}
|
|
550
|
+
async checkIfMerged(d, g3, f2) {
|
|
551
|
+
try {
|
|
552
|
+
return await this.client.get(`/repos/${d}/${g3}/pulls/${f2}/merge`), true;
|
|
553
|
+
} catch (j6) {
|
|
554
|
+
if (j6 instanceof j2 && j6.status === 404)
|
|
555
|
+
return false;
|
|
556
|
+
throw j6;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
548
559
|
}
|
|
549
560
|
|
|
550
561
|
// ../sdk/dist/api/forks.js
|
|
@@ -891,31 +902,29 @@ All notable changes to this project will be documented in this file.
|
|
|
891
902
|
await writeFile(changelogPath, lines.join(`
|
|
892
903
|
`));
|
|
893
904
|
}
|
|
894
|
-
function generateReleaseNotes(commits, config) {
|
|
905
|
+
function generateReleaseNotes(commits, config, repoUrl) {
|
|
895
906
|
const sections = [];
|
|
896
907
|
const breakingCommits = commits.filter((c2) => c2.breaking);
|
|
897
908
|
if (breakingCommits.length > 0) {
|
|
898
|
-
sections.push("⚠️ BREAKING CHANGES
|
|
909
|
+
sections.push("⚠️ BREAKING CHANGES");
|
|
910
|
+
sections.push("");
|
|
899
911
|
for (const commit of breakingCommits) {
|
|
900
|
-
sections.push(
|
|
912
|
+
sections.push(formatCommit(commit, config, repoUrl));
|
|
901
913
|
}
|
|
902
914
|
sections.push("");
|
|
903
915
|
}
|
|
904
916
|
const grouped = groupCommitsByType(commits.filter((c2) => !c2.breaking));
|
|
905
|
-
const typeOrder = ["feat", "fix", "perf", "refactor"];
|
|
917
|
+
const typeOrder = ["feat", "fix", "perf", "refactor", "docs", "test", "build", "ci", "chore", "style", "revert"];
|
|
906
918
|
for (const type of typeOrder) {
|
|
907
919
|
const typeCommits = grouped[type];
|
|
908
920
|
if (!typeCommits || typeCommits.length === 0) {
|
|
909
921
|
continue;
|
|
910
922
|
}
|
|
911
923
|
const title = config.types[type] || type.toUpperCase();
|
|
912
|
-
sections.push(
|
|
924
|
+
sections.push(title);
|
|
925
|
+
sections.push("");
|
|
913
926
|
for (const commit of typeCommits) {
|
|
914
|
-
|
|
915
|
-
if (commit.scope) {
|
|
916
|
-
message = `**${commit.scope}:** ${message}`;
|
|
917
|
-
}
|
|
918
|
-
sections.push(`- ${message}`);
|
|
927
|
+
sections.push(formatCommit(commit, config, repoUrl));
|
|
919
928
|
}
|
|
920
929
|
sections.push("");
|
|
921
930
|
}
|
|
@@ -1002,6 +1011,23 @@ async function getCurrentVersion(packagePath) {
|
|
|
1002
1011
|
}
|
|
1003
1012
|
return pkgJson.version;
|
|
1004
1013
|
}
|
|
1014
|
+
async function getPackageInfo(packagePath) {
|
|
1015
|
+
const { readFile: readFile3 } = await import("node:fs/promises");
|
|
1016
|
+
const { resolve: resolve2 } = await import("node:path");
|
|
1017
|
+
const pkgJsonPath = resolve2(packagePath, "package.json");
|
|
1018
|
+
const content = await readFile3(pkgJsonPath, "utf-8");
|
|
1019
|
+
const pkgJson = JSON.parse(content);
|
|
1020
|
+
if (!pkgJson.name) {
|
|
1021
|
+
throw new Error(`No name found in ${pkgJsonPath}`);
|
|
1022
|
+
}
|
|
1023
|
+
if (!pkgJson.version) {
|
|
1024
|
+
throw new Error(`No version found in ${pkgJsonPath}`);
|
|
1025
|
+
}
|
|
1026
|
+
return {
|
|
1027
|
+
name: pkgJson.name,
|
|
1028
|
+
version: pkgJson.version
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1005
1031
|
async function updatePackageVersion(packagePath, newVersion) {
|
|
1006
1032
|
const { readFile: readFile3, writeFile: writeFile2 } = await import("node:fs/promises");
|
|
1007
1033
|
const { resolve: resolve2 } = await import("node:path");
|
|
@@ -1067,12 +1093,34 @@ function formatVersion(ver) {
|
|
|
1067
1093
|
}
|
|
1068
1094
|
return result;
|
|
1069
1095
|
}
|
|
1070
|
-
function
|
|
1096
|
+
function shouldBumpMajor(currentVersion, mode = "auto") {
|
|
1097
|
+
if (mode === "disabled") {
|
|
1098
|
+
return true;
|
|
1099
|
+
}
|
|
1100
|
+
if (mode === "enabled") {
|
|
1101
|
+
return false;
|
|
1102
|
+
}
|
|
1103
|
+
if (!currentVersion) {
|
|
1104
|
+
return true;
|
|
1105
|
+
}
|
|
1106
|
+
const current = parseVersion(currentVersion);
|
|
1107
|
+
if (mode === "auto") {
|
|
1108
|
+
return current.major >= 1;
|
|
1109
|
+
}
|
|
1110
|
+
try {
|
|
1111
|
+
const _threshold = parseVersion(mode);
|
|
1112
|
+
return compareVersions(currentVersion, mode) >= 0;
|
|
1113
|
+
} catch {
|
|
1114
|
+
return true;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
function determineBumpType(commits, currentVersion, preMajorMode = "auto") {
|
|
1071
1118
|
if (commits.length === 0) {
|
|
1072
1119
|
return null;
|
|
1073
1120
|
}
|
|
1074
1121
|
if (hasBreakingChanges(commits)) {
|
|
1075
|
-
|
|
1122
|
+
const useMajor = shouldBumpMajor(currentVersion, preMajorMode);
|
|
1123
|
+
return useMajor ? "major" : "minor";
|
|
1076
1124
|
}
|
|
1077
1125
|
if (hasFeatures(commits)) {
|
|
1078
1126
|
return "minor";
|
|
@@ -1118,8 +1166,8 @@ function bumpVersion(currentVersion, bumpType, prereleasePrefix) {
|
|
|
1118
1166
|
}
|
|
1119
1167
|
return formatVersion(ver);
|
|
1120
1168
|
}
|
|
1121
|
-
function calculateVersionBump(currentVersion, commits, forceVersion, prerelease) {
|
|
1122
|
-
const bumpType = prerelease ? "prerelease" : determineBumpType(commits) || "patch";
|
|
1169
|
+
function calculateVersionBump(currentVersion, commits, forceVersion, prerelease, preMajorMode) {
|
|
1170
|
+
const bumpType = prerelease ? "prerelease" : determineBumpType(commits, currentVersion, preMajorMode) || "patch";
|
|
1123
1171
|
const newVersion = forceVersion || bumpVersion(currentVersion, bumpType, prerelease);
|
|
1124
1172
|
return {
|
|
1125
1173
|
bumpType,
|
|
@@ -1131,6 +1179,29 @@ function calculateVersionBump(currentVersion, commits, forceVersion, prerelease)
|
|
|
1131
1179
|
newVersion
|
|
1132
1180
|
};
|
|
1133
1181
|
}
|
|
1182
|
+
function compareVersions(a, b) {
|
|
1183
|
+
const verA = parseVersion(a);
|
|
1184
|
+
const verB = parseVersion(b);
|
|
1185
|
+
if (verA.major !== verB.major) {
|
|
1186
|
+
return verA.major > verB.major ? 1 : -1;
|
|
1187
|
+
}
|
|
1188
|
+
if (verA.minor !== verB.minor) {
|
|
1189
|
+
return verA.minor > verB.minor ? 1 : -1;
|
|
1190
|
+
}
|
|
1191
|
+
if (verA.patch !== verB.patch) {
|
|
1192
|
+
return verA.patch > verB.patch ? 1 : -1;
|
|
1193
|
+
}
|
|
1194
|
+
if (verA.prerelease && !verB.prerelease) {
|
|
1195
|
+
return -1;
|
|
1196
|
+
}
|
|
1197
|
+
if (!verA.prerelease && verB.prerelease) {
|
|
1198
|
+
return 1;
|
|
1199
|
+
}
|
|
1200
|
+
if (verA.prerelease && verB.prerelease) {
|
|
1201
|
+
return verA.prerelease.localeCompare(verB.prerelease);
|
|
1202
|
+
}
|
|
1203
|
+
return 0;
|
|
1204
|
+
}
|
|
1134
1205
|
|
|
1135
1206
|
// src/index.ts
|
|
1136
1207
|
function printDryRunInfo(pkg, currentVersion, versionBump, tag, commits, changelogEntry) {
|
|
@@ -1190,7 +1261,7 @@ async function createGitVerseRelease(options, repoInfo, commits, config, pkg, ve
|
|
|
1190
1261
|
}
|
|
1191
1262
|
try {
|
|
1192
1263
|
const gitverseClient = createGitVerseClient(repoInfo);
|
|
1193
|
-
const releaseNotes = generateReleaseNotes(commits, config.changelog);
|
|
1264
|
+
const releaseNotes = generateReleaseNotes(commits, config.changelog, repoInfo.url);
|
|
1194
1265
|
return await gitverseClient.createRelease(tag, `${pkg.packageName} v${versionBump.newVersion}`, releaseNotes, {
|
|
1195
1266
|
prerelease: !!options.prerelease
|
|
1196
1267
|
});
|
|
@@ -1225,7 +1296,7 @@ async function release(packageName, options = {}) {
|
|
|
1225
1296
|
const config = await loadConfig(options.config);
|
|
1226
1297
|
validateConfig(config);
|
|
1227
1298
|
const repoInfo = await getRepoInfo();
|
|
1228
|
-
const pkg = resolvePackage(config, packageName);
|
|
1299
|
+
const pkg = await resolvePackage(config, packageName);
|
|
1229
1300
|
result.packageName = pkg.packageName;
|
|
1230
1301
|
if (!(options.dryRun || await isWorkingTreeClean())) {
|
|
1231
1302
|
throw new Error("Working tree is not clean. Please commit or stash your changes.");
|
|
@@ -1234,7 +1305,7 @@ async function release(packageName, options = {}) {
|
|
|
1234
1305
|
result.oldVersion = currentVersion;
|
|
1235
1306
|
const commits = await collectCommits(pkg, options, result.warnings);
|
|
1236
1307
|
const prereleaseTag = resolvePrereleaseTag(options, config);
|
|
1237
|
-
const versionBump = calculateVersionBump(currentVersion, commits, options.version, prereleaseTag);
|
|
1308
|
+
const versionBump = calculateVersionBump(currentVersion, commits, options.version, prereleaseTag, config.versioning.preMajorMode);
|
|
1238
1309
|
result.newVersion = versionBump.newVersion;
|
|
1239
1310
|
const tag = `${pkg.tagPrefix}${versionBump.newVersion}`;
|
|
1240
1311
|
result.tag = tag;
|
|
@@ -1269,14 +1340,15 @@ async function release(packageName, options = {}) {
|
|
|
1269
1340
|
return result;
|
|
1270
1341
|
}
|
|
1271
1342
|
}
|
|
1272
|
-
function resolvePackage(config, packageName) {
|
|
1343
|
+
async function resolvePackage(config, packageName) {
|
|
1273
1344
|
if (!config.monorepo.enabled) {
|
|
1345
|
+
const pkgInfo = await getPackageInfo(".");
|
|
1274
1346
|
return {
|
|
1275
1347
|
changelog: "CHANGELOG.md",
|
|
1276
1348
|
name: "main",
|
|
1277
|
-
packageName:
|
|
1349
|
+
packageName: pkgInfo.name,
|
|
1278
1350
|
path: ".",
|
|
1279
|
-
tagPrefix:
|
|
1351
|
+
tagPrefix: config.versioning.tagPrefix
|
|
1280
1352
|
};
|
|
1281
1353
|
}
|
|
1282
1354
|
if (!packageName) {
|
|
@@ -1401,4 +1473,4 @@ async function main() {
|
|
|
1401
1473
|
}
|
|
1402
1474
|
main();
|
|
1403
1475
|
|
|
1404
|
-
//# debugId=
|
|
1476
|
+
//# debugId=C891F93BC32B0BA664756E2164756E21
|