@oorabona/release-it-preset 0.11.0 → 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
@@ -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}`)
@@ -167,20 +167,67 @@ export function parseCommitsWithMultiplePrefixes(gitOutput, repoUrl) {
167
167
  return sections.length > 0 ? sections.join('\n').trim() : 'No changes yet.';
168
168
  }
169
169
  /**
170
- * Main function to populate changelog with dependency injection
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`
171
176
  */
172
- export function populateChangelog(deps) {
173
- const changelogPath = deps.getEnv('CHANGELOG_FILE') || 'CHANGELOG.md';
174
- deps.log('📝 Populating [Unreleased] section...');
175
- let latestTag;
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
176
214
  try {
177
- latestTag = deps.execSync('git describe --tags --abbrev=0 2>/dev/null', { encoding: 'utf8' }).trim();
178
- deps.log(`â„šī¸ Latest tag: ${latestTag}`);
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;
179
218
  }
180
219
  catch {
181
220
  deps.log('â„šī¸ No tags found, using all commits');
182
- latestTag = '';
221
+ return '';
183
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);
184
231
  const gitChangelogPath = deps.getEnv('GIT_CHANGELOG_PATH');
185
232
  let pathFilter = '';
186
233
  if (gitChangelogPath !== undefined && gitChangelogPath !== '') {
@@ -192,8 +239,8 @@ export function populateChangelog(deps) {
192
239
  }
193
240
  pathFilter = ` -- ${gitChangelogPath}`;
194
241
  }
195
- const gitLogCommand = latestTag
196
- ? `git log --pretty=format:"%H|%B|||END|||" ${latestTag}..HEAD${pathFilter}`
242
+ const gitLogCommand = since
243
+ ? `git log --pretty=format:"%H|%B|||END|||" ${since}..HEAD${pathFilter}`
197
244
  : `git log --pretty=format:"%H|%B|||END|||"${pathFilter}`;
198
245
  let gitOutput;
199
246
  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,6 +1,6 @@
1
1
  {
2
2
  "name": "@oorabona/release-it-preset",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Shared release-it configuration and scripts for the organisation",
5
5
  "type": "module",
6
6
  "keywords": [