From 7873867c9ff7ae2390c10feab1e49d927446fbd7 Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Thu, 5 Sep 2024 16:36:58 -0700 Subject: [PATCH] Add writeChangelogJson option --- ...-526ee2eb-1931-449a-b24e-cc00cf631525.json | 7 ++++ src/__e2e__/bump.test.ts | 2 +- src/__fixtures__/changelog.ts | 15 +++++++-- .../changelog/writeChangelog.test.ts | 32 +++++++++++++++---- src/changelog/writeChangelog.ts | 26 ++++++++------- src/options/getDefaultOptions.ts | 1 + src/types/BeachballOptions.ts | 5 +++ 7 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 change/beachball-526ee2eb-1931-449a-b24e-cc00cf631525.json diff --git a/change/beachball-526ee2eb-1931-449a-b24e-cc00cf631525.json b/change/beachball-526ee2eb-1931-449a-b24e-cc00cf631525.json new file mode 100644 index 000000000..6a16ac0d7 --- /dev/null +++ b/change/beachball-526ee2eb-1931-449a-b24e-cc00cf631525.json @@ -0,0 +1,7 @@ +{ + "comment": "Add writeChangelogJson option", + "type": "minor", + "packageName": "beachball", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/src/__e2e__/bump.test.ts b/src/__e2e__/bump.test.ts index a8c488750..741632c94 100644 --- a/src/__e2e__/bump.test.ts +++ b/src/__e2e__/bump.test.ts @@ -602,7 +602,7 @@ describe('version bumping', () => { expect(modified).toContain('package2'); const changelogJson = readChangelogJson(repo.pathTo('packages/package2')); - expect(changelogJson.entries[0].comments.patch![0].comment).toBe('Bump package1 to v0.0.2'); + expect(changelogJson?.entries[0].comments.patch![0].comment).toBe('Bump package1 to v0.0.2'); }); it('calls sync prebump hook before packages are bumped', async () => { diff --git a/src/__fixtures__/changelog.ts b/src/__fixtures__/changelog.ts index d9ce88c2f..34b5511a5 100644 --- a/src/__fixtures__/changelog.ts +++ b/src/__fixtures__/changelog.ts @@ -5,15 +5,21 @@ import { SortedChangeTypes } from '../changefile/changeTypes'; import { ChangelogJson } from '../types/ChangeLog'; /** Read the CHANGELOG.md under the given package path, sanitizing any dates for snapshots */ -export function readChangelogMd(packagePath: string): string { +export function readChangelogMd(packagePath: string): string | undefined { const changelogFile = path.join(packagePath, 'CHANGELOG.md'); + if (!fs.existsSync(changelogFile)) { + return undefined; + } const text = fs.readFileSync(changelogFile, { encoding: 'utf-8' }); return text.replace(/\w\w\w, \d\d \w\w\w [\d :]+?GMT/gm, '(date)'); } /** Read the CHANGELOG.json under the given package path */ -export function readChangelogJson(packagePath: string, cleanForSnapshot: boolean = false): ChangelogJson { +export function readChangelogJson(packagePath: string, cleanForSnapshot: boolean = false): ChangelogJson | undefined { const changelogJsonFile = path.join(packagePath, 'CHANGELOG.json'); + if (!fs.existsSync(changelogJsonFile)) { + return undefined; + } const json = fs.readJSONSync(changelogJsonFile, { encoding: 'utf-8' }); return cleanForSnapshot ? cleanChangelogJson(json) : json; } @@ -22,7 +28,10 @@ export function readChangelogJson(packagePath: string, cleanForSnapshot: boolean * Clean changelog json for a snapshot: replace dates and SHAs with placeholders. * Note: this clones the changelog object rather than modifying the original. */ -export function cleanChangelogJson(changelog: ChangelogJson): ChangelogJson { +export function cleanChangelogJson(changelog: ChangelogJson | undefined): ChangelogJson | undefined { + if (!changelog) { + return undefined; + } changelog = _.cloneDeep(changelog); // for a better snapshot, make the fake commit match if the real commit did const fakeCommits: { [commit: string]: string } = {}; diff --git a/src/__functional__/changelog/writeChangelog.test.ts b/src/__functional__/changelog/writeChangelog.test.ts index afe2c4bb1..d93c02341 100644 --- a/src/__functional__/changelog/writeChangelog.test.ts +++ b/src/__functional__/changelog/writeChangelog.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it, beforeAll, afterAll, afterEach } from '@jest/globals'; +import fs from 'fs'; import { generateChangeFiles } from '../../__fixtures__/changeFiles'; import { cleanChangelogJson, readChangelogJson, readChangelogMd } from '../../__fixtures__/changelog'; import { initMockLogs } from '../../__fixtures__/mockLogs'; @@ -8,16 +9,16 @@ import { writeChangelog } from '../../changelog/writeChangelog'; import { getPackageInfos } from '../../monorepo/getPackageInfos'; import { readChangeFiles } from '../../changefile/readChangeFiles'; import { BeachballOptions } from '../../types/BeachballOptions'; -import { ChangeFileInfo, ChangeInfo } from '../../types/ChangeInfo'; +import { ChangeFileInfo, ChangeInfo, ChangeType } from '../../types/ChangeInfo'; import type { Repository } from '../../__fixtures__/repository'; import { getDefaultOptions } from '../../options/getDefaultOptions'; -function getChange(packageName: string, comment: string): ChangeFileInfo { +function getChange(packageName: string, comment: string, type: ChangeType = 'patch'): ChangeFileInfo { return { comment, email: 'test@testtestme.com', packageName, - type: 'patch', + type, dependentChangeType: 'patch', }; } @@ -77,7 +78,7 @@ describe('writeChangelog', () => { expect(cleanChangelogJson(changelogJson)).toMatchSnapshot('changelog json'); // Every entry should have a different commit hash - const patchComments = changelogJson.entries[0].comments.patch!; + const patchComments = changelogJson!.entries[0].comments.patch!; const commits = patchComments.map(entry => entry.commit); expect(new Set(commits).size).toEqual(patchComments.length); @@ -111,7 +112,7 @@ describe('writeChangelog', () => { expect(cleanChangelogJson(changelogJson)).toMatchSnapshot('changelog json'); // Every entry should have a different commit hash - const patchComments = changelogJson.entries[0].comments.patch!; + const patchComments = changelogJson!.entries[0].comments.patch!; const commits = patchComments.map(entry => entry.commit); expect(new Set(commits).size).toEqual(patchComments.length); @@ -151,7 +152,7 @@ describe('writeChangelog', () => { expect(readChangelogJson(repo.pathTo('packages/bar'), true /*clean*/)).toMatchSnapshot('bar CHANGELOG.json'); // Every entry should have a different commit hash - const patchComments = fooJson.entries[0].comments.patch!; + const patchComments = fooJson!.entries[0].comments.patch!; const commits = patchComments.map(entry => entry.commit); expect(new Set(commits).size).toEqual(patchComments.length); @@ -343,4 +344,23 @@ describe('writeChangelog', () => { } } }); + + it('does not write CHANGELOG.json if writeChangelogJson is false', async () => { + repo = repositoryFactory.cloneRepository(); + const options = getOptions({ writeChangelogJson: false }); + + repo.commitChange('foo'); + generateChangeFiles([getChange('foo', 'comment 1')], options); + + const packageInfos = getPackageInfos(repo.rootPath); + const changes = readChangeFiles(options, packageInfos); + + await writeChangelog(options, changes, { foo: 'patch' }, { foo: new Set(['foo']) }, packageInfos); + + // CHANGELOG.md is written + expect(readChangelogMd(repo.rootPath)).toContain('## 1.0.0'); + + // CHANGELOG.json is not written + expect(fs.existsSync(repo.pathTo('CHANGELOG.json'))).toBe(false); + }); }); diff --git a/src/changelog/writeChangelog.ts b/src/changelog/writeChangelog.ts index 435b0aa23..0b599625b 100644 --- a/src/changelog/writeChangelog.ts +++ b/src/changelog/writeChangelog.ts @@ -122,18 +122,20 @@ async function writeChangelogFiles( ): Promise { let previousJson: ChangelogJson | undefined; - // Update CHANGELOG.json - const changelogJsonFile = path.join(changelogPath, 'CHANGELOG.json'); - try { - previousJson = fs.existsSync(changelogJsonFile) ? fs.readJSONSync(changelogJsonFile) : undefined; - } catch (e) { - console.warn(`${changelogJsonFile} is invalid: ${e}`); - } - try { - const nextJson = renderJsonChangelog(newVersionChangelog, previousJson); - fs.writeJSONSync(changelogJsonFile, nextJson, { spaces: 2 }); - } catch (e) { - console.warn(`Problem writing to ${changelogJsonFile}: ${e}`); + if (options.writeChangelogJson) { + // Update CHANGELOG.json + const changelogJsonFile = path.join(changelogPath, 'CHANGELOG.json'); + try { + previousJson = fs.existsSync(changelogJsonFile) ? fs.readJSONSync(changelogJsonFile) : undefined; + } catch (e) { + console.warn(`${changelogJsonFile} is invalid: ${e}`); + } + try { + const nextJson = renderJsonChangelog(newVersionChangelog, previousJson); + fs.writeJSONSync(changelogJsonFile, nextJson, { spaces: 2 }); + } catch (e) { + console.warn(`Problem writing to ${changelogJsonFile}: ${e}`); + } } // Update CHANGELOG.md diff --git a/src/options/getDefaultOptions.ts b/src/options/getDefaultOptions.ts index b3d87dd72..014b2ce92 100644 --- a/src/options/getDefaultOptions.ts +++ b/src/options/getDefaultOptions.ts @@ -36,6 +36,7 @@ export function getDefaultOptions(): BeachballOptions { timeout: undefined, type: null, version: false, + writeChangelogJson: true, yes: env.isCI, }; } diff --git a/src/types/BeachballOptions.ts b/src/types/BeachballOptions.ts index 9b33ce030..c45830ee4 100644 --- a/src/types/BeachballOptions.ts +++ b/src/types/BeachballOptions.ts @@ -171,6 +171,11 @@ export interface RepoOptions { groupChanges?: boolean; /** For shallow clones only: Depth of git history to consider when doing fetch */ depth?: number; + /** + * Whether to write CHANGELOG.json files. + * @default true + */ + writeChangelogJson?: boolean; } export interface PackageOptions {