{"record":{"id":"16d0c768e8bdd59e","repo":"yeasy/docker_practice","slug":"package-json-version-pkg-version-does-not-match","errorCode":null,"errorMessage":"package.json version ${pkg.version} does not match CHANGELOG ${topVersion}","messagePattern":"package\\.json version (.+?) does not match CHANGELOG (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/check_metadata.js","lineNumber":10,"sourceCode":"const fs = require('fs');\n\nconst pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));\nconst changelog = fs.readFileSync('CHANGELOG.md', 'utf8');\nconst readme = fs.readFileSync('README.md', 'utf8');\n\nconst topVersion = changelog.match(/^\\* ([0-9]+\\.[0-9]+\\.[0-9]+)\\b/m)?.[1];\n\nif (pkg.version !== topVersion) {\n  throw new Error(`package.json version ${pkg.version} does not match CHANGELOG ${topVersion}`);\n}\n\nif (pkg.license !== 'CC-BY-NC-SA-4.0' || !readme.includes('CC BY-NC-SA 4.0')) {\n  throw new Error('package.json license must match README license');\n}\n","sourceCodeStart":1,"sourceCodeEnd":16,"githubUrl":"https://github.com/yeasy/docker_practice/blob/00d8a87f55c94ee632a5f506be01e4e38b5dedf1/scripts/check_metadata.js#L1-L16","documentation":"This error comes from scripts/check_metadata.js, a repo CI gate run as the first step of `npm test` (package.json scripts.test). It enforces that the `version` field in package.json equals the topmost version entry in CHANGELOG.md. The script parses CHANGELOG.md with the regex /^\\* ([0-9]+\\.[0-9]+\\.[0-9]+)\\b/m, so only a line starting with `* ` followed by a semver (e.g. `* 1.9.2 2026-05-16`) is recognized; if no such line exists the captured version is undefined and the equality check fails. It exists to keep the released book version and its changelog in lockstep so builds and release notes never drift apart.","triggerScenarios":"Running `npm test` (or `node scripts/check_metadata.js`) when (a) package.json \"version\" was bumped (e.g. 1.9.3) without adding a matching `* 1.9.3 ...` entry at the top of CHANGELOG.md, (b) a CHANGELOG entry was added for a version not yet set in package.json, or (c) the top CHANGELOG entry is formatted so the regex cannot match it — e.g. `## 1.9.3`, `- 1.9.3`, a leading space before `*`, or a non-semver like `1.9.3-beta.1` — which makes topVersion undefined and always mismatches.","commonSituations":"Release prep where the version is bumped in package.json (or by `npm version`) but the changelog update is forgotten; CHANGELOG entries rewritten in a different heading style (`##` headings instead of `* ` bullets) during a docs reformat; PRs that edit CHANGELOG.md without touching package.json; a prerelease suffix in the changelog version that the strict \\d+\\.\\d+\\.\\d+ capture cannot parse, leaving topVersion stale or undefined.","solutions":["Align the two values: add `* <newversion> <date>` as the topmost bullet in CHANGELOG.md (or set package.json \"version\" to the changelog's top version), then rerun `node scripts/check_metadata.js`.","If the changelog was reformatted, restore the bullet format the regex expects: a line starting with `* ` immediately followed by MAJOR.MINOR.PATCH, e.g. `* 1.9.2 2026-05-16`.","If you intentionally use a prerelease version (e.g. 1.9.3-beta.1), either drop the suffix in both files or extend the regex in scripts/check_metadata.js to accept it — but prefer plain semver to keep CI green.","Automate the sync: run `npm version <newversion>` and let a commit hook or release script insert the matching CHANGELOG line in the same commit."],"exampleFix":"// CHANGELOG.md — before\n# 修订记录\n\n## 1.9.3\n* updated chapters\n\n// CHANGELOG.md — after (regex requires a `* <semver>` line)\n# 修订记录\n\n* 1.9.3 2026-08-15\n  * updated chapters\n\n// package.json — keep in sync\n{ \"version\": \"1.9.3\" }","handlingStrategy":"validation","validationCode":"// Run before `npm test` / release to catch drift early\nconst fs = require('fs');\nconst pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));\nconst top = fs.readFileSync('CHANGELOG.md', 'utf8')\n  .match(/^\\* ([0-9]+\\.[0-9]+\\.[0-9]+)\\b/m)?.[1];\nif (top === undefined) {\n  throw new Error('CHANGELOG.md has no top-level `* <semver>` entry for the regex to match');\n}\nif (pkg.version !== top) {\n  throw new Error(`version drift: package.json=${pkg.version} vs CHANGELOG=${top}`);\n}","typeGuard":null,"tryCatchPattern":"// If invoking check_metadata.js programmatically:\nconst { spawnSync } = require('child_process');\nconst r = spawnSync(process.execPath, ['scripts/check_metadata.js'], { encoding: 'utf8' });\nif (r.status !== 0) {\n  console.error('metadata check failed:', r.stderr.trim());\n  // stop the release pipeline before building artifacts\n}","preventionTips":["Update package.json version and the top CHANGELOG.md bullet in the same commit; never one without the other.","Use `npm version <x.y.z>` to bump, and make it prepend the matching `* x.y.z <date>` changelog line via a version script or hook.","Keep the changelog bullet format exactly `* MAJOR.MINOR.PATCH` at line start — heading styles like `## x.y.z` are invisible to the check.","Run `node scripts/check_metadata.js` locally before pushing so CI never reports the drift."],"tags":["ci","versioning","changelog","release-process","nodejs"],"backgroundTag":null,"analyzedSha":"00d8a87f55c94ee632a5f506be01e4e38b5dedf1","analyzedAt":"2026-08-15T23:18:50.239Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}