Skip to content

Commit 5a44432

Browse files
move web to use shared env package
1 parent 9a27904 commit 5a44432

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+165
-215
lines changed

.env.development

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
8484
# NEXT_PUBLIC_SOURCEBOT_VERSION=
8585

8686
# CONFIG_MAX_REPOS_NO_TOKEN=
87-
# NODE_ENV=
87+
NODE_ENV=development
8888
# SOURCEBOT_TENANCY_MODE=single
8989

9090
# NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=

packages/backend/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
"@sourcebot/db": "workspace:*",
3333
"@sourcebot/schemas": "workspace:*",
3434
"@sourcebot/shared": "workspace:*",
35-
"@t3-oss/env-core": "^0.12.0",
3635
"@types/express": "^5.0.0",
3736
"argparse": "^2.0.1",
3837
"azure-devops-node-api": "^15.1.1",
@@ -52,6 +51,6 @@
5251
"posthog-node": "^4.2.1",
5352
"prom-client": "^15.1.3",
5453
"simple-git": "^3.27.0",
55-
"zod": "^3.24.3"
54+
"zod": "^3.25.74"
5655
}
5756
}

packages/backend/src/instrument.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as Sentry from "@sentry/node";
22
import { createLogger } from "@sourcebot/shared";
3-
import { env } from "@sourcebot/shared";
3+
import { env } from "@sourcebot/shared/client";
44

55
const logger = createLogger('instrument');
66

packages/backend/src/posthog.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import { env as clientEnv } from "@sourcebot/shared/client";
12
import { env } from "@sourcebot/shared";
23
import { PostHog } from 'posthog-node';
34
import { PosthogEvent, PosthogEventMap } from './posthogEvents.js';
45

56
let posthog: PostHog | undefined = undefined;
67

