Skip to content

Add splitTestsCompilation solidity setting: main PR#8127

Merged
alcuadrado merged 94 commits intomainfrom
dont-split-compilations
Apr 16, 2026
Merged

Add splitTestsCompilation solidity setting: main PR#8127
alcuadrado merged 94 commits intomainfrom
dont-split-compilations

Conversation

@alcuadrado
Copy link
Copy Markdown
Member

@alcuadrado alcuadrado commented Apr 12, 2026

Adds a splitTestsCompilation Solidity setting that controls if tests are built independently or not.

Docs PR: NomicFoundation/hardhat-website#255

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 12, 2026

🦋 Changeset detected

Latest commit: ff3109b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@nomicfoundation/hardhat-node-test-runner Patch
@nomicfoundation/hardhat-typechain Patch
@nomicfoundation/hardhat-ignition Patch
@nomicfoundation/hardhat-mocha Patch
@nomicfoundation/hardhat-errors Patch
hardhat Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a standalone specification document describing the planned introduction of a new top-level Solidity config field, splitTestsCompilation, to control whether Solidity tests are compiled separately or together with contracts (defaulting to unified compilation).

Changes:

  • Add SPLIT_TESTS_COMPILATION_SPEC.md documenting intended behavior changes across Hardhat build system, tasks, cache, and related plugins.
  • Outline a phased implementation plan (config/plumbing → build system semantics → cache → tasks/runners/plugins → docs/migration).

Comment thread SPLIT_TESTS_COMPILATION_SPEC.md Outdated
Comment thread SPLIT_TESTS_COMPILATION_SPEC.md Outdated
…-phase-6

Add `splitTestsCompilation` solidity setting (6): Solidity test runner updates
…-phase-7

Add `splitTestsCompilation` solidity setting (7): Typechain updates
…-phase-8

Add `splitTestsCompilation` solidity setting (8): Mocha updates
…-phase-9

Add `splitTestsCompilation` solidity setting (9): `node:test` updates
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 43 out of 47 changed files in this pull request and generated 2 comments.

alcuadrado and others added 4 commits April 16, 2026 13:38
…-phase-10

Add `splitTestsCompilation` solidity setting (10): `hardhat-ignition` updates
Co-authored-by: Luis Schaab <schaable@gmail.com>
Co-authored-by: Luis Schaab <schaable@gmail.com>
…-phase-11

Add `splitTestsCompilation` solidity setting (11): closing PR
Copilot AI review requested due to automatic review settings April 16, 2026 16:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 48 out of 52 changed files in this pull request and generated 4 comments.

Comment on lines +76 to 99
(suiteResult) => {
stream.push({
type: "suite:done",
data: suiteResult,
} satisfies TestEvent);
remainingSuites.delete(
formatArtifactId(suiteResult.id, sourceNameToUserSourceName),
);
if (remainingSuites.size === 0) {
if (runCompleted) {
stream.push(null);
}
}
},
);
stream.push({
type: "run:done",
data: solidityTestResult,
} satisfies TestEvent);
runCompleted = true;

