ci: Add Hardhat tooling integration test (#516)

## Description

Adds a CI workflow that builds a small Hardhat project with
`hardhat-polkadot`, exercising the standard JSON interface between
`resolc` and `hardhat-polkadot` end-to-end.

## Resolved Issues

Closes #514
This commit is contained in:
LJ authored and GitHub committed 2026-05-25 14:59:31 +02:00
1 parent dd39bb8198
commit c70efb2c2a
7 files changed
+12908

No files matched your search

+47
View File
@@ -0,0 +1,47 @@
# Tests compilation and E2E integration with hardhat-polkadot, but not runtime correctness.
name: Hardhat Integration
on:
workflow_call:
env:
# Workflow-internal hardhat envs are prefixed with `CI_` to not conflict with the
# `HARDHAT_*` namespace, which hardhat itself will interpret for its configuration.
CI_HARDHAT_PROJECT_ROOT: tooling-projects/hardhat/erc20
jobs:
use-hardhat:
runs-on: ubuntu-24.04
steps:
- name: Checkout revive
uses: actions/checkout@v4
- name: Download resolc Binary
uses: actions/download-artifact@v4
with:
name: resolc-x86_64-unknown-linux-musl
path: resolc-bin
- name: Export resolc Path
run: |
chmod +x resolc-bin/resolc-x86_64-unknown-linux-musl
# This env is used by `hardhat.config.js`.
echo "RESOLC_PATH=$(pwd)/resolc-bin/resolc-x86_64-unknown-linux-musl" >> $GITHUB_ENV
- name: Set Up Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
- name: Install Project Dependencies
working-directory: ${{ env.CI_HARDHAT_PROJECT_ROOT }}
run: npm ci
- name: Compile Project
working-directory: ${{ env.CI_HARDHAT_PROJECT_ROOT }}
run: npx hardhat compile
- name: Verify Output
working-directory: ${{ env.CI_HARDHAT_PROJECT_ROOT }}
run: bash verify-compiler-output.sh
+4
View File
@@ -65,3 +65,7 @@ jobs:
# Only run this if `test` successfully completes.
needs: test
uses: ./.github/workflows/differential-tests.yml
run-hardhat-tests:
needs: run-differential-tests
uses: ./.github/workflows/hardhat.yml
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.22;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Ownable {
constructor(address initialOwner)
ERC20("MyToken", "MTK")
Ownable(initialOwner)
{}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
@@ -0,0 +1,33 @@
require("@nomicfoundation/hardhat-toolbox");
require("@parity/hardhat-polkadot");
const RESOLC_PATH_ENV_NAME = "RESOLC_PATH";
function getEnv(name) {
const value = process.env[name];
if (!value) {
throw new Error(`Required environment variable '${name}' is missing`);
}
return value;
}
/** @type {import('hardhat/config').HardhatUserConfig} */
module.exports = {
solidity: "0.8.35",
resolc: {
compilerSource: "binary",
settings: {
resolcPath: getEnv(RESOLC_PATH_ENV_NAME),
optimizer: {
enabled: true,
parameters: "z"
},
},
},
networks: {
hardhat: {
polkadot: true
},
},
};
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,12 @@
{
"name": "erc20-hardhat",
"private": true,
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@parity/hardhat-polkadot": "^0.3.0",
"hardhat": "^2.26.0"
},
"dependencies": {
"@openzeppelin/contracts": "^5.3.0"
}
}
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Asserts that the compiled project contains the expected compiler output.
# Run from the project's root.
set -euxo pipefail
shopt -s nullglob
build_info_files=(artifacts/build-info/*.json)
if [[ ${#build_info_files[@]} -ne 1 ]]; then
echo "expected exactly one build-info file under artifacts/build-info/, found ${#build_info_files[@]}" >&2
exit 1
fi
build_info=${build_info_files[0]}
contract='.output.contracts["contracts/MyToken.sol"].MyToken'
source='.output.sources["contracts/MyToken.sol"]'
jq -er "$contract.evm.bytecode.object" "$build_info" | grep -q '^50564d'
jq -er "$contract.evm.deployedBytecode.object" "$build_info" | grep -q '^50564d'
jq -e "$contract.evm.methodIdentifiers | length > 0" "$build_info" > /dev/null
jq -e "$contract.abi | length > 0" "$build_info" > /dev/null
jq -e "$contract.storageLayout.storage | length > 0" "$build_info" > /dev/null
jq -e "$contract.metadata | length > 0" "$build_info" > /dev/null
jq -e "$source.ast | length > 0" "$build_info" > /dev/null
jq -e '.output.sources | length > 1' "$build_info" > /dev/null
echo "all checks passed"