A private fork of a live EVM chain for each CI run — made before your tests, deleted after them. State is read from the real chain on demand, so a fork is ready in about a second however large the chain is.
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: foundry-rs/foundry-toolchain@v1
- id: fork
uses: Forkscout/forkstate-action@v1
with:
token: ${{ secrets.FORKSTATE_TOKEN }}
chain: base
fork-block: 30000000 # optional: pin it for reproducible runs
- run: forge test --fork-url ${{ steps.fork.outputs.rpc-url }}Make a token on the forkstate Account page and store it as the
FORKSTATE_TOKEN repository secret.
| Input | Default | |
|---|---|---|
token |
— | forkstate API token. Required. |
chain |
— | Chain to fork: ethereum, base, bsc, … (list). Required. |
fork-block |
head | Block to fork at, decimal or 0x hex. |
chain-id |
derived | Chain id the fork answers with. The default is not the real chain's, so nothing signed here is valid there. |
name |
<repo> run <id>.<attempt> |
Name for the testnet. |
project |
CI |
Project to put it in; made if missing. |
tags |
— | Extra tags, comma-separated. Every testnet the action makes is tagged CI. |
keep |
false |
Leave the testnet after the job, for debugging. |
api-url |
https://forkstate.forkscout.com |
For self-hosted installs. |
| Output | |
|---|---|
rpc-url |
JSON-RPC URL. Masked in logs — it is the credential. Also exported as FORKSTATE_RPC_URL. |
testnet-id |
For the REST API. |
chain-id |
The id the fork answers with. |
fork-block |
The parent block, as 0x hex. |
The testnet is deleted in the job's post step whether the tests passed or not. If the delete fails, the job gets a warning rather than a failure.
- run: npx hardhat test
env:
FORK_URL: ${{ steps.fork.outputs.rpc-url }}with networks.hardhat.forking.url = process.env.FORK_URL in hardhat.config.
The action has no dependencies: main.mjs and post.mjs run as they are.
node test.mjs runs both against a fake server.