Skip to content

Commit 3266b96

Browse files
authored
Improvement: stop depending on NPM changelog (#8687)
* Improvement: stop depending on NPM changelog * Changed log level
1 parent a3c963b commit 3266b96

File tree

4 files changed

+172
-128
lines changed

4 files changed

+172
-128
lines changed

tools/js-sdk-release-tools/src/common/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,19 @@ export function fixChangelogFormat(content: string) {
5858
content = replaceAll(content, '**Bugs Fixed**', '### Bugs Fixed')!;
5959
content = replaceAll(content, '**Other Changes**', '### Other Changes')!;
6060
return content;
61+
}
62+
63+
export function tryReadNpmPackageChangelog(packageFolderPath: string): string {
64+
const changelogPath = path.join(packageFolderPath, 'changelog-temp', 'package', 'CHANGELOG.md');
65+
try {
66+
if (!fs.existsSync(changelogPath)) {
67+
logger.logWarn(`NPM package's changelog "${changelogPath}" does not exists`);
68+
return "";
69+
}
70+
const originalChangeLogContent = fs.readFileSync(changelogPath, { encoding: 'utf-8' });
71+
return originalChangeLogContent;
72+
} catch (err) {
73+
logger.logWarn(`Failed to read NPM package's changelog "${changelogPath}": ${(err as Error)?.stack ?? err}`);
74+
return '';
75+
}
6176
}

tools/js-sdk-release-tools/src/hlc/utils/automaticGenerateChangeLogAndBumpVersion.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { execSync } from "child_process";
2222
import { getversionDate } from "../../utils/version";
2323
import { ApiVersionType } from "../../common/types"
2424
import { getApiVersionType } from '../../xlc/apiVersion/apiVersionTypeExtractor'
25-
import { fixChangelogFormat, getApiReviewPath, getNpmPackageName, getSDKType } from '../../common/utils';
25+
import { fixChangelogFormat, getApiReviewPath, getNpmPackageName, getSDKType, tryReadNpmPackageChangelog } from '../../common/utils';
2626

2727
export async function generateChangelogAndBumpVersion(packageFolderPath: string) {
2828
const jsSdkRepoPath = String(shell.pwd());
@@ -66,7 +66,7 @@ export async function generateChangelogAndBumpVersion(packageFolderPath: string)
6666
const oldSDKType = getSDKType(npmPackageRoot);
6767
const newSDKType = getSDKType(packageFolderPath);
6868
const changelog: Changelog = await extractExportAndGenerateChangelog(apiMdFileNPM, apiMdFileLocal, oldSDKType, newSDKType);
69-
let originalChangeLogContent = fs.readFileSync(path.join(packageFolderPath, 'changelog-temp', 'package', 'CHANGELOG.md'), { encoding: 'utf-8' });
69+
let originalChangeLogContent = tryReadNpmPackageChangelog(packageFolderPath);
7070
if(nextVersion){
7171
shell.cd(path.join(packageFolderPath, 'changelog-temp'));
7272
shell.mkdir(path.join(packageFolderPath, 'changelog-temp', 'next'));
@@ -80,7 +80,7 @@ export async function generateChangelogAndBumpVersion(packageFolderPath: string)
8080
const latestDate = getversionDate(npmViewResult, stableVersion);
8181
const nextDate = getversionDate(npmViewResult,nextVersion);
8282
if (latestDate && nextDate && latestDate <= nextDate){
83-
originalChangeLogContent = fs.readFileSync(path.join(packageFolderPath,'changelog-temp', 'next', 'package', 'CHANGELOG.md'), {encoding: 'utf-8'});
83+
originalChangeLogContent = tryReadNpmPackageChangelog(packageFolderPath);
8484
logger.log('Need to keep previous preview changelog');
8585

8686
}

tools/js-sdk-release-tools/src/llc/utils/generateChangelog.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { NPMScope } from "@ts-common/azure-js-dev-tools";
44
import { logger } from "../../utils/logger";
55
import { getLatestStableVersion } from "../../utils/version";
66
import { extractExportAndGenerateChangelog } from "../../changelog/extractMetaData";
7-
import { fixChangelogFormat, getApiReviewPath, getSDKType } from "../../common/utils";
7+
import { fixChangelogFormat, getApiReviewPath, getSDKType, tryReadNpmPackageChangelog } from "../../common/utils";
88

99
const shell = require('shelljs');
1010
const todayDate = new Date();
@@ -22,7 +22,7 @@ function generateChangelogForFirstRelease(packagePath, version) {
2222
}
2323

2424
function appendChangelog(packagePath, version, changelog) {
25-
let originalChangeLogContent: string = fs.readFileSync(path.join(packagePath, 'changelog-temp', 'package', 'CHANGELOG.md'), { encoding: 'utf-8' });
25+
let originalChangeLogContent: string = tryReadNpmPackageChangelog(packagePath);
2626
originalChangeLogContent = fixChangelogFormat(originalChangeLogContent);
2727

2828
const modifiedChangelogContent = `## ${version} (${date})
Lines changed: 152 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,158 @@
11
import { expect, test } from "vitest";
22
import { extractExportAndGenerateChangelog } from "../../changelog/extractMetaData";
3-
import path from "path";
3+
import path, { join } from "path";
44
import { SDKType } from "../../common/types";
5-
6-
test("HLC -> Modular: Rename", async () => {
7-
const oldViewPath = path.join(
8-
__dirname,
9-
"testCases/operationGroups.1.old.hlc.api.md"
10-
);
11-
const newViewPath = path.join(
12-
__dirname,
13-
"testCases/operationGroups.1.new.modular.api.md"
14-
);
15-
const changelog = await extractExportAndGenerateChangelog(
16-
oldViewPath,
17-
newViewPath,
18-
SDKType.HighLevelClient,
19-
SDKType.ModularClient
20-
);
21-
22-
expect(changelog.addedOperationGroup.length).toBe(0);
23-
expect(changelog.removedOperationGroup.length).toBe(0);
24-
25-
expect(changelog.addedOperation.length).toBe(1);
26-
expect(changelog.removedOperation.length).toBe(1);
27-
28-
expect(changelog.addedOperation[0]).toBe(
29-
"Added operation DataProductsCatalogsOperations.listByResourceGroup_NEW"
30-
);
31-
expect(changelog.removedOperation[0]).toBe(
32-
"Removed operation DataProductsCatalogs.listByResourceGroup"
33-
);
34-
});
35-
36-
test("HLC -> HLC: Change Op", async () => {
37-
const oldViewPath = path.join(
38-
__dirname,
39-
"testCases/operationGroups.2.old.hlc.api.md"
40-
);
41-
const newViewPath = path.join(
42-
__dirname,
43-
"testCases/operationGroups.2.new.hlc.api.md"
44-
);
45-
const changelog = await extractExportAndGenerateChangelog(
46-
oldViewPath,
47-
newViewPath,
48-
SDKType.HighLevelClient,
49-
SDKType.HighLevelClient
50-
);
51-
52-
expect(changelog.addedOperationGroup.length).toBe(0);
53-
expect(changelog.removedOperationGroup.length).toBe(0);
54-
55-
expect(changelog.addedOperation.length).toBe(1);
56-
expect(changelog.removedOperation.length).toBe(1);
57-
58-
expect(changelog.addedOperation[0]).toBe(
59-
"Added operation DataProductsCatalogs.get_NEW"
60-
);
61-
expect(changelog.removedOperation[0]).toBe(
62-
"Removed operation DataProductsCatalogs.get"
63-
);
64-
});
65-
66-
test("Modular -> Modular: Change Op", async () => {
67-
const oldViewPath = path.join(
68-
__dirname,
69-
"testCases/operationGroups.3.old.modular.api.md"
70-
);
71-
const newViewPath = path.join(
72-
__dirname,
73-
"testCases/operationGroups.3.new.modular.api.md"
74-
);
75-
const changelog = await extractExportAndGenerateChangelog(
76-
oldViewPath,
77-
newViewPath,
78-
SDKType.ModularClient,
79-
SDKType.ModularClient
80-
);
81-
82-
expect(changelog.addedOperationGroup.length).toBe(0);
83-
expect(changelog.removedOperationGroup.length).toBe(0);
84-
85-
expect(changelog.addedOperation.length).toBe(1);
86-
expect(changelog.removedOperation.length).toBe(1);
87-
88-
expect(changelog.addedOperation[0]).toBe(
89-
"Added operation DataProductsCatalogsOperations.listByResourceGroup_NEW"
90-
);
91-
expect(changelog.removedOperation[0]).toBe(
92-
"Removed operation DataProductsCatalogsOperations.listByResourceGroup"
93-
);
5+
import { describe } from "node:test";
6+
import { mkdirSync } from "node:fs";
7+
import { tryReadNpmPackageChangelog } from "../../common/utils";
8+
import { rmdirSync, writeFileSync } from "fs";
9+
10+
function getRandomInt(max) {
11+
return Math.floor(Math.random() * max);
12+
}
13+
14+
describe("Breaking change detection", () => {
15+
test("HLC -> Modular: Rename", async () => {
16+
const oldViewPath = path.join(
17+
__dirname,
18+
"testCases/operationGroups.1.old.hlc.api.md"
19+
);
20+
const newViewPath = path.join(
21+
__dirname,
22+
"testCases/operationGroups.1.new.modular.api.md"
23+
);
24+
const changelog = await extractExportAndGenerateChangelog(
25+
oldViewPath,
26+
newViewPath,
27+
SDKType.HighLevelClient,
28+
SDKType.ModularClient
29+
);
30+
31+
expect(changelog.addedOperationGroup.length).toBe(0);
32+
expect(changelog.removedOperationGroup.length).toBe(0);
33+
34+
expect(changelog.addedOperation.length).toBe(1);
35+
expect(changelog.removedOperation.length).toBe(1);
36+
37+
expect(changelog.addedOperation[0]).toBe(
38+
"Added operation DataProductsCatalogsOperations.listByResourceGroup_NEW"
39+
);
40+
expect(changelog.removedOperation[0]).toBe(
41+
"Removed operation DataProductsCatalogs.listByResourceGroup"
42+
);
43+
});
44+
45+
test("HLC -> HLC: Change Op", async () => {
46+
const oldViewPath = path.join(
47+
__dirname,
48+
"testCases/operationGroups.2.old.hlc.api.md"
49+
);
50+
const newViewPath = path.join(
51+
__dirname,
52+
"testCases/operationGroups.2.new.hlc.api.md"
53+
);
54+
const changelog = await extractExportAndGenerateChangelog(
55+
oldViewPath,
56+
newViewPath,
57+
SDKType.HighLevelClient,
58+
SDKType.HighLevelClient
59+
);
60+
61+
expect(changelog.addedOperationGroup.length).toBe(0);
62+
expect(changelog.removedOperationGroup.length).toBe(0);
63+
64+
expect(changelog.addedOperation.length).toBe(1);
65+
expect(changelog.removedOperation.length).toBe(1);
66+
67+
expect(changelog.addedOperation[0]).toBe(
68+
"Added operation DataProductsCatalogs.get_NEW"
69+
);
70+
expect(changelog.removedOperation[0]).toBe(
71+
"Removed operation DataProductsCatalogs.get"
72+
);
73+
});
74+
75+
test("Modular -> Modular: Change Op", async () => {
76+
const oldViewPath = path.join(
77+
__dirname,
78+
"testCases/operationGroups.3.old.modular.api.md"
79+
);
80+
const newViewPath = path.join(
81+
__dirname,
82+
"testCases/operationGroups.3.new.modular.api.md"
83+
);
84+
const changelog = await extractExportAndGenerateChangelog(
85+
oldViewPath,
86+
newViewPath,
87+
SDKType.ModularClient,
88+
SDKType.ModularClient
89+
);
90+
91+
expect(changelog.addedOperationGroup.length).toBe(0);
92+
expect(changelog.removedOperationGroup.length).toBe(0);
93+
94+
expect(changelog.addedOperation.length).toBe(1);
95+
expect(changelog.removedOperation.length).toBe(1);
96+
97+
expect(changelog.addedOperation[0]).toBe(
98+
"Added operation DataProductsCatalogsOperations.listByResourceGroup_NEW"
99+
);
100+
expect(changelog.removedOperation[0]).toBe(
101+
"Removed operation DataProductsCatalogsOperations.listByResourceGroup"
102+
);
103+
});
104+
105+
test("HLC -> HLC: Operation Group Add/Remove/ChangeSig", async () => {
106+
const oldViewPath = path.join(
107+
__dirname,
108+
"testCases/operationGroups.4.old.hlc.api.md"
109+
);
110+
const newViewPath = path.join(
111+
__dirname,
112+
"testCases/operationGroups.4.new.hlc.api.md"
113+
);
114+
const changelog = await extractExportAndGenerateChangelog(
115+
oldViewPath,
116+
newViewPath,
117+
SDKType.HighLevelClient,
118+
SDKType.HighLevelClient
119+
);
120+
121+
expect(changelog.addedOperationGroup.length).toBe(1);
122+
expect(changelog.removedOperationGroup.length).toBe(1);
123+
124+
expect(changelog.addedOperation.length).toBe(0);
125+
expect(changelog.removedOperation.length).toBe(0);
126+
127+
expect(changelog.operationSignatureChange.length).toBe(1);
128+
129+
expect(changelog.addedOperationGroup[0]).toBe(
130+
"Added operation group DataProductsCatalogs_add"
131+
);
132+
expect(changelog.removedOperationGroup[0]).toBe(
133+
"Removed operation group DataProductsCatalogs_remove"
134+
);
135+
expect(changelog.operationSignatureChange[0]).toBe(
136+
"Operation DataProductsCatalogs_sig_change.get has a new signature"
137+
);
138+
});
94139
});
95140

96-
test("HLC -> HLC: Operation Group Add/Remove/ChangeSig", async () => {
97-
const oldViewPath = path.join(
98-
__dirname,
99-
"testCases/operationGroups.4.old.hlc.api.md"
100-
);
101-
const newViewPath = path.join(
102-
__dirname,
103-
"testCases/operationGroups.4.new.hlc.api.md"
104-
);
105-
const changelog = await extractExportAndGenerateChangelog(
106-
oldViewPath,
107-
newViewPath,
108-
SDKType.HighLevelClient,
109-
SDKType.HighLevelClient
110-
);
111-
112-
expect(changelog.addedOperationGroup.length).toBe(1);
113-
expect(changelog.removedOperationGroup.length).toBe(1);
114-
115-
expect(changelog.addedOperation.length).toBe(0);
116-
expect(changelog.removedOperation.length).toBe(0);
117-
118-
expect(changelog.operationSignatureChange.length).toBe(1);
119-
120-
expect(changelog.addedOperationGroup[0]).toBe(
121-
"Added operation group DataProductsCatalogs_add"
122-
);
123-
expect(changelog.removedOperationGroup[0]).toBe(
124-
"Removed operation group DataProductsCatalogs_remove"
125-
);
126-
expect(changelog.operationSignatureChange[0]).toBe(
127-
"Operation DataProductsCatalogs_sig_change.get has a new signature"
128-
);
141+
describe("Changelog reading", () => {
142+
const tempPackageFolder = `./tmp/package-${getRandomInt(10000)}`;
143+
try {
144+
test("Read changelog that doesn't exist", () => {
145+
const content = tryReadNpmPackageChangelog(tempPackageFolder);
146+
expect(content).toBe("");
147+
});
148+
const changelogPath = join(tempPackageFolder, 'CHANGELOG.md')
149+
writeFileSync(changelogPath, 'aaa', 'utf-8');
150+
151+
test("Read changelog that exists", () => {
152+
const content = tryReadNpmPackageChangelog(tempPackageFolder);
153+
expect(content).toBe("aaa");
154+
})
155+
} finally {
156+
rmdirSync(tempPackageFolder);
157+
}
129158
});

0 commit comments

Comments
 (0)