Skip to content

Commit 38f676c

Browse files
committed
fix: remove remaining dotenvx references causing ENOENT in CI
1 parent ffe3325 commit 38f676c

File tree

6 files changed

+76
-46
lines changed

6 files changed

+76
-46
lines changed

.env.precommit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Socket CLI Pre-commit Test Environment
2-
# This file is loaded by dotenvx during pre-commit hooks.
2+
# This file is loaded during pre-commit hooks.
33

44
# Disable API token requirement for unit tests.
55
SOCKET_CLI_NO_API_TOKEN=1

packages/cli/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,20 @@
4040
"clean:node-smol": "del-cli 'build/node-smol'",
4141
"clean:node_modules": "del-cli '**/node_modules'",
4242
"fix": "oxfmt --write . && oxlint --fix -c ../../.oxlintrc.json",
43-
"lint-staged": "dotenvx -q run -f .env.local -- lint-staged",
44-
"precommit": "dotenvx -q run -f .env.local -- lint-staged",
43+
"lint-staged": "lint-staged",
44+
"precommit": "lint-staged",
4545
"prepare": "husky",
46-
"bs": "dotenvx -q run -f .env.local -- pnpm run build && pnpm exec socket --",
47-
"s": "dotenvx -q run -f .env.local -- pnpm exec socket --",
46+
"bs": "pnpm run build && pnpm exec socket --",
47+
"s": "pnpm exec socket --",
4848
"dev": "node --experimental-strip-types src/cli-dispatch.mts",
4949
"dev:npm": "cross-env SOCKET_CLI_MODE=npm node --experimental-strip-types src/cli-dispatch.mts",
5050
"dev:npx": "cross-env SOCKET_CLI_MODE=npx node --experimental-strip-types src/cli-dispatch.mts",
51-
"e2e-tests": "dotenvx -q run -f .env.test -- vitest run --config vitest.e2e.config.mts",
51+
"e2e-tests": "vitest run --config vitest.e2e.config.mts",
5252
"e2e:js": "node scripts/e2e.mts --js",
5353
"e2e:sea": "node scripts/e2e.mts --sea",
5454
"e2e:all": "node scripts/e2e.mts --all",
5555
"test": "run-s check test:*",
56-
"test:prepare": "dotenvx -q run -f .env.test -- pnpm build && del-cli 'test/**/node_modules'",
56+
"test:prepare": "pnpm build && del-cli 'test/**/node_modules'",
5757
"test:unit": "node --import=./scripts/load.mts scripts/test-wrapper.mts",
5858
"test:unit:update": "node --import=./scripts/load.mts scripts/test-wrapper.mts --update",
5959
"test:unit:coverage": "node --import=./scripts/load.mts scripts/test-wrapper.mts --coverage",

packages/cli/scripts/e2e.mts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { getDefaultLogger } from '@socketsecurity/lib/logger'
1414
import { spawn } from '@socketsecurity/lib/spawn'
1515

1616
import { EnvironmentVariables } from './environment-variables.mts'
17+
import { loadEnvFile } from './utils/load-env.mts'
1718

1819
const logger = getDefaultLogger()
1920

