From 8f2b03bd72f5426dbaff2e05252a911468eaa170 Mon Sep 17 00:00:00 2001 From: jdalton Date: Wed, 15 Apr 2026 18:05:43 -0400 Subject: [PATCH 1/4] chore: remove disabled dependabot config --- .github/dependabot.yml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 137a3c846..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Dependabot disabled - we manage dependencies manually -# Using open-pull-requests-limit: 0 to disable version updates -# See: https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates -version: 2 -updates: - - package-ecosystem: npm - directory: / - schedule: - interval: yearly - open-pull-requests-limit: 0 - cooldown: - default-days: 7 From ffe332559f0834bd75a3204bab577ca9b891478d Mon Sep 17 00:00:00 2001 From: jdalton Date: Wed, 15 Apr 2026 18:47:37 -0400 Subject: [PATCH 2/4] chore: disable vitest interopDefault, remove dotenvx Set deps.interopDefault: false in all vitest configs for native CJS resolution matching Node runtime behavior. Remove dotenvx from pre-commit hook, workspace catalog, and devDependencies. Inline SOCKET_CLI_NO_API_TOKEN=1 directly. --- .config/vitest.config.base.mts | 3 + .config/vitest.config.isolated.mts | 3 + .husky/pre-commit | 10 +- package.json | 3 +- packages/cli/vitest.config.mts | 3 + packages/cli/vitest.e2e.config.mts | 3 + packages/cli/vitest.integration.config.mts | 3 + pnpm-lock.yaml | 106 +-------------------- pnpm-workspace.yaml | 1 - vitest.config.mts | 3 + 10 files changed, 25 insertions(+), 113 deletions(-) diff --git a/.config/vitest.config.base.mts b/.config/vitest.config.base.mts index 8543c880b..bbfdfb8e3 100644 --- a/.config/vitest.config.base.mts +++ b/.config/vitest.config.base.mts @@ -68,6 +68,9 @@ export default defineConfig({ useAtomics: true, }, }, + deps: { + interopDefault: false, + }, testTimeout: 30_000, hookTimeout: 30_000, coverage: { diff --git a/.config/vitest.config.isolated.mts b/.config/vitest.config.isolated.mts index 51cf0a9cf..9ef1a2763 100644 --- a/.config/vitest.config.isolated.mts +++ b/.config/vitest.config.isolated.mts @@ -36,6 +36,9 @@ export default defineConfig({ minForks: isCoverageEnabled ? 1 : 2, }, }, + deps: { + interopDefault: false, + }, testTimeout: 30_000, hookTimeout: 10_000, coverage: { diff --git a/.husky/pre-commit b/.husky/pre-commit index d6bf323f9..c140059d3 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -15,15 +15,7 @@ else fi if [ -z "${DISABLE_PRECOMMIT_TEST}" ]; then - if ! command -v dotenvx >/dev/null 2>&1; then - printf "Error: dotenvx not found in PATH\n" >&2 - printf "Install with: pnpm i\n" >&2 - exit 1 - fi - # Note: .env.precommit is optional and not tracked in git (contains local test config). - # If missing, dotenvx will continue without it. Create .env.precommit with test - # environment variables to optimize pre-commit test performance. - dotenvx -q run -f .env.precommit -- pnpm test --staged + SOCKET_CLI_NO_API_TOKEN=1 pnpm test --staged else printf "Skipping testing due to DISABLE_PRECOMMIT_TEST env var\n" fi diff --git a/package.json b/package.json index de7527ce7..92f2fe2ec 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "pretest": "pnpm run build:cli" }, "devDependencies": { - "@typescript/native-preview": "7.0.0-dev.20260415.1", "@anthropic-ai/claude-code": "catalog:", "@babel/core": "catalog:", "@babel/parser": "catalog:", @@ -63,7 +62,6 @@ "@babel/preset-typescript": "catalog:", "@babel/runtime": "catalog:", "@babel/traverse": "catalog:", - "@dotenvx/dotenvx": "catalog:", "@npmcli/arborist": "catalog:", "@npmcli/config": "catalog:", "@octokit/graphql": "catalog:", @@ -96,6 +94,7 @@ "@types/semver": "catalog:", "@types/which": "catalog:", "@types/yargs-parser": "catalog:", + "@typescript/native-preview": "7.0.0-dev.20260415.1", "@vitest/coverage-v8": "catalog:", "@yao-pkg/pkg": "catalog:", "browserslist": "catalog:", diff --git a/packages/cli/vitest.config.mts b/packages/cli/vitest.config.mts index 691e311a6..ec0908280 100644 --- a/packages/cli/vitest.config.mts +++ b/packages/cli/vitest.config.mts @@ -79,6 +79,9 @@ export default defineConfig({ // // Performance impact is acceptable for reliability. isolate: true, + deps: { + interopDefault: false, + }, testTimeout: 30_000, hookTimeout: 30_000, // Enable file-level parallelization for better performance. diff --git a/packages/cli/vitest.e2e.config.mts b/packages/cli/vitest.e2e.config.mts index 1bbdbe34e..7447424fd 100644 --- a/packages/cli/vitest.e2e.config.mts +++ b/packages/cli/vitest.e2e.config.mts @@ -23,6 +23,9 @@ export default defineConfig({ maxWorkers: os.cpus().length, // E2E tests need full isolation for clean execution. isolate: true, + deps: { + interopDefault: false, + }, // E2E tests need longer timeouts for spawning processes. testTimeout: 60_000, hookTimeout: 60_000, diff --git a/packages/cli/vitest.integration.config.mts b/packages/cli/vitest.integration.config.mts index 2a3f903a2..6c260af3f 100644 --- a/packages/cli/vitest.integration.config.mts +++ b/packages/cli/vitest.integration.config.mts @@ -21,6 +21,9 @@ export default defineConfig({ pool: 'threads', maxWorkers: os.cpus().length, isolate: true, + deps: { + interopDefault: false, + }, testTimeout: 60_000, // Integration tests may take longer. hookTimeout: 30_000, fileParallelism: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a64bfed0c..19cc1e347 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -223,9 +223,6 @@ catalogs: '@babel/types': specifier: 7.28.5 version: 7.28.5 - '@dotenvx/dotenvx': - specifier: 1.49.0 - version: 1.49.0 '@gitbeaker/rest': specifier: 43.7.0 version: 43.7.0 @@ -528,9 +525,6 @@ importers: '@babel/traverse': specifier: 'catalog:' version: 7.28.4 - '@dotenvx/dotenvx': - specifier: 'catalog:' - version: 1.49.0 '@npmcli/arborist': specifier: 'catalog:' version: 9.4.2 @@ -1177,16 +1171,6 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@dotenvx/dotenvx@1.49.0': - resolution: {integrity: sha512-M1cyP6YstFQCjih54SAxCqHLMMi8QqV8tenpgGE48RTXWD7vfMYJiw/6xcCDpS2h28AcLpTsFCZA863Ge9yxzA==} - hasBin: true - - '@ecies/ciphers@0.2.6': - resolution: {integrity: sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g==} - engines: {bun: '>=1', deno: '>=2.7.10', node: '>=16'} - peerDependencies: - '@noble/ciphers': ^1.0.0 - '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} @@ -1644,18 +1628,6 @@ packages: resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} engines: {node: '>=18'} - '@noble/ciphers@1.3.0': - resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} - engines: {node: ^14.21.3 || >=16} - - '@noble/curves@1.9.7': - resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} - engines: {node: ^14.21.3 || >=16} - - '@noble/hashes@1.8.0': - resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} - engines: {node: ^14.21.3 || >=16} - '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2915,10 +2887,6 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} - commander@13.1.0: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} @@ -3041,10 +3009,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true - dotenv@17.4.1: - resolution: {integrity: sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw==} - engines: {node: '>=12'} - duplexer2@0.1.4: resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} @@ -3053,10 +3017,6 @@ packages: engines: {node: '>=18'} hasBin: true - eciesjs@0.4.18: - resolution: {integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ==} - engines: {bun: '>=1', deno: '>=2', node: '>=16'} - efrt@2.7.0: resolution: {integrity: sha512-/RInbCy1d4P6Zdfa+TMVsf/ufZVotat5hCw3QXmWtjU+3pFEOvOQ7ibo3aIxyCJw2leIeAMjmPj+1SLJiCpdrQ==} engines: {node: '>=12.0.0'} @@ -3329,10 +3289,6 @@ packages: resolution: {integrity: sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==} engines: {node: ^20.17.0 || >=22.9.0} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - ignore@7.0.5: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} @@ -3824,10 +3780,6 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - object-treeify@1.1.33: - resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} - engines: {node: '>= 10'} - ofetch@1.5.1: resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} @@ -4578,11 +4530,6 @@ packages: engines: {node: '>= 8'} hasBin: true - which@4.0.0: - resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} - engines: {node: ^16.13.0 || >=18.0.0} - hasBin: true - which@5.0.0: resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} engines: {node: ^18.17.0 || >=20.5.0} @@ -4737,7 +4684,7 @@ snapshots: '@babel/generator@7.28.5': dependencies: '@babel/parser': 7.29.2 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -4999,22 +4946,6 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@dotenvx/dotenvx@1.49.0': - dependencies: - commander: 11.1.0 - dotenv: 17.4.1 - eciesjs: 0.4.18 - execa: 5.1.1(patch_hash=ee0e2217eadd7986ec585d2e684030a05ad958593a9b11affa002a14a5d46f77) - fdir: 6.5.0(picomatch@4.0.4) - ignore: 5.3.2 - object-treeify: 1.1.33 - picomatch: 4.0.4 - which: 4.0.0 - - '@ecies/ciphers@0.2.6(@noble/ciphers@1.3.0)': - dependencies: - '@noble/ciphers': 1.3.0 - '@epic-web/invariant@1.0.0': {} '@esbuild/aix-ppc64@0.25.11': @@ -5289,14 +5220,6 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@noble/ciphers@1.3.0': {} - - '@noble/curves@1.9.7': - dependencies: - '@noble/hashes': 1.8.0 - - '@noble/hashes@1.8.0': {} - '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -6004,7 +5927,7 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 24.9.2 + '@types/node': 25.5.2 form-data: 4.0.5 '@types/node@18.19.130': @@ -6025,7 +5948,7 @@ snapshots: '@types/npm-registry-fetch@8.0.9': dependencies: - '@types/node': 24.9.2 + '@types/node': 25.5.2 '@types/node-fetch': 2.6.13 '@types/npm-package-arg': 6.1.4 '@types/npmlog': 7.0.0 @@ -6048,7 +5971,7 @@ snapshots: '@types/npmlog@7.0.0': dependencies: - '@types/node': 24.9.2 + '@types/node': 25.5.2 '@types/pacote@11.1.8': dependencies: @@ -6063,7 +5986,7 @@ snapshots: '@types/ssri@7.1.5': dependencies: - '@types/node': 24.9.2 + '@types/node': 25.5.2 '@types/which@3.0.4': {} @@ -6481,8 +6404,6 @@ snapshots: dependencies: delayed-stream: 1.0.0 - commander@11.1.0: {} - commander@13.1.0: {} commander@14.0.3: {} @@ -6583,8 +6504,6 @@ snapshots: meow: 10.1.5 noop-stream: 1.0.0 - dotenv@17.4.1: {} - duplexer2@0.1.4: dependencies: readable-stream: 2.3.8 @@ -6600,13 +6519,6 @@ snapshots: transitivePeerDependencies: - encoding - eciesjs@0.4.18: - dependencies: - '@ecies/ciphers': 0.2.6(@noble/ciphers@1.3.0) - '@noble/ciphers': 1.3.0 - '@noble/curves': 1.9.7 - '@noble/hashes': 1.8.0 - efrt@2.7.0: {} electron-to-chromium@1.5.332: {} @@ -6914,8 +6826,6 @@ snapshots: dependencies: minimatch: 10.2.5 - ignore@5.3.2: {} - ignore@7.0.5: {} imurmurhash@0.1.4: {} @@ -7395,8 +7305,6 @@ snapshots: dependencies: path-key: 3.1.1 - object-treeify@1.1.33: {} - ofetch@1.5.1: dependencies: destr: 2.0.5 @@ -8240,10 +8148,6 @@ snapshots: dependencies: isexe: 2.0.0 - which@4.0.0: - dependencies: - isexe: 3.1.5 - which@5.0.0: dependencies: isexe: 3.1.5 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 21274c10a..ce38a5e9f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -25,7 +25,6 @@ catalog: '@babel/runtime': 7.28.4 '@babel/traverse': 7.28.4 '@babel/types': 7.28.5 - '@dotenvx/dotenvx': 1.49.0 '@gitbeaker/rest': 43.7.0 '@iarna/toml': 2.2.5 '@npmcli/arborist': 9.4.2 diff --git a/vitest.config.mts b/vitest.config.mts index 3ba9390fd..9fb0c4929 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -55,6 +55,9 @@ export default defineConfig({ useAtomics: true, }, }, + deps: { + interopDefault: false, + }, testTimeout: 30_000, hookTimeout: 30_000, bail: process.env.CI ? 1 : 0, // Exit on first failure in CI for faster feedback. From 38f676c6e86c55abc6fc6b339f798d5d6c171787 Mon Sep 17 00:00:00 2001 From: jdalton Date: Wed, 15 Apr 2026 18:54:52 -0400 Subject: [PATCH 3/4] fix: remove remaining dotenvx references causing ENOENT in CI --- .env.precommit | 2 +- packages/cli/package.json | 12 +++---- packages/cli/scripts/e2e.mts | 16 ++++----- packages/cli/scripts/integration.mts | 15 +++------ packages/cli/scripts/test-wrapper.mts | 32 +++++++----------- packages/cli/scripts/utils/load-env.mts | 45 +++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 46 deletions(-) create mode 100644 packages/cli/scripts/utils/load-env.mts diff --git a/.env.precommit b/.env.precommit index 706c58cb4..1ee9eda75 100644 --- a/.env.precommit +++ b/.env.precommit @@ -1,5 +1,5 @@ # Socket CLI Pre-commit Test Environment -# This file is loaded by dotenvx during pre-commit hooks. +# This file is loaded during pre-commit hooks. # Disable API token requirement for unit tests. SOCKET_CLI_NO_API_TOKEN=1 diff --git a/packages/cli/package.json b/packages/cli/package.json index 7162bd0e2..ac16ab786 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -40,20 +40,20 @@ "clean:node-smol": "del-cli 'build/node-smol'", "clean:node_modules": "del-cli '**/node_modules'", "fix": "oxfmt --write . && oxlint --fix -c ../../.oxlintrc.json", - "lint-staged": "dotenvx -q run -f .env.local -- lint-staged", - "precommit": "dotenvx -q run -f .env.local -- lint-staged", + "lint-staged": "lint-staged", + "precommit": "lint-staged", "prepare": "husky", - "bs": "dotenvx -q run -f .env.local -- pnpm run build && pnpm exec socket --", - "s": "dotenvx -q run -f .env.local -- pnpm exec socket --", + "bs": "pnpm run build && pnpm exec socket --", + "s": "pnpm exec socket --", "dev": "node --experimental-strip-types src/cli-dispatch.mts", "dev:npm": "cross-env SOCKET_CLI_MODE=npm node --experimental-strip-types src/cli-dispatch.mts", "dev:npx": "cross-env SOCKET_CLI_MODE=npx node --experimental-strip-types src/cli-dispatch.mts", - "e2e-tests": "dotenvx -q run -f .env.test -- vitest run --config vitest.e2e.config.mts", + "e2e-tests": "vitest run --config vitest.e2e.config.mts", "e2e:js": "node scripts/e2e.mts --js", "e2e:sea": "node scripts/e2e.mts --sea", "e2e:all": "node scripts/e2e.mts --all", "test": "run-s check test:*", - "test:prepare": "dotenvx -q run -f .env.test -- pnpm build && del-cli 'test/**/node_modules'", + "test:prepare": "pnpm build && del-cli 'test/**/node_modules'", "test:unit": "node --import=./scripts/load.mts scripts/test-wrapper.mts", "test:unit:update": "node --import=./scripts/load.mts scripts/test-wrapper.mts --update", "test:unit:coverage": "node --import=./scripts/load.mts scripts/test-wrapper.mts --coverage", diff --git a/packages/cli/scripts/e2e.mts b/packages/cli/scripts/e2e.mts index 57f4a2715..8c038b36f 100644 --- a/packages/cli/scripts/e2e.mts +++ b/packages/cli/scripts/e2e.mts @@ -14,6 +14,7 @@ import { getDefaultLogger } from '@socketsecurity/lib/logger' import { spawn } from '@socketsecurity/lib/spawn' import { EnvironmentVariables } from './environment-variables.mts' +import { loadEnvFile } from './utils/load-env.mts' const logger = getDefaultLogger() @@ -122,30 +123,25 @@ async function runVitest(binaryType) { // This is required for tests to load external tool versions (coana, cdxgen, synp, etc). const externalToolVersions = EnvironmentVariables.getTestVariables() - // Use dotenvx to load test environment. - const dotenvxCmd = WIN32 ? 'dotenvx.cmd' : 'dotenvx' - const dotenvxPath = path.join(NODE_MODULES_BIN_PATH, dotenvxCmd) + // Load .env.e2e configuration (falls back gracefully if missing). + const e2eEnv = loadEnvFile(path.join(ROOT_DIR, '.env.e2e')) // Resolve vitest path. const vitestCmd = WIN32 ? 'vitest.cmd' : 'vitest' const vitestPath = path.join(NODE_MODULES_BIN_PATH, vitestCmd) const result = await spawn( - dotenvxPath, + vitestPath, [ - '-q', - 'run', - '-f', - '.env.e2e', - '--', - vitestPath, 'run', 'test/e2e/binary-test-suite.e2e.test.mts', '--config', 'vitest.e2e.config.mts', ], { + cwd: ROOT_DIR, env: { + ...e2eEnv, ...process.env, // Automatically enable tests when explicitly running e2e.mts. RUN_E2E_TESTS: '1', diff --git a/packages/cli/scripts/integration.mts b/packages/cli/scripts/integration.mts index f7d630558..72b02cf65 100644 --- a/packages/cli/scripts/integration.mts +++ b/packages/cli/scripts/integration.mts @@ -14,6 +14,7 @@ import { getDefaultLogger } from '@socketsecurity/lib/logger' import { spawn } from '@socketsecurity/lib/spawn' import { EnvironmentVariables } from './environment-variables.mts' +import { loadEnvFile } from './utils/load-env.mts' const logger = getDefaultLogger() const __dirname = path.dirname(fileURLToPath(import.meta.url)) @@ -80,9 +81,8 @@ async function runVitest(binaryType) { return } - // Use dotenvx to load test environment. - const dotenvxCmd = WIN32 ? 'dotenvx.cmd' : 'dotenvx' - const dotenvxPath = path.join(NODE_MODULES_BIN_PATH, dotenvxCmd) + // Load .env.test configuration. + const testEnv = loadEnvFile(path.join(ROOT_DIR, '.env.test')) // Resolve vitest path. const vitestCmd = WIN32 ? 'vitest.cmd' : 'vitest' @@ -92,14 +92,8 @@ async function runVitest(binaryType) { const externalToolVersions = EnvironmentVariables.getTestVariables() const result = await spawn( - dotenvxPath, + vitestPath, [ - '-q', - 'run', - '-f', - '.env.test', - '--', - vitestPath, 'run', 'test/integration/binary/', '--config', @@ -108,6 +102,7 @@ async function runVitest(binaryType) { { cwd: ROOT_DIR, env: { + ...testEnv, ...process.env, // Automatically enable tests when explicitly running integration.mts. RUN_INTEGRATION_TESTS: '1', diff --git a/packages/cli/scripts/test-wrapper.mts b/packages/cli/scripts/test-wrapper.mts index 6be04b8f9..4cb4cb333 100644 --- a/packages/cli/scripts/test-wrapper.mts +++ b/packages/cli/scripts/test-wrapper.mts @@ -5,7 +5,7 @@ * - Memory optimization for RegExp-heavy tests * - Cross-platform compatibility (Windows/Unix) * - Build validation before running tests - * - Environment variable loading from .env.test + * - Environment variable loading from .env.test (via loadEnvFile) * - Inlined variable injection from bundle-tools.json */ @@ -20,6 +20,7 @@ import { getDefaultLogger } from '@socketsecurity/lib/logger' import { spawn } from '@socketsecurity/lib/spawn' import { EnvironmentVariables } from './environment-variables.mts' +import { loadEnvFile } from './utils/load-env.mts' const logger = getDefaultLogger() const __dirname = path.dirname(fileURLToPath(import.meta.url)) @@ -110,9 +111,8 @@ async function main() { ...externalToolVersions, } - // Use dotenvx to load .env.test configuration. - const dotenvxCmd = WIN32 ? 'dotenvx.cmd' : 'dotenvx' - const dotenvxPath = path.join(rootNodeModulesBinPath, dotenvxCmd) + // Load .env.test configuration. + const testEnv = loadEnvFile(path.join(rootPath, '.env.test')) // Handle Windows vs Unix for vitest executable. const vitestCmd = WIN32 ? 'vitest.cmd' : 'vitest' @@ -133,28 +133,22 @@ async function main() { } } - // Wrap vitest with dotenvx to load .env.test. - // Command: dotenvx -q run -f .env.test -- vitest run [args]. - const dotenvxArgs = [ - '-q', - 'run', - '-f', - '.env.test', - '--', - vitestPath, - 'run', - ...expandedArgs, - ] - // On Windows, .cmd files need shell: true. const spawnOptions = { cwd: rootPath, - env: spawnEnv, + env: { + ...testEnv, + ...spawnEnv, + }, stdio: 'inherit', ...(WIN32 ? { shell: true } : {}), } - const result = await spawn(dotenvxPath, dotenvxArgs, spawnOptions) + const result = await spawn( + vitestPath, + ['run', ...expandedArgs], + spawnOptions, + ) process.exitCode = result?.code || 0 } catch (e) { logger.error('Failed to spawn test process:', e) diff --git a/packages/cli/scripts/utils/load-env.mts b/packages/cli/scripts/utils/load-env.mts new file mode 100644 index 000000000..7b4ded489 --- /dev/null +++ b/packages/cli/scripts/utils/load-env.mts @@ -0,0 +1,45 @@ +/** @fileoverview Minimal .env file parser for build and test scripts. */ + +import { readFileSync } from 'node:fs' + +/** + * Parse a .env file and return key-value pairs. + * Supports comments (#), blank lines, KEY=value, KEY="value", KEY='value'. + * Returns an empty object if the file does not exist. + */ +export function loadEnvFile( + filePath: string, +): Record { + const env: Record = { __proto__: null } as Record< + string, + string + > + let content: string + try { + content = readFileSync(filePath, 'utf-8') + } catch { + return env + } + for (const line of content.split('\n')) { + const trimmed = line.trim() + // Skip comments and blank lines. + if (!trimmed || trimmed.startsWith('#')) { + continue + } + const eqIndex = trimmed.indexOf('=') + if (eqIndex === -1) { + continue + } + const key = trimmed.slice(0, eqIndex).trim() + let value = trimmed.slice(eqIndex + 1).trim() + // Strip surrounding quotes. + if ( + (value.startsWith('"') && value.endsWith('"')) || + (value.startsWith("'") && value.endsWith("'")) + ) { + value = value.slice(1, -1) + } + env[key] = value + } + return env +} From d7ad7ab5ad1ef978af91ae0b3463cba8999dd400 Mon Sep 17 00:00:00 2001 From: jdalton Date: Wed, 15 Apr 2026 20:16:03 -0400 Subject: [PATCH 4/4] fix: bump socket-registry action SHA to bbe46386 --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/provenance.yml | 6 +++--- .github/workflows/weekly-update.yml | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c23fb007f..254a4c98c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,7 +109,7 @@ jobs: export default { text, view, renderToString, renderToStringWithWidth, printComponent, eprintComponent, getTerminalSize, TuiRenderer, init } CODE - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' @@ -168,7 +168,7 @@ jobs: export default { text, view, renderToString, renderToStringWithWidth, printComponent, eprintComponent, getTerminalSize, TuiRenderer, init } CODE - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' @@ -234,7 +234,7 @@ jobs: export default { text, view, renderToString, renderToStringWithWidth, printComponent, eprintComponent, getTerminalSize, TuiRenderer, init } CODE - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' node-version: ${{ matrix.node-version }} @@ -310,7 +310,7 @@ jobs: export default { text, view, renderToString, renderToStringWithWidth, printComponent, eprintComponent, getTerminalSize, TuiRenderer, init } CODE - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/provenance.yml b/.github/workflows/provenance.yml index 1bbc3bfb6..456ee6e4d 100644 --- a/.github/workflows/provenance.yml +++ b/.github/workflows/provenance.yml @@ -51,7 +51,7 @@ jobs: with: persist-credentials: false - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' @@ -91,7 +91,7 @@ jobs: with: persist-credentials: false - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' registry-url: 'https://registry.npmjs.org' @@ -141,7 +141,7 @@ jobs: with: persist-credentials: false - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/weekly-update.yml b/.github/workflows/weekly-update.yml index e5944ec84..73c2014c4 100644 --- a/.github/workflows/weekly-update.yml +++ b/.github/workflows/weekly-update.yml @@ -29,7 +29,7 @@ jobs: with: persist-credentials: false - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' @@ -61,7 +61,7 @@ jobs: fetch-depth: 0 persist-credentials: false - - uses: SocketDev/socket-registry/.github/actions/setup-and-install@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-and-install@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: checkout: 'false' @@ -76,7 +76,7 @@ jobs: git checkout -b "$BRANCH_NAME" echo "branch=$BRANCH_NAME" >> $GITHUB_OUTPUT - - uses: SocketDev/socket-registry/.github/actions/setup-git-signing@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/setup-git-signing@bbe46386c0a2bc6baefd02916234956a38e622d5 # main with: gpg-private-key: ${{ secrets.BOT_GPG_PRIVATE_KEY }} @@ -303,7 +303,7 @@ jobs: test.log retention-days: 7 - - uses: SocketDev/socket-registry/.github/actions/cleanup-git-signing@b86b2cb3fefa4ffa6c1a702476f9785f6c3bb887 # main + - uses: SocketDev/socket-registry/.github/actions/cleanup-git-signing@bbe46386c0a2bc6baefd02916234956a38e622d5 # main if: always() notify: