diff --git a/npm/codewhale/scripts/install.js b/npm/codewhale/scripts/install.js index 47ec56c69..9f3231bf0 100644 --- a/npm/codewhale/scripts/install.js +++ b/npm/codewhale/scripts/install.js @@ -78,12 +78,18 @@ class DownloadTimeoutError extends Error { } } -function resolvePackageVersion() { +// Binary-version precedence must match run.js and verify-release-assets.js so +// install-time asset resolution agrees with runtime and release verification. +// `codewhaleBinaryVersion` lets a packaging-only npm release target a specific +// CodeWhale binary; legacy env vars and `deepseekBinaryVersion` stay supported +// for backward compatibility (#3769). `pkgObj`/`env` are injectable for tests. +function resolvePackageVersion(pkgObj = pkg, env = process.env) { const configuredVersion = - process.env.DEEPSEEK_TUI_VERSION || - process.env.DEEPSEEK_VERSION || - pkg.deepseekBinaryVersion || - pkg.version; + env.DEEPSEEK_TUI_VERSION || + env.DEEPSEEK_VERSION || + pkgObj.codewhaleBinaryVersion || + pkgObj.deepseekBinaryVersion || + pkgObj.version; return String(configuredVersion).trim(); } @@ -1148,6 +1154,7 @@ module.exports = { installFailureHint, run, _internal: { + resolvePackageVersion, isOptionalInstall, adoptExistingBinaryIfValid, shouldIgnoreInstallFailure, diff --git a/npm/codewhale/test/install.test.js b/npm/codewhale/test/install.test.js index 2c0f363b6..fdf19854c 100644 --- a/npm/codewhale/test/install.test.js +++ b/npm/codewhale/test/install.test.js @@ -223,3 +223,43 @@ test("manual binaries with mismatched checksums are not adopted", async (t) => { assert.equal(adopted, false); assert.equal(await exists(`${target}.version`), false); }); + +test("resolvePackageVersion honors codewhaleBinaryVersion precedence (#3769)", () => { + const { resolvePackageVersion } = _internal; + + // codewhaleBinaryVersion wins over deepseekBinaryVersion and pkg.version. + assert.equal( + resolvePackageVersion( + { + codewhaleBinaryVersion: "1.2.3", + deepseekBinaryVersion: "0.0.1", + version: "9.9.9", + }, + {}, + ), + "1.2.3", + ); + + // Falls back to deepseekBinaryVersion, then pkg.version. + assert.equal( + resolvePackageVersion({ deepseekBinaryVersion: "0.0.1", version: "9.9.9" }, {}), + "0.0.1", + ); + assert.equal(resolvePackageVersion({ version: "9.9.9" }, {}), "9.9.9"); + + // Legacy env vars still take precedence over package fields, unchanged. + assert.equal( + resolvePackageVersion( + { codewhaleBinaryVersion: "1.2.3", version: "9.9.9" }, + { DEEPSEEK_TUI_VERSION: "7.7.7" }, + ), + "7.7.7", + ); + assert.equal( + resolvePackageVersion( + { codewhaleBinaryVersion: "1.2.3" }, + { DEEPSEEK_VERSION: "8.8.8" }, + ), + "8.8.8", + ); +});