diff --git a/.changeset/version-define-bun-1-4.md b/.changeset/version-define-bun-1-4.md new file mode 100644 index 00000000..b9eb56e0 --- /dev/null +++ b/.changeset/version-define-bun-1-4.md @@ -0,0 +1,5 @@ +--- +"clerk": patch +--- + +Fix release binaries reporting a dev version when compiled with Bun 1.4.0: the `CLI_VERSION` define check moved out of the version macro (Bun 1.4.0 no longer substitutes `--define` globals during macro execution) into module code, so injected release versions are honored again. diff --git a/.claude/rules/versioning.md b/.claude/rules/versioning.md index 00c7e20f..1cc0c1c6 100644 --- a/.claude/rules/versioning.md +++ b/.claude/rules/versioning.md @@ -16,9 +16,11 @@ import { CURRENT_VERSION, IS_DEV_BUILD } from "./version.ts"; including CLI help, user-agent headers, and MCP client info. - Read `IS_DEV_BUILD` when behavior depends on whether the binary is a development build. -- Keep checkout-derived version generation and dev classification in - `version.macro.ts`; the compiled CLI must not execute Git or classify its - version at runtime. +- Keep checkout-derived version generation in `version.macro.ts`; the compiled + CLI must not execute Git at runtime. The `CLI_VERSION` define check and dev + classification live in `version.ts` module code — Bun 1.4.0 stopped + substituting `--define` globals inside macro execution, so the macro must + never read `CLI_VERSION` itself. The constants are evaluated while Bun transpiles or compiles the module, so release builds can use the injected `CLI_VERSION` while local builds retain diff --git a/packages/cli-core/src/lib/version.macro.ts b/packages/cli-core/src/lib/version.macro.ts index 55d721e5..c7fbe880 100644 --- a/packages/cli-core/src/lib/version.macro.ts +++ b/packages/cli-core/src/lib/version.macro.ts @@ -2,23 +2,11 @@ import cliPackage from "../../../cli/package.json"; const DEV_TAG = "dev"; -type VersionValues = { - currentVersion: string; - isDevBuild: boolean; -}; - type GitResult = { exitCode: number; stdout: string; }; -function isDevVersion(version: string): boolean { - const dash = version.indexOf("-"); - if (dash === -1) return false; - const prerelease = version.slice(dash + 1); - return prerelease === DEV_TAG || prerelease.startsWith(`${DEV_TAG}.`); -} - function git(args: string[]): GitResult | undefined { try { // Anchor the lookup on this source file rather than the user's current @@ -53,22 +41,18 @@ function describeCheckout(): string | undefined { } /** - * Resolve the current version and dev-build status during Bun transpilation. + * Derive the checkout-based dev version during Bun transpilation. * - * Bun inlines the returned values at the macro call, so compiled binaries do - * not execute Git commands or classify versions at runtime. + * Bun inlines the returned string at the macro call, so compiled binaries do + * not execute Git commands at runtime. + * + * The macro deliberately does not read the `CLI_VERSION` define: Bun 1.4.0 + * stopped substituting `--define` globals inside macro execution, so the + * injected-version check lives at the call site in `version.ts`, where module + * code still folds the define reliably. The value returned here is always a + * `-dev` prerelease. */ -export function resolveVersionAtBuildTime(): VersionValues { - let currentVersion: string; - if (typeof CLI_VERSION === "undefined") { - const checkout = describeCheckout(); - currentVersion = `${cliPackage.version}-${DEV_TAG}${checkout ? `.${checkout}` : ""}`; - } else { - currentVersion = CLI_VERSION; - } - - return { - currentVersion, - isDevBuild: isDevVersion(currentVersion), - }; +export function resolveDevVersionAtBuildTime(): string { + const checkout = describeCheckout(); + return `${cliPackage.version}-${DEV_TAG}${checkout ? `.${checkout}` : ""}`; } diff --git a/packages/cli-core/src/lib/version.ts b/packages/cli-core/src/lib/version.ts index 0aafd200..0a0b7d8b 100644 --- a/packages/cli-core/src/lib/version.ts +++ b/packages/cli-core/src/lib/version.ts @@ -23,9 +23,24 @@ * `IS_DEV_BUILD`. */ -import { resolveVersionAtBuildTime } from "./version.macro.ts" with { type: "macro" }; +import { resolveDevVersionAtBuildTime } from "./version.macro.ts" with { type: "macro" }; -const { currentVersion, isDevBuild } = resolveVersionAtBuildTime(); +const DEV_TAG = "dev"; + +function isDevVersion(version: string): boolean { + const dash = version.indexOf("-"); + if (dash === -1) return false; + const prerelease = version.slice(dash + 1); + return prerelease === DEV_TAG || prerelease.startsWith(`${DEV_TAG}.`); +} + +// The `CLI_VERSION` check must live in module code, not inside the macro: Bun +// 1.4.0 no longer substitutes `--define` globals during macro execution. The +// macro contributes only the checkout-derived fallback (always a dev version); +// an injected version is classified by the one-line scan above at module load. +const currentVersion = + typeof CLI_VERSION === "undefined" ? resolveDevVersionAtBuildTime() : CLI_VERSION; +const isDevBuild = typeof CLI_VERSION === "undefined" ? true : isDevVersion(CLI_VERSION); /** * The version embedded while this module was transpiled or compiled.