keepchanges 1.0.0-beta.1 → 1.0.0-beta.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 +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/cli.mjs +16 -12
- package/dist/index.d.mts +4 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -150,7 +150,8 @@ different commits.
|
|
|
150
150
|
|
|
151
151
|
Stable releases compare with the previous stable tag. Prereleases compare with
|
|
152
152
|
the nearest previous tag. With `--release`, `--dry` takes precedence and
|
|
153
|
-
prevents all file writes and remote mutations.
|
|
153
|
+
prevents all file writes and remote mutations. Its manual URL opens a new
|
|
154
|
+
Release for a new tag and the edit page for an existing tag.
|
|
154
155
|
|
|
155
156
|
> [!NOTE]
|
|
156
157
|
> A regular `--release` without a token still writes files, commits, tags, and
|
package/README.zh-CN.md
CHANGED
|
@@ -143,7 +143,8 @@ GitHub 和 Gitea 均支持作者解析和 Release 发布;Gitea 使用 `GITEA_T
|
|
|
143
143
|
时会停止,不会强制覆盖。
|
|
144
144
|
|
|
145
145
|
稳定版本会与前一个稳定 tag 对比,预发布版本会与最近的前一个 tag 对比。与
|
|
146
|
-
`--release` 搭配的 `--dry`
|
|
146
|
+
`--release` 搭配的 `--dry` 优先级最高,不会执行任何写入或远程修改。手动链接
|
|
147
|
+
会为新 tag 打开创建 Release 页面,为已有 tag 打开编辑页面。
|
|
147
148
|
|
|
148
149
|
> [!NOTE]
|
|
149
150
|
> 没有 token 的普通 `--release` 仍会执行本地写入、commit、tag 和 push,
|
package/dist/cli.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { resolve } from "node:path";
|
|
|
8
8
|
import ansis from "ansis";
|
|
9
9
|
import { x } from "tinyexec";
|
|
10
10
|
//#region package.json
|
|
11
|
-
var version = "1.0.0-beta.
|
|
11
|
+
var version = "1.0.0-beta.2";
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/git.ts
|
|
14
14
|
async function git(cwd, ...args) {
|
|
@@ -58,6 +58,7 @@ async function readGitCommits(cwd, from, to) {
|
|
|
58
58
|
//#region src/repositories/gitea.ts
|
|
59
59
|
const giteaRepository = {
|
|
60
60
|
name: "Gitea",
|
|
61
|
+
tokenEnv: "GITEA_TOKEN",
|
|
61
62
|
parse(source) {
|
|
62
63
|
try {
|
|
63
64
|
const url = new URL(source.replace(/^git\+/, ""));
|
|
@@ -83,7 +84,8 @@ const giteaRepository = {
|
|
|
83
84
|
compareUrl(repository, from, to) {
|
|
84
85
|
return `${repository.webUrl}/compare/${from}...${to}`;
|
|
85
86
|
},
|
|
86
|
-
manualReleaseUrl(repository, release) {
|
|
87
|
+
manualReleaseUrl(repository, release, action) {
|
|
88
|
+
if (action === "edit") return `${repository.webUrl}/releases/edit/${encodeURIComponent(release.tag)}`;
|
|
87
89
|
const url = new URL(`${repository.webUrl}/releases/new`);
|
|
88
90
|
url.search = new URLSearchParams({ tag: release.tag }).toString();
|
|
89
91
|
return url.toString();
|
|
@@ -143,6 +145,7 @@ const giteaRepository = {
|
|
|
143
145
|
//#region src/repositories/github.ts
|
|
144
146
|
const githubRepository = {
|
|
145
147
|
name: "GitHub",
|
|
148
|
+
tokenEnv: "GITHUB_TOKEN",
|
|
146
149
|
parse(source) {
|
|
147
150
|
const match = /github\.com[:/]([^/]+\/[^/]+?)(?:\.git)?$/.exec(source);
|
|
148
151
|
if (!match) return;
|
|
@@ -164,7 +167,8 @@ const githubRepository = {
|
|
|
164
167
|
compareUrl(repository, from, to) {
|
|
165
168
|
return `${repository.webUrl}/compare/${from}...${to}`;
|
|
166
169
|
},
|
|
167
|
-
manualReleaseUrl(repository, release) {
|
|
170
|
+
manualReleaseUrl(repository, release, action) {
|
|
171
|
+
if (action === "edit") return `${repository.webUrl}/releases/edit/${encodeURIComponent(release.tag)}`;
|
|
168
172
|
const url = new URL(`${repository.webUrl}/releases/new`);
|
|
169
173
|
url.search = new URLSearchParams({
|
|
170
174
|
title: release.name,
|
|
@@ -288,9 +292,9 @@ function printChangesPreview(preview, stdout, colors) {
|
|
|
288
292
|
""
|
|
289
293
|
].join("\n"));
|
|
290
294
|
}
|
|
291
|
-
function printManualReleaseUrl(repository, release, stdout, colors) {
|
|
292
|
-
const url = repository.provider.manualReleaseUrl?.(repository, release);
|
|
293
|
-
if (url) stdout(`${colors.yellow(
|
|
295
|
+
function printManualReleaseUrl(repository, release, stdout, colors, action = "create") {
|
|
296
|
+
const url = repository.provider.manualReleaseUrl?.(repository, release, action);
|
|
297
|
+
if (url) stdout(`${colors.yellow(`Using the following link to ${action} it manually:`)}\n${colors.yellow(url)}\n`);
|
|
294
298
|
}
|
|
295
299
|
function printPublishedRelease(provider, result, stdout, colors) {
|
|
296
300
|
const action = result.action.charAt(0).toUpperCase() + result.action.slice(1);
|
|
@@ -326,7 +330,7 @@ async function createChanges(options, environment) {
|
|
|
326
330
|
const to = releaseRef || options.to;
|
|
327
331
|
const comparisonFrom = from || (repository ? await git(environment.cwd, "rev-list", "--max-parents=0", to).then((value) => value.trim()) : "");
|
|
328
332
|
const commits = parseCommits(await readGitCommits(environment.cwd, from, to));
|
|
329
|
-
if (token && repository
|
|
333
|
+
if (token && repository) await repository.provider.resolveAuthors?.(commits, repository, token, environment.fetch ?? globalThis.fetch);
|
|
330
334
|
const style = {
|
|
331
335
|
emoji: options.emoji,
|
|
332
336
|
capitalize: options.capitalize,
|
|
@@ -355,13 +359,13 @@ async function createChanges(options, environment) {
|
|
|
355
359
|
printChangesPreview(preview, stdout, colors);
|
|
356
360
|
if (options.release) {
|
|
357
361
|
stdout(`${colors.yellow("Dry run. Release skipped.")}\n\n`);
|
|
358
|
-
printManualReleaseUrl(repository, repositoryRelease, stdout, colors);
|
|
362
|
+
printManualReleaseUrl(repository, repositoryRelease, stdout, colors, taggedCommit ? "edit" : "create");
|
|
359
363
|
}
|
|
360
364
|
return;
|
|
361
365
|
}
|
|
362
366
|
if (options.release && taggedCommit) {
|
|
363
367
|
if (!remoteTaggedCommit) await git(environment.cwd, "push", "origin", `refs/tags/${tag}`);
|
|
364
|
-
await publishRelease(repository, repositoryRelease, token, preview, environment);
|
|
368
|
+
await publishRelease(repository, repositoryRelease, token, preview, environment, "edit");
|
|
365
369
|
return;
|
|
366
370
|
}
|
|
367
371
|
const outputPath = resolve(environment.cwd, options.output);
|
|
@@ -390,14 +394,14 @@ async function commitReleaseFiles(options, cwd, outputPath, versionPath, release
|
|
|
390
394
|
const commitMessage = versionPath && !versionChanges.trim() ? `docs(changelog): ${releaseExists ? "update" : "add"} v${options.version} release notes` : `chore(release): v${options.version}`;
|
|
391
395
|
await git(cwd, ...resolveGitIdentity(options.author), "commit", "-m", commitMessage, ...options.author ? ["--author", options.author] : [], "--only", "--", ...releasePaths);
|
|
392
396
|
}
|
|
393
|
-
async function publishRelease(repository, release, token, preview, environment) {
|
|
397
|
+
async function publishRelease(repository, release, token, preview, environment, manualAction = "create") {
|
|
394
398
|
const stdout = environment.stdout ?? ((value) => process.stdout.write(value));
|
|
395
399
|
const colors = environment.colors ?? ansis;
|
|
396
400
|
printChangesPreview(preview, stdout, colors);
|
|
397
401
|
if (!token || !repository.provider.publishRelease) {
|
|
398
402
|
if (!repository.provider.manualReleaseUrl) throw new Error("A repository token is required to release");
|
|
399
|
-
stdout(`${colors.red(`No ${repository.provider.name} token found, specify it via --token or
|
|
400
|
-
printManualReleaseUrl(repository, release, stdout, colors);
|
|
403
|
+
stdout(`${colors.red(`No ${repository.provider.name} token found, specify it via --token or ${repository.provider.tokenEnv} env. Release skipped.`)}\n\n`);
|
|
404
|
+
printManualReleaseUrl(repository, release, stdout, colors, manualAction);
|
|
401
405
|
return;
|
|
402
406
|
}
|
|
403
407
|
const result = await repository.provider.publishRelease(repository, release, token, environment.fetch ?? globalThis.fetch);
|
package/dist/index.d.mts
CHANGED
|
@@ -24,8 +24,10 @@ interface RepositoryReleaseResult {
|
|
|
24
24
|
url: string;
|
|
25
25
|
action: 'created' | 'updated';
|
|
26
26
|
}
|
|
27
|
+
type ManualReleaseAction = 'create' | 'edit';
|
|
27
28
|
interface RepositoryProvider {
|
|
28
29
|
name: string;
|
|
30
|
+
tokenEnv: string;
|
|
29
31
|
parse: (source: string) => Repository | undefined;
|
|
30
32
|
token: (explicit: string | undefined, env: NodeJS.ProcessEnv) => string | undefined;
|
|
31
33
|
commitUrl: (repository: Repository, hash: string) => string;
|
|
@@ -33,7 +35,7 @@ interface RepositoryProvider {
|
|
|
33
35
|
compareUrl: (repository: Repository, from: string, to: string) => string;
|
|
34
36
|
resolveAuthors?: (commits: RepositoryCommit[], repository: Repository, token: string, fetch: typeof globalThis.fetch) => Promise<void>;
|
|
35
37
|
publishRelease?: (repository: Repository, release: RepositoryRelease, token: string, fetch: typeof globalThis.fetch) => Promise<RepositoryReleaseResult>;
|
|
36
|
-
manualReleaseUrl?: (repository: Repository, release: RepositoryRelease) => string;
|
|
38
|
+
manualReleaseUrl?: (repository: Repository, release: RepositoryRelease, action?: ManualReleaseAction) => string;
|
|
37
39
|
}
|
|
38
40
|
//#endregion
|
|
39
41
|
//#region src/git.d.ts
|
|
@@ -149,4 +151,4 @@ declare function writeChangelog(path: string, changelog: string): Promise<void>;
|
|
|
149
151
|
declare function hasRelease(changelog: string, version: string): boolean;
|
|
150
152
|
declare function insertRelease(changelog: string, release: string): string;
|
|
151
153
|
//#endregion
|
|
152
|
-
export { type ChangelogConfig, type ChangelogConfigOverrides, type ChangelogMessages, type ChangelogSectionConfig, type Commit, type GenerateChangelogOptions, type GeneratedChangelog, type KeepChangesConfig, type RawCommit, type Repository, type RepositoryAuthor, type RepositoryCommit, type RepositoryProvider, type RepositoryRelease, type RepositoryReleaseResult, defaultConfig, generateChangelog, hasRelease, insertRelease, parseCommit, parseCommits, readChangelog, resolveChangelogConfig, writeChangelog };
|
|
154
|
+
export { type ChangelogConfig, type ChangelogConfigOverrides, type ChangelogMessages, type ChangelogSectionConfig, type Commit, type GenerateChangelogOptions, type GeneratedChangelog, type KeepChangesConfig, type ManualReleaseAction, type RawCommit, type Repository, type RepositoryAuthor, type RepositoryCommit, type RepositoryProvider, type RepositoryRelease, type RepositoryReleaseResult, defaultConfig, generateChangelog, hasRelease, insertRelease, parseCommit, parseCommits, readChangelog, resolveChangelogConfig, writeChangelog };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keepchanges",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.2",
|
|
5
5
|
"description": "Generate and maintain CHANGELOG.md from Conventional Commits.",
|
|
6
6
|
"author": "edram",
|
|
7
7
|
"license": "MIT",
|
|
@@ -41,19 +41,19 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@antfu/eslint-config": "^9.2.0",
|
|
43
43
|
"@types/node": "^26.1.1",
|
|
44
|
-
"bumpp": "^11.1.0",
|
|
45
44
|
"eslint": "^10.7.0",
|
|
46
45
|
"tsdown": "^0.22.5",
|
|
46
|
+
"tsx": "^4.23.8",
|
|
47
47
|
"typescript": "^6.0.3",
|
|
48
48
|
"vitest": "^4.1.10"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "tsdown",
|
|
52
52
|
"dev": "tsdown --watch",
|
|
53
|
+
"start": "tsx ./src/cli.ts",
|
|
53
54
|
"lint": "eslint",
|
|
54
55
|
"lint:fix": "eslint --fix",
|
|
55
56
|
"test": "pnpm run build && vitest run",
|
|
56
|
-
"typecheck": "tsc --noEmit"
|
|
57
|
-
"release": "bumpp"
|
|
57
|
+
"typecheck": "tsc --noEmit"
|
|
58
58
|
}
|
|
59
59
|
}
|