Skip to content

Commit 979f07b

Browse files
committed
fix(telemetry): derive environment from CLI_VERSION instead of NODE_ENV
The getEnv() migration in v0.21.0 broke esbuild define replacement for process.env.NODE_ENV — all production builds since then report environment: "development" instead of "production", making telemetry invisible on production-filtered dashboards. Derive the environment from CLI_VERSION (correctly injected at build time) instead: "0.0.0-dev" → development, "-dev.<ts>" → nightly, "X.Y.Z" → production.
1 parent 8e8973d commit 979f07b

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

src/lib/constants.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,28 @@ export function getConfiguredSentryUrl(): string | undefined {
6060
export const CLI_VERSION =
6161
typeof SENTRY_CLI_VERSION !== "undefined" ? SENTRY_CLI_VERSION : "0.0.0-dev";
6262

63+
/**
64+
* Derive the telemetry environment from the build-injected version string.
65+
*
66+
* - `"0.0.0-dev"` (no build injection) → `"development"`
67+
* - `"X.Y.Z-dev.<timestamp>"` (nightly CI build) → `"nightly"`
68+
* - `"X.Y.Z"` (stable release) → `"production"`
69+
*
70+
* This replaces the previous `process.env.NODE_ENV` approach which broke
71+
* when the `getEnv()` indirection was introduced — esbuild's `define` can
72+
* only replace literal `process.env.NODE_ENV`, not dynamic property accesses
73+
* like `getEnv().NODE_ENV`.
74+
*/
75+
export function getCliEnvironment(): string {
76+
if (CLI_VERSION === "0.0.0-dev") {
77+
return "development";
78+
}
79+
if (CLI_VERSION.includes("-dev.")) {
80+
return "nightly";
81+
}
82+
return "production";
83+
}
84+
6385
/**
6486
* Generate the User-Agent string for API requests.
6587
* Format: sentry-cli/<version> (<os>-<arch>) <runtime>/<version>

src/lib/telemetry.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { chmodSync, statSync } from "node:fs";
1414
import * as Sentry from "@sentry/node-core/light";
1515
import {
1616
CLI_VERSION,
17+
getCliEnvironment,
1718
getConfiguredSentryUrl,
1819
SENTRY_CLI_DSN,
1920
} from "./constants.js";
@@ -354,7 +355,7 @@ export function initSentry(
354355
options?: { libraryMode?: boolean }
355356
): Sentry.LightNodeClient | undefined {
356357
const libraryMode = options?.libraryMode ?? false;
357-
const environment = getEnv().NODE_ENV ?? "development";
358+
const environment = getCliEnvironment();
358359

359360
// Close the previous client to clean up its internal timers and beforeExit
360361
// handlers (client report flusher interval, log flush listener). Without

test/lib/constants.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
1111
import {
12+
getCliEnvironment,
1213
getConfiguredSentryUrl,
1314
normalizeUrl,
1415
} from "../../src/lib/constants.js";
@@ -82,6 +83,40 @@ describe("normalizeUrl", () => {
8283
});
8384
});
8485

86+
describe("getCliEnvironment", () => {
87+
test("returns 'development' in dev mode (SENTRY_CLI_VERSION not injected)", () => {
88+
// In test/dev mode, CLI_VERSION is "0.0.0-dev" because the build-time
89+
// constant SENTRY_CLI_VERSION is never defined.
90+
expect(getCliEnvironment()).toBe("development");
91+
});
92+
93+
test("derivation logic: stable versions → 'production'", () => {
94+
// Verify the logic that would run in production builds by checking
95+
// the conditions directly against known version formats.
96+
const stableVersions = ["0.20.0", "1.0.0", "0.23.0", "2.5.1"];
97+
for (const v of stableVersions) {
98+
expect(v === "0.0.0-dev").toBe(false);
99+
expect(v.includes("-dev.")).toBe(false);
100+
// Both conditions false → would return "production"
101+
}
102+
});
103+
104+
test("derivation logic: nightly versions contain '-dev.'", () => {
105+
const nightlyVersions = ["0.24.0-dev.1740000000", "1.0.0-dev.1700000000"];
106+
for (const v of nightlyVersions) {
107+
expect(v === "0.0.0-dev").toBe(false);
108+
expect(v.includes("-dev.")).toBe(true);
109+
// First condition false, second true → would return "nightly"
110+
}
111+
});
112+
113+
test("derivation logic: dev fallback is exactly '0.0.0-dev'", () => {
114+
const v = "0.0.0-dev";
115+
expect(v === "0.0.0-dev").toBe(true);
116+
// First condition true → would return "development"
117+
});
118+
});
119+
85120
describe("getConfiguredSentryUrl", () => {
86121
let originalHost: string | undefined;
87122
let originalUrl: string | undefined;

0 commit comments

Comments
 (0)