forked from asgardeo/javascript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaggregate-changelogs.js
More file actions
81 lines (69 loc) · 2.81 KB
/
aggregate-changelogs.js
File metadata and controls
81 lines (69 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Aggregates all CHANGELOG.md files in the Nx workspace into a root CHANGELOG.md.
* Skips node_modules and the root CHANGELOG.md itself.
*/
const fs = require('fs');
const path = require('path');
const rootDir = process.cwd();
const outputFile = path.join(rootDir, 'CHANGELOG.md');
// List of package or directory names to skip when aggregating changelogs
const SKIP_PACKAGES = ['__legacy__', 'node_modules', 'dist', 'build', 'coverage', 'scripts', 'docs'];
const findChangelogs = dir => {
let changelogs = [];
const entries = fs.readdirSync(dir, {withFileTypes: true});
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory() && !SKIP_PACKAGES.includes(entry.name)) {
changelogs = changelogs.concat(findChangelogs(fullPath));
} else if (entry.isFile() && entry.name === 'CHANGELOG.md' && fullPath !== outputFile) {
// Check if the changelog is inside a skipped package
const relPath = path.relative(rootDir, fullPath);
const parts = relPath.split(path.sep);
if (!parts.some(part => SKIP_PACKAGES.includes(part))) {
changelogs.push(fullPath);
}
}
}
return changelogs;
};
const aggregate = () => {
const changelogFiles = findChangelogs(rootDir);
let toc = '<!-- THIS FILE IS AUTOGENERATED. DO NOT EDIT DIRECTLY. -->\n\n';
toc += '# Aggregated CHANGELOG\n\n';
toc += '## Table of Contents\n\n';
changelogFiles.forEach(file => {
const relPath = path.relative(rootDir, file);
// Get the package name (directory containing the CHANGELOG.md)
const pkgName = path.basename(path.dirname(file));
// Anchor links: replace / and . with - for markdown anchor compatibility
const anchor = relPath.replace(/\//g, '').replace(/\./g, '').toLowerCase();
toc += `- [${pkgName}](#${anchor})\n`;
});
toc += '\n';
let output = '';
changelogFiles.forEach(file => {
const relPath = path.relative(rootDir, file);
// Anchor for markdown: '## ' + relPath
output += fs.readFileSync(file, 'utf-8') + '\n\n';
});
fs.writeFileSync(outputFile, toc + output);
console.log(`Aggregated ${changelogFiles.length} changelogs into ${outputFile}`);
};
aggregate();