openvibers/openvibe.contracts Commits

The changelog keeps every release (a test) (#309)

OP OpenVibers committed 7 days ago · 14d90f81bb · 3 files, +33 −3

* The changelog keeps every release: a test fails when entries go missing or fall out of order

A release PR on 11-06 rewrote CHANGELOG.md with only its own entry and the one before, dropping 3,800 lines. The
test counts every 0.x minor from 0.30 to the current version (0.293 was never released) and checks newest-first
order; the two 0.247.0 headings become one.

* Merge remote-tracking branch 'origin/main' into test/changelog-keeps-history

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 7ebb865c..71b3743c 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -591,9 +591,6 @@ the notes were in the tag and commit messages (`git tag -n1`).
## 0.247.0 — 2026-10-30
- Add `bench.run@2`, allowing a null run or task score while human judges have not scored verified outputs. `bench.run@1` stays unchanged.
--
--## 0.247.0 — 2026-10-30
--
- `bench.run@1` allows a null run or task score while human judges have not scored the published output yet.
## 0.246.1 — 2026-10-30
ddiff --git a/test/changelog-history.test.js b/test/changelog-history.test.js
nnew file mode 100644
iindex 00000000..141f3589
---- /dev/null
++++ b/test/changelog-history.test.js
@@@ -0,0 +1,32 @@
++'use strict';
++// The changelog keeps every release. On 2026-11-06 a release PR rewrote CHANGELOG.md with only its own entry and the
++// one before it, dropping 3,800 lines of history; this catches that before it merges.
++const assert = require('assert');
++const fs = require('fs');
++const path = require('path');
++
++const ROOT = path.join(__dirname, '..');
++const text = fs.readFileSync(path.join(ROOT, 'CHANGELOG.md'), 'utf8');
++const pkg = require(path.join(ROOT, 'package.json'));
++
++const versions = [...text.matchAll(/^## (\d+)\.(\d+)\.(\d+)\b/gm)].map((m) => [+m[1], +m[2], +m[3]]);
++const [major, minor] = pkg.version.split('.').map(Number);
++
++// Minor versions that were never released (no tag), so they have no entry.
++const NEVER_RELEASED = new Set([293]);
++const FIRST_MINOR = 30;
++
++assert.strictEqual(major, 0, 'the check counts 0.x minors; update it when 1.0.0 ships');
++assert.ok(versions.some(([a, b]) => a === major && b === minor), `CHANGELOG.md has an entry for the current version ${pkg.version}`);
++const minors = new Set(versions.filter(([a]) => a === 0).map(([, b]) => b));
++const missing = [];
++for (let m = FIRST_MINOR; m <= minor; m++) if (!minors.has(m) && !NEVER_RELEASED.has(m)) missing.push(`0.${m}.x`);
++assert.deepStrictEqual(missing, [], `CHANGELOG.md lost earlier releases' entries: ${missing.slice(0, 10).join(', ')}${missing.length > 10 ? ` and ${missing.length - 10} more` : ''}`);
++
++// Newest first: each heading's version is below the one above it.
++for (let i = 1; i < versions.length; i++) {
++ const [a, b] = [versions[i - 1], versions[i]];
++ const cmp = a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
++ assert.ok(cmp > 0, `CHANGELOG.md is newest first: ${a.join('.')} comes before ${b.join('.')}`);
++}
++console.log(`changelog history: ${versions.length} entries, 0.${FIRST_MINOR} to ${pkg.version}`);
ddiff --git a/test/run.js b/test/run.js
iindex 0a4dd66a..c0a6ec51 100644
---- a/test/run.js
++++ b/test/run.js
@@@ -994,6 +994,7 @@ sub(path.join(__dirname, 'platform-fabric.test.js'));
sub(path.join(__dirname, 'platform-run.test.js'));
sub(path.join(ROOT, 'scripts/generate.js'), '--check');
sub(path.join(ROOT, 'scripts/compat.js'));
++sub(path.join(__dirname, 'changelog-history.test.js'));
{
// A $ref with sibling keywords (SubjectRef1 & co.) or to a $defs entry (Tld, Service...) makes
// json-schema-to-typescript emit a type name it never declares; every name used as a type must be declared.