// The version is stated in several places that a release has to keep in step. // The one in the header was hard-coded and drifted: the application advertised // v5.6.0 while running 5.7.1. Anything a person has to remember at release time // eventually gets forgotten, so these assertions do the remembering. import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; const read = (rel) => readFileSync(new URL(`../${rel}`, import.meta.url), 'utf8'); const pkg = JSON.parse(read('package.json')); const version = pkg.version; assert.match(version, /^\d+\.\d+\.\d+$/, 'package.json must carry a plain semver version'); // package.json is the single source of truth. The header must derive from it // rather than restate it, so no release step is needed to keep them together. { const header = read('src/components/ui/Header.jsx'); assert.match( header, /import\s*\{\s*version[^}]*\}\s*from\s*['"][^'"]*package\.json['"]/, 'the header must import the version from package.json' ); assert.equal( /['"]v\d+\.\d+\.\d+['"]/.test(header), false, 'the header must not contain a hard-coded version literal' ); } // meta.json drives the update check and is regenerated by the build. If it is // behind, the build was not re-run before committing and clients will not be // told an update exists. { const meta = JSON.parse(read('meta.json')); assert.equal( meta.appVersion, version, 'meta.json is stale: run `npm run build` before committing a version bump' ); } // The README badge and the changelog are read by people deciding whether to // update, so a mismatch there is a mismatch in what we are telling them. { const readme = read('README.md'); assert.ok( readme.includes(`version-${version}-`), `the README version badge must show ${version}` ); const changelog = read('CHANGELOG.md'); const firstEntry = changelog.split('\n').find((line) => line.startsWith('## v')); assert.ok( firstEntry && firstEntry.startsWith(`## v${version}`), `the newest changelog entry must be v${version}, found: ${firstEntry}` ); } // Documentation quotes the release it describes. { const crypto = read('doc/CRYPTOGRAPHY.md'); assert.ok( crypto.includes(version), `doc/CRYPTOGRAPHY.md must reference the current release (${version})` ); } console.log('version-consistency.test.mjs: all assertions passed');