Summary
make test-unit-hardhat exists, works, and globs every file in tests/unit/ — but no workflow ever invokes it. As of ac565f2 that leaves 37 tests across 4 files which pass locally and are never executed by CI.
| File |
Tests |
Status today |
tests/helpers/matchers/index.test.ts |
15 |
passes locally, never run in CI |
tests/unit/deployer-nonce.test.ts |
14 |
passes locally, never run in CI |
tests/unit/protocol-config-genesis.test.ts |
4 |
passes locally, never run in CI |
tests/unit/validator-manager-genesis-validation.test.ts |
4 |
passes locally, never run in CI |
Evidence
The target exists and is already glob-driven:
test-unit-hardhat: ## Run hardhat unit tests
npx hardhat test ./tests/helpers/matchers/index.test.ts ./tests/unit/*.test.ts --no-compile
Nothing calls it:
$ grep -rn 'test-unit-hardhat\|hardhat test' .github/workflows/
(no matches)
ci.yml runs ten jobs, none of which touch TypeScript tests: rust-fmt, rust-deps, rust-lint, rust-test, rust-integration-test, proto, contracts-lint, contracts-build, contracts-test, docker-build.
Why this bites now
The glob means a new unit test file is adopted with zero wiring, which is convenient — but it also means freshly merged regression tests land directly in the inert set:
Both invariants can now regress with CI staying green.
What the job actually needs — measured, including one trap
I tried to keep this to a Node-only job, and that does not work. Worth writing down, because the naive patch looks right and fails:
$ env PATH="${PATH-without-foundry}" make test-unit-hardhat
Error in plugin hardhat-foundry: Couldn't run `forge`. Please check that your foundry installation is correct.
make: *** [Makefile:177: test-unit-hardhat] Error 1
hardhat.config.ts imports @nomicfoundation/hardhat-foundry, and that plugin shells out to forge during config resolution — so it is required even with --no-compile, and even though none of these 37 tests touch a contract.
What it does not need is equally useful, since it keeps the job cheap. On a fresh --depth 3 clone of ac565f2 with all three contracts/lib/* submodule directories empty, no hardhat compile (typechain-types/ absent) and no contract artifacts of any kind:
$ npm ci && make test-unit-hardhat
37 passing (58ms)
real 0m3.141s
So the job needs Node plus the forge binary, and can skip the git submodule update --init ... step that contracts-lint, contracts-build, contracts-test and docker-build all carry.
One caveat on my own measurement: the run above used forge 1.1.0-dev, whereas the repo pins v1.4.4 in .foundry-version. The patch below reads the pinned version the same way the existing jobs do, so CI would exercise 1.4.4 rather than what I happened to have.
Suggested patch
ts-unit-test:
name: TypeScript Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: npm
- name: Install Node dependencies
run: npm ci
- name: Read Foundry version
id: foundry-version
run: echo "version=$(cat .foundry-version)" >> $GITHUB_OUTPUT
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: ${{ steps.foundry-version.outputs.version }}
- name: Run hardhat unit tests
run: make test-unit-hardhat
No submodule init and no compile step. I checked that this splices into ci.yml and parses cleanly — eleven jobs, with no needs edge so it runs in parallel with the Rust lanes.
Two things a patch alone will not cover:
- Someone with admin rights has to add the job to the repo's required status checks, otherwise it runs but does not gate merges.
- External fork PRs here do not get CI runs until a maintainer approves the workflow, so a fork-based PR for this cannot demonstrate itself green — the evidence has to come from a local run like the one above.
Related
Same class of gap, different suites: #248 (arcup and finalize-release shell suites never run) and #247 (arcup shell tests plus shellcheck), with #249 open for the finalize-release half. This is the TypeScript/hardhat instance of the same pattern and is independent of those.
Disclosure: I am osr21, external to Circle — an unaffiliated community contributor with no write access to this repository. This report is advisory only; the measurements above are from my own local runs and should be reproduced before acting on them.
Summary
make test-unit-hardhatexists, works, and globs every file intests/unit/— but no workflow ever invokes it. As ofac565f2that leaves 37 tests across 4 files which pass locally and are never executed by CI.tests/helpers/matchers/index.test.tstests/unit/deployer-nonce.test.tstests/unit/protocol-config-genesis.test.tstests/unit/validator-manager-genesis-validation.test.tsEvidence
The target exists and is already glob-driven:
Nothing calls it:
ci.ymlruns ten jobs, none of which touch TypeScript tests:rust-fmt,rust-deps,rust-lint,rust-test,rust-integration-test,proto,contracts-lint,contracts-build,contracts-test,docker-build.Why this bites now
The glob means a new unit test file is adopted with zero wiring, which is convenient — but it also means freshly merged regression tests land directly in the inert set:
Both invariants can now regress with CI staying green.
What the job actually needs — measured, including one trap
I tried to keep this to a Node-only job, and that does not work. Worth writing down, because the naive patch looks right and fails:
hardhat.config.tsimports@nomicfoundation/hardhat-foundry, and that plugin shells out toforgeduring config resolution — so it is required even with--no-compile, and even though none of these 37 tests touch a contract.What it does not need is equally useful, since it keeps the job cheap. On a fresh
--depth 3clone ofac565f2with all threecontracts/lib/*submodule directories empty, nohardhat compile(typechain-types/absent) and no contract artifacts of any kind:So the job needs Node plus the
forgebinary, and can skip thegit submodule update --init ...step thatcontracts-lint,contracts-build,contracts-testanddocker-buildall carry.One caveat on my own measurement: the run above used
forge 1.1.0-dev, whereas the repo pinsv1.4.4in.foundry-version. The patch below reads the pinned version the same way the existing jobs do, so CI would exercise 1.4.4 rather than what I happened to have.Suggested patch
No submodule init and no compile step. I checked that this splices into
ci.ymland parses cleanly — eleven jobs, with noneedsedge so it runs in parallel with the Rust lanes.Two things a patch alone will not cover:
Related
Same class of gap, different suites: #248 (arcup and finalize-release shell suites never run) and #247 (arcup shell tests plus shellcheck), with #249 open for the finalize-release half. This is the TypeScript/hardhat instance of the same pattern and is independent of those.
Disclosure: I am osr21, external to Circle — an unaffiliated community contributor with no write access to this repository. This report is advisory only; the measurements above are from my own local runs and should be reproduced before acting on them.