Infrastructure scripts for CI, releases and local development.
| Command | Description |
|---|---|
pnpm test:scripts |
Run every *.test.ts under scripts/ |
pnpm tsc:scripts |
Type-check against scripts/tsconfig.json |
pnpm test:workflows |
Run every *.test.ts under .github/scripts/ |
pnpm tsc:workflows |
Type-check against .github/scripts/tsconfig.json |
pnpm lint runs both type-checks and Prettier over both directories.
Run one script with node scripts/detect_edr_platform.ts, or one test file with node --test scripts/detect_edr_platform.test.ts.
Language — Bash for orchestrating other commands, as publish_to_verdaccio.sh does; TypeScript for anything with logic worth testing. Do not add JavaScript; script-language.test.ts fails on a .js file in either directory. Node strips the types at runtime (unflagged since Node 22.18, the floor in the root engines.node), so nothing is compiled to run a script.
Erasable syntax only — no enum, no namespace with a body, no parameter properties. Node erases types, it does not compile them. erasableSyntaxOnly in both tsconfigs catches a violation when you type-check, rather than when the script runs.
Entrypoints — put the executable part behind if (import.meta.main) and export the logic, so tests can import the module without running it. A dead guard is silent, so cover the CLI with a spawnSync test.
Tests — a .test.ts beside the script it covers, using node:test and node:assert/strict. Prefer testing exported pure functions; reach for a subprocess only for the CLI contract.
ESM — scripts/package.json and .github/scripts/package.json each mark their own directory as ESM. The root package.json cannot be "type": "module", because .syncpackrc.js and config/eslint/eslintrc.js are CommonJS and resolve against it. .github/scripts needs its own marker for a second reason too: workflow jobs check that directory out on its own, so the marking has to travel with the scripts.
Which directory — .github/scripts is for scripts a workflow job loads without a full checkout or a pnpm install. Everything else belongs here, including scripts that CI runs. See .github/scripts/README.md for the constraints that come with that directory.
These are not scripts, and converting them would break something:
- Tool config loaded as CommonJS by eslint, mocha and syncpack —
.syncpackrc.js,config/eslint/eslintrc.js,config/mocha.cjs, and the per-package.eslintrc.{js,cjs}and.mocharc.cjsfiles undercrates/edr_napi/,hardhat-tests/,js/benchmark/andjs/helpers/. crates/edr_napi/index.js— generated by@napi-rs/cliand published in the package.hardhat-tests/test/fixture-projects/**/hardhat.config.js— fixtures that deliberately exercise JavaScript Hardhat configs.