relizy 1.4.5 → 1.4.6

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/dist/cli.mjs CHANGED
@@ -5,7 +5,7 @@ import process from 'node:process';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { printBanner, logger } from '@maz-ui/node';
7
7
  import { Command } from 'commander';
8
- import { aq as isInCI, ar as getCIName, b as bump, c as changelog, g as publish, e as providerRelease, h as social, p as prComment, r as release } from './shared/relizy.-Cr2hO3N.mjs';
8
+ import { aq as isInCI, ar as getCIName, b as bump, c as changelog, g as publish, e as providerRelease, h as social, p as prComment, r as release } from './shared/relizy.CzL6Efad.mjs';
9
9
  import 'node:child_process';
10
10
  import '@maz-ui/utils';
11
11
  import 'c12';
package/dist/index.d.mts CHANGED
@@ -88,19 +88,41 @@ type ResolvedRelizyConfig = ResolvedConfig & {
88
88
  declare function defineConfig(config: RelizyConfig): RelizyConfig;
89
89
 
90
90
  /**
91
- * Generate changelog for a specific package
91
+ * Controls which sections of the rendered changelog are produced.
92
+ * Each flag defaults to `true`. `compareLink` and `contributors` are
93
+ * additionally suppressed when `minify: true` (see `generateChangelog`).
92
94
  */
93
- declare function generateChangelog({ pkg, config, dryRun, newVersion, minify, }: {
95
+ interface ChangelogInclude {
96
+ title?: boolean;
97
+ compareLink?: boolean;
98
+ body?: boolean;
99
+ contributors?: boolean;
100
+ }
101
+ /**
102
+ * Generate the changelog string for a single package.
103
+ *
104
+ * - Fetches commits internally using `changelog: true`, so types that only
105
+ * declare a `title` (e.g. `docs: { title: '📖 Documentation' }`) are
106
+ * included even though they don't trigger a version bump. Callers must
107
+ * provide `pkg.path` — `pkg.commits` is no longer consumed.
108
+ * - `include` toggles which sections appear in the output. `compareLink`
109
+ * and `contributors` are also skipped when `minify` is true.
110
+ * - `transformBody` is invoked between body rendering and final assembly,
111
+ * used by provider releases to plug an AI rewrite step on the body only.
112
+ */
113
+ declare function generateChangelog({ pkg, config, dryRun, newVersion, minify, include, transformBody, }: {
94
114
  pkg: {
95
115
  fromTag?: string;
96
116
  name: string;
117
+ path: string;
97
118
  newVersion?: string;
98
- commits: GitCommit[];
99
119
  };
100
120
  config: ResolvedRelizyConfig;
101
121
  dryRun: boolean;
102
122
  newVersion: string;
103
123
  minify?: boolean;
124
+ include?: ChangelogInclude;
125
+ transformBody?: (body: string) => Promise<string> | string;
104
126
  }): Promise<string>;
105
127
  /**
106
128
  * Write changelog to file
@@ -1876,4 +1898,4 @@ declare function socialSafetyCheck({ config }: {
1876
1898
  declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
1877
1899
 
1878
1900
  export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
1879
- export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
1901
+ export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogInclude, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
package/dist/index.d.ts CHANGED
@@ -88,19 +88,41 @@ type ResolvedRelizyConfig = ResolvedConfig & {
88
88
  declare function defineConfig(config: RelizyConfig): RelizyConfig;
89
89
 
90
90
  /**
91
- * Generate changelog for a specific package
91
+ * Controls which sections of the rendered changelog are produced.
92
+ * Each flag defaults to `true`. `compareLink` and `contributors` are
93
+ * additionally suppressed when `minify: true` (see `generateChangelog`).
92
94
  */
93
- declare function generateChangelog({ pkg, config, dryRun, newVersion, minify, }: {
95
+ interface ChangelogInclude {
96
+ title?: boolean;
97
+ compareLink?: boolean;
98
+ body?: boolean;
99
+ contributors?: boolean;
100
+ }
101
+ /**
102
+ * Generate the changelog string for a single package.
103
+ *
104
+ * - Fetches commits internally using `changelog: true`, so types that only
105
+ * declare a `title` (e.g. `docs: { title: '📖 Documentation' }`) are
106
+ * included even though they don't trigger a version bump. Callers must
107
+ * provide `pkg.path` — `pkg.commits` is no longer consumed.
108
+ * - `include` toggles which sections appear in the output. `compareLink`
109
+ * and `contributors` are also skipped when `minify` is true.
110
+ * - `transformBody` is invoked between body rendering and final assembly,
111
+ * used by provider releases to plug an AI rewrite step on the body only.
112
+ */
113
+ declare function generateChangelog({ pkg, config, dryRun, newVersion, minify, include, transformBody, }: {
94
114
  pkg: {
95
115
  fromTag?: string;
96
116
  name: string;
117
+ path: string;
97
118
  newVersion?: string;
98
- commits: GitCommit[];
99
119
  };
100
120
  config: ResolvedRelizyConfig;
101
121
  dryRun: boolean;
102
122
  newVersion: string;
103
123
  minify?: boolean;
124
+ include?: ChangelogInclude;
125
+ transformBody?: (body: string) => Promise<string> | string;
104
126
  }): Promise<string>;
105
127
  /**
106
128
  * Write changelog to file
@@ -1876,4 +1898,4 @@ declare function socialSafetyCheck({ config }: {
1876
1898
  declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
1877
1899
 
1878
1900
  export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
1879
- export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
1901
+ export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogInclude, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { ak as NEW_PACKAGE_MARKER, $ as PR_COMMENT_MARKER, M as buildChangelogBody, a as buildCommentBody, L as buildCompareLink, O as buildContributors, b as bump, ay as capReleaseTypeForZeroMajor, c as changelog, v as checkGitStatusIfDirty, N as collectContributorNames, X as collectPackageBumps, aM as confirmBump, B as createCommitAndTags, J as createGitlabRelease, k as defineConfig, y as detectGitProvider, R as detectPackageManager, _ as detectPullRequest, S as determinePublishTag, aA as determineReleaseType, az as determineSemverChange, at as executeBuildCmd, as as executeFormatCmd, ap as executeHook, q as expandPackagesToBumpWithDependents, ad as extractChangelogSummary, aE as extractVersionFromPackageTag, aP as extractVersionFromTag, x as fetchGitTags, av as filterOutPrivatePackages, Y as findGitHubPR, Z as findGitLabMR, a9 as formatChangelogForSlack, aa as formatPackagesForSlack, ab as formatSlackMessage, an as formatTweetMessage, i as generateChangelog, P as generateMarkDown, V as getAuthCommand, aN as getBumpedIndependentPackages, aL as getBumpedPackageIndependently, ar as getCIName, aQ as getCanaryVersion, F as getCurrentGitBranch, G as getCurrentGitRef, j as getDefaultConfig, o as getDependentsOf, E as getFirstCommit, u as getGitStatus, af as getIndependentTag, aj as getLastPackageTag, ai as getLastRepoTag, ag as getLastStableTag, ah as getLastTag, A as getModifiedReleaseFilePatterns, a5 as getPackageCommits, n as getPackageDependencies, aC as getPackageNewVersion, a4 as getPackages, aw as getPackagesOrBumpedPackages, U as getPackagesToPublishInIndependentMode, T as getPackagesToPublishInSelectiveMode, aJ as getPreid, ae as getReleaseUrl, a2 as getRootPackage, H as getShortCommitSha, a7 as getSlackToken, a8 as getSlackWebhookUrl, am as getTwitterCredentials, I as github, K as gitlab, a6 as hasLernaJson, au as isBumpedPackage, aK as isChangedPreid, aI as isGraduating, ax as isGraduatingToStableBetweenVersion, aq as isInCI, aF as isPrerelease, aH as isPrereleaseReleaseType, aG as isStableReleaseType, aR as isTagVersionCompatibleWithCurrent, l as loadRelizyConfig, m as mergeTypes, Q as parseChangelogMarkdown, z as parseGitRemoteUrl, a0 as postPrComment, ac as postReleaseToSlack, ao as postReleaseToTwitter, p as prComment, e as providerRelease, d as providerReleaseSafetyCheck, g as publish, W as publishPackage, f as publishSafetyCheck, C as pushCommitAndTags, a1 as readPackageJson, a3 as readPackages, r as release, al as resolveTags, D as rollbackModifiedFiles, aO as shouldFilterPrereleaseTags, h as social, s as socialSafetyCheck, t as topologicalSort, aD as updateLernaVersion, w as writeChangelogToFile, aB as writeVersion } from './shared/relizy.-Cr2hO3N.mjs';
1
+ export { ak as NEW_PACKAGE_MARKER, $ as PR_COMMENT_MARKER, M as buildChangelogBody, a as buildCommentBody, L as buildCompareLink, O as buildContributors, b as bump, ay as capReleaseTypeForZeroMajor, c as changelog, v as checkGitStatusIfDirty, N as collectContributorNames, X as collectPackageBumps, aM as confirmBump, B as createCommitAndTags, J as createGitlabRelease, k as defineConfig, y as detectGitProvider, R as detectPackageManager, _ as detectPullRequest, S as determinePublishTag, aA as determineReleaseType, az as determineSemverChange, at as executeBuildCmd, as as executeFormatCmd, ap as executeHook, q as expandPackagesToBumpWithDependents, ad as extractChangelogSummary, aE as extractVersionFromPackageTag, aP as extractVersionFromTag, x as fetchGitTags, av as filterOutPrivatePackages, Y as findGitHubPR, Z as findGitLabMR, a9 as formatChangelogForSlack, aa as formatPackagesForSlack, ab as formatSlackMessage, an as formatTweetMessage, i as generateChangelog, P as generateMarkDown, V as getAuthCommand, aN as getBumpedIndependentPackages, aL as getBumpedPackageIndependently, ar as getCIName, aQ as getCanaryVersion, F as getCurrentGitBranch, G as getCurrentGitRef, j as getDefaultConfig, o as getDependentsOf, E as getFirstCommit, u as getGitStatus, af as getIndependentTag, aj as getLastPackageTag, ai as getLastRepoTag, ag as getLastStableTag, ah as getLastTag, A as getModifiedReleaseFilePatterns, a5 as getPackageCommits, n as getPackageDependencies, aC as getPackageNewVersion, a4 as getPackages, aw as getPackagesOrBumpedPackages, U as getPackagesToPublishInIndependentMode, T as getPackagesToPublishInSelectiveMode, aJ as getPreid, ae as getReleaseUrl, a2 as getRootPackage, H as getShortCommitSha, a7 as getSlackToken, a8 as getSlackWebhookUrl, am as getTwitterCredentials, I as github, K as gitlab, a6 as hasLernaJson, au as isBumpedPackage, aK as isChangedPreid, aI as isGraduating, ax as isGraduatingToStableBetweenVersion, aq as isInCI, aF as isPrerelease, aH as isPrereleaseReleaseType, aG as isStableReleaseType, aR as isTagVersionCompatibleWithCurrent, l as loadRelizyConfig, m as mergeTypes, Q as parseChangelogMarkdown, z as parseGitRemoteUrl, a0 as postPrComment, ac as postReleaseToSlack, ao as postReleaseToTwitter, p as prComment, e as providerRelease, d as providerReleaseSafetyCheck, g as publish, W as publishPackage, f as publishSafetyCheck, C as pushCommitAndTags, a1 as readPackageJson, a3 as readPackages, r as release, al as resolveTags, D as rollbackModifiedFiles, aO as shouldFilterPrereleaseTags, h as social, s as socialSafetyCheck, t as topologicalSort, aD as updateLernaVersion, w as writeChangelogToFile, aB as writeVersion } from './shared/relizy.CzL6Efad.mjs';
2
2
  import '@maz-ui/node';
3
3
  import 'node:child_process';
4
4
  import 'node:process';
@@ -2589,68 +2589,138 @@ function groupBy(items, key) {
2589
2589
  return groups;
2590
2590
  }
2591
2591
 
2592
- function fromTagIsFirstCommit(fromTag, cwd) {
2593
- return fromTag === getFirstCommit(cwd);
2592
+ function resolveSections(include) {
2593
+ return {
2594
+ title: include?.title ?? true,
2595
+ compareLink: include?.compareLink ?? true,
2596
+ body: include?.body ?? true,
2597
+ contributors: include?.contributors ?? true
2598
+ };
2594
2599
  }
2595
- async function generateChangelog({
2600
+ function resolveChangelogTags({
2596
2601
  pkg,
2597
2602
  config,
2598
- dryRun,
2599
- newVersion,
2600
- minify
2603
+ newVersion
2601
2604
  }) {
2602
- let fromTag = config.from || pkg.fromTag || getFirstCommit(config.cwd);
2603
- const isFirstCommit = fromTagIsFirstCommit(fromTag, config.cwd);
2604
- if (isFirstCommit) {
2605
- fromTag = config.monorepo?.versionMode === "independent" ? getIndependentTag({ version: "0.0.0", name: pkg.name }) : config.templates.tagBody.replace("{{newVersion}}", "0.0.0");
2605
+ const isIndependent = config.monorepo?.versionMode === "independent";
2606
+ const gitFromRef = config.from || pkg.fromTag || getFirstCommit(config.cwd);
2607
+ const isFirstCommit = gitFromRef === getFirstCommit(config.cwd);
2608
+ const displayFromTag = isFirstCommit ? isIndependent ? getIndependentTag({ version: "0.0.0", name: pkg.name }) : config.templates.tagBody.replace("{{newVersion}}", "0.0.0") : gitFromRef;
2609
+ const gitToRef = config.to || getCurrentGitRef(config.cwd);
2610
+ const displayToTag = config.to || (isIndependent ? getIndependentTag({ version: newVersion, name: pkg.name }) : config.templates.tagBody.replace("{{newVersion}}", newVersion));
2611
+ if (!displayToTag) {
2612
+ throw new Error(`No tag found for ${pkg.name}`);
2606
2613
  }
2607
- let toTag = config.to;
2608
- if (!toTag) {
2609
- toTag = config.monorepo?.versionMode === "independent" ? getIndependentTag({ version: newVersion, name: pkg.name }) : config.templates.tagBody.replace("{{newVersion}}", newVersion);
2614
+ return { gitFromRef, gitToRef, displayFromTag, displayToTag, isFirstCommit };
2615
+ }
2616
+ function renderTitle({
2617
+ fromTag,
2618
+ toTag,
2619
+ config
2620
+ }) {
2621
+ const template = config.templates?.changelogTitle || "{{oldVersion}}...{{newVersion}}";
2622
+ const changelogTitle = template.replace("{{oldVersion}}", fromTag).replace("{{newVersion}}", toTag).replace("{{date}}", (/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
2623
+ return `## ${changelogTitle}`;
2624
+ }
2625
+ async function renderChangelogParts({
2626
+ commits,
2627
+ config,
2628
+ fromTag,
2629
+ toTag,
2630
+ isFirstCommit,
2631
+ sections,
2632
+ minify,
2633
+ transformBody
2634
+ }) {
2635
+ const parts = [];
2636
+ if (sections.title) {
2637
+ parts.push(renderTitle({ fromTag, toTag, config }));
2610
2638
  }
2611
- if (!toTag) {
2612
- throw new Error(`No tag found for ${pkg.name}`);
2639
+ if (sections.compareLink && !minify) {
2640
+ const compareLink = buildCompareLink({ config, from: fromTag, to: toTag, isFirstCommit });
2641
+ if (compareLink) {
2642
+ parts.push(compareLink);
2643
+ }
2613
2644
  }
2614
- logger.debug(`Generating changelog for ${pkg.name} - from ${fromTag} to ${toTag}`);
2645
+ if (sections.body) {
2646
+ let body = buildChangelogBody({ commits, config, minify });
2647
+ if (transformBody && body) {
2648
+ body = await transformBody(body);
2649
+ }
2650
+ if (body) {
2651
+ parts.push(body);
2652
+ }
2653
+ }
2654
+ if (sections.contributors && !minify) {
2655
+ const contributors = await buildContributors({ commits, config });
2656
+ if (contributors) {
2657
+ parts.push(contributors);
2658
+ }
2659
+ }
2660
+ return parts;
2661
+ }
2662
+ function isFullChangelogOutput(sections, minify) {
2663
+ return !minify && sections.title && sections.compareLink && sections.body && sections.contributors;
2664
+ }
2665
+ async function generateChangelog({
2666
+ pkg,
2667
+ config,
2668
+ dryRun,
2669
+ newVersion,
2670
+ minify,
2671
+ include,
2672
+ transformBody
2673
+ }) {
2674
+ const sections = resolveSections(include);
2675
+ const { gitFromRef, gitToRef, displayFromTag, displayToTag, isFirstCommit } = resolveChangelogTags({ pkg, config, newVersion });
2676
+ logger.debug(`Generating changelog for ${pkg.name} - git ${gitFromRef}..${gitToRef} - display ${displayFromTag}...${displayToTag}`);
2615
2677
  try {
2616
- config = {
2617
- ...config,
2618
- from: fromTag,
2619
- to: toTag
2620
- };
2621
- const generatedChangelog = await generateMarkDown({
2622
- commits: pkg.commits,
2623
- config,
2624
- from: fromTag,
2678
+ const commits = await getPackageCommits({
2679
+ pkg,
2680
+ from: gitFromRef,
2681
+ to: gitToRef,
2682
+ config: { ...config, from: gitFromRef, to: gitToRef },
2683
+ changelog: true
2684
+ });
2685
+ const displayConfig = { ...config, from: displayFromTag, to: displayToTag };
2686
+ const parts = await renderChangelogParts({
2687
+ commits,
2688
+ config: displayConfig,
2689
+ fromTag: displayFromTag,
2690
+ toTag: displayToTag,
2625
2691
  isFirstCommit,
2626
- to: toTag,
2627
- minify
2692
+ sections,
2693
+ minify,
2694
+ transformBody
2628
2695
  });
2629
- let changelog = generatedChangelog;
2630
- if (pkg.commits.length === 0) {
2696
+ let changelog = parts.filter(Boolean).join("\n\n").trim();
2697
+ const isFullOutput = isFullChangelogOutput(sections, minify);
2698
+ if (commits.length === 0 && sections.body && isFullOutput) {
2631
2699
  changelog = `${changelog}
2632
2700
 
2633
- ${config.templates.emptyChangelogContent}`;
2701
+ ${displayConfig.templates.emptyChangelogContent}`;
2702
+ }
2703
+ if (isFullOutput) {
2704
+ const changelogResult = await executeHook("generate:changelog", displayConfig, dryRun, {
2705
+ commits,
2706
+ changelog
2707
+ });
2708
+ changelog = changelogResult || changelog;
2634
2709
  }
2635
- const changelogResult = await executeHook("generate:changelog", config, dryRun, {
2636
- commits: pkg.commits,
2637
- changelog
2638
- });
2639
- changelog = changelogResult || changelog;
2640
2710
  logger.verbose(`Output changelog for ${pkg.name}:
2641
2711
  ${changelog}`);
2642
- logger.debug(`Changelog generated for ${pkg.name} (${pkg.commits.length} commits)`);
2712
+ logger.debug(`Changelog generated for ${pkg.name} (${commits.length} commits)`);
2643
2713
  logger.verbose(`Final changelog for ${pkg.name}:
2644
2714
 
2645
2715
  ${changelog}
2646
2716
 
2647
2717
  `);
2648
2718
  if (dryRun) {
2649
- logger.info(`[dry-run] ${pkg.name} - Generate changelog ${fromTag}...${toTag}`);
2719
+ logger.info(`[dry-run] ${pkg.name} - Generate changelog ${displayFromTag}...${displayToTag}`);
2650
2720
  }
2651
2721
  return changelog;
2652
2722
  } catch (error) {
2653
- throw new Error(`Error generating changelog for ${pkg.name} (${fromTag}...${toTag}): ${getErrorMessage(error)}`, { cause: error });
2723
+ throw new Error(`Error generating changelog for ${pkg.name}: ${getErrorMessage(error)}`, { cause: error });
2654
2724
  }
2655
2725
  }
2656
2726
  function writeChangelogToFile({
@@ -2900,6 +2970,52 @@ function handleFallback(config, rawBody, error) {
2900
2970
  return rawBody;
2901
2971
  }
2902
2972
 
2973
+ async function publishIndependentRelease({
2974
+ pkg,
2975
+ config,
2976
+ dryRun,
2977
+ repoConfig
2978
+ }) {
2979
+ const newVersion = isBumpedPackage(pkg) && pkg.newVersion || pkg.version;
2980
+ const from = config.from || pkg.fromTag;
2981
+ const to = config.to || getIndependentTag({ version: newVersion, name: pkg.name });
2982
+ if (!from) {
2983
+ logger.warn(`No from tag found for ${pkg.name}, skipping release`);
2984
+ return void 0;
2985
+ }
2986
+ const toTag = dryRun ? "HEAD" : to;
2987
+ logger.debug(`Processing ${pkg.name}: ${from} \u2192 ${toTag}`);
2988
+ const releaseBody = await generateChangelog({
2989
+ pkg: { ...pkg, fromTag: from },
2990
+ config,
2991
+ dryRun,
2992
+ newVersion,
2993
+ include: { title: false, compareLink: true, body: true, contributors: true },
2994
+ transformBody: isAIProviderReleaseEnabled(config) ? (body) => generateAIProviderReleaseBody({ config, rawBody: body }) : void 0
2995
+ });
2996
+ const release = {
2997
+ tag_name: to,
2998
+ name: to,
2999
+ body: releaseBody,
3000
+ prerelease: isPrerelease(newVersion)
3001
+ };
3002
+ logger.debug(`Creating release for ${to}${release.prerelease ? " (prerelease)" : ""}`);
3003
+ if (dryRun) {
3004
+ logger.info(`[dry-run] Publish GitHub release for ${release.tag_name}`);
3005
+ logger.box("[dry-run] Release Preview", `Tag: ${release.tag_name}
3006
+
3007
+ ${releaseBody}`);
3008
+ } else {
3009
+ logger.debug(`Publishing release ${to} to GitHub...`);
3010
+ await createGithubRelease({ ...config, from, to, repo: repoConfig }, release);
3011
+ }
3012
+ return {
3013
+ name: pkg.name,
3014
+ tag: release.tag_name,
3015
+ version: newVersion,
3016
+ prerelease: release.prerelease
3017
+ };
3018
+ }
2903
3019
  async function githubIndependentMode({
2904
3020
  config,
2905
3021
  dryRun,
@@ -2924,55 +3040,9 @@ async function githubIndependentMode({
2924
3040
  logger.info(`Creating ${packages.length} GitHub release(s)`);
2925
3041
  const postedReleases = [];
2926
3042
  for (const pkg of packages) {
2927
- const newVersion = isBumpedPackage(pkg) && pkg.newVersion || pkg.version;
2928
- const from = config.from || pkg.fromTag;
2929
- const to = config.to || getIndependentTag({ version: newVersion, name: pkg.name });
2930
- if (!from) {
2931
- logger.warn(`No from tag found for ${pkg.name}, skipping release`);
2932
- continue;
2933
- }
2934
- const toTag = dryRun ? "HEAD" : to;
2935
- logger.debug(`Processing ${pkg.name}: ${from} \u2192 ${toTag}`);
2936
- const isFirstCommit = from === getFirstCommit(config.cwd);
2937
- const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
2938
- let body = buildChangelogBody({ commits: pkg.commits, config });
2939
- const contributors = await buildContributors({ commits: pkg.commits, config });
2940
- if (isAIProviderReleaseEnabled(config)) {
2941
- body = await generateAIProviderReleaseBody({ config, rawBody: body });
2942
- }
2943
- const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
2944
- const release = {
2945
- tag_name: to,
2946
- name: to,
2947
- body: releaseBody,
2948
- prerelease: isPrerelease(newVersion)
2949
- };
2950
- logger.debug(`Creating release for ${to}${release.prerelease ? " (prerelease)" : ""}`);
2951
- if (dryRun) {
2952
- logger.info(`[dry-run] Publish GitHub release for ${release.tag_name}`);
2953
- postedReleases.push({
2954
- name: pkg.name,
2955
- tag: release.tag_name,
2956
- version: newVersion,
2957
- prerelease: release.prerelease
2958
- });
2959
- logger.box("[dry-run] Release Preview", `Tag: ${release.tag_name}
2960
-
2961
- ${releaseBody}`);
2962
- } else {
2963
- logger.debug(`Publishing release ${to} to GitHub...`);
2964
- await createGithubRelease({
2965
- ...config,
2966
- from,
2967
- to,
2968
- repo: repoConfig
2969
- }, release);
2970
- postedReleases.push({
2971
- name: pkg.name,
2972
- tag: release.tag_name,
2973
- version: newVersion,
2974
- prerelease: release.prerelease
2975
- });
3043
+ const posted = await publishIndependentRelease({ pkg, config, dryRun, repoConfig });
3044
+ if (posted) {
3045
+ postedReleases.push(posted);
2976
3046
  }
2977
3047
  }
2978
3048
  if (postedReleases.length === 0) {
@@ -3000,14 +3070,14 @@ async function githubUnified({
3000
3070
  const to = config.to || config.templates.tagBody.replace("{{newVersion}}", newVersion);
3001
3071
  const firstCommit = getFirstCommit(config.cwd);
3002
3072
  const from = config.from || rootPackage.fromTag || firstCommit;
3003
- const isFirstCommit = from === firstCommit;
3004
- const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
3005
- let body = buildChangelogBody({ commits: rootPackage.commits, config });
3006
- const contributors = await buildContributors({ commits: rootPackage.commits, config });
3007
- if (isAIProviderReleaseEnabled(config)) {
3008
- body = await generateAIProviderReleaseBody({ config, rawBody: body });
3009
- }
3010
- const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
3073
+ const releaseBody = await generateChangelog({
3074
+ pkg: { ...rootPackage, fromTag: from },
3075
+ config,
3076
+ dryRun,
3077
+ newVersion,
3078
+ include: { title: false, compareLink: true, body: true, contributors: true },
3079
+ transformBody: isAIProviderReleaseEnabled(config) ? (body) => generateAIProviderReleaseBody({ config, rawBody: body }) : void 0
3080
+ });
3011
3081
  const release = {
3012
3082
  tag_name: to,
3013
3083
  name: to,
@@ -3193,18 +3263,25 @@ async function gitlabIndependentMode({
3193
3263
  continue;
3194
3264
  }
3195
3265
  logger.debug(`Processing ${pkg.name}: ${from} \u2192 ${to}`);
3196
- const isFirstCommit = from === getFirstCommit(config.cwd);
3197
- const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
3198
- let body = buildChangelogBody({ commits: pkg.commits, config });
3199
- const contributors = await buildContributors({ commits: pkg.commits, config });
3200
- if (!body) {
3266
+ const bodyOnly = await generateChangelog({
3267
+ pkg: { ...pkg, fromTag: from },
3268
+ config,
3269
+ dryRun,
3270
+ newVersion,
3271
+ include: { title: false, compareLink: false, body: true, contributors: false }
3272
+ });
3273
+ if (!bodyOnly.trim()) {
3201
3274
  logger.warn(`No changelog found for ${pkg.name}`);
3202
3275
  continue;
3203
3276
  }
3204
- if (isAIProviderReleaseEnabled(config)) {
3205
- body = await generateAIProviderReleaseBody({ config, rawBody: body });
3206
- }
3207
- const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
3277
+ const releaseBody = await generateChangelog({
3278
+ pkg: { ...pkg, fromTag: from },
3279
+ config,
3280
+ dryRun,
3281
+ newVersion,
3282
+ include: { title: false, compareLink: true, body: true, contributors: true },
3283
+ transformBody: isAIProviderReleaseEnabled(config) ? (body) => generateAIProviderReleaseBody({ config, rawBody: body }) : void 0
3284
+ });
3208
3285
  const release = {
3209
3286
  tag_name: to,
3210
3287
  name: to,
@@ -3250,14 +3327,14 @@ async function gitlabUnified({
3250
3327
  const to = config.templates.tagBody.replace("{{newVersion}}", newVersion);
3251
3328
  const firstCommit = getFirstCommit(config.cwd);
3252
3329
  const from = config.from || rootPackage.fromTag || firstCommit;
3253
- const isFirstCommit = from === firstCommit;
3254
- const compareLink = buildCompareLink({ config, from, to, isFirstCommit });
3255
- let body = buildChangelogBody({ commits: rootPackage.commits, config });
3256
- const contributors = await buildContributors({ commits: rootPackage.commits, config });
3257
- if (isAIProviderReleaseEnabled(config)) {
3258
- body = await generateAIProviderReleaseBody({ config, rawBody: body });
3259
- }
3260
- const releaseBody = [compareLink, body, contributors].filter(Boolean).join("\n\n").trim();
3330
+ const releaseBody = await generateChangelog({
3331
+ pkg: { ...rootPackage, fromTag: from },
3332
+ config,
3333
+ dryRun,
3334
+ newVersion,
3335
+ include: { title: false, compareLink: true, body: true, contributors: true },
3336
+ transformBody: isAIProviderReleaseEnabled(config) ? (body) => generateAIProviderReleaseBody({ config, rawBody: body }) : void 0
3337
+ });
3261
3338
  logger.debug("Getting current branch...");
3262
3339
  const { stdout: currentBranch } = await execPromise("git rev-parse --abbrev-ref HEAD", {
3263
3340
  noSuccess: true,
@@ -3754,7 +3831,7 @@ function extractChangelogSummary(changelog, { stripBoldMarkers = false, maxLengt
3754
3831
  if (changelog.trim() === "") {
3755
3832
  return "";
3756
3833
  }
3757
- let cleaned = changelog.split("\n").filter((line) => !line.startsWith("#")).join("\n");
3834
+ let cleaned = changelog.split("\n").filter((line) => !line.startsWith("#") && line.trim() !== "").join("\n");
3758
3835
  if (stripBoldMarkers) {
3759
3836
  cleaned = cleaned.replace(/\*\*([^*]+):\*\*/g, "$1:");
3760
3837
  }
@@ -3814,7 +3891,7 @@ function formatPackagesForSlack(packages) {
3814
3891
  return "";
3815
3892
  }
3816
3893
  return packages.map(
3817
- (pkg) => pkg.hasTransition ? `\u2022 **${pkg.name}** : \`${pkg.oldVersion}\` \u2192 \`${pkg.newVersion}\`` : `\u2022 **${pkg.name}** : \`${pkg.version}\``
3894
+ (pkg) => pkg.hasTransition ? `\u2022 *${pkg.name}* : \`${pkg.oldVersion}\` \u2192 \`${pkg.newVersion}\`` : `\u2022 *${pkg.name}* : \`${pkg.version}\``
3818
3895
  ).join("\n");
3819
3896
  }
3820
3897
  function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors = [], packages = [], postMaxLength = 2500 }) {
@@ -4627,11 +4704,12 @@ async function generateIndependentRootChangelog({
4627
4704
  logger.debug("Generating aggregated root changelog for independent mode");
4628
4705
  const packageChangelogs = [];
4629
4706
  for (const pkg of packages) {
4707
+ const newVersion = isBumpedPackage(pkg) && pkg.newVersion || pkg.version;
4630
4708
  const changelog2 = await generateChangelog({
4631
4709
  pkg,
4632
4710
  config,
4633
4711
  dryRun,
4634
- newVersion: isBumpedPackage(pkg) && pkg.newVersion || pkg.version
4712
+ newVersion
4635
4713
  });
4636
4714
  if (changelog2) {
4637
4715
  packageChangelogs.push(changelog2);
@@ -4769,13 +4847,7 @@ async function changelog(options = {}) {
4769
4847
  let generatedCount = 0;
4770
4848
  for await (const pkg of packages) {
4771
4849
  const newVersion = options.bumpResult?.bumpedPackages?.find((p) => p.name === pkg.name)?.newVersion || pkg.newVersion || pkg.version;
4772
- const { from, to } = await resolveTags({
4773
- config,
4774
- step: "changelog",
4775
- pkg,
4776
- newVersion
4777
- });
4778
- logger.debug(`Processing ${pkg.name} (${from}...${to})`);
4850
+ logger.debug(`Processing ${pkg.name}`);
4779
4851
  const changelog2 = await generateChangelog({
4780
4852
  pkg,
4781
4853
  config,
@@ -5574,8 +5646,22 @@ async function social(options = {}) {
5574
5646
  from: fromTag,
5575
5647
  to
5576
5648
  });
5577
- const minifiedBody = buildChangelogBody({ commits: rootPackage.commits, config, minify: true });
5578
- const richBody = buildChangelogBody({ commits: rootPackage.commits, config, minify: false });
5649
+ const minifiedBody = await generateChangelog({
5650
+ pkg: { ...rootPackage, fromTag },
5651
+ config,
5652
+ dryRun,
5653
+ newVersion,
5654
+ include: { title: false, compareLink: false, body: true, contributors: false },
5655
+ minify: true
5656
+ });
5657
+ const richBody = await generateChangelog({
5658
+ pkg: { ...rootPackage, fromTag },
5659
+ config,
5660
+ dryRun,
5661
+ newVersion,
5662
+ include: { title: false, compareLink: false, body: true, contributors: false },
5663
+ minify: false
5664
+ });
5579
5665
  const hasContent = !!minifiedBody.trim();
5580
5666
  const twitterReleaseUrl = getReleaseUrl(config, to);
5581
5667
  const twitterChangelogUrl = config.social?.changelogUrl;
@@ -5625,13 +5711,20 @@ ${twitterChangelog}`);
5625
5711
  newVersion,
5626
5712
  tag: to
5627
5713
  });
5714
+ const changelogCommits = await getPackageCommits({
5715
+ pkg: rootPackage,
5716
+ from: fromTag,
5717
+ to: "HEAD",
5718
+ config,
5719
+ changelog: true
5720
+ });
5628
5721
  const slackResponse = await handleSlackPost({
5629
5722
  config,
5630
5723
  changelog: slackChangelog,
5631
5724
  dryRun,
5632
5725
  newVersion,
5633
5726
  tag: to,
5634
- commits: rootPackage.commits,
5727
+ commits: changelogCommits,
5635
5728
  bumpedPackages: options.bumpResult?.bumpedPackages
5636
5729
  });
5637
5730
  const results = [];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "relizy",
3
3
  "type": "module",
4
- "version": "1.4.5",
4
+ "version": "1.4.6",
5
5
  "description": "Changelogen adapter for monorepo management with unified and independent versioning",
6
6
  "author": "Louis Mazel <me@loicmazuel.com>",
7
7
  "license": "MIT",
@@ -126,7 +126,7 @@
126
126
  "test:unit": "vitest run",
127
127
  "test:unit:watch": "vitest watch",
128
128
  "test:unit:coverage": "vitest run --coverage",
129
- "health": "pnpm typecheck && pnpm lint:all && pnpm test:unit:coverage && pnpm build && pnpm -F docs build",
129
+ "health": "pnpm typecheck && pnpm -F docs typecheck && pnpm lint:fix:all && pnpm test:unit:coverage && pnpm build && pnpm -F docs build",
130
130
  "pre-commit": "lint-staged"
131
131
  }
132
132
  }