@@ -122,30 +123,25 @@ async function runVitest(binaryType) {
122123
// This is required for tests to load external tool versions (coana, cdxgen, synp, etc).
123124
const externalToolVersions = EnvironmentVariables.getTestVariables()
124125

125-
// Use dotenvx to load test environment.
126-
const dotenvxCmd = WIN32 ? 'dotenvx.cmd' : 'dotenvx'
127-
const dotenvxPath = path.join(NODE_MODULES_BIN_PATH, dotenvxCmd)
126+
// Load .env.e2e configuration (falls back gracefully if missing).
127+
const e2eEnv = loadEnvFile(path.join(ROOT_DIR, '.env.e2e'))
128128

129129
// Resolve vitest path.
130130
const vitestCmd = WIN32 ? 'vitest.cmd' : 'vitest'
131131
const vitestPath = path.join(NODE_MODULES_BIN_PATH, vitestCmd)
132132

133133
const result = await spawn(
134-
dotenvxPath,
134+
vitestPath,
135135
[
136-
'-q',
137-
'run',
138-
'-f',
139-
'.env.e2e',
140-
'--',
141-
vitestPath,
142136
'run',
143137
'test/e2e/binary-test-suite.e2e.test.mts',
144138
'--config',
145139
'vitest.e2e.config.mts',
146140
],
147141
{
142+
cwd: ROOT_DIR,
148143
env: {
144+
...e2eEnv,
149145
...process.env,
150146
// Automatically enable tests when explicitly running e2e.mts.
151147
RUN_E2E_TESTS: '1',

packages/cli/scripts/integration.mts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { getDefaultLogger } from '@socketsecurity/lib/logger'
1414
import { spawn } from '@socketsecurity/lib/spawn'
1515

1616
import { EnvironmentVariables } from './environment-variables.mts'
17+
import { loadEnvFile } from './utils/load-env.mts'
1718

1819
const logger = getDefaultLogger()
1920
const __dirname = path.dirname(fileURLToPath(import.meta.url))
@@ -80,9 +81,8 @@ async function runVitest(binaryType) {
8081
return
8182
}
8283

83-
// Use dotenvx to load test environment.
84-
const dotenvxCmd = WIN32 ? 'dotenvx.cmd' : 'dotenvx'
85-
const dotenvxPath = path.join(NODE_MODULES_BIN_PATH, dotenvxCmd)
84+
// Load .env.test configuration.
85+
const testEnv = loadEnvFile(path.join(ROOT_DIR, '.env.test'))
8686

8787
// Resolve vitest path.
8888
const vitestCmd = WIN32 ? 'vitest.cmd' : 'vitest'
@@ -92,14 +92,8 @@ async function runVitest(binaryType) {
9292
const externalToolVersions = EnvironmentVariables.getTestVariables()
9393

9494
const result = await spawn(
95-
dotenvxPath,
95+
vitestPath,
9696
[
97-
'-q',
98-
'run',
99-
'-f',
100-
'.env.test',
101-
'--',
102-
vitestPath,
10397
'run',
10498
'test/integration/binary/',
10599
'--config',
@@ -108,6 +102,7 @@ async function runVitest(binaryType) {
108102
{
109103
cwd: ROOT_DIR,
110104
env: {
105+
...testEnv,
111106
...process.env,
112107
// Automatically enable tests when explicitly running integration.mts.
113108
RUN_INTEGRATION_TESTS: '1',

packages/cli/scripts/test-wrapper.mts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* - Memory optimization for RegExp-heavy tests
66
* - Cross-platform compatibility (Windows/Unix)
77
* - Build validation before running tests
8-
* - Environment variable loading from .env.test
8+
* - Environment variable loading from .env.test (via loadEnvFile)
99
* - Inlined variable injection from bundle-tools.json
1010
*/
1111

@@ -20,6 +20,7 @@ import { getDefaultLogger } from '@socketsecurity/lib/logger'
2020
import { spawn } from '@socketsecurity/lib/spawn'
2121

2222
import { EnvironmentVariables } from './environment-variables.mts'
23+
import { loadEnvFile } from './utils/load-env.mts'
2324

2425
const logger = getDefaultLogger()
2526
const __dirname = path.dirname(fileURLToPath(import.meta.url))
@@ -110,9 +111,8 @@ async function main() {
110111
...externalToolVersions,
111112
}
112113

113-
// Use dotenvx to load .env.test configuration.
114-
const dotenvxCmd = WIN32 ? 'dotenvx.cmd' : 'dotenvx'
115-
const dotenvxPath = path.join(rootNodeModulesBinPath, dotenvxCmd)
114+
// Load .env.test configuration.
115+
const testEnv = loadEnvFile(path.join(rootPath, '.env.test'))
116116

117117
// Handle Windows vs Unix for vitest executable.
118118
const vitestCmd = WIN32 ? 'vitest.cmd' : 'vitest'
@@ -133,28 +133,22 @@ async function main() {
133133
}
134134
}
135135

136-
// Wrap vitest with dotenvx to load .env.test.
137-
// Command: dotenvx -q run -f .env.test -- vitest run [args].
138-
const dotenvxArgs = [
139-
'-q',
140-
'run',
141-
'-f',
142-
'.env.test',
143-
'--',
144-
vitestPath,
145-
'run',
146-
...expandedArgs,
147-
]
148-
149136
// On Windows, .cmd files need shell: true.
150137
const spawnOptions = {
151138
cwd: rootPath,
152-
env: spawnEnv,
139+
env: {
140+
...testEnv,
141+
...spawnEnv,
142+
},
153143
stdio: 'inherit',
154144
...(WIN32 ? { shell: true } : {}),
155145
}
156146

157-
const result = await spawn(dotenvxPath, dotenvxArgs, spawnOptions)
147+
const result = await spawn(
148+
vitestPath,
149+
['run', ...expandedArgs],
150+
spawnOptions,
151+
)
158152
process.exitCode = result?.code || 0
159153
} catch (e) {
160154
logger.error('Failed to spawn test process:', e)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/** @fileoverview Minimal .env file parser for build and test scripts. */
2+
3+
import { readFileSync } from 'node:fs'
4+
5+
/**
6+
* Parse a .env file and return key-value pairs.
7+
* Supports comments (#), blank lines, KEY=value, KEY="value", KEY='value'.
8+
* Returns an empty object if the file does not exist.
9+
*/
10+
export function loadEnvFile(
11+
filePath: string,
12+
): Record<string, string> {
13+
const env: Record<string, string> = { __proto__: null } as Record<
14+
string,
15+
string
16+
>
17+
let content: string
18+
try {
19+
content = readFileSync(filePath, 'utf-8')
20+
} catch {
21+
return env
22+
}
23+
for (const line of content.split('\n')) {
24+
const trimmed = line.trim()
25+
// Skip comments and blank lines.
26+
if (!trimmed || trimmed.startsWith('#')) {
27+
continue
28+
}
29+
const eqIndex = trimmed.indexOf('=')
30+
if (eqIndex === -1) {
31+
continue
32+
}
33+
const key = trimmed.slice(0, eqIndex).trim()
34+
let value = trimmed.slice(eqIndex + 1).trim()
35+
// Strip surrounding quotes.
36+
if (
37+
(value.startsWith('"') && value.endsWith('"')) ||
38+
(value.startsWith("'") && value.endsWith("'"))
39+
) {
40+
value = value.slice(1, -1)
41+
}
42+
env[key] = value
43+
}
44+
return env
45+
}

0 commit comments

Comments
 (0)