Skip to content

Commit

Permalink
fix(versions): support changelogPreset.header, fixes #852 (#864)
Browse files Browse the repository at this point in the history
* fix(versions): support `changelogPreset.header`, fixes #852
  • Loading branch information
ghiscoding committed May 15, 2024
1 parent debaed7 commit 358324c
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 17 deletions.
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"packages/cli/dist/cli.js",
"version",
"--dry-run",
"--yes",
"--changelog-include-commits-client-login",
"--conventional-commits"
],
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/models/command-options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RemoteClientType } from './interfaces.js';
import { ChangelogPresetOptions, RemoteClientType } from './interfaces.js';

export interface ChangedCommandOption {
/** use conventional-changelog to determine version bump and generate CHANGELOG. */
Expand Down Expand Up @@ -185,7 +185,7 @@ export interface VersionCommandOption {
changelogIncludeCommitsClientLogin?: boolean | string;

/** Defaults 'angular', custom conventional-changelog preset. */
changelogPreset?: string;
changelogPreset?: string | ChangelogPresetOptions;

/** Create an official GitHub or GitLab release for every version. */
createRelease?: RemoteClientType;
Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/models/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ export interface CommandOptions {
rollVersion?: boolean;
}

export interface ChangelogPresetOptions {
name: string;
header?: string;
types?: Array<{ type: string; section: string; hidden?: boolean }>;
issuePrefixes?: string[];
issueUrlFormat?: string;
commitUrlFormat?: string;
compareUrlFormat?: string;
userUrlFormat?: string;
releaseCommitMessageFormat?: string;
}

export type CommandType = '' | 'changed' | 'exec' | 'info' | 'init' | 'list' | 'publish' | 'run' | 'version';

export interface DescribeRefOptions {
Expand Down
2 changes: 2 additions & 0 deletions packages/version/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ If the preset exports a builder function (e.g. `conventional-changelog-conventio
}
```

> **Note** the option `changelogPreset.releaseCommitMessageFormat` is not supported and will throw, you can simply use [`--message`](#--message-msg) to have the same result.
### `--conventional-commits`

```sh
Expand Down
12 changes: 12 additions & 0 deletions packages/version/src/__tests__/version-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,18 @@ describe('VersionCommand', () => {
expect(command.changelogIncludeCommitsClientLogin).toBe(true);
expect(getCommitsSinceLastRelease).toHaveBeenCalled();
});

it('throws an error if changelogPreset is defined and includes releaseCommitMessageFormat', async () => {
const cwd = await initFixture('normal');
const command = new VersionCommand({
conventionalCommits: true,
changelogPreset: { name: 'conventionalcommits', releaseCommitMessageFormat: 'test' },
} as unknown as VersionCommandOption);

await expect(command).rejects.toThrow(
'The Lerna config "changelogPreset.releaseCommitMessageFormat" is not supported, you should simply use "version.message" instead which will give you the same end result.'
);
});
});

describe('independent mode', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`conventional-commits > updateChangelog() > creates changelog with changelogPreset when defined > leaf 1`] = `
My Custom Header
## 1.1.0 (YYYY-MM-DD)
### ✨ Features
* I should be placed in the CHANGELOG ([SHA](https://github.com/lerna/changelog-missing/commit/GIT_HEAD))
`;

exports[`conventional-commits > updateChangelog() > creates changelog with changelogPreset when defined > root 1`] = `
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 1.1.0 (YYYY-MM-DD)
### Features
* I should be placed in the CHANGELOG ([SHA](https://github.com/lerna/changelog-missing/commit/GIT_HEAD))
`;

exports[`conventional-commits > updateChangelog() > creates files if they do not exist > leaf 1`] = `
# Change Log
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,66 @@ describe('conventional-commits', () => {
expect(rootChangelogContent).toMatchSnapshot('root');
});

it('creates changelog with changelogPreset when defined', async () => {
const cwd = (await initFixture('changelog-missing')) as string;

const [pkg1] = await Project.getPackages(cwd);
const rootPkg = {
name: 'root',
location: cwd,
};

// make a change in package-1
await pkg1.set('changed', 1).serialize();
await gitAdd(cwd, pkg1.manifestLocation);
await gitCommit(cwd, 'feat: I should be placed in the CHANGELOG');

// update version
await pkg1.set('version', '1.1.0').serialize();

const [leafChangelog, rootChangelog] = await Promise.all([
updateChangelog(pkg1, 'fixed', {
changelogPreset: {
name: 'conventionalcommits',
header: 'My Custom Header',
types: [
{
type: 'feat',
section: '✨ Features',
},
{
type: 'fix',
section: '🐛 Bug Fixes',
},
{
type: 'chore',
section: '🚀 Chore',
hidden: true,
},
{
type: 'docs',
section: '📝 Documentation',
},
],
issuePrefixes: ['#'],
issueUrlFormat: '{{host}}/{{owner}}/{{repository}}/issues/{{id}}',
commitUrlFormat: '{{host}}/{{owner}}/{{repository}}/commit/{{hash}}',
compareUrlFormat: '{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}',
userUrlFormat: '{{host}}/{{user}}',
},
}),
updateChangelog(rootPkg as Package, 'root', { version: '1.1.0' }),
]);

expect(leafChangelog.logPath).toBe(join(pkg1.location, 'CHANGELOG.md'));
expect(rootChangelog.logPath).toBe(join(rootPkg.location, 'CHANGELOG.md'));

const [leafChangelogContent, rootChangelogContent] = await Promise.all([getFileContent(leafChangelog), getFileContent(rootChangelog)]);

expect(leafChangelogContent).toMatchSnapshot('leaf');
expect(rootChangelogContent).toMatchSnapshot('root');
});

it('updates fixed changelogs', async () => {
const cwd = await initFixture('fixed');
const rootPkg = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class GetChangelogConfig {
let config: ChangelogConfig | Promise<ChangelogConfig> = GetChangelogConfig.cfgCache.get(cacheKey);

if (!config) {
let presetPackageName = presetName;
let presetPackageName = presetName as string;

// https://github.com/npm/npm-package-arg#result-object
const parsed: any = npa(presetPackageName, rootPath);
Expand Down
9 changes: 4 additions & 5 deletions packages/version/src/conventional-commits/update-changelog.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EOL, Package } from '@lerna-lite/core';
import { ChangelogPresetOptions, EOL, Package } from '@lerna-lite/core';
import conventionalChangelogCore, { Context } from 'conventional-changelog-core';
import { Options as WriterOptions } from 'conventional-changelog-writer';
import { writeFile } from 'fs/promises';
Expand Down Expand Up @@ -94,10 +94,9 @@ export async function updateChangelog(pkg: Package, type: ChangelogType, updateO

log.silly(type, 'writing new entry: %j', newEntry);

const changelogHeader = CHANGELOG_HEADER.replace(
/%s/g,
changelogHeaderMessage?.length > 0 ? changelogHeaderMessage + EOL : ''
);
const changelogHeader =
(changelogPreset as ChangelogPresetOptions)?.header ??
CHANGELOG_HEADER.replace(/%s/g, changelogHeaderMessage?.length > 0 ? changelogHeaderMessage + EOL : '');

const content = [changelogHeader, newEntry, changelogContents]
.join(BLANK_LINE)
Expand Down
6 changes: 3 additions & 3 deletions packages/version/src/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExecOpts, Package } from '@lerna-lite/core';
import { ChangelogPresetOptions, ExecOpts, Package } from '@lerna-lite/core';
import { GitRawCommitsOptions, ParserOptions } from 'conventional-changelog-core';
import { Options as WriterOptions } from 'conventional-changelog-writer';
import { Options as RecommendedBumpOptions } from 'conventional-recommended-bump';
Expand All @@ -17,7 +17,7 @@ export interface GitTagOption {

export type VersioningStrategy = 'fixed' | 'independent';
export type ChangelogType = 'fixed' | 'independent' | 'root';
export type ChangelogPresetConfig = string | { name: string; [key: string]: unknown };
export type ChangelogPresetConfig = string | ChangelogPresetOptions;

export interface BaseChangelogOptions {
changelogPreset?: ChangelogPresetConfig;
Expand Down Expand Up @@ -56,7 +56,7 @@ export type RemoteCommit = {

export interface UpdateChangelogOption {
changelogHeaderMessage?: string;
changelogPreset?: string;
changelogPreset?: ChangelogPresetConfig;
changelogIncludeCommitsGitAuthor?: boolean | string;
changelogIncludeCommitsClientLogin?: boolean | string;
commitsSinceLastRelease?: RemoteCommit[];
Expand Down
24 changes: 18 additions & 6 deletions packages/version/src/version-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ import semver from 'semver';

import {
EOL,
type ChangelogPresetOptions,
checkWorkingTree,
collectPackages,
collectUpdates,
Command,
CommandType,
type CommandType,
createRunner,
logOutput,
Package,
PackageGraphNode,
ProjectConfig,
type Package,
type PackageGraphNode,
type ProjectConfig,
promptConfirmation,
runTopologically,
throwIfUncommitted,
UpdateCollectorOptions,
type UpdateCollectorOptions,
ValidationError,
VersionCommandOption,
type VersionCommandOption,
} from '@lerna-lite/core';

import { getCurrentBranch } from './lib/get-current-branch.js';
Expand Down Expand Up @@ -162,6 +163,17 @@ export class VersionCommand extends Command<VersionCommandOption> {
throw new ValidationError('ERELEASE', 'To create a release, you cannot pass --no-changelog');
}

if (
this.options.conventionalCommits &&
typeof this.options.changelogPreset === 'object' &&
(this.options.changelogPreset as ChangelogPresetOptions)?.releaseCommitMessageFormat
) {
throw new ValidationError(
'ENOTSUPPORTED',
'The Lerna config "changelogPreset.releaseCommitMessageFormat" is not supported, you should simply use "version.message" instead which will give you the same end result.'
);
}

this.gitOpts = {
amend,
commitHooks,
Expand Down

0 comments on commit 358324c

Please sign in to comment.