@peiyanlu/release 1.0.0 → 1.1.1
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 +23 -8
- package/dist/cli.mjs +135 -109
- package/dist/index.d.mts +18 -15
- package/dist/index.mjs +64 -73
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -56,14 +56,21 @@ pnpm release minor --ci
|
|
|
56
56
|
|
|
57
57
|
### 通用参数
|
|
58
58
|
|
|
59
|
-
| 参数
|
|
60
|
-
|
|
61
|
-
| `-v, --version`
|
|
62
|
-
| `-h, --help`
|
|
63
|
-
| `-n, --dry-run`
|
|
64
|
-
| `--show-release`
|
|
65
|
-
| `--show-changelog`
|
|
66
|
-
| `--ci`
|
|
59
|
+
| 参数 | 说明 |
|
|
60
|
+
|---------------------------------------|------------------------------------------------------------|
|
|
61
|
+
| `-v, --version` | 输出当前 CLI 版本并退出 |
|
|
62
|
+
| `-h, --help` | 显示帮助信息 |
|
|
63
|
+
| `-n, --dry-run` | 空跑模式,展示将要执行的发布流程但不做任何修改 |
|
|
64
|
+
| `--show-release` | 打印即将发布的版本号并退出 |
|
|
65
|
+
| `--show-changelog` | 打印生成的 Changelog 并退出 |
|
|
66
|
+
| `--ci` | 启用 CI 模式:禁用交互提示,缺少必要参数时直接失败;GitHub Actions 等 CI/CD 环境中默认启用 |
|
|
67
|
+
| `-r, --release-count <count>` | 生成多少个版本的变更日志 |
|
|
68
|
+
| `--include-hidden` | 生成 CHANGELOG 时包含默认隐藏的 commit 类型 |
|
|
69
|
+
| `--only-changelog` | 仅更新 CHANGELOG |
|
|
70
|
+
| `-C, --no-require-clean-working-tree` | 是否要求工作目录保持干净(无未提交的更改) |
|
|
71
|
+
| `--skip-git` | 跳过 git、github 环境检查以及后续操作 |
|
|
72
|
+
| `--skip-npm` | 跳过 npm 环境检查以及后续操作 |
|
|
73
|
+
| `--skip-github` | 跳过 github 环境检查以及后续操作 |
|
|
67
74
|
|
|
68
75
|
### Prepare 相关参数
|
|
69
76
|
|
|
@@ -81,6 +88,7 @@ pnpm release minor --prepare --ci --package pkg-a
|
|
|
81
88
|
|
|
82
89
|
| 参数 | 说明 |
|
|
83
90
|
|-----------------------|----------------------------------|
|
|
91
|
+
| `-m, --is-monorepo` | Monorepo 项目 |
|
|
84
92
|
| `-p, --package <pkg>` | 指定要发布的子包名称(仅用于 Monorepo 的 CI 场景) |
|
|
85
93
|
|
|
86
94
|
```bash
|
|
@@ -194,6 +202,7 @@ release init
|
|
|
194
202
|
|------------------|---------------------|
|
|
195
203
|
| `-f, --force` | 覆盖已存在的配置文件 |
|
|
196
204
|
| `-m, --monorepo` | 生成 Monorepo 项目的配置模板 |
|
|
205
|
+
| `-a, --add` | 自动暂存配置文件 |
|
|
197
206
|
|
|
198
207
|
#### 行为说明
|
|
199
208
|
|
|
@@ -232,6 +241,12 @@ COMMIT_TYPES:
|
|
|
232
241
|
- 默认:`feat | feature | fix | perf | revert | docs | style | chore | refactor | test | build | ci`
|
|
233
242
|
- 自定义:`config | deps | security | i18n | ux | hotfix`
|
|
234
243
|
|
|
244
|
+
| Effect | Types | 说明 |
|
|
245
|
+
|-----------------|----------------------------------------------------------------|-----------------------------------|
|
|
246
|
+
| **`bump`** | `feat`, `feature`, `fix`, `perf`, `revert` | 影响版本号(Minor/Patch),同时写入 CHANGELOG |
|
|
247
|
+
| **`changelog`** | `docs`, `refactor`, `deps`, `security`, `hotfix`, `i18n`, `ux` | 不影响版本号,仅写入 CHANGELOG |
|
|
248
|
+
| **`hidden`** | `style`, `chore`, `test`, `build`, `ci`, `config`, `tool` | 不影响版本号,也不会写入 CHANGELOG |
|
|
249
|
+
|
|
235
250
|
支持 **--show-changelog** 预览模式:
|
|
236
251
|
|
|
237
252
|
- 仅展示用于生成 Changelog 的 Commits
|
package/dist/cli.mjs
CHANGED
|
@@ -12,8 +12,10 @@ import { inc, neq } from "semver";
|
|
|
12
12
|
import { inspect } from "node:util";
|
|
13
13
|
import { ConventionalChangelog } from "conventional-changelog";
|
|
14
14
|
import createPreset from "conventional-changelog-conventionalcommits";
|
|
15
|
+
import { Bumper } from "conventional-recommended-bump";
|
|
15
16
|
import { writeFile } from "node:fs/promises";
|
|
16
17
|
import { finished } from "node:stream/promises";
|
|
18
|
+
import { bold, compareUrl, each, heading, link, list, newline, segments, small, words } from "@conventional-changelog/template";
|
|
17
19
|
import { Octokit } from "@octokit/rest";
|
|
18
20
|
import { contentType } from "mime-types";
|
|
19
21
|
import open from "open";
|
|
@@ -79,7 +81,8 @@ const MSG = {
|
|
|
79
81
|
SHOW_VERSION: (version) => `🎉 Released ${green(version)}`,
|
|
80
82
|
SHOW_CHANGELOG: "🎉 Changelog collected",
|
|
81
83
|
CHANGELOG_EMPTY: "No commits found since last release",
|
|
82
|
-
CHANGES_EMPTY: "Working tree clean. No files changed"
|
|
84
|
+
CHANGES_EMPTY: "Working tree clean. No files changed",
|
|
85
|
+
ONLY_CHANGELOG: "🎉 Changelog generation completed"
|
|
83
86
|
},
|
|
84
87
|
CHECK: {
|
|
85
88
|
GIT: {
|
|
@@ -306,7 +309,7 @@ const option = (label, value, hint) => ({
|
|
|
306
309
|
value,
|
|
307
310
|
hint: hint ?? value
|
|
308
311
|
});
|
|
309
|
-
const runVersionPrompts = async (ctx, config) => {
|
|
312
|
+
const runVersionPrompts = async (ctx, config, inferred) => {
|
|
310
313
|
const { pkg: { current, fromPreRelease } } = ctx;
|
|
311
314
|
const selectVersion = async () => {
|
|
312
315
|
const versions = createVersionMap(current);
|
|
@@ -326,7 +329,7 @@ const runVersionPrompts = async (ctx, config) => {
|
|
|
326
329
|
const type = await select({
|
|
327
330
|
message: question(MSG.PROMPT.SELECT_VERSION, "version"),
|
|
328
331
|
options,
|
|
329
|
-
initialValue: fromPreRelease ? "prerelease" : "patch"
|
|
332
|
+
initialValue: inferred ?? (fromPreRelease ? "prerelease" : "patch")
|
|
330
333
|
});
|
|
331
334
|
abortSinglePrompt(type);
|
|
332
335
|
return type;
|
|
@@ -357,6 +360,7 @@ const createDefaultContext = () => {
|
|
|
357
360
|
release: false,
|
|
358
361
|
showRelease: false,
|
|
359
362
|
showChangelog: false,
|
|
363
|
+
onlyChangelog: false,
|
|
360
364
|
dryRun: false,
|
|
361
365
|
noGit: false,
|
|
362
366
|
noNpm: false,
|
|
@@ -436,7 +440,9 @@ const createDefaultConfig = (isCI) => {
|
|
|
436
440
|
tagPrefix(pkg) {
|
|
437
441
|
return "";
|
|
438
442
|
},
|
|
439
|
-
releaseCount: 1
|
|
443
|
+
releaseCount: 1,
|
|
444
|
+
includeHidden: false,
|
|
445
|
+
transformTypes: (t) => t
|
|
440
446
|
},
|
|
441
447
|
skipGit: false,
|
|
442
448
|
skipNpm: false,
|
|
@@ -478,179 +484,178 @@ const defaultTypes = [
|
|
|
478
484
|
{
|
|
479
485
|
type: "feat",
|
|
480
486
|
section: "✨ 新功能",
|
|
487
|
+
effect: "bump",
|
|
481
488
|
description: "新增功能"
|
|
482
489
|
},
|
|
483
490
|
{
|
|
484
491
|
type: "feature",
|
|
485
492
|
section: "✨ 新功能",
|
|
493
|
+
effect: "bump",
|
|
486
494
|
description: "新增功能"
|
|
487
495
|
},
|
|
488
496
|
{
|
|
489
497
|
type: "fix",
|
|
490
498
|
section: "🐛 Bug 修复",
|
|
499
|
+
effect: "bump",
|
|
491
500
|
description: "修复 bug"
|
|
492
501
|
},
|
|
493
502
|
{
|
|
494
503
|
type: "perf",
|
|
495
504
|
section: "⚡ 性能优化",
|
|
505
|
+
effect: "bump",
|
|
496
506
|
description: "提升性能"
|
|
497
507
|
},
|
|
498
508
|
{
|
|
499
509
|
type: "revert",
|
|
500
510
|
section: "⏪ 回退",
|
|
511
|
+
effect: "bump",
|
|
501
512
|
description: "回退到之前版本"
|
|
502
513
|
},
|
|
503
514
|
{
|
|
504
515
|
type: "docs",
|
|
505
516
|
section: "📝 文档",
|
|
517
|
+
effect: "changelog",
|
|
506
518
|
description: "文档更新"
|
|
507
519
|
},
|
|
508
520
|
{
|
|
509
521
|
type: "style",
|
|
510
522
|
section: "💄 样式调整",
|
|
523
|
+
effect: "hidden",
|
|
511
524
|
description: "样式或格式修改"
|
|
512
525
|
},
|
|
513
526
|
{
|
|
514
527
|
type: "chore",
|
|
515
528
|
section: "🧹 其他更新",
|
|
529
|
+
effect: "hidden",
|
|
516
530
|
description: "非功能性更改"
|
|
517
531
|
},
|
|
518
532
|
{
|
|
519
533
|
type: "refactor",
|
|
520
534
|
section: "♻️ 代码重构",
|
|
535
|
+
effect: "changelog",
|
|
521
536
|
description: "重构代码"
|
|
522
537
|
},
|
|
523
538
|
{
|
|
524
539
|
type: "test",
|
|
525
540
|
section: "🧪 测试",
|
|
541
|
+
effect: "hidden",
|
|
526
542
|
description: "测试更新"
|
|
527
543
|
},
|
|
528
544
|
{
|
|
529
545
|
type: "build",
|
|
530
546
|
section: "🏗️ 构建系统",
|
|
547
|
+
effect: "hidden",
|
|
531
548
|
description: "构建工具和系统修改"
|
|
532
549
|
},
|
|
533
550
|
{
|
|
534
551
|
type: "ci",
|
|
535
552
|
section: "🤖 CI",
|
|
553
|
+
effect: "hidden",
|
|
536
554
|
description: "持续集成配置"
|
|
537
555
|
},
|
|
538
|
-
{
|
|
539
|
-
type: "config",
|
|
540
|
-
section: "⚙️ 配置",
|
|
541
|
-
description: "配置文件更新"
|
|
542
|
-
},
|
|
543
556
|
{
|
|
544
557
|
type: "deps",
|
|
545
558
|
section: "📦 依赖更新",
|
|
559
|
+
effect: "changelog",
|
|
546
560
|
description: "依赖版本变更"
|
|
547
561
|
},
|
|
548
562
|
{
|
|
549
563
|
type: "security",
|
|
550
564
|
section: "🛡️ 安全修复",
|
|
565
|
+
effect: "changelog",
|
|
551
566
|
description: "安全性更新"
|
|
552
567
|
},
|
|
568
|
+
{
|
|
569
|
+
type: "hotfix",
|
|
570
|
+
section: "🚑 热修复",
|
|
571
|
+
effect: "changelog",
|
|
572
|
+
description: "紧急修复"
|
|
573
|
+
},
|
|
553
574
|
{
|
|
554
575
|
type: "i18n",
|
|
555
576
|
section: "🌐 国际化",
|
|
577
|
+
effect: "changelog",
|
|
556
578
|
description: "国际化相关更新"
|
|
557
579
|
},
|
|
558
580
|
{
|
|
559
581
|
type: "ux",
|
|
560
582
|
section: "🎨 用户体验",
|
|
583
|
+
effect: "changelog",
|
|
561
584
|
description: "用户体验改进"
|
|
562
585
|
},
|
|
563
586
|
{
|
|
564
|
-
type: "
|
|
565
|
-
section: "
|
|
566
|
-
|
|
587
|
+
type: "config",
|
|
588
|
+
section: "⚙️ 配置",
|
|
589
|
+
effect: "hidden",
|
|
590
|
+
description: "配置文件更新"
|
|
567
591
|
},
|
|
568
592
|
{
|
|
569
593
|
type: "tool",
|
|
570
594
|
section: "🛠️ 工具链",
|
|
595
|
+
effect: "hidden",
|
|
571
596
|
description: "工具链变更"
|
|
572
597
|
}
|
|
573
598
|
];
|
|
574
599
|
//#endregion
|
|
600
|
+
//#region src/git/templates.ts
|
|
601
|
+
const isLikelyHash = (value) => /^[0-9a-f]{7,40}$/i.test(value);
|
|
602
|
+
function headerPartial(context) {
|
|
603
|
+
const { isPatch, linkCompare, version, title, date, previousTag } = context;
|
|
604
|
+
const fullTitle = words(linkCompare && !isLikelyHash(previousTag) ? link(version, compareUrl(context)) : version, title && `"${title}"`, date && `(${date})`);
|
|
605
|
+
return heading(2, isPatch ? small(fullTitle) : fullTitle);
|
|
606
|
+
}
|
|
607
|
+
function template(context) {
|
|
608
|
+
const { headerPartial, preamblePartial, commitPartial, footerPartial, noteGroups, commitGroups } = context;
|
|
609
|
+
return segments(headerPartial(context), preamblePartial(context), each(noteGroups, (group) => segments(heading(3, words("⚠", group.title)), list(group.notes, (note) => {
|
|
610
|
+
return each([words(note.commit.scope && bold(`${note.commit.scope}:`), commitPartial(context, note.commit)), note.commit.subject.trim() !== note.text.trim() ? list([note.text], (t) => t) : ""], (t) => t, newline());
|
|
611
|
+
})), newline(2)), each(commitGroups, (group) => segments(group.title && heading(3, group.title), list(group.commits, (commit) => commitPartial(context, commit))), newline(2)), footerPartial(context));
|
|
612
|
+
}
|
|
613
|
+
//#endregion
|
|
575
614
|
//#region src/git/changelog.ts
|
|
576
|
-
const parsePreset =
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
615
|
+
const parsePreset = (options = {}) => {
|
|
616
|
+
const { includeHidden, transformTypes } = options;
|
|
617
|
+
let types = [...defaultTypes];
|
|
618
|
+
if (includeHidden) types.forEach((type) => {
|
|
619
|
+
if (type.effect === "hidden") type.effect = "changelog";
|
|
620
|
+
});
|
|
621
|
+
types = transformTypes?.(types) ?? types;
|
|
622
|
+
const preset = createPreset({ types });
|
|
581
623
|
preset.writer ??= {};
|
|
582
|
-
preset.writer.headerPartial =
|
|
583
|
-
|
|
584
|
-
[{{version}}](
|
|
585
|
-
{{~#if @root.repository~}}
|
|
586
|
-
{{~#if @root.host}}
|
|
587
|
-
{{~@root.host}}/
|
|
588
|
-
{{~/if}}
|
|
589
|
-
{{~#if @root.owner}}
|
|
590
|
-
{{~@root.owner}}/
|
|
591
|
-
{{~/if}}
|
|
592
|
-
{{~@root.repository}}
|
|
593
|
-
{{~else}}
|
|
594
|
-
{{~@root.repoUrl}}
|
|
595
|
-
{{~/if~}}
|
|
596
|
-
/compare/{{previousTag}}...{{currentTag}})
|
|
597
|
-
{{~else}}
|
|
598
|
-
{{~version}}
|
|
599
|
-
{{~/if}}
|
|
600
|
-
{{~#if title}} "{{title}}"
|
|
601
|
-
{{~/if}}
|
|
602
|
-
{{~#if date}} ({{date}})
|
|
603
|
-
{{~/if}}
|
|
604
|
-
{{~#if isPatch~}} </small> {{~/if}}
|
|
605
|
-
`.trim() + eol();
|
|
606
|
-
preset.writer.mainTemplate = `{{> header}}
|
|
607
|
-
{{#if noteGroups}}
|
|
608
|
-
{{#each noteGroups}}
|
|
609
|
-
|
|
610
|
-
### ⚠ {{title}}
|
|
611
|
-
|
|
612
|
-
{{#each notes}}
|
|
613
|
-
* {{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{commit.subject}} {{#if commit.hash}}([{{commit.shortHash}}](https://github.com/{{@root.owner}}/{{@root.repository}}/commit/{{commit.hash}})){{/if}}
|
|
614
|
-
{{/each}}
|
|
615
|
-
{{/each}}
|
|
616
|
-
{{/if}}
|
|
617
|
-
{{#each commitGroups}}
|
|
618
|
-
|
|
619
|
-
{{#if title}}
|
|
620
|
-
### {{title}}
|
|
621
|
-
|
|
622
|
-
{{/if}}
|
|
623
|
-
{{#each commits}}
|
|
624
|
-
{{> commit root=@root}}
|
|
625
|
-
{{/each}}
|
|
626
|
-
{{/each}}`.trim();
|
|
624
|
+
preset.writer.headerPartial = headerPartial;
|
|
625
|
+
preset.writer.template = template;
|
|
627
626
|
return preset;
|
|
628
627
|
};
|
|
629
|
-
const
|
|
628
|
+
const inferReleaseType = async (options) => {
|
|
629
|
+
const preset = parsePreset(options);
|
|
630
|
+
const res = await new Bumper().config(preset).bump(preset.whatBump);
|
|
631
|
+
if (!("releaseType" in res)) return void 0;
|
|
632
|
+
const { releaseType, reason } = res;
|
|
633
|
+
return options?.json ? {
|
|
634
|
+
releaseType,
|
|
635
|
+
reason
|
|
636
|
+
} : releaseType;
|
|
637
|
+
};
|
|
638
|
+
const createGenerator = async (options) => {
|
|
639
|
+
const { getPkgDir, tagPrefix, releaseCount = 1, includeHidden, transformTypes } = options;
|
|
630
640
|
const pkgDir = getPkgDir();
|
|
631
|
-
|
|
632
|
-
|
|
641
|
+
return new ConventionalChangelog().readPackage(`${pkgDir}/package.json`).config(parsePreset({
|
|
642
|
+
includeHidden,
|
|
643
|
+
transformTypes
|
|
644
|
+
})).options({ releaseCount }).commits({ path: pkgDir }).tags({ prefix: tagPrefix });
|
|
633
645
|
};
|
|
634
|
-
const getChangelog = async (
|
|
635
|
-
const generator = await createGenerator(
|
|
636
|
-
getPkgDir,
|
|
637
|
-
tagPrefix,
|
|
638
|
-
releaseCount
|
|
639
|
-
});
|
|
646
|
+
const getChangelog = async (options) => {
|
|
647
|
+
const generator = await createGenerator(options);
|
|
640
648
|
let changelog = "";
|
|
641
649
|
for await (const chunk of generator.write()) changelog += chunk;
|
|
642
650
|
return changelog.trimEnd();
|
|
643
651
|
};
|
|
644
|
-
const generateChangelog = async (
|
|
652
|
+
const generateChangelog = async (options) => {
|
|
653
|
+
const { getPkgDir, releaseCount = 1 } = options;
|
|
645
654
|
const infile = join(getPkgDir(), "CHANGELOG.md");
|
|
646
655
|
if (!existsSync(infile)) await writeFile(infile, "");
|
|
647
656
|
const exist = readFileSync(infile, "utf-8");
|
|
648
657
|
const writeStream = createWriteStream(infile);
|
|
649
|
-
const generator = await createGenerator(
|
|
650
|
-
getPkgDir,
|
|
651
|
-
tagPrefix,
|
|
652
|
-
releaseCount
|
|
653
|
-
});
|
|
658
|
+
const generator = await createGenerator(options);
|
|
654
659
|
for await (const chunk of generator.write()) writeStream.write(chunk);
|
|
655
660
|
const override = isZero(releaseCount);
|
|
656
661
|
if (!(isZero(exist.trim().length) || override)) {
|
|
@@ -981,16 +986,17 @@ var Action = class {
|
|
|
981
986
|
async createContext(cmdArgs, options, prepare = false) {
|
|
982
987
|
const { version: cVersion, name: cName } = readJsonFile(join(__dirname, "../package.json"));
|
|
983
988
|
const { otp, package: defPkg, releaseCount, ...others } = options;
|
|
984
|
-
const { showChangelog, showRelease, ci, dryRun } = mapObjectValues(others, (v) => Boolean(v));
|
|
989
|
+
const { showChangelog, showRelease, ci, dryRun, onlyChangelog } = mapObjectValues(others, (v) => Boolean(v));
|
|
985
990
|
process.env["dryRun"] = String(dryRun);
|
|
986
991
|
const { configFile, config: local } = await resolveConfig(process.cwd());
|
|
987
992
|
const config = mergeConfig(createDefaultConfig(ci ? true : void 0), local);
|
|
988
993
|
info(MSG.INFO.TOOL(cName, cVersion));
|
|
989
994
|
info(MSG.INFO.CONFIG(configFile));
|
|
990
995
|
{
|
|
991
|
-
const { requireCleanWorkingTree, skipGit, skipNpm, skipGithub, isMonorepo } = mapObjectValues(others, (v) => Boolean(v));
|
|
996
|
+
const { requireCleanWorkingTree, skipGit, skipNpm, skipGithub, isMonorepo, includeHidden } = mapObjectValues(others, (v) => Boolean(v));
|
|
992
997
|
const count = Number(releaseCount);
|
|
993
998
|
config.changelog.releaseCount = isNaN(count) ? 0 : count;
|
|
999
|
+
config.changelog.includeHidden = includeHidden;
|
|
994
1000
|
config.git.requireCleanWorkingTree = requireCleanWorkingTree;
|
|
995
1001
|
config.skipGit = skipGit;
|
|
996
1002
|
config.skipNpm = skipNpm;
|
|
@@ -1026,6 +1032,7 @@ var Action = class {
|
|
|
1026
1032
|
dryRun,
|
|
1027
1033
|
showRelease,
|
|
1028
1034
|
showChangelog,
|
|
1035
|
+
onlyChangelog,
|
|
1029
1036
|
npm: { otp: String(otp) },
|
|
1030
1037
|
increment: cmdArgs,
|
|
1031
1038
|
isIncrement: true,
|
|
@@ -1057,8 +1064,32 @@ var Action = class {
|
|
|
1057
1064
|
config
|
|
1058
1065
|
};
|
|
1059
1066
|
}
|
|
1067
|
+
async printChangelog(ctx, config) {
|
|
1068
|
+
const { showChangelog, selectedPkg, noGit, isIncrement } = ctx;
|
|
1069
|
+
const { isMonorepo, getPkgDir, changelog: { tagPrefix, releaseCount, includeHidden, transformTypes } } = config;
|
|
1070
|
+
if (noGit) return;
|
|
1071
|
+
const match = isMonorepo ? `${tagPrefix?.(selectedPkg)}*` : "*";
|
|
1072
|
+
const { from, to } = isZero(releaseCount) ? {
|
|
1073
|
+
from: "",
|
|
1074
|
+
to: "HEAD"
|
|
1075
|
+
} : await resolveChangelogRange(isIncrement, match);
|
|
1076
|
+
const commits = await getLogSince(from, to, getPkgDir(selectedPkg));
|
|
1077
|
+
const changelog = await getChangelog({
|
|
1078
|
+
getPkgDir: () => getPkgDir(selectedPkg),
|
|
1079
|
+
tagPrefix: tagPrefix?.(selectedPkg),
|
|
1080
|
+
releaseCount,
|
|
1081
|
+
includeHidden,
|
|
1082
|
+
transformTypes
|
|
1083
|
+
});
|
|
1084
|
+
Object.assign(ctx.github, { changelog });
|
|
1085
|
+
if (commits) {
|
|
1086
|
+
msg("GIT", `Changelog(${from}...${to}):${eol(2)}` + changelog);
|
|
1087
|
+
msg("GIT", `Commits(${from}...${to}):${eol(2)}` + commits);
|
|
1088
|
+
if (showChangelog) taskEnd(MSG.LOG.SHOW_CHANGELOG);
|
|
1089
|
+
} else msg("GIT", MSG.LOG.CHANGELOG_EMPTY);
|
|
1090
|
+
}
|
|
1060
1091
|
async checkTask(ctx, config) {
|
|
1061
|
-
const { dryRun } = ctx;
|
|
1092
|
+
const { dryRun, onlyChangelog } = ctx;
|
|
1062
1093
|
await tasks([
|
|
1063
1094
|
{
|
|
1064
1095
|
title: MSG.CHECK.GIT.CHECKING,
|
|
@@ -1075,7 +1106,7 @@ var Action = class {
|
|
|
1075
1106
|
const { pkg: { publishConfig: { registry } } } = ctx;
|
|
1076
1107
|
return success(MSG.CHECK.NPM.CHECKED(registry, msg), dryRun);
|
|
1077
1108
|
},
|
|
1078
|
-
enabled: !ctx.noNpm
|
|
1109
|
+
enabled: !(ctx.noNpm || onlyChangelog)
|
|
1079
1110
|
},
|
|
1080
1111
|
{
|
|
1081
1112
|
title: MSG.CHECK.GITHUB.CHECKING,
|
|
@@ -1085,19 +1116,27 @@ var Action = class {
|
|
|
1085
1116
|
const repository = getGithubUrl(owner, repo);
|
|
1086
1117
|
return success(MSG.CHECK.GITHUB.CHECKED(repository, msg), dryRun);
|
|
1087
1118
|
},
|
|
1088
|
-
enabled: !ctx.noGitHub
|
|
1119
|
+
enabled: !(ctx.noGitHub || onlyChangelog)
|
|
1089
1120
|
}
|
|
1090
1121
|
]).catch(abortOnError);
|
|
1091
1122
|
}
|
|
1092
1123
|
async bumpTask(ctx, config) {
|
|
1093
|
-
const { pkg: { current }, dryRun, isCI, showRelease,
|
|
1094
|
-
const {
|
|
1124
|
+
const { pkg: { current }, dryRun, isCI, showRelease, selectedPkg, onlyChangelog } = ctx;
|
|
1125
|
+
const { hooks, getPkgDir, changelog: { includeHidden, transformTypes } } = config;
|
|
1126
|
+
if (onlyChangelog) return;
|
|
1095
1127
|
const need = (ctx) => {
|
|
1096
1128
|
const { pkg: { next }, isIncrement } = ctx;
|
|
1097
1129
|
return !next && isIncrement;
|
|
1098
1130
|
};
|
|
1099
1131
|
if (need(ctx)) {
|
|
1100
|
-
const
|
|
1132
|
+
const res = await inferReleaseType({
|
|
1133
|
+
includeHidden,
|
|
1134
|
+
transformTypes,
|
|
1135
|
+
json: true
|
|
1136
|
+
});
|
|
1137
|
+
if (res) msg("BUMP", res.reason);
|
|
1138
|
+
const inferred = res?.releaseType;
|
|
1139
|
+
const nextVersion = (isCI ? inferred ?? inc(current, "patch") : void 0) || await runVersionPrompts(ctx, config, inferred);
|
|
1101
1140
|
ctx.isIncrement = neq(current, nextVersion);
|
|
1102
1141
|
const { version: next, isPrerelease: toPreRelease, preId, preBase } = parseVersion(nextVersion);
|
|
1103
1142
|
Object.assign(ctx.pkg, {
|
|
@@ -1107,7 +1146,7 @@ var Action = class {
|
|
|
1107
1146
|
preBase
|
|
1108
1147
|
});
|
|
1109
1148
|
}
|
|
1110
|
-
const { pkg: { next }
|
|
1149
|
+
const { pkg: { next } } = ctx;
|
|
1111
1150
|
if (showRelease) taskEnd(MSG.LOG.SHOW_VERSION(next));
|
|
1112
1151
|
await runLifeCycleHook(hooks, "before:bump", dryRun);
|
|
1113
1152
|
await tasks([{
|
|
@@ -1117,31 +1156,15 @@ var Action = class {
|
|
|
1117
1156
|
await formatTemplate(ctx, config);
|
|
1118
1157
|
const to = `(${current}...${diff(current, next)})`;
|
|
1119
1158
|
return success(MSG.TASK.VERSION.END(to), dryRun);
|
|
1120
|
-
}
|
|
1159
|
+
},
|
|
1160
|
+
enabled: true
|
|
1121
1161
|
}]).catch((err) => abortOnError(err, ctx));
|
|
1122
1162
|
await runLifeCycleHook(hooks, "after:bump", dryRun);
|
|
1123
|
-
|
|
1124
|
-
const match = isMonorepo ? `${tagPrefix?.(selectedPkg)}*` : "*";
|
|
1125
|
-
const { from, to } = isZero(releaseCount) ? {
|
|
1126
|
-
from: "",
|
|
1127
|
-
to: "HEAD"
|
|
1128
|
-
} : await resolveChangelogRange(isIncrement, match);
|
|
1129
|
-
const commits = await getLogSince(from, to, getPkgDir(selectedPkg));
|
|
1130
|
-
const changelog = await getChangelog({
|
|
1131
|
-
getPkgDir: () => getPkgDir(selectedPkg),
|
|
1132
|
-
tagPrefix: tagPrefix?.(selectedPkg),
|
|
1133
|
-
releaseCount
|
|
1134
|
-
});
|
|
1135
|
-
Object.assign(ctx.github, { changelog });
|
|
1136
|
-
if (commits) {
|
|
1137
|
-
msg("GIT", `Changelog(${from}...${to}):${eol(2)}` + changelog);
|
|
1138
|
-
msg("GIT", `Commits(${from}...${to}):${eol(2)}` + commits);
|
|
1139
|
-
if (showChangelog) taskEnd(MSG.LOG.SHOW_CHANGELOG);
|
|
1140
|
-
} else msg("GIT", MSG.LOG.CHANGELOG_EMPTY);
|
|
1163
|
+
await this.printChangelog(ctx, config);
|
|
1141
1164
|
}
|
|
1142
1165
|
async changelogTask(ctx, config) {
|
|
1143
|
-
const { isIncrement, dryRun, selectedPkg, noGit } = ctx;
|
|
1144
|
-
const { getPkgDir, changelog: { tagPrefix, releaseCount } } = config;
|
|
1166
|
+
const { isIncrement, dryRun, selectedPkg, noGit, onlyChangelog } = ctx;
|
|
1167
|
+
const { getPkgDir, changelog: { tagPrefix, releaseCount, includeHidden, transformTypes } } = config;
|
|
1145
1168
|
if (noGit) return;
|
|
1146
1169
|
await tasks([{
|
|
1147
1170
|
title: MSG.TASK.CHANGELOG.START,
|
|
@@ -1149,7 +1172,9 @@ var Action = class {
|
|
|
1149
1172
|
await generateChangelog({
|
|
1150
1173
|
getPkgDir: () => getPkgDir(selectedPkg),
|
|
1151
1174
|
tagPrefix: tagPrefix?.(selectedPkg),
|
|
1152
|
-
releaseCount
|
|
1175
|
+
releaseCount,
|
|
1176
|
+
includeHidden,
|
|
1177
|
+
transformTypes
|
|
1153
1178
|
});
|
|
1154
1179
|
await gitAddAll();
|
|
1155
1180
|
return success(MSG.TASK.CHANGELOG.END, dryRun);
|
|
@@ -1159,6 +1184,7 @@ var Action = class {
|
|
|
1159
1184
|
const changeset = await getShortStatus();
|
|
1160
1185
|
if (changeset) msg("GIT", `Changes:${eol(2)}` + coloredStatus(changeset));
|
|
1161
1186
|
else msg("GIT", MSG.LOG.CHANGES_EMPTY);
|
|
1187
|
+
if (onlyChangelog) taskEnd(MSG.LOG.ONLY_CHANGELOG);
|
|
1162
1188
|
}
|
|
1163
1189
|
async gitTask(ctx, config) {
|
|
1164
1190
|
const { noGit, dryRun } = ctx;
|
|
@@ -1220,7 +1246,7 @@ var Action = class {
|
|
|
1220
1246
|
//#endregion
|
|
1221
1247
|
//#region src/cli.ts
|
|
1222
1248
|
const pkg = readJsonFile(join(__dirname, "..", "package.json"));
|
|
1223
|
-
program.name("release").description(pkg.description).version(pkg.version, "-v, --version", "Print the tool version and exit.").usage("[release-type] [options]").argument("[release-type]", "Version bump type: patch | minor | major").option("-n, --dry-run", "Run in dry mode", false).option("-p, --package <pkg>", "Specify package name (Mono-repo CI only).", "").option("--otp <code>", "One-time password for npm publish.", "").option("--prepare", "Prepare a release.", false).option("--ci", "Enable CI mode.", false).option("--show-changelog", "Print changelog and exit.", false).option("--show-release", "Print release version and exit.", false).option("-r, --release-count <count>", "Release count for release.", (value) => Number(value), 1).option("-
|
|
1249
|
+
program.name("release").description(pkg.description).version(pkg.version, "-v, --version", "Print the tool version and exit.").usage("[release-type] [options]").argument("[release-type]", "Version bump type: patch | minor | major").option("-n, --dry-run", "Run in dry mode", false).option("-m, --is-monorepo", "Mono-repo project", false).option("-p, --package <pkg>", "Specify package name (Mono-repo CI only).", "").option("--otp <code>", "One-time password for npm publish.", "").option("--prepare", "Prepare a release.", false).option("--ci", "Enable CI mode.", false).option("--show-changelog", "Print changelog and exit.", false).option("--show-release", "Print release version and exit.", false).option("-r, --release-count <count>", "Release count for release.", (value) => Number(value), 1).option("--include-hidden", "Include hidden commit types in the changelog.", false).option("--only-changelog", "Only update the changelog.", false).option("-C, --no-require-clean-working-tree", "Allow releasing with uncommitted changes.", true).option("--skip-git", "Skip all Git-related checks and operations.", false).option("--skip-npm", "Skip all npm-related checks and operations.", false).option("--skip-github", "Skip all GitHub-related checks and operations.", false).helpOption("-h, --help", "Display help information.").action(async (releaseType, options) => {
|
|
1224
1250
|
const { prepare } = options;
|
|
1225
1251
|
const action = new Action();
|
|
1226
1252
|
prepare ? await action.handlePrepareRelease(releaseType, options) : await action.handleRelease(releaseType, options);
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DeepPartial, DeepRequired } from "@peiyanlu/ts-utils";
|
|
2
2
|
import { ConventionalChangelog } from "conventional-changelog";
|
|
3
|
+
import { CommitType } from "conventional-changelog-conventionalcommits";
|
|
3
4
|
import { log } from "@clack/prompts";
|
|
4
5
|
|
|
5
6
|
//#region src/types.d.ts
|
|
@@ -36,6 +37,14 @@ interface ReleaseConfig {
|
|
|
36
37
|
* 生成多少个版本的变更日志,详见 {@link Options}
|
|
37
38
|
*/
|
|
38
39
|
releaseCount: number;
|
|
40
|
+
/**
|
|
41
|
+
* 生成 CHANGELOG 时包含默认隐藏的 commit 类型
|
|
42
|
+
*/
|
|
43
|
+
includeHidden: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* 对默认 commit types 进行转换
|
|
46
|
+
*/
|
|
47
|
+
transformTypes: (types: CommitType[]) => CommitType[];
|
|
39
48
|
};
|
|
40
49
|
/** 跳过 git、github 环境检查以及后续操作 */
|
|
41
50
|
skipGit: boolean;
|
|
@@ -179,21 +188,15 @@ interface GenerateOptions {
|
|
|
179
188
|
/** 生成多少个变更日志,详见 {@link Options} */
|
|
180
189
|
releaseCount?: number;
|
|
181
190
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}: GenerateOptions) => Promise<string>;
|
|
192
|
-
declare const generateChangelog: ({
|
|
193
|
-
getPkgDir,
|
|
194
|
-
tagPrefix,
|
|
195
|
-
releaseCount
|
|
196
|
-
}: GenerateOptions) => Promise<void>;
|
|
191
|
+
interface ParsePresetOptions {
|
|
192
|
+
/** 生成 CHANGELOG 时包含默认隐藏的 commit 类型 */
|
|
193
|
+
includeHidden?: boolean;
|
|
194
|
+
/** 对默认 commit types 进行转换 */
|
|
195
|
+
transformTypes?: (types: CommitType[]) => CommitType[];
|
|
196
|
+
}
|
|
197
|
+
declare const createGenerator: (options: GenerateOptions & ParsePresetOptions) => Promise<ConventionalChangelog>;
|
|
198
|
+
declare const getChangelog: (options: GenerateOptions & ParsePresetOptions) => Promise<string>;
|
|
199
|
+
declare const generateChangelog: (options: GenerateOptions & ParsePresetOptions) => Promise<void>;
|
|
197
200
|
//#endregion
|
|
198
201
|
//#region src/npm/publish.d.ts
|
|
199
202
|
interface PublishTagOptions {
|
package/dist/index.mjs
CHANGED
|
@@ -4,8 +4,10 @@ import { join } from "node:path";
|
|
|
4
4
|
import { eol, getPackageInfo, publishPackage, resolvePublishTag } from "@peiyanlu/cli-utils";
|
|
5
5
|
import { ConventionalChangelog } from "conventional-changelog";
|
|
6
6
|
import createPreset from "conventional-changelog-conventionalcommits";
|
|
7
|
+
import "conventional-recommended-bump";
|
|
7
8
|
import { writeFile } from "node:fs/promises";
|
|
8
9
|
import { finished } from "node:stream/promises";
|
|
10
|
+
import { bold, compareUrl, each, heading, link, list, newline, segments, small, words } from "@conventional-changelog/template";
|
|
9
11
|
import { blue, cyan, green, magenta, red, underline, yellow } from "ansis";
|
|
10
12
|
//#region src/config.ts
|
|
11
13
|
function defineConfig(config) {
|
|
@@ -31,179 +33,168 @@ const defaultTypes = [
|
|
|
31
33
|
{
|
|
32
34
|
type: "feat",
|
|
33
35
|
section: "✨ 新功能",
|
|
36
|
+
effect: "bump",
|
|
34
37
|
description: "新增功能"
|
|
35
38
|
},
|
|
36
39
|
{
|
|
37
40
|
type: "feature",
|
|
38
41
|
section: "✨ 新功能",
|
|
42
|
+
effect: "bump",
|
|
39
43
|
description: "新增功能"
|
|
40
44
|
},
|
|
41
45
|
{
|
|
42
46
|
type: "fix",
|
|
43
47
|
section: "🐛 Bug 修复",
|
|
48
|
+
effect: "bump",
|
|
44
49
|
description: "修复 bug"
|
|
45
50
|
},
|
|
46
51
|
{
|
|
47
52
|
type: "perf",
|
|
48
53
|
section: "⚡ 性能优化",
|
|
54
|
+
effect: "bump",
|
|
49
55
|
description: "提升性能"
|
|
50
56
|
},
|
|
51
57
|
{
|
|
52
58
|
type: "revert",
|
|
53
59
|
section: "⏪ 回退",
|
|
60
|
+
effect: "bump",
|
|
54
61
|
description: "回退到之前版本"
|
|
55
62
|
},
|
|
56
63
|
{
|
|
57
64
|
type: "docs",
|
|
58
65
|
section: "📝 文档",
|
|
66
|
+
effect: "changelog",
|
|
59
67
|
description: "文档更新"
|
|
60
68
|
},
|
|
61
69
|
{
|
|
62
70
|
type: "style",
|
|
63
71
|
section: "💄 样式调整",
|
|
72
|
+
effect: "hidden",
|
|
64
73
|
description: "样式或格式修改"
|
|
65
74
|
},
|
|
66
75
|
{
|
|
67
76
|
type: "chore",
|
|
68
77
|
section: "🧹 其他更新",
|
|
78
|
+
effect: "hidden",
|
|
69
79
|
description: "非功能性更改"
|
|
70
80
|
},
|
|
71
81
|
{
|
|
72
82
|
type: "refactor",
|
|
73
83
|
section: "♻️ 代码重构",
|
|
84
|
+
effect: "changelog",
|
|
74
85
|
description: "重构代码"
|
|
75
86
|
},
|
|
76
87
|
{
|
|
77
88
|
type: "test",
|
|
78
89
|
section: "🧪 测试",
|
|
90
|
+
effect: "hidden",
|
|
79
91
|
description: "测试更新"
|
|
80
92
|
},
|
|
81
93
|
{
|
|
82
94
|
type: "build",
|
|
83
95
|
section: "🏗️ 构建系统",
|
|
96
|
+
effect: "hidden",
|
|
84
97
|
description: "构建工具和系统修改"
|
|
85
98
|
},
|
|
86
99
|
{
|
|
87
100
|
type: "ci",
|
|
88
101
|
section: "🤖 CI",
|
|
102
|
+
effect: "hidden",
|
|
89
103
|
description: "持续集成配置"
|
|
90
104
|
},
|
|
91
|
-
{
|
|
92
|
-
type: "config",
|
|
93
|
-
section: "⚙️ 配置",
|
|
94
|
-
description: "配置文件更新"
|
|
95
|
-
},
|
|
96
105
|
{
|
|
97
106
|
type: "deps",
|
|
98
107
|
section: "📦 依赖更新",
|
|
108
|
+
effect: "changelog",
|
|
99
109
|
description: "依赖版本变更"
|
|
100
110
|
},
|
|
101
111
|
{
|
|
102
112
|
type: "security",
|
|
103
113
|
section: "🛡️ 安全修复",
|
|
114
|
+
effect: "changelog",
|
|
104
115
|
description: "安全性更新"
|
|
105
116
|
},
|
|
117
|
+
{
|
|
118
|
+
type: "hotfix",
|
|
119
|
+
section: "🚑 热修复",
|
|
120
|
+
effect: "changelog",
|
|
121
|
+
description: "紧急修复"
|
|
122
|
+
},
|
|
106
123
|
{
|
|
107
124
|
type: "i18n",
|
|
108
125
|
section: "🌐 国际化",
|
|
126
|
+
effect: "changelog",
|
|
109
127
|
description: "国际化相关更新"
|
|
110
128
|
},
|
|
111
129
|
{
|
|
112
130
|
type: "ux",
|
|
113
131
|
section: "🎨 用户体验",
|
|
132
|
+
effect: "changelog",
|
|
114
133
|
description: "用户体验改进"
|
|
115
134
|
},
|
|
116
135
|
{
|
|
117
|
-
type: "
|
|
118
|
-
section: "
|
|
119
|
-
|
|
136
|
+
type: "config",
|
|
137
|
+
section: "⚙️ 配置",
|
|
138
|
+
effect: "hidden",
|
|
139
|
+
description: "配置文件更新"
|
|
120
140
|
},
|
|
121
141
|
{
|
|
122
142
|
type: "tool",
|
|
123
143
|
section: "🛠️ 工具链",
|
|
144
|
+
effect: "hidden",
|
|
124
145
|
description: "工具链变更"
|
|
125
146
|
}
|
|
126
147
|
];
|
|
127
148
|
//#endregion
|
|
149
|
+
//#region src/git/templates.ts
|
|
150
|
+
const isLikelyHash = (value) => /^[0-9a-f]{7,40}$/i.test(value);
|
|
151
|
+
function headerPartial(context) {
|
|
152
|
+
const { isPatch, linkCompare, version, title, date, previousTag } = context;
|
|
153
|
+
const fullTitle = words(linkCompare && !isLikelyHash(previousTag) ? link(version, compareUrl(context)) : version, title && `"${title}"`, date && `(${date})`);
|
|
154
|
+
return heading(2, isPatch ? small(fullTitle) : fullTitle);
|
|
155
|
+
}
|
|
156
|
+
function template(context) {
|
|
157
|
+
const { headerPartial, preamblePartial, commitPartial, footerPartial, noteGroups, commitGroups } = context;
|
|
158
|
+
return segments(headerPartial(context), preamblePartial(context), each(noteGroups, (group) => segments(heading(3, words("⚠", group.title)), list(group.notes, (note) => {
|
|
159
|
+
return each([words(note.commit.scope && bold(`${note.commit.scope}:`), commitPartial(context, note.commit)), note.commit.subject.trim() !== note.text.trim() ? list([note.text], (t) => t) : ""], (t) => t, newline());
|
|
160
|
+
})), newline(2)), each(commitGroups, (group) => segments(group.title && heading(3, group.title), list(group.commits, (commit) => commitPartial(context, commit))), newline(2)), footerPartial(context));
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
128
163
|
//#region src/git/changelog.ts
|
|
129
|
-
const parsePreset =
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
164
|
+
const parsePreset = (options = {}) => {
|
|
165
|
+
const { includeHidden, transformTypes } = options;
|
|
166
|
+
let types = [...defaultTypes];
|
|
167
|
+
if (includeHidden) types.forEach((type) => {
|
|
168
|
+
if (type.effect === "hidden") type.effect = "changelog";
|
|
169
|
+
});
|
|
170
|
+
types = transformTypes?.(types) ?? types;
|
|
171
|
+
const preset = createPreset({ types });
|
|
134
172
|
preset.writer ??= {};
|
|
135
|
-
preset.writer.headerPartial =
|
|
136
|
-
|
|
137
|
-
[{{version}}](
|
|
138
|
-
{{~#if @root.repository~}}
|
|
139
|
-
{{~#if @root.host}}
|
|
140
|
-
{{~@root.host}}/
|
|
141
|
-
{{~/if}}
|
|
142
|
-
{{~#if @root.owner}}
|
|
143
|
-
{{~@root.owner}}/
|
|
144
|
-
{{~/if}}
|
|
145
|
-
{{~@root.repository}}
|
|
146
|
-
{{~else}}
|
|
147
|
-
{{~@root.repoUrl}}
|
|
148
|
-
{{~/if~}}
|
|
149
|
-
/compare/{{previousTag}}...{{currentTag}})
|
|
150
|
-
{{~else}}
|
|
151
|
-
{{~version}}
|
|
152
|
-
{{~/if}}
|
|
153
|
-
{{~#if title}} "{{title}}"
|
|
154
|
-
{{~/if}}
|
|
155
|
-
{{~#if date}} ({{date}})
|
|
156
|
-
{{~/if}}
|
|
157
|
-
{{~#if isPatch~}} </small> {{~/if}}
|
|
158
|
-
`.trim() + eol();
|
|
159
|
-
preset.writer.mainTemplate = `{{> header}}
|
|
160
|
-
{{#if noteGroups}}
|
|
161
|
-
{{#each noteGroups}}
|
|
162
|
-
|
|
163
|
-
### ⚠ {{title}}
|
|
164
|
-
|
|
165
|
-
{{#each notes}}
|
|
166
|
-
* {{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{commit.subject}} {{#if commit.hash}}([{{commit.shortHash}}](https://github.com/{{@root.owner}}/{{@root.repository}}/commit/{{commit.hash}})){{/if}}
|
|
167
|
-
{{/each}}
|
|
168
|
-
{{/each}}
|
|
169
|
-
{{/if}}
|
|
170
|
-
{{#each commitGroups}}
|
|
171
|
-
|
|
172
|
-
{{#if title}}
|
|
173
|
-
### {{title}}
|
|
174
|
-
|
|
175
|
-
{{/if}}
|
|
176
|
-
{{#each commits}}
|
|
177
|
-
{{> commit root=@root}}
|
|
178
|
-
{{/each}}
|
|
179
|
-
{{/each}}`.trim();
|
|
173
|
+
preset.writer.headerPartial = headerPartial;
|
|
174
|
+
preset.writer.template = template;
|
|
180
175
|
return preset;
|
|
181
176
|
};
|
|
182
|
-
const createGenerator = async (
|
|
177
|
+
const createGenerator = async (options) => {
|
|
178
|
+
const { getPkgDir, tagPrefix, releaseCount = 1, includeHidden, transformTypes } = options;
|
|
183
179
|
const pkgDir = getPkgDir();
|
|
184
|
-
|
|
185
|
-
|
|
180
|
+
return new ConventionalChangelog().readPackage(`${pkgDir}/package.json`).config(parsePreset({
|
|
181
|
+
includeHidden,
|
|
182
|
+
transformTypes
|
|
183
|
+
})).options({ releaseCount }).commits({ path: pkgDir }).tags({ prefix: tagPrefix });
|
|
186
184
|
};
|
|
187
|
-
const getChangelog = async (
|
|
188
|
-
const generator = await createGenerator(
|
|
189
|
-
getPkgDir,
|
|
190
|
-
tagPrefix,
|
|
191
|
-
releaseCount
|
|
192
|
-
});
|
|
185
|
+
const getChangelog = async (options) => {
|
|
186
|
+
const generator = await createGenerator(options);
|
|
193
187
|
let changelog = "";
|
|
194
188
|
for await (const chunk of generator.write()) changelog += chunk;
|
|
195
189
|
return changelog.trimEnd();
|
|
196
190
|
};
|
|
197
|
-
const generateChangelog = async (
|
|
191
|
+
const generateChangelog = async (options) => {
|
|
192
|
+
const { getPkgDir, releaseCount = 1 } = options;
|
|
198
193
|
const infile = join(getPkgDir(), "CHANGELOG.md");
|
|
199
194
|
if (!existsSync(infile)) await writeFile(infile, "");
|
|
200
195
|
const exist = readFileSync(infile, "utf-8");
|
|
201
196
|
const writeStream = createWriteStream(infile);
|
|
202
|
-
const generator = await createGenerator(
|
|
203
|
-
getPkgDir,
|
|
204
|
-
tagPrefix,
|
|
205
|
-
releaseCount
|
|
206
|
-
});
|
|
197
|
+
const generator = await createGenerator(options);
|
|
207
198
|
for await (const chunk of generator.write()) writeStream.write(chunk);
|
|
208
199
|
const override = isZero(releaseCount);
|
|
209
200
|
if (!(isZero(exist.trim().length) || override)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peiyanlu/release",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Release project tool.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -34,9 +34,10 @@
|
|
|
34
34
|
"@peiyanlu/ts-utils": "^0.0.8",
|
|
35
35
|
"ansis": "^4.3.1",
|
|
36
36
|
"commander": "^15.0.0",
|
|
37
|
-
"conventional-changelog": "^
|
|
38
|
-
"conventional-changelog-conventionalcommits": "^
|
|
39
|
-
"conventional-
|
|
37
|
+
"conventional-changelog": "^8.0.0",
|
|
38
|
+
"conventional-changelog-conventionalcommits": "^10.2.0",
|
|
39
|
+
"conventional-recommended-bump": "^12.0.0",
|
|
40
|
+
"@conventional-changelog/template": "^1.2.0",
|
|
40
41
|
"mime-types": "^3.0.2",
|
|
41
42
|
"open": "^11.0.0",
|
|
42
43
|
"publint": "^0.3.21",
|