Skip to content

Commit 3432230

Browse files
committed
refactor: reset foundry.yml
1 parent b942b32 commit 3432230

File tree

1 file changed

+286
-0
lines changed

1 file changed

+286
-0
lines changed

β€Ž.github/workflows/foundry.yml

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
name: Foundry
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
push:
7+
branches:
8+
- main
9+
10+
11+
env:
12+
FOUNDRY_PROFILE: medium
13+
14+
jobs:
15+
# -----------------------------------------------------------------------
16+
# Forge Test
17+
# -----------------------------------------------------------------------
18+
19+
test-suite:
20+
name: Test
21+
runs-on: protocol-x64-16core
22+
strategy:
23+
matrix:
24+
suite: [Unit, Integration, Fork]
25+
26+
steps:
27+
# Check out repository with all submodules for complete codebase access.
28+
- uses: actions/checkout@v4
29+
with:
30+
submodules: recursive
31+
32+
# Restore Forge cache
33+
- name: Cache Forge Build
34+
uses: actions/cache@v3
35+
with:
36+
path: |
37+
cache/
38+
out/
39+
key: ${{ runner.os }}-forge-${{ hashFiles('**/foundry.toml', '**/remappings.txt', 'src/**/*.sol', 'lib/**/*.sol') }}
40+
restore-keys: |
41+
${{ runner.os }}-forge-
42+
43+
# Install the Foundry toolchain.
44+
- name: Install Foundry
45+
uses: foundry-rs/foundry-toolchain@v1
46+
with:
47+
version: stable
48+
49+
# Run Forge's formatting checker to ensure consistent code style.
50+
- name: "Forge Fmt"
51+
run: |
52+
forge fmt --check
53+
FOUNDRY_PROFILE=test forge fmt --check
54+
id: fmt
55+
56+
# Build the project and display contract sizes.
57+
- name: Forge Build
58+
run: |
59+
forge --version
60+
forge build --sizes
61+
62+
# Run the test suite in parallel based on the matrix configuration.
63+
- name: Run ${{ matrix.suite }} tests
64+
run: |
65+
case "${{ matrix.suite }}" in
66+
Unit) forge test --no-match-contract Integration ;;
67+
Integration) forge test --match-contract Integration ;;
68+
Fork) forge test --match-contract Integration ;;
69+
esac
70+
env:
71+
FOUNDRY_PROFILE: ${{ matrix.suite == 'Fork' && 'forktest' || 'medium' }}
72+
RPC_MAINNET: https://billowing-capable-sound.quiknode.pro/
73+
74+
# -----------------------------------------------------------------------
75+
# Forge Storage Diff
76+
# -----------------------------------------------------------------------
77+
78+
storage-diff:
79+
name: Test (Storage)
80+
runs-on: protocol-x64-16core
81+
steps:
82+
# Check out repository with all submodules for complete codebase access.
83+
- uses: actions/checkout@v4
84+
with:
85+
submodules: recursive
86+
87+
# Restore Forge cache
88+
- name: Cache Forge Build
89+
uses: actions/cache@v3
90+
with:
91+
path: |
92+
cache/
93+
out/
94+
key: ${{ runner.os }}-forge-${{ hashFiles('**/foundry.toml', '**/remappings.txt', 'src/**/*.sol', 'lib/**/*.sol') }}
95+
restore-keys: |
96+
${{ runner.os }}-forge-
97+
98+
# Install the Foundry toolchain.
99+
- name: "Install Foundry"
100+
uses: foundry-rs/foundry-toolchain@v1
101+
with:
102+
version: stable
103+
104+
# Run storage diff check to detect storage layout incompatibilities.
105+
- name: "Mainnet Storage Diff"
106+
run: |
107+
bash bin/storage-diff.sh --rpc-url ${{ secrets.RPC_MAINNET }} --etherscan-key ${{ secrets.ETHERSCAN_API_KEY }} --input .github/configs/storage-diff.json
108+
id: storage-diff
109+
110+
# -----------------------------------------------------------------------
111+
# Forge Coverage
112+
# -----------------------------------------------------------------------
113+
114+
run-coverage:
115+
name: Coverage
116+
runs-on: protocol-x64-16core
117+
# Only run coverage checks on main, preprod, testnet, and mainnet branches, or PRs targeting these branches
118+
if: |
119+
github.ref == 'refs/heads/main' ||
120+
github.ref == 'refs/heads/preprod' ||
121+
github.ref == 'refs/heads/testnet' ||
122+
github.ref == 'refs/heads/mainnet' ||
123+
github.base_ref == 'main' ||
124+
github.base_ref == 'preprod' ||
125+
github.base_ref == 'testnet' ||
126+
github.base_ref == 'mainnet'
127+
strategy:
128+
fail-fast: true
129+
steps:
130+
# Check out repository with all submodules for complete codebase access.
131+
- uses: actions/checkout@v4
132+
with:
133+
submodules: recursive
134+
135+
# Restore Foundry and Forge cache
136+
- name: Cache Foundry Dependencies
137+
uses: actions/cache@v3
138+
with:
139+
path: |
140+
~/.cargo
141+
~/.foundry
142+
out/
143+
cache/
144+
key: ${{ runner.os }}-forge-${{ hashFiles('**/foundry.toml', '**/remappings.txt', 'src/**/*.sol', 'lib/**/*.sol', '**/Cargo.lock') }}
145+
restore-keys: |
146+
${{ runner.os }}-foundry-
147+
148+
# Install the Foundry toolchain.
149+
- name: "Install Foundry"
150+
uses: foundry-rs/foundry-toolchain@v1
151+
with:
152+
version: stable
153+
154+
# Install LCOV for coverage report generation.
155+
- name: Install LCOV (Prebuilt)
156+
run: |
157+
curl -L https://github.com/linux-test-project/lcov/releases/download/v1.16/lcov-1.16.tar.gz | tar xz
158+
sudo cp lcov-1.16/bin/* /usr/local/bin/
159+
sudo cp -r lcov-1.16/man/* /usr/share/man/
160+
161+
# Build the project and display contract sizes.
162+
- name: "Forge Build"
163+
run: |
164+
forge --version
165+
forge build --sizes
166+
id: build
167+
168+
# Run Forge coverage with LCOV report format, excluding test and script files
169+
- name: Forge Coverage
170+
run: |
171+
FOUNDRY_DENY_WARNINGS=false \
172+
FOUNDRY_PROFILE=coverage \
173+
FOUNDRY_CACHE=true \
174+
FOUNDRY_CACHE_PATH=cache \
175+
forge coverage --report lcov --report summary --no-match-coverage "script|test" -j $(nproc)
176+
genhtml -q -o report ./lcov.info
177+
178+
# Upload coverage report as artifact before potential failure
179+
- name: Upload Coverage Report
180+
uses: actions/upload-artifact@v4
181+
with:
182+
name: code-coverage-report
183+
path: report/*
184+
if-no-files-found: error
185+
186+
# Check coverage threshold after uploading report
187+
- name: Check Coverage Threshold
188+
run: |
189+
LINES_PCT=$(lcov --summary lcov.info | grep "lines" | cut -d ':' -f 2 | cut -d '%' -f 1 | tr -d '[:space:]')
190+
FUNCTIONS_PCT=$(lcov --summary lcov.info | grep "functions" | cut -d ':' -f 2 | cut -d '%' -f 1 | tr -d '[:space:]')
191+
FAILED=0
192+
193+
if (( $(echo "$LINES_PCT < 90" | bc -l) )); then
194+
echo -e "\033[1;31m❌ Lines coverage ($LINES_PCT%) is below minimum threshold of 90%\033[0m"
195+
FAILED=1
196+
else
197+
echo -e "\033[1;32mβœ… Lines coverage ($LINES_PCT%) meets minimum threshold of 90%\033[0m"
198+
fi
199+
200+
if (( $(echo "$FUNCTIONS_PCT < 90" | bc -l) )); then
201+
echo -e "\033[1;31m❌ Functions coverage ($FUNCTIONS_PCT%) is below minimum threshold of 90%\033[0m"
202+
FAILED=1
203+
else
204+
echo -e "\033[1;32mβœ… Functions coverage ($FUNCTIONS_PCT%) meets minimum threshold of 90%\033[0m"
205+
fi
206+
207+
if [ $FAILED -eq 1 ]; then
208+
exit 1
209+
fi
210+
211+
# -----------------------------------------------------------------------
212+
# Forge Size Diff
213+
# -----------------------------------------------------------------------
214+
215+
compare-contract-sizes:
216+
name: Size Diff
217+
runs-on: protocol-x64-16core
218+
steps:
219+
# Check out repository with all submodules for complete codebase access.
220+
- uses: actions/checkout@v4
221+
with:
222+
submodules: recursive
223+
224+
# Install the Foundry toolchain.
225+
- name: "Install Foundry"
226+
uses: foundry-rs/foundry-toolchain@v1
227+
with:
228+
version: stable
229+
230+
- name: Build contracts on PR branch
231+
run: |
232+
forge build --json --sizes | jq '.' > pr_sizes.json
233+
234+
- name: Checkout target branch
235+
run: |
236+
git fetch origin ${{ github.base_ref }}
237+
git checkout ${{ github.base_ref }}
238+
239+
- name: Build contracts on target branch
240+
run: |
241+
forge build --json --sizes | jq '.' > target_sizes.json
242+
243+
- name: Compare contract sizes using Bash
244+
run: |
245+
# Extract contract names
246+
contracts=$(jq -r 'keys[]' pr_sizes.json)
247+
248+
# Track if there are any differences
249+
has_differences=0
250+
251+
echo -e "\nπŸ“Š \033[1;34mContract Size Comparison Report\033[0m πŸ“Š\n"
252+
253+
# Iterate through contracts and compare sizes
254+
for contract in $contracts; do
255+
pr_runtime=$(jq -r --arg contract "$contract" '.[$contract].runtime_size // 0' pr_sizes.json)
256+
pr_init=$(jq -r --arg contract "$contract" '.[$contract].init_size // 0' pr_sizes.json)
257+
258+
target_runtime=$(jq -r --arg contract "$contract" '.[$contract].runtime_size // 0' target_sizes.json)
259+
target_init=$(jq -r --arg contract "$contract" '.[$contract].init_size // 0' target_sizes.json)
260+
261+
runtime_diff=$((pr_runtime - target_runtime))
262+
init_diff=$((pr_init - target_init))
263+
264+
if [ "$runtime_diff" -ne 0 ] || [ "$init_diff" -ne 0 ]; then
265+
echo -e "\033[1;36mπŸ“ $contract:\033[0m"
266+
if [ "$runtime_diff" -ne 0 ]; then
267+
if [ "$runtime_diff" -gt 0 ]; then
268+
echo -e " Runtime: \033[1;31m+$runtime_diff bytes\033[0m πŸ“ˆ"
269+
else
270+
echo -e " Runtime: \033[1;32m$runtime_diff bytes\033[0m πŸ“‰"
271+
fi
272+
fi
273+
if [ "$init_diff" -ne 0 ]; then
274+
if [ "$init_diff" -gt 0 ]; then
275+
echo -e " Init: \033[1;31m+$init_diff bytes\033[0m πŸ“ˆ"
276+
else
277+
echo -e " Init: \033[1;32m$init_diff bytes\033[0m πŸ“‰"
278+
fi
279+
fi
280+
has_differences=1
281+
fi
282+
done
283+
284+
if [ "$has_differences" -eq 0 ]; then
285+
echo -e "\033[1;32m✨ No contract size changes detected ✨\033[0m"
286+
fi

0 commit comments

Comments
Β (0)