7-
if (env.NEXT_PUBLIC_POSTHOG_PAPIK) {
8+
if (clientEnv.NEXT_PUBLIC_POSTHOG_PAPIK) {
89
posthog = new PostHog(
9-
env.NEXT_PUBLIC_POSTHOG_PAPIK,
10+
clientEnv.NEXT_PUBLIC_POSTHOG_PAPIK,
1011
{
1112
host: "https://us.i.posthog.com",
1213
}
@@ -23,7 +24,7 @@ export function captureEvent<E extends PosthogEvent>(event: E, properties: Posth
2324
event: event,
2425
properties: {
2526
...properties,
26-
sourcebot_version: env.NEXT_PUBLIC_SOURCEBOT_VERSION,
27+
sourcebot_version: clientEnv.NEXT_PUBLIC_SOURCEBOT_VERSION,
2728
},
2829
});
2930
}

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"strip-json-comments": "^5.0.1",
2121
"triple-beam": "^1.4.1",
2222
"winston": "^3.15.0",
23-
"zod": "^3.24.3"
23+
"zod": "^3.25.74"
2424
},
2525
"devDependencies": {
2626
"@types/micromatch": "^4.0.9",

packages/shared/src/crypto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import crypto from 'crypto';
22
import fs from 'fs';
3-
import { env } from './env.js';
3+
import { env } from './env.server.js';
44
import { Token } from '@sourcebot/schemas/v3/shared.type';
55
import { SecretManagerServiceClient } from "@google-cloud/secret-manager";
66

packages/shared/src/entitlements.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { base64Decode } from "./utils.js";
22
import { z } from "zod";
33
import { createLogger } from "./logger.js";
4-
import { env } from "./env.js";
4+
import { env } from "./env.server.js";
5+
import { env as clientEnv } from "./env.client.js";
56
import { SOURCEBOT_SUPPORT_EMAIL, SOURCEBOT_UNLIMITED_SEATS } from "./constants.js";
67
import { verifySignature } from "./crypto.js";
78

@@ -89,8 +90,8 @@ export const getLicenseKey = (): LicenseKeyPayload | null => {
8990
}
9091

9192
export const getPlan = (): Plan => {
92-
if (env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT) {
93-
if (env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT === "demo") {
93+
if (clientEnv.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT) {
94+
if (clientEnv.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT === "demo") {
9495
return "cloud:demo";
9596
}
9697

packages/shared/src/env.client.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { createEnv } from "@t3-oss/env-core";
2+
import { z } from "zod";
3+
import { SOURCEBOT_CLOUD_ENVIRONMENT } from "./constants.js";
4+
5+
export const env = createEnv({
6+
clientPrefix: "NEXT_PUBLIC_",
7+
client: {
8+
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT: z.enum(SOURCEBOT_CLOUD_ENVIRONMENT).optional(),
9+
NEXT_PUBLIC_SOURCEBOT_VERSION: z.string().default("unknown"),
10+
NEXT_PUBLIC_POSTHOG_PAPIK: z.string().optional(),
11+
NEXT_PUBLIC_SENTRY_BACKEND_DSN: z.string().optional(),
12+
NEXT_PUBLIC_SENTRY_ENVIRONMENT: z.string().optional(),
13+
NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY: z.string().optional(),
14+
NEXT_PUBLIC_LANGFUSE_BASE_URL: z.string().optional()
15+
},
16+
runtimeEnvStrict: {
17+
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT: process.env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT,
18+
NEXT_PUBLIC_SOURCEBOT_VERSION: process.env.NEXT_PUBLIC_SOURCEBOT_VERSION,
19+
NEXT_PUBLIC_POSTHOG_PAPIK: process.env.NEXT_PUBLIC_POSTHOG_PAPIK,
20+
NEXT_PUBLIC_SENTRY_BACKEND_DSN: process.env.NEXT_PUBLIC_SENTRY_BACKEND_DSN,
21+
NEXT_PUBLIC_SENTRY_ENVIRONMENT: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
22+
NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY: process.env.NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY,
23+
NEXT_PUBLIC_LANGFUSE_BASE_URL: process.env.NEXT_PUBLIC_LANGFUSE_BASE_URL,
24+
},
25+
emptyStringAsUndefined: true,
26+
skipValidation: process.env.SKIP_ENV_VALIDATION === "1",
27+
});
Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,69 @@
1-
import { createEnv } from "@t3-oss/env-nextjs";
1+
import { createEnv } from "@t3-oss/env-core";
22
import { z } from "zod";
3-
import { SOURCEBOT_CLOUD_ENVIRONMENT } from "@sourcebot/shared/client";
3+
import { SourcebotConfig } from "@sourcebot/schemas/v3/index.type";
4+
import { getTokenFromConfig } from "./crypto.js";
5+
import { loadConfig } from "./utils.js";
6+
import { tenancyModeSchema } from "./types.js";
47

58
// Booleans are specified as 'true' or 'false' strings.
69
const booleanSchema = z.enum(["true", "false"]);
7-
export const tenancyModeSchema = z.enum(["multi", "single"]);
810

911
// Numbers are treated as strings in .env files.
1012
// coerce helps us convert them to numbers.
1113
// @see: https://zod.dev/?id=coercion-for-primitives
1214
const numberSchema = z.coerce.number();
1315

16+
17+
const resolveEnvironmentVariableOverridesFromConfig = async (config: SourcebotConfig): Promise<Record<string, string>> => {
18+
if (!config.environmentOverrides) {
19+
return {};
20+
}
21+
22+
const resolved: Record<string, string> = {};
23+
console.debug('resolving environment variable overrides');
24+
25+
for (const [key, override] of Object.entries(config.environmentOverrides)) {
26+
switch (override.type) {
27+
case 'token':
28+
resolved[key] = await getTokenFromConfig(override.value);
29+
break;
30+
case 'boolean':
31+
resolved[key] = override.value ? 'true' : 'false';
32+
break;
33+
case 'number':
34+
resolved[key] = override.value.toString();
35+
break;
36+
case 'string':
37+
resolved[key] = override.value;
38+
break;
39+
}
40+
}
41+
42+
return resolved;
43+
}
44+
45+
// Merge process.env with environment variables resolved from config.json
46+
const runtimeEnv = await (async () => {
47+
const configPath = process.env.CONFIG_PATH;
48+
if (!configPath) {
49+
return process.env;
50+
}
51+
52+
const config = await loadConfig(configPath);
53+
const overrides = await resolveEnvironmentVariableOverridesFromConfig(config);
54+
return {
55+
...process.env,
56+
...overrides,
57+
}
58+
})();
59+
1460
export const env = createEnv({
1561
server: {
1662
// Zoekt
1763
ZOEKT_WEBSERVER_URL: z.string().url().default("http://localhost:6070"),
1864

1965
// Auth
2066
FORCE_ENABLE_ANONYMOUS_ACCESS: booleanSchema.default('false'),
21-
2267
AUTH_SECRET: z.string(),
2368
AUTH_URL: z.string().url(),
2469
AUTH_CREDENTIALS_LOGIN_ENABLED: booleanSchema.default('true'),
@@ -75,7 +120,7 @@ export const env = createEnv({
75120
DATABASE_URL: z.string().url(),
76121

77122
SOURCEBOT_TENANCY_MODE: tenancyModeSchema.default("single"),
78-
CONFIG_PATH: z.string().optional(),
123+
CONFIG_PATH: z.string(),
79124

80125
// Misc UI flags
81126
SECURITY_CARD_ENABLED: booleanSchema.default('false'),
@@ -137,31 +182,30 @@ export const env = createEnv({
137182
// @NOTE: Take care to update actions.ts when changing the name of this.
138183
EXPERIMENT_SELF_SERVE_REPO_INDEXING_GITHUB_TOKEN: z.string().optional(),
139184
EXPERIMENT_EE_PERMISSION_SYNC_ENABLED: booleanSchema.default('false'),
140-
},
141-
// @NOTE: Please make sure of the following:
142-
// - Make sure you destructure all client variables in
143-
// the `experimental__runtimeEnv` block below.
144-
// - Update the Dockerfile to pass these variables as build-args.
145-
client: {
146-
// PostHog
147-
NEXT_PUBLIC_POSTHOG_PAPIK: z.string().optional(),
148185

149-
// Misc
150-
NEXT_PUBLIC_SOURCEBOT_VERSION: z.string().default('unknown'),
186+
SOURCEBOT_ENCRYPTION_KEY: z.string(),
187+
SOURCEBOT_INSTALL_ID: z.string().default("unknown"),
151188

152-
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT: z.enum(SOURCEBOT_CLOUD_ENVIRONMENT).optional(),
189+
FALLBACK_GITHUB_CLOUD_TOKEN: z.string().optional(),
190+
FALLBACK_GITLAB_CLOUD_TOKEN: z.string().optional(),
191+
FALLBACK_GITEA_CLOUD_TOKEN: z.string().optional(),
153192

154-
NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY: z.string().optional(),
155-
NEXT_PUBLIC_LANGFUSE_BASE_URL: z.string().optional()
156-
},
157-
// For Next.js >= 13.4.4, you only need to destructure client variables:
158-
experimental__runtimeEnv: {
159-
NEXT_PUBLIC_POSTHOG_PAPIK: process.env.NEXT_PUBLIC_POSTHOG_PAPIK,
160-
NEXT_PUBLIC_SOURCEBOT_VERSION: process.env.NEXT_PUBLIC_SOURCEBOT_VERSION,
161-
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT: process.env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT,
162-
NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY: process.env.NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY,
163-
NEXT_PUBLIC_LANGFUSE_BASE_URL: process.env.NEXT_PUBLIC_LANGFUSE_BASE_URL,
193+
REDIS_URL: z.string().url().default("redis://localhost:6379"),
194+
REDIS_REMOVE_ON_COMPLETE: numberSchema.default(0),
195+
REDIS_REMOVE_ON_FAIL: numberSchema.default(100),
196+
197+
DEBUG_ENABLE_GROUPMQ_LOGGING: booleanSchema.default('false'),
198+
199+
CONNECTION_MANAGER_UPSERT_TIMEOUT_MS: numberSchema.default(300000),
200+
REPO_SYNC_RETRY_BASE_SLEEP_SECONDS: numberSchema.default(60),
201+
202+
GITLAB_CLIENT_QUERY_TIMEOUT_SECONDS: numberSchema.default(60 * 10),
203+
204+
SOURCEBOT_LOG_LEVEL: z.enum(["info", "debug", "warn", "error"]).default("info"),
205+
SOURCEBOT_STRUCTURED_LOGGING_ENABLED: booleanSchema.default("false"),
206+
SOURCEBOT_STRUCTURED_LOGGING_FILE: z.string().optional(),
164207
},
165-
skipValidation: process.env.SKIP_ENV_VALIDATION === "1",
208+
runtimeEnv,
166209
emptyStringAsUndefined: true,
210+
skipValidation: process.env.SKIP_ENV_VALIDATION === "1",
167211
});

packages/shared/src/env.ts

Lines changed: 0 additions & 110 deletions
This file was deleted.

0 commit comments

Comments
 (0)