зеркало из https://github.com/microsoft/beachball.git
Changelog JSON fixes (#903)
This commit is contained in:
Родитель
6a450f70ea
Коммит
749812afdc
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"type": "minor",
|
||||
"comment": "Add an index signature to ChangelogEntry",
|
||||
"packageName": "beachball",
|
||||
"email": "elcraig@microsoft.com",
|
||||
"dependentChangeType": "patch"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "Stop recording incorrect bump commits in CHANGELOG.json",
|
||||
"packageName": "beachball",
|
||||
"email": "elcraig@microsoft.com",
|
||||
"dependentChangeType": "patch"
|
||||
}
|
|
@ -255,7 +255,7 @@ describe('writeChangelog', () => {
|
|||
expect(readChangelogMd(monoRepo.pathTo('packages/foo'))).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Verify that the changeFile transform functions are run, if provided', async () => {
|
||||
it('runs transform.changeFiles functions if provided', async () => {
|
||||
const editedComment: string = 'Edited comment for testing';
|
||||
const monoRepo = monoRepoFactory.cloneRepository();
|
||||
monoRepo.commitChange('foo');
|
||||
|
|
|
@ -1,123 +1,203 @@
|
|||
import { describe, expect, it } from '@jest/globals';
|
||||
import { describe, expect, it, jest } from '@jest/globals';
|
||||
import { getPackageChangelogs } from '../../changelog/getPackageChangelogs';
|
||||
import { BumpInfo } from '../../types/BumpInfo';
|
||||
import { ChangeSet } from '../../types/ChangeInfo';
|
||||
import { ChangeFileInfo, ChangeSet } from '../../types/ChangeInfo';
|
||||
import { PackageInfos } from '../../types/PackageInfo';
|
||||
import { makePackageInfos } from '../../__fixtures__/packageInfos';
|
||||
|
||||
// Mock the methods used from workspace-tools so we don't access the filesystem
|
||||
jest.mock('workspace-tools', () => ({
|
||||
findProjectRoot: () => '.',
|
||||
getFileAddedHash: () => 'deadbeef',
|
||||
}));
|
||||
|
||||
function makeChangeInfo(pkg: string, overrides?: Partial<ChangeFileInfo>): ChangeSet[number] {
|
||||
return {
|
||||
changeFile: `${pkg}.json`,
|
||||
change: {
|
||||
comment: `comment for ${pkg}`,
|
||||
dependentChangeType: 'patch',
|
||||
email: 'something@something.com',
|
||||
packageName: pkg,
|
||||
type: 'patch',
|
||||
...overrides,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('getPackageChangelogs', () => {
|
||||
it('should have multiple comment entries when a package has a changefile AND was part of a dependent bump', () => {
|
||||
it('generates correct changelog entries for a single package', () => {
|
||||
const changeFileChangeInfos: ChangeSet = [
|
||||
{
|
||||
changeFile: 'foo.json',
|
||||
change: {
|
||||
comment: 'comment for foo',
|
||||
commit: 'deadbeef',
|
||||
dependentChangeType: 'patch',
|
||||
email: 'something@something.com',
|
||||
packageName: 'foo',
|
||||
type: 'patch',
|
||||
},
|
||||
},
|
||||
{
|
||||
changeFile: 'bar.json',
|
||||
change: {
|
||||
comment: 'comment for bar',
|
||||
commit: 'deadbeef',
|
||||
dependentChangeType: 'patch',
|
||||
email: 'something@something.com',
|
||||
packageName: 'bar',
|
||||
type: 'patch',
|
||||
},
|
||||
},
|
||||
makeChangeInfo('foo'),
|
||||
makeChangeInfo('foo', { type: 'minor', comment: 'other comment' }),
|
||||
];
|
||||
const packageInfos = makePackageInfos({ foo: { version: '1.0.0' } });
|
||||
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
calculatedChangeTypes: { foo: 'patch' },
|
||||
packageInfos,
|
||||
cwd: '.',
|
||||
});
|
||||
|
||||
expect(changelogs.foo).toEqual({
|
||||
comments: {
|
||||
minor: [{ author: 'something@something.com', comment: 'other comment', commit: 'deadbeef', package: 'foo' }],
|
||||
patch: [{ author: 'something@something.com', comment: 'comment for foo', commit: 'deadbeef', package: 'foo' }],
|
||||
},
|
||||
date: expect.any(Date),
|
||||
name: 'foo',
|
||||
tag: 'foo_v1.0.0',
|
||||
version: '1.0.0',
|
||||
});
|
||||
expect(changelogs.foo.comments.patch).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('generates correct changelog entries for multiple packages', () => {
|
||||
const changeFileChangeInfos: ChangeSet = [makeChangeInfo('foo'), makeChangeInfo('bar')];
|
||||
const packageInfos = makePackageInfos({
|
||||
foo: { version: '1.0.0' },
|
||||
bar: { version: '2.0.0' },
|
||||
});
|
||||
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
calculatedChangeTypes: { foo: 'patch', bar: 'patch' },
|
||||
packageInfos,
|
||||
cwd: '.',
|
||||
});
|
||||
|
||||
expect(changelogs.foo).toEqual({
|
||||
comments: {
|
||||
patch: [{ author: 'something@something.com', comment: 'comment for foo', commit: 'deadbeef', package: 'foo' }],
|
||||
},
|
||||
date: expect.any(Date),
|
||||
name: 'foo',
|
||||
tag: 'foo_v1.0.0',
|
||||
version: '1.0.0',
|
||||
});
|
||||
expect(changelogs.bar).toEqual({
|
||||
comments: {
|
||||
patch: [{ author: 'something@something.com', comment: 'comment for bar', commit: 'deadbeef', package: 'bar' }],
|
||||
},
|
||||
date: expect.any(Date),
|
||||
name: 'bar',
|
||||
tag: 'bar_v2.0.0',
|
||||
version: '2.0.0',
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves custom properties from change files', () => {
|
||||
const changeFileChangeInfos: ChangeSet = [makeChangeInfo('foo', { extra: 'prop' })];
|
||||
const packageInfos: PackageInfos = makePackageInfos({ foo: { version: '1.0.0' } });
|
||||
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
calculatedChangeTypes: { foo: 'patch' },
|
||||
packageInfos,
|
||||
cwd: '.',
|
||||
});
|
||||
|
||||
expect(changelogs.foo.comments.patch![0]).toMatchObject({ extra: 'prop' });
|
||||
});
|
||||
|
||||
it('records dependent bumps', () => {
|
||||
const changeFileChangeInfos: ChangeSet = [makeChangeInfo('foo')];
|
||||
|
||||
const dependentChangedBy: BumpInfo['dependentChangedBy'] = {
|
||||
bar: new Set(['foo']),
|
||||
};
|
||||
|
||||
const packageInfos: PackageInfos = {
|
||||
foo: {
|
||||
combinedOptions: {} as any,
|
||||
name: 'foo',
|
||||
packageJsonPath: 'packages/foo/package.json',
|
||||
packageOptions: {},
|
||||
private: false,
|
||||
version: '1.0.0',
|
||||
dependencies: {
|
||||
bar: '^1.0.0',
|
||||
},
|
||||
},
|
||||
bar: {
|
||||
combinedOptions: {} as any,
|
||||
name: 'bar',
|
||||
packageJsonPath: 'packages/bar/package.json',
|
||||
packageOptions: {},
|
||||
private: false,
|
||||
version: '1.0.0',
|
||||
},
|
||||
};
|
||||
const packageInfos = makePackageInfos({
|
||||
foo: { version: '1.0.0' },
|
||||
bar: { version: '2.0.0', dependencies: { foo: '^1.0.0' } },
|
||||
});
|
||||
|
||||
const changelogs = getPackageChangelogs(
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
{ foo: 'patch', bar: 'patch' },
|
||||
calculatedChangeTypes: { foo: 'patch', bar: 'patch' },
|
||||
dependentChangedBy,
|
||||
packageInfos,
|
||||
'.'
|
||||
);
|
||||
cwd: '.',
|
||||
});
|
||||
|
||||
expect(Object.keys(changelogs.bar.comments.patch!)).toHaveLength(2);
|
||||
expect(Object.keys(changelogs.foo.comments.patch!)).toHaveLength(1);
|
||||
expect(changelogs.bar).toEqual({
|
||||
comments: {
|
||||
patch: [
|
||||
{
|
||||
author: 'beachball',
|
||||
package: 'bar',
|
||||
comment: 'Bump foo to v1.0.0',
|
||||
// IMPORTANT: this should not record an actual commit hash, because it will be incorrect
|
||||
commit: 'not available',
|
||||
},
|
||||
],
|
||||
},
|
||||
date: expect.any(Date),
|
||||
name: 'bar',
|
||||
tag: 'bar_v2.0.0',
|
||||
version: '2.0.0',
|
||||
});
|
||||
expect(Object.keys(changelogs.bar.comments.patch!)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should not generate change logs for dependent bumps of private packages', () => {
|
||||
const changeFileChangeInfos: ChangeSet = [
|
||||
{
|
||||
changeFile: 'bar.json',
|
||||
change: {
|
||||
comment: 'comment for bar',
|
||||
commit: 'deadbeef',
|
||||
dependentChangeType: 'patch',
|
||||
email: 'something@something.com',
|
||||
packageName: 'bar',
|
||||
type: 'patch',
|
||||
},
|
||||
},
|
||||
];
|
||||
it('records multiple comment entries when a package has a change file AND was part of a dependent bump', () => {
|
||||
const changeFileChangeInfos: ChangeSet = [makeChangeInfo('foo'), makeChangeInfo('bar')];
|
||||
|
||||
const dependentChangedBy: BumpInfo['dependentChangedBy'] = {
|
||||
bar: new Set(['foo']),
|
||||
};
|
||||
|
||||
const packageInfos = makePackageInfos({
|
||||
foo: { version: '1.0.0' },
|
||||
bar: { version: '2.0.0', dependencies: { foo: '^1.0.0' } },
|
||||
});
|
||||
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
calculatedChangeTypes: { foo: 'patch', bar: 'patch' },
|
||||
dependentChangedBy,
|
||||
packageInfos,
|
||||
cwd: '.',
|
||||
});
|
||||
|
||||
expect(changelogs.bar.comments).toEqual({
|
||||
patch: [
|
||||
expect.objectContaining({ comment: 'comment for bar' }),
|
||||
expect.objectContaining({ comment: 'Bump foo to v1.0.0' }),
|
||||
],
|
||||
});
|
||||
expect(changelogs.foo.comments).toEqual({
|
||||
patch: [expect.objectContaining({ comment: 'comment for foo' })],
|
||||
});
|
||||
});
|
||||
|
||||
it('does not generate changelogs for dependent bumps of private packages', () => {
|
||||
const changeFileChangeInfos: ChangeSet = [makeChangeInfo('bar')];
|
||||
|
||||
const dependentChangedBy: BumpInfo['dependentChangedBy'] = {
|
||||
'private-pkg': new Set(['bar']),
|
||||
};
|
||||
|
||||
const packageInfos: PackageInfos = {
|
||||
const packageInfos = makePackageInfos({
|
||||
'private-pkg': {
|
||||
combinedOptions: {} as any,
|
||||
name: 'private-pkg',
|
||||
packageJsonPath: 'packages/private-pkg/package.json',
|
||||
packageOptions: {},
|
||||
version: '1.0.0',
|
||||
private: true,
|
||||
version: '1.0.0',
|
||||
dependencies: {
|
||||
bar: '^1.0.0',
|
||||
},
|
||||
dependencies: { bar: '^1.0.0' },
|
||||
},
|
||||
bar: {
|
||||
combinedOptions: {} as any,
|
||||
name: 'bar',
|
||||
packageJsonPath: 'packages/bar/package.json',
|
||||
packageOptions: {},
|
||||
private: false,
|
||||
version: '1.0.0',
|
||||
},
|
||||
};
|
||||
bar: { version: '1.0.0' },
|
||||
});
|
||||
|
||||
const changelogs = getPackageChangelogs(
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
{ bar: 'patch', 'private-pkg': 'patch' },
|
||||
calculatedChangeTypes: { bar: 'patch', 'private-pkg': 'patch' },
|
||||
dependentChangedBy,
|
||||
packageInfos,
|
||||
'.'
|
||||
);
|
||||
cwd: '.',
|
||||
});
|
||||
|
||||
expect(changelogs.bar).toBeTruthy();
|
||||
expect(changelogs['private-pkg']).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { describe, expect, it } from '@jest/globals';
|
||||
import { describe, expect, it, jest } from '@jest/globals';
|
||||
import { initMockLogs } from '../../__fixtures__/mockLogs';
|
||||
import { MarkdownChangelogRenderOptions, renderChangelog, markerComment } from '../../changelog/renderChangelog';
|
||||
import { ChangelogEntry } from '../../types/ChangeLog';
|
||||
|
||||
const previousHeader = `# Change Log - foo
|
||||
|
||||
|
@ -25,18 +26,8 @@ describe('renderChangelog', () => {
|
|||
comments: {
|
||||
major: [],
|
||||
minor: [
|
||||
{
|
||||
comment: 'Awesome change',
|
||||
author: 'user1@example.com',
|
||||
commit: 'sha1',
|
||||
package: 'foo',
|
||||
},
|
||||
{
|
||||
comment: 'Boring change',
|
||||
author: 'user2@example.com',
|
||||
commit: 'sha2',
|
||||
package: 'foo',
|
||||
},
|
||||
{ comment: 'Awesome change', author: 'user1@example.com', commit: 'sha1', package: 'foo' },
|
||||
{ comment: 'Boring change', author: 'user2@example.com', commit: 'sha2', package: 'foo' },
|
||||
],
|
||||
patch: [
|
||||
{ comment: 'Fix', author: 'user1@example.com', commit: 'sha3', package: 'foo' },
|
||||
|
@ -116,4 +107,29 @@ describe('renderChangelog', () => {
|
|||
expect(result).toContain('content here'); // includes previous content
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('passes custom change file properties to renderers', async () => {
|
||||
const options = getOptions();
|
||||
options.newVersionChangelog.comments = {
|
||||
patch: [
|
||||
{
|
||||
comment: 'Awesome change',
|
||||
author: 'user1@example.com',
|
||||
commit: 'sha1',
|
||||
package: 'foo',
|
||||
extra: 'custom',
|
||||
},
|
||||
],
|
||||
};
|
||||
options.changelogOptions.customRenderers = {
|
||||
renderEntry: jest.fn(async (entry: ChangelogEntry) => `- ${entry.comment} ${entry.extra})`),
|
||||
};
|
||||
|
||||
const result = await renderChangelog(options);
|
||||
expect(result).toContain('Awesome change custom');
|
||||
expect(options.changelogOptions.customRenderers.renderEntry).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ extra: 'custom' }),
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import { describe, expect, it } from '@jest/globals';
|
||||
import { ChangelogJson, PackageChangelog } from '../..';
|
||||
import { renderJsonChangelog } from '../../changelog/renderJsonChangelog';
|
||||
|
||||
describe('renderJsonChangelog', () => {
|
||||
function getChangelog(): PackageChangelog {
|
||||
return {
|
||||
date: new Date('Thu Aug 22 2019 14:20:40 GMT-0700 (Pacific Daylight Time)'),
|
||||
name: 'foo',
|
||||
tag: 'foo_v1.2.3',
|
||||
version: '1.2.3',
|
||||
comments: {
|
||||
minor: [
|
||||
{ comment: 'Awesome change', author: 'user1@example.com', commit: 'sha1', package: 'foo' },
|
||||
{ comment: 'Boring change', author: 'user2@example.com', commit: 'sha2', package: 'foo' },
|
||||
],
|
||||
patch: [
|
||||
{ comment: 'Fix', author: 'user1@example.com', commit: 'sha3', package: 'foo' },
|
||||
{ comment: 'stuff', author: 'user2@example.com', commit: 'sha4', package: 'foo' },
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
it('renders if no previous changelog', () => {
|
||||
const changelog = getChangelog();
|
||||
const { name, ...rest } = changelog;
|
||||
|
||||
const finalChangeLog = renderJsonChangelog(changelog, undefined);
|
||||
expect(finalChangeLog).toEqual({
|
||||
name,
|
||||
entries: [
|
||||
{
|
||||
...rest,
|
||||
date: 'Thu, 22 Aug 2019 21:20:40 GMT',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves previous entries', () => {
|
||||
const changelog = getChangelog();
|
||||
const previousChangelog: ChangelogJson = {
|
||||
name: 'foo',
|
||||
entries: [
|
||||
{
|
||||
date: 'Thu, 21 Aug 2019 20:20:40 GMT',
|
||||
version: '1.2.2',
|
||||
tag: 'foo_v1.2.2',
|
||||
comments: {
|
||||
patch: [{ comment: 'Fix', author: 'user1@example.com', commit: 'sha3', package: 'foo' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const finalChangeLog = renderJsonChangelog(changelog, previousChangelog);
|
||||
expect(finalChangeLog).toEqual({
|
||||
name: 'foo',
|
||||
entries: [expect.objectContaining({ version: '1.2.3' }), expect.objectContaining({ version: '1.2.2' })],
|
||||
});
|
||||
});
|
||||
});
|
|
@ -19,18 +19,8 @@ describe('changelog renderers -', () => {
|
|||
comments: {
|
||||
major: [],
|
||||
minor: [
|
||||
{
|
||||
comment: 'Awesome change',
|
||||
author: 'user1@example.com',
|
||||
commit: 'sha1',
|
||||
package: 'foo',
|
||||
},
|
||||
{
|
||||
comment: 'Boring change',
|
||||
author: 'user2@example.com',
|
||||
commit: 'sha2',
|
||||
package: 'foo',
|
||||
},
|
||||
{ comment: 'Awesome change', author: 'user1@example.com', commit: 'sha1', package: 'foo' },
|
||||
{ comment: 'Boring change', author: 'user2@example.com', commit: 'sha2', package: 'foo' },
|
||||
],
|
||||
patch: [
|
||||
{ comment: 'Fix', author: 'user1@example.com', commit: 'sha3', package: 'foo' },
|
||||
|
|
|
@ -1,35 +1,40 @@
|
|||
import path from 'path';
|
||||
import { PackageInfo } from '../types/PackageInfo';
|
||||
import { PackageInfo, PackageInfos } from '../types/PackageInfo';
|
||||
import { PackageChangelog } from '../types/ChangeLog';
|
||||
import { generateTag } from '../git/generateTag';
|
||||
import { BumpInfo } from '../types/BumpInfo';
|
||||
import { getChangePath } from '../paths';
|
||||
import { getCurrentHash, getFileAddedHash } from 'workspace-tools';
|
||||
import { getFileAddedHash } from 'workspace-tools';
|
||||
import { ChangeSet } from '../types/ChangeInfo';
|
||||
|
||||
export function getPackageChangelogs(
|
||||
changeFileChangeInfos: ChangeSet,
|
||||
calculatedChangeTypes: BumpInfo['calculatedChangeTypes'],
|
||||
dependentChangedBy: BumpInfo['dependentChangedBy'],
|
||||
packageInfos: {
|
||||
[pkg: string]: PackageInfo;
|
||||
},
|
||||
cwd: string
|
||||
): { [pkgName: string]: PackageChangelog } {
|
||||
const changelogs: { [pkgName: string]: PackageChangelog } = {};
|
||||
/**
|
||||
* Used for `ChangelogEntry.commit` if the commit hash is not available.
|
||||
*/
|
||||
const commitNotAvailable = 'not available';
|
||||
|
||||
/**
|
||||
* Get the preliminary changelog info for each modified package, based on change files and dependent bumps.
|
||||
* @returns Mapping from package name to package changelog.
|
||||
*/
|
||||
export function getPackageChangelogs(params: {
|
||||
changeFileChangeInfos: ChangeSet;
|
||||
calculatedChangeTypes: BumpInfo['calculatedChangeTypes'];
|
||||
dependentChangedBy?: BumpInfo['dependentChangedBy'];
|
||||
packageInfos: PackageInfos;
|
||||
cwd: string;
|
||||
}): Record<string, PackageChangelog> {
|
||||
const { changeFileChangeInfos, calculatedChangeTypes, dependentChangedBy = {}, packageInfos, cwd } = params;
|
||||
|
||||
const changelogs: Record<string, PackageChangelog> = {};
|
||||
|
||||
const changeFileCommits: { [changeFile: string]: string } = {};
|
||||
const changePath = getChangePath(cwd);
|
||||
|
||||
for (let { change, changeFile } of changeFileChangeInfos) {
|
||||
for (const { change, changeFile } of changeFileChangeInfos) {
|
||||
const { packageName, type: changeType, dependentChangeType, email, ...rest } = change;
|
||||
if (!changelogs[packageName]) {
|
||||
changelogs[packageName] = createChangeLog(packageInfos[packageName]);
|
||||
}
|
||||
changelogs[packageName] ??= createPackageChangelog(packageInfos[packageName]);
|
||||
|
||||
if (!changeFileCommits[changeFile]) {
|
||||
changeFileCommits[changeFile] = getFileAddedHash(path.join(changePath, changeFile), cwd) || 'not available';
|
||||
}
|
||||
changeFileCommits[changeFile] ??= getFileAddedHash(path.join(changePath, changeFile), cwd) || commitNotAvailable;
|
||||
|
||||
changelogs[packageName].comments ??= {};
|
||||
changelogs[packageName].comments[changeType] ??= [];
|
||||
|
@ -43,18 +48,14 @@ export function getPackageChangelogs(
|
|||
});
|
||||
}
|
||||
|
||||
const commit = getCurrentHash(cwd) || 'not available';
|
||||
|
||||
for (let [dependent, changedBy] of Object.entries(dependentChangedBy)) {
|
||||
for (const [dependent, changedBy] of Object.entries(dependentChangedBy)) {
|
||||
if (packageInfos[dependent].private === true) {
|
||||
// Avoid creation of change log files for private packages since the version is
|
||||
// not managed by beachball and the log would only contain bumps to dependencies.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!changelogs[dependent]) {
|
||||
changelogs[dependent] = createChangeLog(packageInfos[dependent]);
|
||||
}
|
||||
changelogs[dependent] ??= createPackageChangelog(packageInfos[dependent]);
|
||||
|
||||
const changeType = calculatedChangeTypes[dependent];
|
||||
|
||||
|
@ -67,7 +68,11 @@ export function getPackageChangelogs(
|
|||
author: 'beachball',
|
||||
package: dependent,
|
||||
comment: `Bump ${dep} to v${packageInfos[dep].version}`,
|
||||
commit,
|
||||
// This change will be made in the commit that is currently being created, so unless we
|
||||
// split publishing into two commits (one for bumps and one for changelog updates),
|
||||
// there's no way to know the hash yet. It's better to record nothing than incorrect info.
|
||||
// https://github.com/microsoft/beachball/issues/901
|
||||
commit: commitNotAvailable,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +81,7 @@ export function getPackageChangelogs(
|
|||
return changelogs;
|
||||
}
|
||||
|
||||
function createChangeLog(packageInfo: PackageInfo): PackageChangelog {
|
||||
function createPackageChangelog(packageInfo: PackageInfo): PackageChangelog {
|
||||
const name = packageInfo.name;
|
||||
const version = packageInfo.version;
|
||||
return {
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
import { generateTag } from '../git/generateTag';
|
||||
import { PackageChangelog, ChangelogJson, ChangelogJsonEntry } from '../types/ChangeLog';
|
||||
import { PackageChangelog, ChangelogJson } from '../types/ChangeLog';
|
||||
|
||||
export function renderJsonChangelog(
|
||||
changelog: PackageChangelog,
|
||||
previousChangelog: ChangelogJson | undefined
|
||||
): ChangelogJson {
|
||||
const result: ChangelogJson = {
|
||||
name: changelog.name,
|
||||
entries: previousChangelog?.entries ? [...previousChangelog.entries] : [],
|
||||
const { name, date, ...rest } = changelog;
|
||||
return {
|
||||
name,
|
||||
entries: [
|
||||
{
|
||||
date: changelog.date.toUTCString(),
|
||||
...rest,
|
||||
},
|
||||
...(previousChangelog?.entries || []),
|
||||
],
|
||||
};
|
||||
const newEntry: ChangelogJsonEntry = {
|
||||
date: changelog.date.toUTCString(),
|
||||
tag: generateTag(changelog.name, changelog.version),
|
||||
version: changelog.version,
|
||||
comments: changelog.comments,
|
||||
};
|
||||
result.entries.unshift(newEntry);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -27,13 +27,13 @@ export async function writeChangelog(
|
|||
);
|
||||
const groupedChangelogPathSet = new Set(groupedChangelogPaths);
|
||||
|
||||
const changelogs = getPackageChangelogs(
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
calculatedChangeTypes,
|
||||
dependentChangedBy,
|
||||
packageInfos,
|
||||
options.path
|
||||
);
|
||||
cwd: options.path,
|
||||
});
|
||||
// Use a standard for loop here to prevent potentially firing off multiple network requests at once
|
||||
// (in case any custom renderers have network requests)
|
||||
for (const pkg of Object.keys(changelogs)) {
|
||||
|
@ -62,7 +62,12 @@ async function writeGroupedChangelog(
|
|||
}
|
||||
|
||||
// Grouped changelogs should not contain dependency bump entries
|
||||
const changelogs = getPackageChangelogs(changeFileChangeInfos, calculatedChangeTypes, {}, packageInfos, options.path);
|
||||
const changelogs = getPackageChangelogs({
|
||||
changeFileChangeInfos,
|
||||
calculatedChangeTypes,
|
||||
packageInfos,
|
||||
cwd: options.path,
|
||||
});
|
||||
const groupedChangelogs: {
|
||||
[path: string]: {
|
||||
changelogs: PackageChangelog[];
|
||||
|
|
|
@ -2,12 +2,17 @@ export type ChangeType = 'prerelease' | 'patch' | 'minor' | 'major' | 'none';
|
|||
|
||||
/**
|
||||
* Info saved in each change file.
|
||||
* (For entries in CHANGELOG.json, see `ChangelogEntry` in ./ChangeLog.ts.)
|
||||
*/
|
||||
export interface ChangeFileInfo {
|
||||
type: ChangeType;
|
||||
/** Change comment */
|
||||
comment: string;
|
||||
/** Package name the change was in */
|
||||
packageName: string;
|
||||
/** Author email */
|
||||
email: string;
|
||||
/** How to bump packages that depend on this one */
|
||||
dependentChangeType: ChangeType;
|
||||
/** Extra info added to the change file via custom prompts */
|
||||
[extraInfo: string]: any;
|
||||
|
@ -20,11 +25,14 @@ export interface ChangeInfo extends ChangeFileInfo {
|
|||
commit: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Info saved in each grouped change file.
|
||||
*/
|
||||
export interface ChangeInfoMultiple {
|
||||
changes: ChangeInfo[];
|
||||
}
|
||||
|
||||
/**
|
||||
* List of change file infos
|
||||
* List of change file infos (not actually a set).
|
||||
*/
|
||||
export type ChangeSet = { changeFile: string; change: ChangeFileInfo }[];
|
||||
|
|
|
@ -5,20 +5,37 @@
|
|||
|
||||
import { ChangeType } from './ChangeInfo';
|
||||
|
||||
/**
|
||||
* Entry ("comment") in CHANGELOG.json from a change file or dependent bump.
|
||||
* These objects are saved under the `ChangelogJson`'s `entries[].comments[type]`.
|
||||
*
|
||||
* (This is based on an individual `ChangeFileInfo` from ./ChangeInfo.ts, but with some different
|
||||
* naming and details.)
|
||||
*/
|
||||
export interface ChangelogEntry {
|
||||
/** Change comment */
|
||||
comment: string;
|
||||
/** Author email */
|
||||
author: string;
|
||||
/** Commit hash */
|
||||
/**
|
||||
* Commit hash.
|
||||
*
|
||||
* For changelogs generated by beachball versions \>=2.36.0, should be `"not available"` for
|
||||
* bump entries, because the correct commit doesn't exist yet (see [issue](https://github.com/microsoft/beachball/issues/901)).
|
||||
*
|
||||
* Could also be `"not available"` for other commits if there was an issue determing the hash
|
||||
* at changelog generation time.
|
||||
*/
|
||||
commit: string;
|
||||
/** Package name the change was in */
|
||||
package: string;
|
||||
/** Extra info added to the change file via custom prompts */
|
||||
[extraInfo: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changelog info for an individual version. Usually this is for a single package.
|
||||
* If using grouped changelogs, it could be for multiple packages.
|
||||
* Intermediate info used to generate a CHANGELOG.json entry for an individual version.
|
||||
* Usually this is for a single package. If using grouped changelogs, it could be for multiple packages.
|
||||
*/
|
||||
export interface PackageChangelog {
|
||||
/** Package name (if a grouped changelog, for the primary package) */
|
||||
|
@ -34,15 +51,20 @@ export interface PackageChangelog {
|
|||
}
|
||||
|
||||
/**
|
||||
* CHANGELOG.json entry for an individual version. Usually this is for a single package.
|
||||
* If using grouped changelogs, it could be for multiple packages.
|
||||
* CHANGELOG.json entry for an individual version (under `ChangelogJson`'s `entries`).
|
||||
* Usually this is for a single package. If using grouped changelogs, it could be for multiple packages.
|
||||
*/
|
||||
export type ChangelogJsonEntry = Omit<PackageChangelog, 'name' | 'date'> & {
|
||||
/** Version creation date as a string */
|
||||
date: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* CHANGELOG.json file contents.
|
||||
*/
|
||||
export interface ChangelogJson {
|
||||
/** Package name */
|
||||
name: string;
|
||||
/** Entries for each package version */
|
||||
entries: ChangelogJsonEntry[];
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче