Skip to content

Commit 795f8fa

Browse files
committed
fix
1 parent dfb8048 commit 795f8fa

1 file changed

Lines changed: 58 additions & 27 deletions

File tree

scripts/aggregate-ui-changelog.js

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// scripts/aggregate-ui-changelog.js
2-
// Node 18+ (or Bun). Requires GITHUB_TOKEN.
2+
// Node 18+ (or Bun). Requires GITHUB_TOKEN with read access to the UI repos.
33

44
import {execSync} from 'node:child_process';
55
import {readdirSync, writeFileSync} from 'node:fs';
66

7+
// Look for bundled UI zips inside the Pano module
78
const UI_DIR = 'Pano/src/main/resources/UIFiles';
9+
10+
// Organization / repository mapping
811
const OWNER = 'PanoMC';
912
const REPOS = {
1013
'panel-ui': 'panel-ui',
@@ -18,16 +21,23 @@ if (!token) {
1821
process.exit(1);
1922
}
2023

24+
/**
25+
* Parse zip file name: "<component>-v1.0.0-dev.34.zip" (the "v" is optional)
26+
*/
2127
function parseZip(name) {
2228
const m = name.match(/^([a-z0-9-]+)-((?:v)?\d+\.\d+\.\d+(?:-[a-z0-9.]+)?)\.zip$/i);
2329
if (!m) return null;
2430
return {comp: m[1], version: m[2].startsWith('v') ? m[2] : `v${m[2]}`};
2531
}
2632

33+
/**
34+
* Read current UI zip versions from working tree
35+
*/
2736
function listCurrentVersions() {
2837
const entries = readdirSync(UI_DIR, {withFileTypes: true})
2938
.filter((d) => d.isFile() && d.name.endsWith('.zip'))
3039
.map((d) => d.name);
40+
3141
const map = {};
3242
for (const f of entries) {
3343
const p = parseZip(f);
@@ -36,6 +46,9 @@ function listCurrentVersions() {
3646
return map;
3747
}
3848

49+
/**
50+
* Get the previous tag (semantic-release last tag)
51+
*/
3952
function getPrevTag() {
4053
try {
4154
return execSync('git describe --tags --abbrev=0 HEAD^', {encoding: 'utf8'}).trim();
@@ -48,6 +61,9 @@ function getPrevTag() {
4861
}
4962
}
5063

64+
/**
65+
* Read UI zip versions from the previous tag’s tree without checkout
66+
*/
5167
function listPreviousVersionsFromTag(prevTag) {
5268
if (!prevTag) return {};
5369
let listing = '';
@@ -65,6 +81,9 @@ function listPreviousVersionsFromTag(prevTag) {
6581
return map;
6682
}
6783

84+
/**
85+
* Minimal GitHub API helper
86+
*/
6887
async function ghJson(path, params = {}) {
6988
const url = `https://api.github.com${path}`;
7089
const res = await fetch(url, {
@@ -82,10 +101,18 @@ async function ghJson(path, params = {}) {
82101
return await res.json();
83102
}
84103

85-
// Normalize UI repo release body into clean bullet lines
104+
/**
105+
* Normalize a UI repo release body to clean bullet lines:
106+
* - drop any heading lines (start with #) and section names (Features, Bug Fixes, etc.)
107+
* - drop version/date headings
108+
* - drop code blocks
109+
* - flatten to "- ..." bullets
110+
* - de-duplicate
111+
*/
86112
function normalizeReleaseBody(body) {
87113
const out = [];
88114
let inCode = false;
115+
89116
for (const raw of body.split('\n')) {
90117
const line = raw.replace(/\s+$/, ''); // rtrim
91118
const t = line.trim();
@@ -100,33 +127,28 @@ function normalizeReleaseBody(body) {
100127
// skip empty
101128
if (!t) continue;
102129

103-
// drop version/date headings & section headers
130+
// drop any markdown headings
131+
if (/^#{1,6}\s*/.test(t)) continue;
132+
133+
// drop common section headers and separators
104134
if (
105-
/^#{1,6}\s*(v?\d+\.\d+\.\d+(?:-[^\s)]+)?)(\s*\(\d{4}-\d{2}-\d{2}\))?/i.test(t) ||
106-
/^(v?\d+\.\d+\.\d+(?:-[^\s)]+)?)(\s*\(\d{4}-\d{2}-\d{2}\))?$/.test(t) ||
107-
/^#{1,6}\s*(features|bug fixes|fixes|performance improvements|reverts|chores|chore|ci|build)\s*$/i.test(t) ||
108-
/^(features|bug fixes|fixes|performance improvements|reverts|chores|chore|ci|build)\s*$/i.test(t) ||
109-
/^-{3,}$/.test(t)
135+
/^(features|bug fixes|fix(es)?|performance improvements|reverts|chores?|ci|build|changes)\s*:?$/i.test(t) ||
136+
/^[-_]{3,}$/.test(t)
110137
) continue;
111138

112-
// normalize list items / commit-like lines
113-
let item = t.replace(/^[-*]\s+/, ''); // strip leading list marker
114-
item = item.replace(/^\d+\.\s+/, ''); // strip ordered list
139+
// drop version/date headings like "1.0.0 (2025-08-28)" or "v1.2.3"
140+
if (/^(v?\d+\.\d+\.\d+(?:-[^\s)]+)?)(\s*\(\d{4}-\d{2}-\d{2}\))?$/i.test(t)) continue;
141+
142+
// normalize list items / ordered items
143+
let item = t.replace(/^[-*]\s+/, ''); // strip leading list marker
144+
item = item.replace(/^\d+\.\s+/, ''); // strip ordered list
115145
item = item.replace(/^\s+/, '');
116146

117-
// if it looks like a conventional header or a plain message, bullet it
118-
if (!/^[-*]\s+/.test(t)) {
119-
if (/^(feat|fix|perf|refactor|docs|chore|build|ci)(\(.+\))?:/i.test(item)) {
120-
out.push(`- ${item}`);
121-
} else {
122-
out.push(`- ${item}`);
123-
}
124-
} else {
125-
out.push(`- ${item}`);
126-
}
147+
// bulletize anything left (including conventional headers)
148+
out.push(`- ${item}`);
127149
}
128150

129-
// dedupe (case-insensitive)
151+
// de-duplicate (case-insensitive)
130152
const seen = new Set();
131153
const uniq = [];
132154
for (const l of out) {
@@ -139,11 +161,16 @@ function normalizeReleaseBody(body) {
139161
return uniq;
140162
}
141163

164+
/**
165+
* Collect notes between fromTag…toTag for a repo:
166+
* 1) Conventional commit headers from compare API
167+
* 2) Target tag’s normalized GitHub Release body (if exists)
168+
*/
142169
async function collectNotesForRange(repo, fromTag, toTag) {
143-
const set = new Set(); // for dedupe
170+
const set = new Set();
144171
const lines = [];
145172

146-
// 1) Conventional commit headers via compare API
173+
// 1) Conventional commits via compare API
147174
try {
148175
const cmp = await ghJson(
149176
`/repos/${OWNER}/${repo}/compare/${encodeURIComponent(fromTag)}...${encodeURIComponent(toTag)}`
@@ -164,7 +191,7 @@ async function collectNotesForRange(repo, fromTag, toTag) {
164191
// ignore
165192
}
166193

167-
// 2) Append normalized release body (toTag), if any
194+
// 2) Append normalized release body of toTag
168195
try {
169196
const releases = await ghJson(`/repos/${OWNER}/${repo}/releases?per_page=100`);
170197
for (const r of releases) {
@@ -186,6 +213,9 @@ async function collectNotesForRange(repo, fromTag, toTag) {
186213
return lines.length ? lines.join('\n') : null;
187214
}
188215

216+
/**
217+
* Main
218+
*/
189219
(async () => {
190220
const current = listCurrentVersions();
191221
const prevTag = getPrevTag();
@@ -201,9 +231,10 @@ async function collectNotesForRange(repo, fromTag, toTag) {
201231
const notes = await collectNotesForRange(repo, oldV, nowV);
202232
if (!notes) continue;
203233

234+
// Section title WITHOUT "###" — use bold line instead
204235
sections.push(
205236
[
206-
`### ${comp}: ${oldV}${nowV}`,
237+
`**${comp}: ${oldV}${nowV}**`,
207238
'',
208239
notes
209240
].join('\n')
@@ -216,7 +247,7 @@ async function collectNotesForRange(repo, fromTag, toTag) {
216247
return;
217248
}
218249

219-
// Visible spacing in GitHub release body
250+
// Visible spacing in GitHub release body (don’t rely on collapsed newlines)
220251
const SPACER = '\n<br/>\n<br/>\n';
221252
const output = `${SPACER}${sections.join(SPACER)}\n`;
222253

0 commit comments

Comments
 (0)