@oorabona/release-it-preset 0.11.0 â 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -661,6 +661,7 @@ Customize behavior with environment variables:
|
|
|
661
661
|
### Changelog
|
|
662
662
|
- `CHANGELOG_FILE` - Changelog file path (default: `CHANGELOG.md`)
|
|
663
663
|
- `GIT_CHANGELOG_PATH` - Optional. When set to a repository-relative path (e.g. `packages/tar-xz`), restrict changelog generation to commits touching that path. Useful for monorepo per-package CHANGELOG files. Empty / unset = repository-wide (default).
|
|
664
|
+
- `GIT_CHANGELOG_SINCE` - Optional. Override the `since` baseline for changelog generation (any git ref: SHA, tag, branch). When set, bypasses both the per-package release-commit detection and the `git describe --tags` fallback. Useful for monorepo workspaces with non-standard release commit patterns. Empty / unset = use auto-detection.
|
|
664
665
|
|
|
665
666
|
### Git
|
|
666
667
|
- `GIT_COMMIT_MESSAGE` - Commit message template (default: `release: bump v${version}`)
|
|
@@ -95,7 +95,41 @@ export function parseCommitsWithMultiplePrefixes(gitOutput, repoUrl) {
|
|
|
95
95
|
}
|
|
96
96
|
if (sha && body) {
|
|
97
97
|
const shortSha = sha.trim().substring(0, 7);
|
|
98
|
-
|
|
98
|
+
// Compute the header block: first contiguous run of non-empty lines.
|
|
99
|
+
// This prevents paragraph-separated footer tokens like "Refs: #42" or
|
|
100
|
+
// "Co-authored-by: ..." from matching the conventional-commit regex
|
|
101
|
+
// via the 'gm' flag in extractConventionalCommitParts. AC#5 (consecutive
|
|
102
|
+
// multi-prefix lines) is preserved because those lines share no blank line.
|
|
103
|
+
const headerBlock = body.split('\n').reduce((acc, line) => {
|
|
104
|
+
if (!acc.done) {
|
|
105
|
+
if (line.trim() === '') {
|
|
106
|
+
acc.done = true;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
acc.lines.push(line);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return acc;
|
|
113
|
+
}, { lines: [], done: false }).lines.join('\n');
|
|
114
|
+
const parts = extractConventionalCommitParts(headerBlock, shortSha);
|
|
115
|
+
// Detect "BREAKING CHANGE:" trailer in the full body (not just header).
|
|
116
|
+
// This handles the footer-style breaking annotation per Conventional Commits spec.
|
|
117
|
+
const breakingFooterMatch = /^BREAKING[- ]CHANGE:\s*(.+)/m.exec(body);
|
|
118
|
+
if (breakingFooterMatch) {
|
|
119
|
+
if (parts.length > 0) {
|
|
120
|
+
// Promote the first emitted part to breaking.
|
|
121
|
+
parts[0] = { ...parts[0], breaking: true };
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// No leading conventional prefix found; emit a standalone breaking entry.
|
|
125
|
+
parts.push({
|
|
126
|
+
type: 'misc',
|
|
127
|
+
description: breakingFooterMatch[1].trim(),
|
|
128
|
+
sha: shortSha,
|
|
129
|
+
breaking: true,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
99
133
|
if (parts.length === 0) {
|
|
100
134
|
const firstLine = body.split('\n')[0].trim();
|
|
101
135
|
if (firstLine) {
|
|
@@ -167,20 +201,67 @@ export function parseCommitsWithMultiplePrefixes(gitOutput, repoUrl) {
|
|
|
167
201
|
return sections.length > 0 ? sections.join('\n').trim() : 'No changes yet.';
|
|
168
202
|
}
|
|
169
203
|
/**
|
|
170
|
-
*
|
|
204
|
+
* Resolve the `since` baseline for changelog generation.
|
|
205
|
+
*
|
|
206
|
+
* Priority:
|
|
207
|
+
* 1. GIT_CHANGELOG_SINCE env var (any git ref â trust the user)
|
|
208
|
+
* 2. Per-package detection via `chore(<pkg>): release v` commit when GIT_CHANGELOG_PATH is set
|
|
209
|
+
* 3. Fallback: `git describe --tags --abbrev=0`
|
|
171
210
|
*/
|
|
172
|
-
export function
|
|
173
|
-
|
|
174
|
-
deps.
|
|
175
|
-
|
|
211
|
+
export function resolveSinceBaseline(deps) {
|
|
212
|
+
// 1. Explicit override wins
|
|
213
|
+
const sinceOverride = deps.getEnv('GIT_CHANGELOG_SINCE');
|
|
214
|
+
if (sinceOverride && sinceOverride.trim()) {
|
|
215
|
+
deps.log(`âšī¸ Using GIT_CHANGELOG_SINCE override: ${sinceOverride.trim()}`);
|
|
216
|
+
return sinceOverride.trim();
|
|
217
|
+
}
|
|
218
|
+
// 2. Per-package detection: only when running scoped to a subdir
|
|
219
|
+
const path = deps.getEnv('GIT_CHANGELOG_PATH');
|
|
220
|
+
if (path && path.trim()) {
|
|
221
|
+
let pkgName = '';
|
|
222
|
+
try {
|
|
223
|
+
const pkgJsonRaw = deps.readFileSync('package.json', 'utf8');
|
|
224
|
+
const pkgNameFull = JSON.parse(pkgJsonRaw).name;
|
|
225
|
+
if (pkgNameFull) {
|
|
226
|
+
pkgName = pkgNameFull.startsWith('@')
|
|
227
|
+
? (pkgNameFull.split('/').pop() ?? '')
|
|
228
|
+
: pkgNameFull;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// package.json missing or unreadable â skip per-package detection
|
|
233
|
+
}
|
|
234
|
+
if (pkgName) {
|
|
235
|
+
try {
|
|
236
|
+
const sha = deps.execSync(`git log --grep="^chore(${pkgName}): release v" -n 1 --pretty=format:"%H"`, { encoding: 'utf8' }).trim();
|
|
237
|
+
if (sha) {
|
|
238
|
+
deps.log(`âšī¸ Per-package baseline (chore(${pkgName}): release âĻ): ${sha.substring(0, 7)}`);
|
|
239
|
+
return sha;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// fall through to tag fallback
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// 3. Fallback: existing git describe behavior
|
|
176
248
|
try {
|
|
177
|
-
|
|
178
|
-
deps.log(`âšī¸ Latest tag: ${
|
|
249
|
+
const tag = deps.execSync('git describe --tags --abbrev=0 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
250
|
+
deps.log(`âšī¸ Latest tag: ${tag}`);
|
|
251
|
+
return tag;
|
|
179
252
|
}
|
|
180
253
|
catch {
|
|
181
254
|
deps.log('âšī¸ No tags found, using all commits');
|
|
182
|
-
|
|
255
|
+
return '';
|
|
183
256
|
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Main function to populate changelog with dependency injection
|
|
260
|
+
*/
|
|
261
|
+
export function populateChangelog(deps) {
|
|
262
|
+
const changelogPath = deps.getEnv('CHANGELOG_FILE') || 'CHANGELOG.md';
|
|
263
|
+
deps.log('đ Populating [Unreleased] section...');
|
|
264
|
+
const since = resolveSinceBaseline(deps);
|
|
184
265
|
const gitChangelogPath = deps.getEnv('GIT_CHANGELOG_PATH');
|
|
185
266
|
let pathFilter = '';
|
|
186
267
|
if (gitChangelogPath !== undefined && gitChangelogPath !== '') {
|
|
@@ -192,8 +273,8 @@ export function populateChangelog(deps) {
|
|
|
192
273
|
}
|
|
193
274
|
pathFilter = ` -- ${gitChangelogPath}`;
|
|
194
275
|
}
|
|
195
|
-
const gitLogCommand =
|
|
196
|
-
? `git log --pretty=format:"%H|%B|||END|||" ${
|
|
276
|
+
const gitLogCommand = since
|
|
277
|
+
? `git log --pretty=format:"%H|%B|||END|||" ${since}..HEAD${pathFilter}`
|
|
197
278
|
: `git log --pretty=format:"%H|%B|||END|||"${pathFilter}`;
|
|
198
279
|
let gitOutput;
|
|
199
280
|
try {
|
|
@@ -50,6 +50,15 @@ export declare function normalizeCommitType(type: string): string | false;
|
|
|
50
50
|
* Parse git log output and extract all conventional commit parts
|
|
51
51
|
*/
|
|
52
52
|
export declare function parseCommitsWithMultiplePrefixes(gitOutput: string, repoUrl: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the `since` baseline for changelog generation.
|
|
55
|
+
*
|
|
56
|
+
* Priority:
|
|
57
|
+
* 1. GIT_CHANGELOG_SINCE env var (any git ref â trust the user)
|
|
58
|
+
* 2. Per-package detection via `chore(<pkg>): release v` commit when GIT_CHANGELOG_PATH is set
|
|
59
|
+
* 3. Fallback: `git describe --tags --abbrev=0`
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveSinceBaseline(deps: PopulateChangelogDeps): string;
|
|
53
62
|
/**
|
|
54
63
|
* Main function to populate changelog with dependency injection
|
|
55
64
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oorabona/release-it-preset",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Shared release-it
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"description": "Shared release-it preset with OIDC trusted publishing, smart npm dist-tag selection, and monorepo per-package changelog support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"release-it",
|
|
@@ -9,7 +9,16 @@
|
|
|
9
9
|
"version",
|
|
10
10
|
"changelog",
|
|
11
11
|
"conventional-commits",
|
|
12
|
-
"keep-a-changelog"
|
|
12
|
+
"keep-a-changelog",
|
|
13
|
+
"monorepo",
|
|
14
|
+
"npm-publish",
|
|
15
|
+
"provenance",
|
|
16
|
+
"oidc",
|
|
17
|
+
"trusted-publishing",
|
|
18
|
+
"github-actions",
|
|
19
|
+
"automation",
|
|
20
|
+
"typescript",
|
|
21
|
+
"semver"
|
|
13
22
|
],
|
|
14
23
|
"author": "Olivier Orabona",
|
|
15
24
|
"license": "MIT",
|