Skip to content

Commit b5d3d5b

Browse files
committed
fix: Changelog version sorting with same dates
1 parent 3740e41 commit b5d3d5b

File tree

1 file changed

+59
-3
lines changed

1 file changed

+59
-3
lines changed

scripts/generate-changelog.js

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,47 @@ function fetchUrl(url) {
3434
});
3535
}
3636

37+
/**
38+
* Parse version string into comparable parts
39+
* Returns object with major, minor, patch, and prerelease info
40+
*/
41+
function parseVersion(versionString) {
42+
const parts = versionString.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
43+
if (!parts) return null;
44+
45+
return {
46+
major: parseInt(parts[1]),
47+
minor: parseInt(parts[2]),
48+
patch: parseInt(parts[3]),
49+
prerelease: parts[4] || null
50+
};
51+
}
52+
53+
/**
54+
* Compare two version strings
55+
* Returns: -1 if a < b, 0 if equal, 1 if a > b
56+
*/
57+
function compareVersions(versionA, versionB) {
58+
const a = parseVersion(versionA);
59+
const b = parseVersion(versionB);
60+
61+
if (!a || !b) return 0;
62+
63+
// Compare major, minor, patch
64+
if (a.major !== b.major) return a.major - b.major;
65+
if (a.minor !== b.minor) return a.minor - b.minor;
66+
if (a.patch !== b.patch) return a.patch - b.patch;
67+
68+
// If versions are equal up to patch, handle prerelease
69+
// Stable versions (no prerelease) come AFTER prereleases
70+
if (!a.prerelease && !b.prerelease) return 0;
71+
if (!a.prerelease) return 1; // a is stable, b is prerelease
72+
if (!b.prerelease) return -1; // a is prerelease, b is stable
73+
74+
// Both are prereleases, compare prerelease strings
75+
return a.prerelease.localeCompare(b.prerelease);
76+
}
77+
3778
function parseChangelog(markdown, type) {
3879
const lines = markdown.split('\n');
3980
const versions = [];
@@ -195,12 +236,20 @@ async function generateChangelog() {
195236
function limitStableWithDev(versions, maxStable) {
196237
const stable = versions
197238
.filter(v => !v.isDev)
198-
.sort((a, b) => new Date(b.date) - new Date(a.date))
239+
.sort((a, b) => {
240+
const dateCompare = new Date(b.date) - new Date(a.date);
241+
if (dateCompare !== 0) return dateCompare;
242+
return compareVersions(b.version, a.version);
243+
})
199244
.slice(0, maxStable);
200245

201246
const dev = versions
202247
.filter(v => v.isDev)
203-
.sort((a, b) => new Date(b.date) - new Date(a.date));
248+
.sort((a, b) => {
249+
const dateCompare = new Date(b.date) - new Date(a.date);
250+
if (dateCompare !== 0) return dateCompare;
251+
return compareVersions(b.version, a.version);
252+
});
204253

205254
return [...stable, ...dev];
206255
}
@@ -209,7 +258,14 @@ async function generateChangelog() {
209258
const limitedPatchesVersions = limitStableWithDev(patchesVersions, MAX_PATCHES_RELEASES);
210259

211260
const allVersions = [...limitedManagerVersions, ...limitedPatchesVersions]
212-
.sort((a, b) => new Date(b.date) - new Date(a.date));
261+
.sort((a, b) => {
262+
// First sort by date (newest first)
263+
const dateCompare = new Date(b.date) - new Date(a.date);
264+
if (dateCompare !== 0) return dateCompare;
265+
266+
// If dates are equal, sort by version (newest first)
267+
return compareVersions(b.version, a.version);
268+
});
213269

214270
console.log(`✅ Found ${allVersions.length} releases`);
215271

0 commit comments

Comments
 (0)