Adds a deterministic changelog-archive split so scripts/release.mjs stops regenerating one ever-growing root CHANGELOG.md and instead keeps only current release notes at the root while durably archiving pre-0.50.0 history. - Add scripts/lib/changelog-archive.mjs with partitionVersionsByCutoff (splits a version-ordered list at the 0.50.0 cutoff, preserving order and treating non-parseable keys as archived) and archivePointerLine (renders the "older releases" pointer appended to the current changelog). - Rework scripts/release.mjs's syncRootChangelog to build CHANGELOG.md (current versions + archive pointer) and a new CHANGELOG-archive.md (versions before 0.50.0) via a shared buildRootChangelogLines/normalizeChangelogLines helper instead of one monolithic file. - Add scripts/__tests__/changelog-archive.test.mjs covering cutoff partitioning, boundary/patch handling, non-parseable keys, custom cutoffs, and the archive pointer text. - Regenerate CHANGELOG.md (now only 0.50.0+) and add CHANGELOG-archive.md containing the pre-0.50.0 history moved out of the root file. Files changed: CHANGELOG-archive.md | 10882 +++++++++++++++++++++++ CHANGELOG.md | 11717 ++----------------------- scripts/__tests__/changelog-archive.test.mjs | 58 + scripts/lib/changelog-archive.mjs | 56 + scripts/release.mjs | 49 +- 5 files changed, 11710 insertions(+), 11052 deletions(-) Fusion-Task-Id: FN-7875 Fusion-Task-Lineage: 220e6aa1-54fb-4800-a86e-6d8d21f6bf18 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
57 lines
1.9 KiB
JavaScript
57 lines
1.9 KiB
JavaScript
/**
|
|
* FNXC:ReleaseChangelog 2026-07-12-00:00:
|
|
* The root CHANGELOG.md is regenerated by scripts/release.mjs on every release, so pruning old release notes by hand would be reverted.
|
|
* Keep the 0.50.0 cutoff in generator-owned pure logic so current release notes stay in CHANGELOG.md and older notes are durably split into CHANGELOG-archive.md.
|
|
*/
|
|
export const CHANGELOG_ARCHIVE_CUTOFF = "0.50.0";
|
|
export const CHANGELOG_ARCHIVE_FILE = "CHANGELOG-archive.md";
|
|
|
|
/**
|
|
* Partition version keys while preserving the source changelog order inside each bucket.
|
|
* Versions greater than or equal to the cutoff remain in the current changelog; versions below it, including non-parseable keys treated as 0.0.0, move to the archive.
|
|
*
|
|
* @param {string[]} versionOrder
|
|
* @param {string} cutoff
|
|
* @returns {{ current: string[], archived: string[] }}
|
|
*/
|
|
export function partitionVersionsByCutoff(versionOrder, cutoff = CHANGELOG_ARCHIVE_CUTOFF) {
|
|
const current = [];
|
|
const archived = [];
|
|
|
|
for (const version of versionOrder) {
|
|
if (compareSemver(version, cutoff) >= 0) {
|
|
current.push(version);
|
|
} else {
|
|
archived.push(version);
|
|
}
|
|
}
|
|
|
|
return { current, archived };
|
|
}
|
|
|
|
/**
|
|
* Return the stable archive pointer appended to the current root changelog.
|
|
*
|
|
* @param {string} archiveFile
|
|
* @returns {string}
|
|
*/
|
|
export function archivePointerLine(archiveFile = CHANGELOG_ARCHIVE_FILE) {
|
|
return `> Older releases (before ${CHANGELOG_ARCHIVE_CUTOFF}) are archived in [\`${archiveFile}\`](./${archiveFile}).`;
|
|
}
|
|
|
|
/** Compare two semver-ish version strings ("0.2.5", "0.4.0 (pre-release)"). */
|
|
function compareSemver(a, b) {
|
|
const pa = parseVersionKey(a);
|
|
const pb = parseVersionKey(b);
|
|
for (let i = 0; i < 3; i++) {
|
|
if (pa[i] !== pb[i]) return pa[i] - pb[i];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
function parseVersionKey(key) {
|
|
const m = key.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
if (!m) return [0, 0, 0];
|
|
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
}
|