gitverse-release 3.3.0 → 3.3.2
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 +165 -2
- package/dist/cli.js +40 -39
- package/dist/cli.js.map +5 -5
- package/dist/index.js +40 -39
- package/dist/index.js.map +5 -5
- package/dist/utils/parser.d.ts +7 -0
- package/package.json +3 -7
package/README.md
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
- 🏷️ **Автоматические git теги и коммиты**
|
|
16
16
|
- 🔍 **Режим dry-run** для безопасного тестирования
|
|
17
17
|
- ⚙️ **Гибкая конфигурация** через `.gitversereleaserc.json`
|
|
18
|
+
- 🔧 **Автогенерация commitlint конфига** из release конфигурации
|
|
19
|
+
- 🪝 **Хуки beforeCommit** для автоматической подготовки файлов перед релизом
|
|
18
20
|
|
|
19
21
|
## Установка
|
|
20
22
|
|
|
@@ -224,6 +226,88 @@ git commit -m "fix(ui): исправлена ошибка компонента"
|
|
|
224
226
|
git commit -m "chore: обновлены зависимости"
|
|
225
227
|
```
|
|
226
228
|
|
|
229
|
+
## Генерация Commitlint конфига
|
|
230
|
+
|
|
231
|
+
Инструмент может автоматически генерировать `commitlint.config.ts` из вашей release конфигурации, обеспечивая синхронизацию между форматом коммитов и генерацией релизов.
|
|
232
|
+
|
|
233
|
+
### Быстрый старт
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Генерировать commitlint конфиг
|
|
237
|
+
npx gitverse-release generate-commitlint
|
|
238
|
+
|
|
239
|
+
# Preview без записи файла
|
|
240
|
+
npx gitverse-release generate-commitlint --dry-run
|
|
241
|
+
|
|
242
|
+
# С кастомными параметрами
|
|
243
|
+
npx gitverse-release generate-commitlint --format js --output .commitlintrc.js
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Что генерируется?
|
|
247
|
+
|
|
248
|
+
Команда автоматически извлекает:
|
|
249
|
+
- **Типы коммитов** из `changelog.types` (feat, fix, docs, etc.)
|
|
250
|
+
- **Scopes** из названий пакетов в монорепо + дополнительные scopes
|
|
251
|
+
- **Правила валидации** (max length, case, required fields)
|
|
252
|
+
|
|
253
|
+
### Конфигурация defaults
|
|
254
|
+
|
|
255
|
+
Добавьте секцию `commitlint` в `.gitversereleaserc.json`:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"commitlint": {
|
|
260
|
+
"output": "commitlint.config.ts",
|
|
261
|
+
"format": "ts",
|
|
262
|
+
"scopes": ["deps", "ci", "docs"],
|
|
263
|
+
"scopeRequired": false,
|
|
264
|
+
"headerMaxLength": 100,
|
|
265
|
+
"comments": true
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Теперь можно просто запускать `npx gitverse-release generate-commitlint` без параметров!
|
|
271
|
+
|
|
272
|
+
### CLI опции
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
--output <path> Путь для вывода (default: из конфига)
|
|
276
|
+
--format <ts|js|json> Формат файла (default: из конфига)
|
|
277
|
+
--scopes <list> Дополнительные scopes через запятую
|
|
278
|
+
--scope-required Требовать обязательный scope
|
|
279
|
+
--header-max-length <n> Максимальная длина header
|
|
280
|
+
--no-comments Отключить комментарии в файле
|
|
281
|
+
--dry-run Preview без записи
|
|
282
|
+
--verbose Подробный вывод
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Примеры использования
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Использовать настройки из конфига
|
|
289
|
+
npx gitverse-release generate-commitlint
|
|
290
|
+
|
|
291
|
+
# Preview сгенерированного файла
|
|
292
|
+
npx gitverse-release generate-commitlint --dry-run --verbose
|
|
293
|
+
|
|
294
|
+
# Генерировать JS вместо TS
|
|
295
|
+
npx gitverse-release generate-commitlint --format js --output .commitlintrc.js
|
|
296
|
+
|
|
297
|
+
# Добавить дополнительные scopes
|
|
298
|
+
npx gitverse-release generate-commitlint --scopes api,cli,tests
|
|
299
|
+
|
|
300
|
+
# Требовать обязательный scope
|
|
301
|
+
npx gitverse-release generate-commitlint --scope-required
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Преимущества
|
|
305
|
+
|
|
306
|
+
✅ **Единый источник истины** - типы и scopes определяются в одном месте
|
|
307
|
+
✅ **Автоматическая синхронизация** - изменения в release конфиге автоматически отражаются в commitlint
|
|
308
|
+
✅ **Меньше ошибок** - нет риска рассинхронизации конфигов
|
|
309
|
+
✅ **CI-friendly** - легко интегрируется в pipelines для проверки актуальности конфига
|
|
310
|
+
|
|
227
311
|
## Конфигурация
|
|
228
312
|
|
|
229
313
|
### Полный пример
|
|
@@ -231,6 +315,7 @@ git commit -m "chore: обновлены зависимости"
|
|
|
231
315
|
```json
|
|
232
316
|
{
|
|
233
317
|
"git": {
|
|
318
|
+
"beforeCommit": "bun run lint:fix",
|
|
234
319
|
"commitMessage": "chore(release): v{version} [skip ci]",
|
|
235
320
|
"tagMessage": "Release {version}",
|
|
236
321
|
"push": true,
|
|
@@ -265,10 +350,54 @@ git commit -m "chore: обновлены зависимости"
|
|
|
265
350
|
"monorepo": {
|
|
266
351
|
"enabled": false,
|
|
267
352
|
"packages": []
|
|
353
|
+
},
|
|
354
|
+
"commitlint": {
|
|
355
|
+
"output": "commitlint.config.ts",
|
|
356
|
+
"format": "ts",
|
|
357
|
+
"scopes": ["deps", "ci", "docs"],
|
|
358
|
+
"scopeRequired": false,
|
|
359
|
+
"headerMaxLength": 100,
|
|
360
|
+
"comments": true
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### beforeCommit хук
|
|
366
|
+
|
|
367
|
+
Хук `beforeCommit` запускается **перед проверкой чистоты working tree** и позволяет автоматически подготовить файлы перед созданием релиза:
|
|
368
|
+
|
|
369
|
+
```json
|
|
370
|
+
{
|
|
371
|
+
"git": {
|
|
372
|
+
"beforeCommit": "bun run lint:fix"
|
|
268
373
|
}
|
|
269
374
|
}
|
|
270
375
|
```
|
|
271
376
|
|
|
377
|
+
**Как это работает:**
|
|
378
|
+
1. Запускается команда `beforeCommit` (например, линтер)
|
|
379
|
+
2. Если команда выполнилась успешно (exit code 0):
|
|
380
|
+
- Все измененные файлы добавляются в staging area (`git add -A`)
|
|
381
|
+
- Эти изменения войдут в коммит релиза вместе с version/changelog
|
|
382
|
+
3. Проверяется чистота working tree (только unstaged изменения)
|
|
383
|
+
|
|
384
|
+
**Примеры использования:**
|
|
385
|
+
```json
|
|
386
|
+
// Форматирование кода
|
|
387
|
+
"beforeCommit": "bun run format"
|
|
388
|
+
|
|
389
|
+
// Линтинг и автофикс
|
|
390
|
+
"beforeCommit": "bun run lint:fix"
|
|
391
|
+
|
|
392
|
+
// Обновление lock файлов
|
|
393
|
+
"beforeCommit": "bun install --frozen-lockfile=false"
|
|
394
|
+
|
|
395
|
+
// Несколько команд
|
|
396
|
+
"beforeCommit": "bun run lint:fix && bun run format"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Важно:** Если хук завершается с ошибкой (exit code ≠ 0), изменения НЕ добавляются в staging area и релиз продолжается как обычно.
|
|
400
|
+
|
|
272
401
|
### Переменные окружения
|
|
273
402
|
|
|
274
403
|
```bash
|
|
@@ -332,19 +461,53 @@ env:
|
|
|
332
461
|
|
|
333
462
|
## CLI опции
|
|
334
463
|
|
|
335
|
-
|
|
464
|
+
### Основные команды
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
# Создать релиз
|
|
336
468
|
npx gitverse-release [package] [options]
|
|
337
469
|
|
|
470
|
+
# Генерировать commitlint конфиг
|
|
471
|
+
npx gitverse-release generate-commitlint [options]
|
|
472
|
+
|
|
473
|
+
# Создать только GitVerse Release для существующего тега (recovery mode)
|
|
474
|
+
npx gitverse-release create-only --tag <tag> [--package <name>]
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Опции для релиза
|
|
478
|
+
|
|
479
|
+
```
|
|
338
480
|
Аргументы:
|
|
339
481
|
package Имя пакета для релиза (для монорепозиториев)
|
|
340
482
|
|
|
341
483
|
Опции:
|
|
342
484
|
--dry-run Запуск без внесения изменений
|
|
485
|
+
--config <path> Путь к конфиг файлу (default: .gitversereleaserc.json)
|
|
486
|
+
--package <name> Имя пакета для релиза (для монорепо)
|
|
343
487
|
--version <version> Указать конкретную версию
|
|
344
|
-
--
|
|
488
|
+
--prerelease [tag] Создать prerelease версию (beta, alpha, rc)
|
|
489
|
+
--no-commit Не создавать git коммит
|
|
490
|
+
--no-tag Не создавать git тег
|
|
491
|
+
--no-push Не пушить в remote
|
|
492
|
+
--no-release Не создавать GitVerse Release
|
|
493
|
+
--verbose Подробный вывод
|
|
345
494
|
--help Показать справку
|
|
346
495
|
```
|
|
347
496
|
|
|
497
|
+
### Опции для generate-commitlint
|
|
498
|
+
|
|
499
|
+
```
|
|
500
|
+
Опции:
|
|
501
|
+
--output <path> Путь для вывода (default: commitlint.config.ts)
|
|
502
|
+
--format <ts|js|json> Формат файла (default: ts)
|
|
503
|
+
--scopes <scopes> Дополнительные scopes (comma-separated)
|
|
504
|
+
--scope-required Требовать обязательный scope
|
|
505
|
+
--header-max-length <n> Максимальная длина header (default: 100)
|
|
506
|
+
--no-comments Отключить комментарии в файле
|
|
507
|
+
--dry-run Preview без записи
|
|
508
|
+
--verbose Подробный вывод
|
|
509
|
+
```
|
|
510
|
+
|
|
348
511
|
## CI/CD интеграция
|
|
349
512
|
|
|
350
513
|
### GitVerse Actions
|
package/dist/cli.js
CHANGED
|
@@ -601,9 +601,9 @@ class q3 {
|
|
|
601
601
|
}
|
|
602
602
|
|
|
603
603
|
// ../sdk/dist/client.js
|
|
604
|
-
var
|
|
604
|
+
var J2 = { DELETE: "DELETE", GET: "GET", PATCH: "PATCH", POST: "POST", PUT: "PUT" };
|
|
605
605
|
|
|
606
|
-
class
|
|
606
|
+
class $ {
|
|
607
607
|
baseUrl;
|
|
608
608
|
token;
|
|
609
609
|
apiVersion;
|
|
@@ -615,10 +615,11 @@ class _ {
|
|
|
615
615
|
this.token = j5;
|
|
616
616
|
}
|
|
617
617
|
extractRateLimitInfo(j5) {
|
|
618
|
-
let x2 = j5.get("GitVerse-RateLimit-Limit"), q4 = j5.get("GitVerse-RateLimit-Remaining"), z2 = j5.get("GitVerse-RateLimit-Retry-After"), B2 = j5.get("Gitverse-Ratelimit-Reset");
|
|
619
|
-
if (!(x2 &&
|
|
618
|
+
let x2 = j5.get("GitVerse-RateLimit-Limit"), q4 = j5.get("GitVerse-RateLimit-User-Remaining") || j5.get("GitVerse-RateLimit-Remaining"), z2 = j5.get("GitVerse-RateLimit-Retry-After"), B2 = j5.get("Gitverse-Ratelimit-Reset");
|
|
619
|
+
if (!(x2 && z2))
|
|
620
620
|
return;
|
|
621
|
-
|
|
621
|
+
let K = Number.parseInt(z2, 10), D = B2 ? Number.parseInt(B2, 10) : Math.floor(Date.now() / 1000) + K, U = q4 ? Number.parseInt(q4, 10) : 0;
|
|
622
|
+
return { limit: Number.parseInt(x2, 10), remaining: U, reset: D, retryAfter: K };
|
|
622
623
|
}
|
|
623
624
|
extractApiVersionInfo(j5) {
|
|
624
625
|
let x2 = j5.get("Gitverse-Api-Version"), q4 = j5.get("Gitverse-Api-Latest-Version"), z2 = j5.get("Gitverse-Api-Deprecation") === "true", B2 = j5.get("Gitverse-Api-Decommissioning");
|
|
@@ -635,37 +636,37 @@ class _ {
|
|
|
635
636
|
return { apiVersion: q4, rateLimit: x2 };
|
|
636
637
|
}
|
|
637
638
|
async request(j5, x2, q4, z2) {
|
|
638
|
-
let B2 = j5.startsWith("/") ? j5.slice(1) : j5,
|
|
639
|
-
if (
|
|
640
|
-
|
|
641
|
-
let
|
|
639
|
+
let B2 = j5.startsWith("/") ? j5.slice(1) : j5, K = `${this.baseUrl}/${B2}`, D = new Headers;
|
|
640
|
+
if (D.set("Content-Type", "application/json"), D.set("Accept", `application/vnd.gitverse.object+json; version=${this.apiVersion}`), this.token)
|
|
641
|
+
D.set("Authorization", `Bearer ${this.token}`);
|
|
642
|
+
let U = { body: q4 ? JSON.stringify(q4) : undefined, headers: D, method: x2, signal: z2?.signal }, F = await fetch(K, U), Q = this.extractMetadata(F.headers), S;
|
|
642
643
|
try {
|
|
643
|
-
|
|
644
|
+
S = await F.json();
|
|
644
645
|
} catch {
|
|
645
|
-
|
|
646
|
+
S = undefined;
|
|
646
647
|
}
|
|
647
|
-
if (!
|
|
648
|
-
let
|
|
649
|
-
if (
|
|
650
|
-
throw new k2(
|
|
651
|
-
throw new j2(
|
|
648
|
+
if (!F.ok) {
|
|
649
|
+
let X = S?.message || F.statusText;
|
|
650
|
+
if (F.status === 429 && Q.rateLimit)
|
|
651
|
+
throw new k2(X || "Превышен лимит запросов. Попробуйте позже.", Q.rateLimit, Q);
|
|
652
|
+
throw new j2(F.status, X, Q);
|
|
652
653
|
}
|
|
653
|
-
return
|
|
654
|
+
return S;
|
|
654
655
|
}
|
|
655
656
|
get(j5, x2) {
|
|
656
|
-
return this.request(j5,
|
|
657
|
+
return this.request(j5, J2.GET, undefined, x2);
|
|
657
658
|
}
|
|
658
659
|
post(j5, x2, q4) {
|
|
659
|
-
return this.request(j5,
|
|
660
|
+
return this.request(j5, J2.POST, x2, q4);
|
|
660
661
|
}
|
|
661
662
|
put(j5, x2, q4) {
|
|
662
|
-
return this.request(j5,
|
|
663
|
+
return this.request(j5, J2.PUT, x2, q4);
|
|
663
664
|
}
|
|
664
665
|
delete(j5, x2, q4) {
|
|
665
|
-
return this.request(j5,
|
|
666
|
+
return this.request(j5, J2.DELETE, x2, q4);
|
|
666
667
|
}
|
|
667
668
|
patch(j5, x2, q4) {
|
|
668
|
-
return this.request(j5,
|
|
669
|
+
return this.request(j5, J2.PATCH, x2, q4);
|
|
669
670
|
}
|
|
670
671
|
}
|
|
671
672
|
|
|
@@ -720,7 +721,7 @@ class Z {
|
|
|
720
721
|
git;
|
|
721
722
|
actions;
|
|
722
723
|
constructor(d2 = {}) {
|
|
723
|
-
this.client = new
|
|
724
|
+
this.client = new $(d2), this.users = new f(this.client), this.repos = new A(this.client), this.contents = new k4(this.client), this.pulls = new y(this.client), this.forks = new q3(this.client), this.emails = new d(this.client), this.issues = new B(this.client), this.stars = new k3(this.client), this.branches = new g(this.client), this.commits = new j(this.client), this.collaborators = new j3(this.client), this.organizations = new k(this.client), this.teams = new k5(this.client), this.releases = new q2(this.client), this.git = new j4(this.client), this.actions = new x(this.client);
|
|
724
725
|
}
|
|
725
726
|
setToken(d2) {
|
|
726
727
|
return this.client.setToken(d2), this;
|
|
@@ -843,6 +844,12 @@ function groupCommitsByType(commits) {
|
|
|
843
844
|
}
|
|
844
845
|
return groups;
|
|
845
846
|
}
|
|
847
|
+
function filterCommitsForPackage(commits, packageName, isMonorepo) {
|
|
848
|
+
if (!isMonorepo) {
|
|
849
|
+
return commits;
|
|
850
|
+
}
|
|
851
|
+
return commits.filter((commit) => !commit.scope || commit.scope === packageName);
|
|
852
|
+
}
|
|
846
853
|
function hasBreakingChanges(commits) {
|
|
847
854
|
return commits.some((commit) => commit.breaking);
|
|
848
855
|
}
|
|
@@ -1139,12 +1146,6 @@ async function isWorkingTreeClean() {
|
|
|
1139
1146
|
return false;
|
|
1140
1147
|
}
|
|
1141
1148
|
}
|
|
1142
|
-
async function addChangedFiles() {
|
|
1143
|
-
console.log("\uD83D\uDCE5 Adding changed files to staging area...");
|
|
1144
|
-
await git("add -A");
|
|
1145
|
-
console.log(`✅ Files added to staging area
|
|
1146
|
-
`);
|
|
1147
|
-
}
|
|
1148
1149
|
async function tagExists(tag) {
|
|
1149
1150
|
try {
|
|
1150
1151
|
await git(`rev-parse "${tag}"`);
|
|
@@ -1384,13 +1385,13 @@ async function updatePackageFiles(pkg, newVersion, changelogEntry) {
|
|
|
1384
1385
|
await updateChangelogFile(changelogPath, changelogEntry);
|
|
1385
1386
|
return changelogPath;
|
|
1386
1387
|
}
|
|
1387
|
-
async function collectCommits(pkg, options, warnings) {
|
|
1388
|
+
async function collectCommits(pkg, options, warnings, isMonorepo) {
|
|
1388
1389
|
const rawCommits = await getCommitsSinceTag(pkg.tagPrefix, pkg.path);
|
|
1389
1390
|
if (rawCommits.length === 0 && !options.version) {
|
|
1390
1391
|
throw new Error(`No commits found since last release for ${pkg.packageName}`);
|
|
1391
1392
|
}
|
|
1392
1393
|
const commits = parseCommits(rawCommits);
|
|
1393
|
-
const filteredCommits = commits
|
|
1394
|
+
const filteredCommits = filterCommitsForPackage(commits, pkg.name, isMonorepo);
|
|
1394
1395
|
if (filteredCommits.length === 0 && !options.version) {
|
|
1395
1396
|
warnings.push("No conventional commits found, but will proceed with patch bump");
|
|
1396
1397
|
}
|
|
@@ -1426,6 +1427,12 @@ async function createGitVerseRelease(options, repoInfo, commits, config, pkg, ve
|
|
|
1426
1427
|
}
|
|
1427
1428
|
async function performGitOperations(config, options, pkg, newVersion, tag, changelogPath) {
|
|
1428
1429
|
if (config.git.commitChanges && !options.noCommit) {
|
|
1430
|
+
if (config.git.beforeCommit) {
|
|
1431
|
+
const hookSuccess = await runBeforeCommitHook(config.git.beforeCommit);
|
|
1432
|
+
if (!hookSuccess) {
|
|
1433
|
+
console.warn("⚠️ beforeCommit hook failed, proceeding with unformatted files");
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1429
1436
|
const commitMessage = config.git.commitMessage.replace("{{package}}", pkg.name).replace("{{version}}", newVersion);
|
|
1430
1437
|
await createCommit(commitMessage, [resolve2(pkg.path, "package.json"), changelogPath]);
|
|
1431
1438
|
}
|
|
@@ -1452,18 +1459,12 @@ async function release(packageName, options = {}) {
|
|
|
1452
1459
|
const repoInfo = await getRepoInfo();
|
|
1453
1460
|
const pkg = await resolvePackage(config, packageName);
|
|
1454
1461
|
result.packageName = pkg.packageName;
|
|
1455
|
-
if (!options.dryRun && config.git.beforeCommit) {
|
|
1456
|
-
const hookSuccess = await runBeforeCommitHook(config.git.beforeCommit);
|
|
1457
|
-
if (hookSuccess) {
|
|
1458
|
-
await addChangedFiles();
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
1462
|
if (!(options.dryRun || await isWorkingTreeClean())) {
|
|
1462
1463
|
throw new Error("Working tree is not clean. Please commit or stash your changes.");
|
|
1463
1464
|
}
|
|
1464
1465
|
const currentVersion = await getCurrentVersion(pkg.path);
|
|
1465
1466
|
result.oldVersion = currentVersion;
|
|
1466
|
-
const commits = await collectCommits(pkg, options, result.warnings);
|
|
1467
|
+
const commits = await collectCommits(pkg, options, result.warnings, config.monorepo.enabled);
|
|
1467
1468
|
const prereleaseTag = resolvePrereleaseTag(options, config);
|
|
1468
1469
|
const versionBump = calculateVersionBump(currentVersion, commits, options.version, prereleaseTag, config.versioning.preMajorMode);
|
|
1469
1470
|
result.newVersion = versionBump.newVersion;
|
|
@@ -1887,4 +1888,4 @@ Usage: gitverse-release create-only --tag <tag> [--package <name>]`);
|
|
|
1887
1888
|
}
|
|
1888
1889
|
main();
|
|
1889
1890
|
|
|
1890
|
-
//# debugId=
|
|
1891
|
+
//# debugId=A2D09E9236DE6AFE64756E2164756E21
|