@oorabona/release-it-preset 0.10.1 → 0.12.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
|
@@ -660,6 +660,8 @@ Customize behavior with environment variables:
|
|
|
660
660
|
|
|
661
661
|
### Changelog
|
|
662
662
|
- `CHANGELOG_FILE` - Changelog file path (default: `CHANGELOG.md`)
|
|
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.
|
|
663
665
|
|
|
664
666
|
### Git
|
|
665
667
|
- `GIT_COMMIT_MESSAGE` - Commit message template (default: `release: bump v${version}`)
|
|
@@ -678,6 +680,7 @@ Customize behavior with environment variables:
|
|
|
678
680
|
- `NPM_PUBLISH` - Enable npm publishing (default: `false`)
|
|
679
681
|
- `NPM_SKIP_CHECKS` - Skip npm checks (default: `false`)
|
|
680
682
|
- `NPM_ACCESS` - npm access level (default: `public`)
|
|
683
|
+
- `NPM_TAG` - Optional. When set, the npm publish step appends `--tag <value>` (e.g. `legacy-v0.10.0`). Used to assign version-named dist-tags when republishing older versions so `latest` is not overwritten. Empty / unset = npm uses `latest`.
|
|
681
684
|
|
|
682
685
|
> ℹ️ By default, the presets skip GitHub releases and npm publishing. Set `GITHUB_RELEASE=true` and/or `NPM_PUBLISH=true` in the environment (typically in CI) when you are ready to perform those steps.
|
|
683
686
|
|
package/config/base-config.js
CHANGED
|
@@ -41,15 +41,24 @@ export function createBaseGitConfig(overrides = {}) {
|
|
|
41
41
|
* @returns {Object} Npm configuration object
|
|
42
42
|
*/
|
|
43
43
|
export function createBaseNpmConfig(overrides = {}) {
|
|
44
|
+
const publishArgs = [
|
|
45
|
+
...NPM_DEFAULTS.PUBLISH_ARGS_BASE,
|
|
46
|
+
'--access',
|
|
47
|
+
process.env.NPM_ACCESS || NPM_DEFAULTS.ACCESS,
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// Optional --tag <name> for npm dist-tag control (e.g. republishing an older
|
|
51
|
+
// version without overwriting `latest`). When unset, npm uses `latest`.
|
|
52
|
+
const npmTag = process.env.NPM_TAG;
|
|
53
|
+
if (npmTag) {
|
|
54
|
+
publishArgs.push('--tag', npmTag);
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
const defaults = {
|
|
45
58
|
skipChecks: process.env.NPM_SKIP_CHECKS === 'true',
|
|
46
59
|
publish: process.env.NPM_PUBLISH === 'true',
|
|
47
60
|
versionArgs: NPM_DEFAULTS.VERSION_ARGS,
|
|
48
|
-
publishArgs
|
|
49
|
-
...NPM_DEFAULTS.PUBLISH_ARGS_BASE,
|
|
50
|
-
'--access',
|
|
51
|
-
process.env.NPM_ACCESS || NPM_DEFAULTS.ACCESS,
|
|
52
|
-
],
|
|
61
|
+
publishArgs,
|
|
53
62
|
};
|
|
54
63
|
|
|
55
64
|
return {
|
|
@@ -22,6 +22,7 @@ import { readFileSync, writeFileSync } from 'node:fs';
|
|
|
22
22
|
import { getGitHubRepoUrl } from './lib/git-utils.js';
|
|
23
23
|
import { CONVENTIONAL_COMMIT_REGEX } from './lib/commit-parser.js';
|
|
24
24
|
import { runScript } from './lib/run-script.js';
|
|
25
|
+
import { ValidationError } from './lib/errors.js';
|
|
25
26
|
/**
|
|
26
27
|
* Extract all conventional commit patterns from a commit body
|
|
27
28
|
*/
|
|
@@ -166,23 +167,81 @@ export function parseCommitsWithMultiplePrefixes(gitOutput, repoUrl) {
|
|
|
166
167
|
return sections.length > 0 ? sections.join('\n').trim() : 'No changes yet.';
|
|
167
168
|
}
|
|
168
169
|
/**
|
|
169
|
-
*
|
|
170
|
+
* Resolve the `since` baseline for changelog generation.
|
|
171
|
+
*
|
|
172
|
+
* Priority:
|
|
173
|
+
* 1. GIT_CHANGELOG_SINCE env var (any git ref — trust the user)
|
|
174
|
+
* 2. Per-package detection via `chore(<pkg>): release v` commit when GIT_CHANGELOG_PATH is set
|
|
175
|
+
* 3. Fallback: `git describe --tags --abbrev=0`
|
|
170
176
|
*/
|
|
171
|
-
export function
|
|
172
|
-
|
|
173
|
-
deps.
|
|
174
|
-
|
|
177
|
+
export function resolveSinceBaseline(deps) {
|
|
178
|
+
// 1. Explicit override wins
|
|
179
|
+
const sinceOverride = deps.getEnv('GIT_CHANGELOG_SINCE');
|
|
180
|
+
if (sinceOverride && sinceOverride.trim()) {
|
|
181
|
+
deps.log(`ℹ️ Using GIT_CHANGELOG_SINCE override: ${sinceOverride.trim()}`);
|
|
182
|
+
return sinceOverride.trim();
|
|
183
|
+
}
|
|
184
|
+
// 2. Per-package detection: only when running scoped to a subdir
|
|
185
|
+
const path = deps.getEnv('GIT_CHANGELOG_PATH');
|
|
186
|
+
if (path && path.trim()) {
|
|
187
|
+
let pkgName = '';
|
|
188
|
+
try {
|
|
189
|
+
const pkgJsonRaw = deps.readFileSync('package.json', 'utf8');
|
|
190
|
+
const pkgNameFull = JSON.parse(pkgJsonRaw).name;
|
|
191
|
+
if (pkgNameFull) {
|
|
192
|
+
pkgName = pkgNameFull.startsWith('@')
|
|
193
|
+
? (pkgNameFull.split('/').pop() ?? '')
|
|
194
|
+
: pkgNameFull;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// package.json missing or unreadable — skip per-package detection
|
|
199
|
+
}
|
|
200
|
+
if (pkgName) {
|
|
201
|
+
try {
|
|
202
|
+
const sha = deps.execSync(`git log --grep="^chore(${pkgName}): release v" -n 1 --pretty=format:"%H"`, { encoding: 'utf8' }).trim();
|
|
203
|
+
if (sha) {
|
|
204
|
+
deps.log(`ℹ️ Per-package baseline (chore(${pkgName}): release …): ${sha.substring(0, 7)}`);
|
|
205
|
+
return sha;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// fall through to tag fallback
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// 3. Fallback: existing git describe behavior
|
|
175
214
|
try {
|
|
176
|
-
|
|
177
|
-
deps.log(`ℹ️ Latest tag: ${
|
|
215
|
+
const tag = deps.execSync('git describe --tags --abbrev=0 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
216
|
+
deps.log(`ℹ️ Latest tag: ${tag}`);
|
|
217
|
+
return tag;
|
|
178
218
|
}
|
|
179
219
|
catch {
|
|
180
220
|
deps.log('ℹ️ No tags found, using all commits');
|
|
181
|
-
|
|
221
|
+
return '';
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Main function to populate changelog with dependency injection
|
|
226
|
+
*/
|
|
227
|
+
export function populateChangelog(deps) {
|
|
228
|
+
const changelogPath = deps.getEnv('CHANGELOG_FILE') || 'CHANGELOG.md';
|
|
229
|
+
deps.log('📝 Populating [Unreleased] section...');
|
|
230
|
+
const since = resolveSinceBaseline(deps);
|
|
231
|
+
const gitChangelogPath = deps.getEnv('GIT_CHANGELOG_PATH');
|
|
232
|
+
let pathFilter = '';
|
|
233
|
+
if (gitChangelogPath !== undefined && gitChangelogPath !== '') {
|
|
234
|
+
// Validate: must be a relative path — no leading slash, no ".." segments, no shell metacharacters
|
|
235
|
+
if (gitChangelogPath.startsWith('/') ||
|
|
236
|
+
/(^|[/\\])\.\.([/\\]|$)/.test(gitChangelogPath) ||
|
|
237
|
+
/[`$;&|<>{}()\\*?!#"']/.test(gitChangelogPath)) {
|
|
238
|
+
throw new ValidationError(`GIT_CHANGELOG_PATH must be a relative path under the repository (got: ${gitChangelogPath})`);
|
|
239
|
+
}
|
|
240
|
+
pathFilter = ` -- ${gitChangelogPath}`;
|
|
182
241
|
}
|
|
183
|
-
const gitLogCommand =
|
|
184
|
-
? `git log --pretty=format:"%H|%B|||END|||" ${
|
|
185
|
-
: `git log --pretty=format:"%H|%B|||END|||"`;
|
|
242
|
+
const gitLogCommand = since
|
|
243
|
+
? `git log --pretty=format:"%H|%B|||END|||" ${since}..HEAD${pathFilter}`
|
|
244
|
+
: `git log --pretty=format:"%H|%B|||END|||"${pathFilter}`;
|
|
186
245
|
let gitOutput;
|
|
187
246
|
try {
|
|
188
247
|
gitOutput = deps.execSync(gitLogCommand, { encoding: 'utf8' }).trim();
|
|
@@ -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
|
*/
|