controller.error(
new HardhatError(
HardhatError.ERRORS.CORE.SOLIDITY_TESTS.UNHANDLED_EDR_ERROR_SOLIDITY_TESTS,
{
error: error.message,
},
),
);
if (remainingSuites.size === 0) {
stream.push(null);
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stream.push(null) can be called from both the suite callback (when runCompleted is true) and after runSolidityTests resolves. If the EDR callback can fire after runSolidityTests resolves, this risks pushing EOF twice, which can trigger ERR_STREAM_PUSH_AFTER_EOF. Consider centralizing stream termination in a helper (e.g. endOnce()) or guarding with stream.readableEnded/stream.destroyed before pushing null.

Copilot uses AI. Check for mistakes.
Comment on lines +80 to +100
let scope = scopeBySource.get(sourceName);
if (scope === undefined) {
const fsPath = path.resolve(projectRoot, sourceName);

// npm files will be classified as "contracts" because their sourceName is
// not an existing file, and "contracts" is the default.
//
// If the package name clashed with
// ```ts
// path.relative(
// context.config.paths.root,
// context.config.paths.tests.solidity
// )
// ```
//
// They could be misclassified as test files. This is highly improbable,
// so we don't check it. You could read the artifact and see if the
// inputSourceName starts with `npm/` to rule this out.
scope = await context.solidity.getScope(fsPath);
scopeBySource.set(sourceName, scope);
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In unified mode, getContractArtifactPaths resolves each artifact sourceName to path.resolve(projectRoot, sourceName) and then calls context.solidity.getScope(fsPath). For npm-dependency artifacts, sourceName is not an on-disk project file, and this can be misclassified as a test if the package name matches the configured Solidity tests directory (e.g. test/... with paths.tests.solidity = "test"), causing types to be skipped incorrectly. Consider treating non-existent paths as npm sources (defaulting to "contracts"), or detecting npm artifacts via artifact metadata (e.g. input/source name prefix) instead of relying on getScope for paths that don't exist.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1 @@
// Empty file to trigger the full CI
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says this PR only adds a spec file and isn't meant to be reviewed, but the diff includes substantial production and test changes across multiple packages (build system behavior, errors, plugin integration tests, fixture projects, etc.). Please update the PR description to reflect the actual scope (or split/retitle the PR) to avoid confusion during review and release notes.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1 @@
// Empty file to trigger the full CI
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This placeholder source file under src/internal/ looks like it’s only meant to force CI to run. Please remove it (or move the CI trigger to a non-shipping location) before merging, so it doesn’t accidentally get released/published.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 16, 2026 16:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 53 changed files in this pull request and generated 3 comments.

Comment on lines +99 to +112
if (hre.config.solidity.splitTestsCompilation) {
if (noCompile !== true) {
await hre.tasks.getTask("build").run({
noTests: true,
});
}

// EDR needs all artifacts (contracts + tests)
const edrArtifactsWithMetadata: EdrArtifactWithMetadata[] = [];
const allBuildInfosAndOutputs: BuildInfoAndOutput[] = [];
for (const scope of ["contracts", "tests"] as const) {
const artifactsDir = await hre.solidity.getArtifactsDirectory(scope);
const artifactManager = new ArtifactManagerImplementation(artifactsDir);
edrArtifactsWithMetadata.push(
...(await buildEdrArtifactsWithMetadata(artifactManager)),
);
allBuildInfosAndOutputs.push(
...(await getBuildInfosAndOutputs(artifactManager)),
);
({ testRootPaths: testRootPathsToRun } = await hre.tasks
.getTask("build")
.run({
files: testFiles,
noContracts: true,
}));
console.log();
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In splitTestsCompilation mode, the --no-compile flag is only skipping the contracts build, but still always runs hre.tasks.getTask("build").run({ files: testFiles, noContracts: true }), which compiles the project despite the flag (the task option description says it should not compile the project). Consider skipping both build invocations when noCompile === true, and instead: (1) compute testRootPathsToRun from testFiles (resolved) or solidity.getRootFilePaths({ scope: "tests" }), (2) load artifacts from both scopes, and (3) validate that the selected test roots have compiled artifacts (similar to the unified-mode branch).

Copilot uses AI. Check for mistakes.
//
// They could be misclassified as test files. This is highly improbable,
// so we don't check it. You could read the artifact and see if the
// inputSourceName starts with `npm/` to rule this out.
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment refers to npm/ as the prefix for npm sources, but the Solidity build system root-path format uses the npm: prefix (e.g. npm:<package>/<file>). Updating the comment to match the actual prefix would avoid confusion for future maintainers.

Suggested change
// inputSourceName starts with `npm/` to rule this out.
// inputSourceName starts with `npm:` to rule this out.

Copilot uses AI. Check for mistakes.
"hardhat": minor
---

Make the split of contracts and solidity tests compilation optional, and controlled with a new `splitTestsCompilation` config field.
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description says this PR “only introduces a spec file” and is “not meant to be reviewed”, but this changeset (and the diff overall) indicates the feature is being implemented and released (new config field, error descriptors, build-system behavior, multiple tests/fixtures). Please update the PR description to match the actual scope of changes, or split out the spec-only PR if that’s still the intent.

Copilot uses AI. Check for mistakes.
@alcuadrado alcuadrado enabled auto-merge April 16, 2026 16:57
@alcuadrado alcuadrado added this pull request to the merge queue Apr 16, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 16, 2026
@alcuadrado alcuadrado added this pull request to the merge queue Apr 16, 2026
Merged via the queue into main with commit 5995f0f Apr 16, 2026
263 of 264 checks passed
@alcuadrado alcuadrado deleted the dont-split-compilations branch April 16, 2026 17:24
@github-actions github-actions Bot mentioned this pull request Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants