openvibers/openvibe.shared Commits
Pin drift: the newest tag without a CHANGELOG date counts as just out (raw.githubusercontent's cached CHANGELOG lagged SDK v0.55.0 and failed every repo pinned two minors back for minutes after the release) (#91)
Changes
@@@ -9,7 +9,9 @@* - is more than one minor behind a release that has been out for more than GRACE_DAYS (14): 0.40 fails* once 0.42 is two weeks old. The grace keeps CI green on the day a library ships and still catches* pins left behind. Release dates come from the library's CHANGELOG.md on main ("## 0.42.0 — 2026-09-25"-- * or "## 0.9.1 (2026-09-24)"); a release with no date there counts as old.++ * or "## 0.9.1 (2026-09-24)"); a release with no date there counts as old, except the newest tag: raw.githubusercontent++ * serves a CHANGELOG cached for minutes, so a CI run right after a release read no date for it and failed every++ * repository pinned two minors back (SDK v0.55.0, 2026-10-20). The newest tag without a date counts as just out.** node scripts/pin-drift.js [dir] every package.json under dir (git-tracked), default .* curl -fsSL https://raw.githubusercontent.com/OpenVibers/OpenVibe.Shared/main/scripts/pin-drift.js | node - [dir]@@@ -52,7 +54,8 @@ function judge(pin, published, { dates = new Map(), now = Date.now(), graceDays// The releases two or more minors ahead of the pin that have been out longer than the grace period.const old = tags.filter((t) => t[0] === pin[0] && t[1] - pin[1] > 1).filter((t) => {const at = dates.get(t.join('.'));-- return !(Number.isFinite(at) && now - at <= graceDays * 86400000);++ if (!Number.isFinite(at)) return cmp(t, latest) !== 0; // the newest tag may be newer than the cached CHANGELOG++ return now - at > graceDays * 86400000;});if (old.length) return { ok: false, reason: `v${pin.join('.')} is ${latest[1] - pin[1]} minors behind v${latest.join('.')} (v${old[old.length - 1].join('.')} is over ${graceDays} days old)` };if (latest[1] - pin[1] > 1) return { ok: true, reason: `latest v${latest.join('.')}; behind by ${latest[1] - pin[1]} minors, within the ${graceDays}-day grace` };@@@ -9,7 +9,12 @@ const { judge, main, releaseDates, sharedCopies } = require('../scripts/pin-drifconst tags = ['v0.40.0', 'v0.41.0', 'v0.41.1', 'v0.42.0'];assert.strictEqual(judge([0, 42, 0], tags).ok, true);assert.strictEqual(judge([0, 41, 1], tags).ok, true, 'one minor behind is allowed');--assert.match(judge([0, 40, 0], tags).reason, /2 minors behind v0\.42\.0/, 'without dates every release counts as old');++assert.strictEqual(judge([0, 40, 0], tags).ok, true, 'the newest tag without a date counts as just out (a cached CHANGELOG lags a release)');++assert.match(judge([0, 40, 0], [...tags, 'v0.43.0']).reason, /3 minors behind v0\.43\.0 \(v0\.42\.0 is over 14 days old\)/, 'the releases before the newest count as old without a date');++// SDK v0.55.0 on 2026-10-20: the CHANGELOG raw.githubusercontent served had no 0.55.0 entry yet; 0.52-0.54 were days old.++const sdkTags = ['v0.50.1', 'v0.51.0', 'v0.52.0', 'v0.53.0', 'v0.54.0', 'v0.55.0'];++const sdkDates = releaseDates('## 0.54.0 (2026-10-20)\n## 0.53.0 (2026-10-20)\n## 0.52.0 (2026-10-20)\n## 0.51.0 (2026-10-17)\n');++assert.strictEqual(judge([0, 50, 1], sdkTags, { dates: sdkDates, now: Date.parse('2026-10-20T19:33:00Z') }).ok, true, 'a release minutes old does not fail CI');const DAY = 86400000, now = Date.parse('2026-10-20T00:00:00Z');const dates = releaseDates('## 0.42.0 — 2026-10-15\n...\n## 0.41.1 (2026-09-30)\n## [0.41.0] - 2026-09-20\n');assert.strictEqual(dates.get('0.42.0'), Date.parse('2026-10-15T00:00:00Z')); assert.strictEqual(dates.get('0.41.0'), Date.parse('2026-09-20T00:00:00Z'));
@@ -9,7 +9,9 @@
@@ -9,7 +9,9 @@
* - is more than one minor behind a release that has been out for more than GRACE_DAYS (14): 0.40 fails
* - is more than one minor behind a release that has been out for more than GRACE_DAYS (14): 0.40 fails
* once 0.42 is two weeks old. The grace keeps CI green on the day a library ships and still catches
* once 0.42 is two weeks old. The grace keeps CI green on the day a library ships and still catches
* pins left behind. Release dates come from the library's CHANGELOG.md on main ("## 0.42.0 — 2026-09-25"
* pins left behind. Release dates come from the library's CHANGELOG.md on main ("## 0.42.0 — 2026-09-25"
- * or "## 0.9.1 (2026-09-24)"); a release with no date there counts as old.
+ * or "## 0.9.1 (2026-09-24)"); a release with no date there counts as old, except the newest tag: raw.githubusercontent
+ * serves a CHANGELOG cached for minutes, so a CI run right after a release read no date for it and failed every
+ * repository pinned two minors back (SDK v0.55.0, 2026-10-20). The newest tag without a date counts as just out.
*
*
* node scripts/pin-drift.js [dir] every package.json under dir (git-tracked), default .
* node scripts/pin-drift.js [dir] every package.json under dir (git-tracked), default .
* curl -fsSL https://raw.githubusercontent.com/OpenVibers/OpenVibe.Shared/main/scripts/pin-drift.js | node - [dir]
* curl -fsSL https://raw.githubusercontent.com/OpenVibers/OpenVibe.Shared/main/scripts/pin-drift.js | node - [dir]
@@ -52,7 +54,8 @@ function judge(pin, published, { dates = new Map(), now = Date.now(), graceDays
@@ -52,7 +54,8 @@ function judge(pin, published, { dates = new Map(), now = Date.now(), graceDays
// The releases two or more minors ahead of the pin that have been out longer than the grace period.
// The releases two or more minors ahead of the pin that have been out longer than the grace period.
const old = tags.filter((t) => t[0] === pin[0] && t[1] - pin[1] > 1).filter((t) => {
const old = tags.filter((t) => t[0] === pin[0] && t[1] - pin[1] > 1).filter((t) => {
const at = dates.get(t.join('.'));
const at = dates.get(t.join('.'));
- return !(Number.isFinite(at) && now - at <= graceDays * 86400000);
+ if (!Number.isFinite(at)) return cmp(t, latest) !== 0; // the newest tag may be newer than the cached CHANGELOG
+ return now - at > graceDays * 86400000;
});
});
if (old.length) return { ok: false, reason: `v${pin.join('.')} is ${latest[1] - pin[1]} minors behind v${latest.join('.')} (v${old[old.length - 1].join('.')} is over ${graceDays} days old)` };
if (old.length) return { ok: false, reason: `v${pin.join('.')} is ${latest[1] - pin[1]} minors behind v${latest.join('.')} (v${old[old.length - 1].join('.')} is over ${graceDays} days old)` };
if (latest[1] - pin[1] > 1) return { ok: true, reason: `latest v${latest.join('.')}; behind by ${latest[1] - pin[1]} minors, within the ${graceDays}-day grace` };
if (latest[1] - pin[1] > 1) return { ok: true, reason: `latest v${latest.join('.')}; behind by ${latest[1] - pin[1]} minors, within the ${graceDays}-day grace` };
@@ -9,7 +9,12 @@ const { judge, main, releaseDates, sharedCopies } = require('../scripts/pin-drif
@@ -9,7 +9,12 @@ const { judge, main, releaseDates, sharedCopies } = require('../scripts/pin-drif
const tags = ['v0.40.0', 'v0.41.0', 'v0.41.1', 'v0.42.0'];
const tags = ['v0.40.0', 'v0.41.0', 'v0.41.1', 'v0.42.0'];
assert.strictEqual(judge([0, 42, 0], tags).ok, true);
assert.strictEqual(judge([0, 42, 0], tags).ok, true);
assert.strictEqual(judge([0, 41, 1], tags).ok, true, 'one minor behind is allowed');
assert.strictEqual(judge([0, 41, 1], tags).ok, true, 'one minor behind is allowed');
-assert.match(judge([0, 40, 0], tags).reason, /2 minors behind v0\.42\.0/, 'without dates every release counts as old');
+assert.strictEqual(judge([0, 40, 0], tags).ok, true, 'the newest tag without a date counts as just out (a cached CHANGELOG lags a release)');
+assert.match(judge([0, 40, 0], [...tags, 'v0.43.0']).reason, /3 minors behind v0\.43\.0 \(v0\.42\.0 is over 14 days old\)/, 'the releases before the newest count as old without a date');
+// SDK v0.55.0 on 2026-10-20: the CHANGELOG raw.githubusercontent served had no 0.55.0 entry yet; 0.52-0.54 were days old.
+const sdkTags = ['v0.50.1', 'v0.51.0', 'v0.52.0', 'v0.53.0', 'v0.54.0', 'v0.55.0'];
+const sdkDates = releaseDates('## 0.54.0 (2026-10-20)\n## 0.53.0 (2026-10-20)\n## 0.52.0 (2026-10-20)\n## 0.51.0 (2026-10-17)\n');
+assert.strictEqual(judge([0, 50, 1], sdkTags, { dates: sdkDates, now: Date.parse('2026-10-20T19:33:00Z') }).ok, true, 'a release minutes old does not fail CI');
const DAY = 86400000, now = Date.parse('2026-10-20T00:00:00Z');
const DAY = 86400000, now = Date.parse('2026-10-20T00:00:00Z');
const dates = releaseDates('## 0.42.0 — 2026-10-15\n...\n## 0.41.1 (2026-09-30)\n## [0.41.0] - 2026-09-20\n');
const dates = releaseDates('## 0.42.0 — 2026-10-15\n...\n## 0.41.1 (2026-09-30)\n## [0.41.0] - 2026-09-20\n');
assert.strictEqual(dates.get('0.42.0'), Date.parse('2026-10-15T00:00:00Z')); assert.strictEqual(dates.get('0.41.0'), Date.parse('2026-09-20T00:00:00Z'));
assert.strictEqual(dates.get('0.42.0'), Date.parse('2026-10-15T00:00:00Z')); assert.strictEqual(dates.get('0.41.0'), Date.parse('2026-09-20T00:00:00Z'));