@aklinker1/zero-changelog 0.1.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/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/changelog-section.d.mts +7 -0
- package/dist/changelog-section.mjs +1 -0
- package/dist/conventional-commit.d.mts +28 -0
- package/dist/conventional-commit.mjs +1 -0
- package/dist/create-github-release.d.mts +15 -0
- package/dist/create-github-release.mjs +61 -0
- package/dist/detect-version-bump.d.mts +13 -0
- package/dist/detect-version-bump.mjs +43 -0
- package/dist/find-previous-tag-Cj2oZAty.mjs +27 -0
- package/dist/find-previous-tag.d.mts +10 -0
- package/dist/find-previous-tag.mjs +2 -0
- package/dist/get-current-version.d.mts +4 -0
- package/dist/get-current-version.mjs +24 -0
- package/dist/get-github-release.d.mts +15 -0
- package/dist/get-github-release.mjs +11 -0
- package/dist/get-github-repo.d.mts +4 -0
- package/dist/get-github-repo.mjs +20 -0
- package/dist/get-release-notes.d.mts +6 -0
- package/dist/get-release-notes.mjs +37 -0
- package/dist/git-commit.d.mts +13 -0
- package/dist/git-commit.mjs +1 -0
- package/dist/list-commits-since-DycWgHTi.mjs +44 -0
- package/dist/list-commits-since.d.mts +11 -0
- package/dist/list-commits-since.mjs +2 -0
- package/dist/parse-changelog.d.mts +6 -0
- package/dist/parse-changelog.mjs +23 -0
- package/dist/parse-commit.d.mts +8 -0
- package/dist/parse-commit.mjs +34 -0
- package/dist/parse-commits.d.mts +8 -0
- package/dist/parse-commits.mjs +8 -0
- package/dist/release.d.mts +384 -0
- package/dist/release.mjs +125 -0
- package/dist/semver-type--Q1lYCiZ.d.mts +11 -0
- package/dist/semver-type-map.d.mts +8 -0
- package/dist/semver-type-map.mjs +1 -0
- package/dist/semver-type.d.mts +2 -0
- package/dist/semver-type.mjs +1 -0
- package/dist/semver-types/aklinker1.d.mts +6 -0
- package/dist/semver-types/aklinker1.mjs +38 -0
- package/dist/semver.d.mts +37 -0
- package/dist/semver.mjs +142 -0
- package/dist/serialize-changelog.d.mts +6 -0
- package/dist/serialize-changelog.mjs +28 -0
- package/dist/summarize-unreleased-commits.d.mts +50 -0
- package/dist/summarize-unreleased-commits.mjs +30 -0
- package/dist/sync-release.d.mts +4 -0
- package/dist/sync-release.mjs +6 -0
- package/dist/sync-releases.d.mts +4 -0
- package/dist/sync-releases.mjs +6 -0
- package/dist/update-version-files.d.mts +4 -0
- package/dist/update-version-files.mjs +26 -0
- package/dist/utils-BO6byvK5.mjs +22 -0
- package/dist/version-regex-C82OGsTC.mjs +23 -0
- package/dist/wait-for-child-process-lyAoE4WE.mjs +25 -0
- package/package.json +134 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/parse-commit.ts
|
|
2
|
+
const SUBJECT_REGEX = /^(?<type>\w+)(\((?<scope>.*?)\))?(?<breaking>!)?:\s+(?<description>.+)$/;
|
|
3
|
+
const FOOTER_REGEX = /^(?<key>BREAKING CHANGE|\S+):\s+(?<value>.+)$/;
|
|
4
|
+
const AUTHOR_REGEX = /^(?<name>.+) <(?<email>.+)>$/;
|
|
5
|
+
/** Convert a commit to a {@link ConventionalCommit}, returning `undefined` for unknown formats */
|
|
6
|
+
function parseCommit(commit) {
|
|
7
|
+
const titleMatch = commit.subject.match(SUBJECT_REGEX);
|
|
8
|
+
if (!titleMatch) return void 0;
|
|
9
|
+
const { type, scope, breaking, description } = titleMatch.groups;
|
|
10
|
+
if (type == null || description == null) return void 0;
|
|
11
|
+
const footers = [];
|
|
12
|
+
if (commit.body) for (const line of commit.body.split("\n")) {
|
|
13
|
+
const match = line.match(FOOTER_REGEX);
|
|
14
|
+
if (!match?.groups) continue;
|
|
15
|
+
footers.push({
|
|
16
|
+
key: match.groups.key.toLowerCase(),
|
|
17
|
+
value: match.groups.value
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
type,
|
|
22
|
+
scope,
|
|
23
|
+
description,
|
|
24
|
+
body: commit.body,
|
|
25
|
+
isBreaking: !!breaking || footers.some((footer) => footer.key === "breaking change"),
|
|
26
|
+
footers,
|
|
27
|
+
authors: [commit.author, ...footers.filter((footer) => footer.key === "co-authored-by").map((footer) => footer.value.match(AUTHOR_REGEX)?.groups).filter((group) => group != null).map((group) => ({
|
|
28
|
+
name: group.name,
|
|
29
|
+
email: group.email
|
|
30
|
+
}))]
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { parseCommit };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ConventionalCommit } from "./conventional-commit.mjs";
|
|
2
|
+
import { GitCommit } from "./git-commit.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/parse-commits.d.ts
|
|
5
|
+
/** Convert commits to an array of {@link Change}, ignoring commits with an unknown format. */
|
|
6
|
+
declare function parseCommits(commits: GitCommit[]): ConventionalCommit[];
|
|
7
|
+
//#endregion
|
|
8
|
+
export { parseCommits };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { parseCommit } from "./parse-commit.mjs";
|
|
2
|
+
//#region src/parse-commits.ts
|
|
3
|
+
/** Convert commits to an array of {@link Change}, ignoring commits with an unknown format. */
|
|
4
|
+
function parseCommits(commits) {
|
|
5
|
+
return commits.map(parseCommit).filter((change) => change != null);
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { parseCommits };
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import { BumpBy } from "./semver.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/release.d.ts
|
|
4
|
+
type ReleaseOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* How to bump the version during the release.
|
|
7
|
+
*
|
|
8
|
+
* - `undefined`: Detect based on the commit messages since {@link ReleaseOptions#since}
|
|
9
|
+
* - `"major"`: Bump the major version (e.g. `1.0.0` → `2.0.0`)
|
|
10
|
+
* - `"minor"`: Bump the minor version (e.g. `1.0.0` → `1.1.0`)
|
|
11
|
+
* - `"patch"`: Bump the patch version (e.g. `1.0.0` → `1.0.1`)
|
|
12
|
+
* - `"X.Y.Z"`: Use a specific version (e.g. `1.0.0` → `1.0.0`)
|
|
13
|
+
*
|
|
14
|
+
* - You may set this string to any valid semver (e.g. `"2.0.0"`, `"1.2.3-beta.1"`).
|
|
15
|
+
*
|
|
16
|
+
* JS Usage:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* await release({ bump: "minor" });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* GitHub Actions:
|
|
23
|
+
*
|
|
24
|
+
* ```yml
|
|
25
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
26
|
+
* with:
|
|
27
|
+
* bump: ${{ inputs.version }}
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @default undefined
|
|
31
|
+
*/
|
|
32
|
+
bump?: BumpBy;
|
|
33
|
+
/**
|
|
34
|
+
* The directory to release
|
|
35
|
+
*
|
|
36
|
+
* JS Usage:
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* await release({ path: "packages/my-package" });
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* GitHub Actions:
|
|
43
|
+
*
|
|
44
|
+
* ```yml
|
|
45
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
46
|
+
* with:
|
|
47
|
+
* path: ${{ inputs.packageDir }}
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @default process.cwd()
|
|
51
|
+
*/
|
|
52
|
+
path?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Additional directories to include commits from when computing the version bump.
|
|
55
|
+
*
|
|
56
|
+
* > **IMPORTANT**: You may use glob patterns for ONLY the github action. They are not automatically
|
|
57
|
+
* > expanded when using the JS API. If you use the JS API and want to use glob patterns, [install a
|
|
58
|
+
* > glob pattern library](https://www.npmjs.com/search?q=glob) and call it yourself.
|
|
59
|
+
*
|
|
60
|
+
* JS Usage:
|
|
61
|
+
*
|
|
62
|
+
* ```ts
|
|
63
|
+
* await release({
|
|
64
|
+
* path: "packages/my-package",
|
|
65
|
+
* additionalDirs: ["../../.github", "../../scripts"],
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* GitHub Actions:
|
|
70
|
+
*
|
|
71
|
+
* ```yml
|
|
72
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
73
|
+
* with:
|
|
74
|
+
* path: ${{ inputs.packageDir }}
|
|
75
|
+
* additionalDirs: |-
|
|
76
|
+
* ../../.github
|
|
77
|
+
* ../../scripts
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
additionalDirs?: string[];
|
|
81
|
+
/**
|
|
82
|
+
* Tag prefix to use while generating the tag name.
|
|
83
|
+
*
|
|
84
|
+
* The default value changes based on {@link ReleaseOptions#path}:
|
|
85
|
+
*
|
|
86
|
+
* - When `undefined`, defaults to `"v"`
|
|
87
|
+
* - When set, defaults to `basename(path) + "-v"`
|
|
88
|
+
*
|
|
89
|
+
* JS Usage:
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
92
|
+
* await release({
|
|
93
|
+
* tagPrefix: "npm-v",
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* GitHub Actions:
|
|
98
|
+
*
|
|
99
|
+
* ```yml
|
|
100
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
101
|
+
* with:
|
|
102
|
+
* tagPrefix: npm-v
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
tagPrefix?: string;
|
|
106
|
+
/**
|
|
107
|
+
* Customize the commit message.
|
|
108
|
+
*
|
|
109
|
+
* Template vars:
|
|
110
|
+
*
|
|
111
|
+
* - `{{version}}`: The version after being bumped.
|
|
112
|
+
* - `{{path}}`: The {@link ReleaseOptions#path} relative to the current working directory.
|
|
113
|
+
* - `{{dirname}}`: The path's base name.
|
|
114
|
+
*
|
|
115
|
+
* JS Usage:
|
|
116
|
+
*
|
|
117
|
+
* ```ts
|
|
118
|
+
* await release({
|
|
119
|
+
* path: "packages/my-package",
|
|
120
|
+
* commitTemplate: "chore(release): My Package v{{version}}",
|
|
121
|
+
* });
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* GitHub Actions:
|
|
125
|
+
*
|
|
126
|
+
* ```yml
|
|
127
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
128
|
+
* with:
|
|
129
|
+
* path: packages/my-package
|
|
130
|
+
* commitTemplate: "chore(release): My Package v{{version}}"
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @default "chore(release): v{{version}}"
|
|
134
|
+
*/
|
|
135
|
+
commitTemplate?: string;
|
|
136
|
+
/**
|
|
137
|
+
* A git ref to use as the starting point when generating changelog and determining which version
|
|
138
|
+
* to bump to.
|
|
139
|
+
*
|
|
140
|
+
* When not provided, the last tag that starts with your {@link ReleaseOptions#tagPrefix} will be
|
|
141
|
+
* used.
|
|
142
|
+
*
|
|
143
|
+
* JS Usage:
|
|
144
|
+
*
|
|
145
|
+
* ```ts
|
|
146
|
+
* await release({
|
|
147
|
+
* since: "some-tag",
|
|
148
|
+
* });
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* GitHub Actions:
|
|
152
|
+
*
|
|
153
|
+
* ```yml
|
|
154
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
155
|
+
* with:
|
|
156
|
+
* since: "some-tag"
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
since?: string;
|
|
160
|
+
/**
|
|
161
|
+
* If `true`, the release will not be committed or tagged.
|
|
162
|
+
*
|
|
163
|
+
* JS Usage:
|
|
164
|
+
*
|
|
165
|
+
* ```ts
|
|
166
|
+
* await release({
|
|
167
|
+
* dryRun: true,
|
|
168
|
+
* });
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* GitHub Actions:
|
|
172
|
+
*
|
|
173
|
+
* ```yml
|
|
174
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
175
|
+
* with:
|
|
176
|
+
* dryRun: true
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* @default false
|
|
180
|
+
*/
|
|
181
|
+
dryRun?: boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Customize the release title.
|
|
184
|
+
*
|
|
185
|
+
* Template vars:
|
|
186
|
+
*
|
|
187
|
+
* - `{{version}}`: The version after being bumped.
|
|
188
|
+
* - `{{tag}}`: The tag that will be used for the release.
|
|
189
|
+
* - `{{path}}`: The {@link ReleaseOptions#path} relative to the current working directory.
|
|
190
|
+
* - `{{dirname}}`: The path's base name.
|
|
191
|
+
*
|
|
192
|
+
* JS Usage:
|
|
193
|
+
*
|
|
194
|
+
* ```ts
|
|
195
|
+
* await release({
|
|
196
|
+
* path: "packages/my-package",
|
|
197
|
+
* releaseNameTemplate: "My Package {{version}}",
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* GitHub Actions:
|
|
202
|
+
*
|
|
203
|
+
* ```yml
|
|
204
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
205
|
+
* with:
|
|
206
|
+
* path: "packages/my-package"
|
|
207
|
+
* releaseNameTemplate: "My Package {{version}}"
|
|
208
|
+
* ```
|
|
209
|
+
*
|
|
210
|
+
* @default "{{tag}}"
|
|
211
|
+
*/
|
|
212
|
+
releaseNameTemplate?: string;
|
|
213
|
+
/**
|
|
214
|
+
* A custom publish command to run before committing and creating the release.
|
|
215
|
+
*
|
|
216
|
+
* If not provided, nothing is ran.
|
|
217
|
+
*
|
|
218
|
+
* JS Usage:
|
|
219
|
+
*
|
|
220
|
+
* ```ts
|
|
221
|
+
* await release({
|
|
222
|
+
* publishCommands: ["npm publish", "jsr publish"],
|
|
223
|
+
* });
|
|
224
|
+
* ```
|
|
225
|
+
*
|
|
226
|
+
* GitHub Actions:
|
|
227
|
+
*
|
|
228
|
+
* ```yml
|
|
229
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
230
|
+
* with:
|
|
231
|
+
* publishCommands: |-
|
|
232
|
+
* npm publish
|
|
233
|
+
* jsr publish
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
publishCommands?: string[];
|
|
237
|
+
/**
|
|
238
|
+
* If your {@link ReleaseOptions#publishCommands} has a dry run variant, you can provide it here.
|
|
239
|
+
*
|
|
240
|
+
* When provided, this command will be ran instead of the regular publishCommands when
|
|
241
|
+
* {@link ReleaseOptions#dryRun} is true.
|
|
242
|
+
*
|
|
243
|
+
* JS Usage:
|
|
244
|
+
*
|
|
245
|
+
* ```ts
|
|
246
|
+
* await release({
|
|
247
|
+
* dryRunPublishCommands: ["npm publish --dry-run", "jsr publish --dry-run"],
|
|
248
|
+
* });
|
|
249
|
+
* ```
|
|
250
|
+
*
|
|
251
|
+
* GitHub Actions:
|
|
252
|
+
*
|
|
253
|
+
* ```yml
|
|
254
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
255
|
+
* with:
|
|
256
|
+
* dryRunPublishCommands: |-
|
|
257
|
+
* npm publish --dry-run
|
|
258
|
+
* jsr publish --dry-run
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
dryRunPublishCommands?: string[];
|
|
262
|
+
/**
|
|
263
|
+
* List of files to bump versions inside, relative to the {@link ReleaseOptions#path}.
|
|
264
|
+
*
|
|
265
|
+
* - If none of the files exist, an error will be thrown.
|
|
266
|
+
* - If the file is not present, the path will be logged.
|
|
267
|
+
*
|
|
268
|
+
* > **IMPORTANT**: You may use glob patterns for ONLY the github action. They are not automatically
|
|
269
|
+
* > expanded when using the JS API. If you use the JS API and want to use glob patterns, [install a
|
|
270
|
+
* > glob pattern library](https://www.npmjs.com/search?q=glob) and call it yourself.
|
|
271
|
+
*
|
|
272
|
+
* JS Usage:
|
|
273
|
+
*
|
|
274
|
+
* ```ts
|
|
275
|
+
* await release({
|
|
276
|
+
* versionFiles: ["package.json", "jsr.json"],
|
|
277
|
+
* });
|
|
278
|
+
* ```
|
|
279
|
+
*
|
|
280
|
+
* GitHub Actions:
|
|
281
|
+
*
|
|
282
|
+
* ```yml
|
|
283
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
284
|
+
* with:
|
|
285
|
+
* versionFiles: |-
|
|
286
|
+
* package.json
|
|
287
|
+
* jsr.json
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
290
|
+
* @default ["package.json", "jsr.json", "deno.json", "Cargo.toml"]
|
|
291
|
+
*/
|
|
292
|
+
versionFiles?: string[];
|
|
293
|
+
/**
|
|
294
|
+
* List of paths to artifacts to upload on the github release. Does NOT support globs.
|
|
295
|
+
*
|
|
296
|
+
* > **IMPORTANT**: You may use glob patterns for ONLY the github action. They are not automatically
|
|
297
|
+
* > expanded when using the JS API. If you use the JS API and want to use glob patterns, [install a
|
|
298
|
+
* > glob pattern library](https://www.npmjs.com/search?q=glob) and call it yourself.
|
|
299
|
+
*
|
|
300
|
+
* JS Usage:
|
|
301
|
+
*
|
|
302
|
+
* ```ts
|
|
303
|
+
* await release({
|
|
304
|
+
* releaseArtifacts: ["file1", "file2"],
|
|
305
|
+
* });
|
|
306
|
+
* ```
|
|
307
|
+
*
|
|
308
|
+
* GitHub Actions:
|
|
309
|
+
*
|
|
310
|
+
* ```yml
|
|
311
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
312
|
+
* with:
|
|
313
|
+
* releaseArtifacts: |-
|
|
314
|
+
* file1
|
|
315
|
+
* file2
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
releaseArtifacts?: string[];
|
|
319
|
+
/**
|
|
320
|
+
* When `true`, throw an error if no commits contain semver changes. When `false` or `undefined`,
|
|
321
|
+
* use `bump: "patch"` when no changes are detected.
|
|
322
|
+
*
|
|
323
|
+
* > IMPORTANT**: This option is only effective when the {@link ReleaseOptions#bump} is `undefined`.
|
|
324
|
+
*
|
|
325
|
+
* @default false
|
|
326
|
+
*/
|
|
327
|
+
throwOnNoChanges?: boolean;
|
|
328
|
+
/**
|
|
329
|
+
* The repo to create the release on.
|
|
330
|
+
*
|
|
331
|
+
* JS Usage:
|
|
332
|
+
*
|
|
333
|
+
* ```ts
|
|
334
|
+
* await release({
|
|
335
|
+
* githubRepo: "aklinker1/zero-changelog",
|
|
336
|
+
* });
|
|
337
|
+
* ```
|
|
338
|
+
*
|
|
339
|
+
* GitHub Actions:
|
|
340
|
+
*
|
|
341
|
+
* ```yml
|
|
342
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
343
|
+
* with:
|
|
344
|
+
* githubRepo: "some-other/repo" # Defaults to the current repo
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
githubRepo?: `${string}/${string}`;
|
|
348
|
+
/**
|
|
349
|
+
* A github API token with access to the repo for creating a release.
|
|
350
|
+
*
|
|
351
|
+
* JS Usage:
|
|
352
|
+
*
|
|
353
|
+
* ```ts
|
|
354
|
+
* await release({
|
|
355
|
+
* githubToken: process.env.GITHUB_TOKEN!,
|
|
356
|
+
* });
|
|
357
|
+
* ```
|
|
358
|
+
*
|
|
359
|
+
* GitHub Actions:
|
|
360
|
+
*
|
|
361
|
+
* ```yml
|
|
362
|
+
* - uses: aklinker1/zero-changelog/actions/release
|
|
363
|
+
* with:
|
|
364
|
+
* githubToken: ${{ secrets.GITHUB_TOKEN }}
|
|
365
|
+
* ```
|
|
366
|
+
*
|
|
367
|
+
* @default process.env.GITHUB_TOKEN
|
|
368
|
+
*/
|
|
369
|
+
githubToken?: string;
|
|
370
|
+
/**
|
|
371
|
+
* Set to false to prevent marking the github release as "latest"
|
|
372
|
+
*
|
|
373
|
+
* @default true
|
|
374
|
+
*/
|
|
375
|
+
latestRelease?: boolean;
|
|
376
|
+
};
|
|
377
|
+
type ReleaseMeta = {
|
|
378
|
+
/** The new version it was bumped to. */version: string; /** The tag used. */
|
|
379
|
+
tag: string; /** The release notes added to the changelog for the version */
|
|
380
|
+
releaseNotes: string;
|
|
381
|
+
};
|
|
382
|
+
declare function release(options: ReleaseOptions): Promise<ReleaseMeta>;
|
|
383
|
+
//#endregion
|
|
384
|
+
export { ReleaseMeta, ReleaseOptions, release };
|
package/dist/release.mjs
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createGithubRelease } from "./create-github-release.mjs";
|
|
2
|
+
import { detectVersionBump } from "./detect-version-bump.mjs";
|
|
3
|
+
import { t as findPreviousTag } from "./find-previous-tag-Cj2oZAty.mjs";
|
|
4
|
+
import { getCurrentVersion } from "./get-current-version.mjs";
|
|
5
|
+
import { getGithubRepo } from "./get-github-repo.mjs";
|
|
6
|
+
import { getReleaseNotes } from "./get-release-notes.mjs";
|
|
7
|
+
import { t as listCommitsSince } from "./list-commits-since-DycWgHTi.mjs";
|
|
8
|
+
import { parseChangelog } from "./parse-changelog.mjs";
|
|
9
|
+
import { parseCommits } from "./parse-commits.mjs";
|
|
10
|
+
import { n as template } from "./utils-BO6byvK5.mjs";
|
|
11
|
+
import { isPrerelease, parseSemver } from "./semver.mjs";
|
|
12
|
+
import { serializeChangelog } from "./serialize-changelog.mjs";
|
|
13
|
+
import { updateVersionFiles } from "./update-version-files.mjs";
|
|
14
|
+
import { exec } from "node:child_process";
|
|
15
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
16
|
+
import { basename, resolve } from "node:path";
|
|
17
|
+
//#region src/internal/run.ts
|
|
18
|
+
/** Run a command, inheriting stdio. */
|
|
19
|
+
async function run(options) {
|
|
20
|
+
console.log("Running command:", options);
|
|
21
|
+
if (options.dryRun) {
|
|
22
|
+
console.log(" -> Skipping, dry run");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const child = exec(options.cmd, { cwd: options.cwd }, (error) => {
|
|
27
|
+
if (error) return reject(error);
|
|
28
|
+
else resolve();
|
|
29
|
+
});
|
|
30
|
+
child.stderr?.on("data", (data) => {
|
|
31
|
+
process.stderr.write(data);
|
|
32
|
+
});
|
|
33
|
+
child.stdout?.on("data", (data) => {
|
|
34
|
+
process.stdout.write(data);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/release.ts
|
|
40
|
+
async function release(options) {
|
|
41
|
+
const { additionalDirs = [], commitTemplate = "chore(release): v{{version}}", dryRun = false, dryRunPublishCommands, publishCommands, releaseNameTemplate = "{{tag}}", versionFiles = [
|
|
42
|
+
"package.json",
|
|
43
|
+
"jsr.json",
|
|
44
|
+
"deno.json",
|
|
45
|
+
"Cargo.toml"
|
|
46
|
+
], releaseArtifacts = [], throwOnNoChanges = false, githubToken = process.env.GITHUB_TOKEN, githubRepo = await getGithubRepo(), latestRelease = true } = options;
|
|
47
|
+
const cwd = process.cwd();
|
|
48
|
+
const path = options.path ? resolve(options.path) : cwd;
|
|
49
|
+
const dirname = basename(path);
|
|
50
|
+
const tagPrefix = path === cwd ? "v" : `${dirname}-v`;
|
|
51
|
+
if (!githubToken) throw Error("No github token provided");
|
|
52
|
+
if (!githubRepo) throw Error("No github repo provided");
|
|
53
|
+
const currentVersion = parseSemver(await getCurrentVersion(path, versionFiles));
|
|
54
|
+
const since = options.since ?? await findPreviousTag(tagPrefix);
|
|
55
|
+
const changes = parseCommits(await listCommitsSince({
|
|
56
|
+
since,
|
|
57
|
+
dirs: [path, ...additionalDirs]
|
|
58
|
+
}));
|
|
59
|
+
const bump = (options.bump?.trim() || void 0) ?? detectVersionBump(changes, throwOnNoChanges);
|
|
60
|
+
const version = currentVersion.bump(bump);
|
|
61
|
+
const tag = tagPrefix + version;
|
|
62
|
+
console.log("Bumping version to:", version);
|
|
63
|
+
console.log("Tag:", tag);
|
|
64
|
+
await updateVersionFiles(path, versionFiles, version);
|
|
65
|
+
const releaseNotes = getReleaseNotes(changes, since, tag, githubRepo);
|
|
66
|
+
const changelog = parseChangelog(await readFile("CHANGELOG.md", "utf8"));
|
|
67
|
+
changelog.unshift({
|
|
68
|
+
header: `v${version}`,
|
|
69
|
+
body: releaseNotes
|
|
70
|
+
});
|
|
71
|
+
await writeFile("CHANGELOG.md", serializeChangelog(changelog), "utf8");
|
|
72
|
+
if (dryRun && dryRunPublishCommands?.length) for (const cmd of dryRunPublishCommands) await run({
|
|
73
|
+
dryRun: false,
|
|
74
|
+
cwd: path,
|
|
75
|
+
cmd
|
|
76
|
+
});
|
|
77
|
+
else if (publishCommands?.length) for (const cmd of publishCommands) await run({
|
|
78
|
+
dryRun,
|
|
79
|
+
cwd: path,
|
|
80
|
+
cmd
|
|
81
|
+
});
|
|
82
|
+
await run({
|
|
83
|
+
dryRun,
|
|
84
|
+
cwd: path,
|
|
85
|
+
cmd: `git commit -am "${template(commitTemplate, {
|
|
86
|
+
version,
|
|
87
|
+
path,
|
|
88
|
+
dirname
|
|
89
|
+
})}"`
|
|
90
|
+
});
|
|
91
|
+
await run({
|
|
92
|
+
dryRun,
|
|
93
|
+
cwd: path,
|
|
94
|
+
cmd: `git tag ${tag}`
|
|
95
|
+
});
|
|
96
|
+
await run({
|
|
97
|
+
dryRun,
|
|
98
|
+
cwd: path,
|
|
99
|
+
cmd: "git push"
|
|
100
|
+
});
|
|
101
|
+
await run({
|
|
102
|
+
dryRun,
|
|
103
|
+
cwd: path,
|
|
104
|
+
cmd: "git push --tags"
|
|
105
|
+
});
|
|
106
|
+
await createGithubRelease({
|
|
107
|
+
repo: githubRepo,
|
|
108
|
+
token: githubToken,
|
|
109
|
+
dryRun,
|
|
110
|
+
tag,
|
|
111
|
+
name: template(releaseNameTemplate, {
|
|
112
|
+
version,
|
|
113
|
+
tag,
|
|
114
|
+
path,
|
|
115
|
+
dirname
|
|
116
|
+
}),
|
|
117
|
+
body: releaseNotes,
|
|
118
|
+
artifacts: releaseArtifacts,
|
|
119
|
+
latest: latestRelease,
|
|
120
|
+
prerelease: isPrerelease(parseSemver(version))
|
|
121
|
+
});
|
|
122
|
+
throw Error("Not implemented");
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
export { release };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/semver-type.d.ts
|
|
2
|
+
type SemverType = {
|
|
3
|
+
/** The title of the section for this type of commit in the changelog. */title: string;
|
|
4
|
+
/**
|
|
5
|
+
* Describe how this type of conventional commit should bump the version when detecting the type
|
|
6
|
+
* of version bump based on the commits.
|
|
7
|
+
*/
|
|
8
|
+
bump?: "minor" | "patch";
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { SemverType as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/semver-types/aklinker1.ts
|
|
2
|
+
const types = {
|
|
3
|
+
feat: {
|
|
4
|
+
title: "🚀 Features",
|
|
5
|
+
bump: "minor"
|
|
6
|
+
},
|
|
7
|
+
perf: {
|
|
8
|
+
title: "🔥 Performance",
|
|
9
|
+
bump: "patch"
|
|
10
|
+
},
|
|
11
|
+
fix: {
|
|
12
|
+
title: "🩹 Fixes",
|
|
13
|
+
bump: "patch"
|
|
14
|
+
},
|
|
15
|
+
refactor: {
|
|
16
|
+
title: "💅 Refactors",
|
|
17
|
+
bump: "patch"
|
|
18
|
+
},
|
|
19
|
+
docs: {
|
|
20
|
+
title: "📖 Documentation",
|
|
21
|
+
bump: "patch"
|
|
22
|
+
},
|
|
23
|
+
build: {
|
|
24
|
+
title: "📦 Build",
|
|
25
|
+
bump: "patch"
|
|
26
|
+
},
|
|
27
|
+
types: {
|
|
28
|
+
title: "🌊 Types",
|
|
29
|
+
bump: "patch"
|
|
30
|
+
},
|
|
31
|
+
chore: { title: "🏡 Chore" },
|
|
32
|
+
examples: { title: "🏀 Examples" },
|
|
33
|
+
test: { title: "✅ Tests" },
|
|
34
|
+
style: { title: "🎨 Styles" },
|
|
35
|
+
ci: { title: "🤖 CI" }
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
export { types as default };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/semver.d.ts
|
|
2
|
+
type RelativeBump = "major" | "minor" | "patch";
|
|
3
|
+
type BumpBy = RelativeBump | (string & {});
|
|
4
|
+
interface Semver {
|
|
5
|
+
type: unknown;
|
|
6
|
+
version: string;
|
|
7
|
+
bump(this: void, by: BumpBy): string;
|
|
8
|
+
compare(this: void, other: Semver): -1 | 0 | 1;
|
|
9
|
+
}
|
|
10
|
+
declare const STABLE_TYPE: unique symbol;
|
|
11
|
+
interface StableVersion extends Semver {
|
|
12
|
+
type: typeof STABLE_TYPE;
|
|
13
|
+
major: number;
|
|
14
|
+
minor: number;
|
|
15
|
+
patch: number;
|
|
16
|
+
}
|
|
17
|
+
declare function parseSemver(version: string): Semver;
|
|
18
|
+
declare function isStable(semver: Semver): semver is StableVersion;
|
|
19
|
+
declare const UNSTABLE_TYPE: unique symbol;
|
|
20
|
+
interface UnstableVersion extends Semver {
|
|
21
|
+
type: typeof UNSTABLE_TYPE;
|
|
22
|
+
major: 0;
|
|
23
|
+
minor: number;
|
|
24
|
+
patch: number;
|
|
25
|
+
}
|
|
26
|
+
declare function isUnstable(semver: Semver): semver is UnstableVersion;
|
|
27
|
+
declare const PRERELEASE_TYPE: unique symbol;
|
|
28
|
+
interface PrereleaseVersion extends Semver {
|
|
29
|
+
type: typeof PRERELEASE_TYPE;
|
|
30
|
+
major: number;
|
|
31
|
+
prerelease: number;
|
|
32
|
+
prereleaseType: PrereleaseType;
|
|
33
|
+
}
|
|
34
|
+
type PrereleaseType = "alpha" | "beta" | "rc";
|
|
35
|
+
declare function isPrerelease(semver: Semver): semver is PrereleaseVersion;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { BumpBy, PrereleaseType, PrereleaseVersion, RelativeBump, Semver, StableVersion, UnstableVersion, isPrerelease, isStable, isUnstable, parseSemver };
|