Skip to content

perf: use foundry official docker to run CI and speed up CI #168

perf: use foundry official docker to run CI and speed up CI

perf: use foundry official docker to run CI and speed up CI #168

Workflow file for this run

name: Foundry
on:
workflow_dispatch:
pull_request:
push:
branches:
- "dev"
env:
FOUNDRY_PROFILE: ci
RPC_MAINNET: ${{ secrets.RPC_MAINNET }}
RPC_HOLESKY: ${{ secrets.RPC_HOLESKY }}
CHAIN_ID: ${{ secrets.CHAIN_ID }}
jobs:
# -----------------------------------------------------------------------
# Forge Test
# -----------------------------------------------------------------------
test-suite:
name: Test
runs-on: protocol-x64-16core
strategy:
matrix:
suite: [Unit, Integration, Fork]
steps:
# Check out repository with all submodules for complete codebase access.
- uses: actions/checkout@v4
with:
submodules: recursive
# Pull the Foundry Docker image (if not already pulled)
- name: pull foundry docker
run: |
docker pull ghcr.io/foundry-rs/foundry:stable
# Run Forge's formatting checker to ensure consistent code style.
- name: "Forge Fmt"
run: |
docker run --rm -v $(pwd):/mnt -w /mnt ghcr.io/foundry-rs/foundry:stable bash -c "forge fmt --check"
# Build the project and display contract sizes.
- name: Forge Version
run: |
docker run --rm -v $(pwd):/mnt -w /mnt ghcr.io/foundry-rs/foundry:stable bash -c "forge --version"
# Build the project and display contract sizes.
- name: Forge Build
run: |
docker run --rm -v $(pwd):/mnt -w /mnt ghcr.io/foundry-rs/foundry:stable bash -c "forge build --sizes"
# Run the test suite in parallel based on the matrix configuration.
- name: Run ${{ matrix.suite }} tests
run: |
case "${{ matrix.suite }}" in
Unit) docker run --rm -v $(pwd):/mnt -w /mnt ghcr.io/foundry-rs/foundry:stable \
bash -c "forge test --no-match-contract Integration" ;;
Integration) docker run --rm -v $(pwd):/mnt -w /mnt ghcr.io/foundry-rs/foundry:stable \
bash -c "forge test --match-contract Integration" ;;
Fork) docker run --rm -v $(pwd):/mnt -w /mnt ghcr.io/foundry-rs/foundry:stable \
bash -c "forge test --match-contract Integration" ;;
esac
env:
FOUNDRY_PROFILE: ${{ matrix.suite == 'Fork' && 'forktest' || 'ci' }}
# -----------------------------------------------------------------------
# Forge Test (Intense)
# -----------------------------------------------------------------------
# continuous-fuzzing:
# name: Test (Intense)
# runs-on: protocol-x64-16core
# container:
# image: ghcr.io/foundry-rs/foundry:stable
# # Only run on push events to dev branch, not on PR events
# if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
# strategy:
# fail-fast: true
# steps:
# # Check out repository with all submodules for complete codebase access.
# - uses: actions/checkout@v4
# with:
# submodules: recursive
# # Build the project and display contract sizes.
# - name: "Forge Build"
# run: |
# forge --version
# forge build --sizes
# id: build
# # Run Forge Test (Intense)
# - name: Forge Test (Intense)
# run: |
# echo -e "\033[1;33mWarning: This workflow may take several hours to complete.\033[0m"
# echo -e "\033[1;33mThis intense fuzzing workflow is optional but helps catch edge cases through extended testing.\033[0m"
# FOUNDRY_PROFILE=intense forge test -vvv
# # -----------------------------------------------------------------------
# # Forge Storage Diff
# # -----------------------------------------------------------------------
# storage-diff:
# name: Test (Storage)
# runs-on: protocol-x64-16core
# container:
# image: ghcr.io/foundry-rs/foundry:stable
# steps:
# # Check out repository with all submodules for complete codebase access.
# - uses: actions/checkout@v4
# with:
# submodules: recursive
# # Run storage diff check to detect storage layout incompatibilities.
# - name: "Mainnet Storage Diff"
# run: |
# bash bin/storage-diff.sh --rpc-url ${{ secrets.RPC_MAINNET }} --etherscan-key ${{ secrets.ETHERSCAN_API_KEY }} --input .github/configs/storage-diff.json
# id: storage-diff
# # -----------------------------------------------------------------------
# # Forge Coverage
# # -----------------------------------------------------------------------
# run-coverage:
# name: Coverage
# runs-on: protocol-x64-16core
# container:
# image: ghcr.io/foundry-rs/foundry:stable
# # Only run coverage checks on dev, testnet-holesky, and mainnet branches, or PRs targeting these branches
# if: |
# github.ref == 'refs/heads/dev' ||
# github.ref == 'refs/heads/testnet-holesky' ||
# github.ref == 'refs/heads/mainnet' ||
# github.base_ref == 'dev' ||
# github.base_ref == 'testnet-holesky' ||
# github.base_ref == 'mainnet'
# strategy:
# fail-fast: true
# steps:
# # Check out repository with all submodules for complete codebase access.
# - uses: actions/checkout@v4
# with:
# submodules: recursive
# # Install LCOV for coverage report generation.
# - name: Install LCOV
# run: |
# sudo apt-get install lcov
# id: lcov
# # Build the project and display contract sizes.
# - name: "Forge Build"
# run: |
# forge --version
# forge build --sizes
# id: build
# # Run Forge coverage with LCOV report format, excluding test and script files
# - name: Forge Coverage
# run: |
# FOUNDRY_DENY_WARNINGS=false FOUNDRY_PROFILE=ci forge coverage --report lcov --report summary --no-match-coverage "script|test"
# genhtml -q -o report ./lcov.info
# # Upload coverage report as artifact before potential failure
# - name: Upload Coverage Report
# uses: actions/upload-artifact@v4
# with:
# name: code-coverage-report
# path: report/*
# # Check coverage threshold after uploading report
# - name: Check Coverage Threshold
# run: |
# LINES_PCT=$(lcov --summary lcov.info | grep "lines" | cut -d ':' -f 2 | cut -d '%' -f 1 | tr -d '[:space:]')
# FUNCTIONS_PCT=$(lcov --summary lcov.info | grep "functions" | cut -d ':' -f 2 | cut -d '%' -f 1 | tr -d '[:space:]')
# FAILED=0
# if (( $(echo "$LINES_PCT < 90" | bc -l) )); then
# echo -e "\033[1;31m❌ Lines coverage ($LINES_PCT%) is below minimum threshold of 90%\033[0m"
# FAILED=1
# else
# echo -e "\033[1;32m✅ Lines coverage ($LINES_PCT%) meets minimum threshold of 90%\033[0m"
# fi
# if (( $(echo "$FUNCTIONS_PCT < 90" | bc -l) )); then
# echo -e "\033[1;31m❌ Functions coverage ($FUNCTIONS_PCT%) is below minimum threshold of 90%\033[0m"
# FAILED=1
# else
# echo -e "\033[1;32m✅ Functions coverage ($FUNCTIONS_PCT%) meets minimum threshold of 90%\033[0m"
# fi
# if [ $FAILED -eq 1 ]; then
# exit 1
# fi
# # -----------------------------------------------------------------------
# # Forge Size Diff
# # -----------------------------------------------------------------------
# compare-contract-sizes:
# name: Size Diff
# runs-on: protocol-x64-16core
# container:
# image: ghcr.io/foundry-rs/foundry:stable
# steps:
# # Check out repository with all submodules for complete codebase access.
# - uses: actions/checkout@v4
# with:
# submodules: recursive
# - name: Build contracts on PR branch
# run: |
# forge build --json --sizes | jq '.' > pr_sizes.json
# - name: Checkout target branch
# run: |
# git fetch origin ${{ github.base_ref }}
# git checkout ${{ github.base_ref }}
# - name: Build contracts on target branch
# run: |
# forge build --json --sizes | jq '.' > target_sizes.json
# - name: Compare contract sizes using Bash
# run: |
# # Extract contract names
# contracts=$(jq -r 'keys[]' pr_sizes.json)
# # Track if there are any differences
# has_differences=0
# echo -e "\n📊 \033[1;34mContract Size Comparison Report\033[0m 📊\n"
# # Iterate through contracts and compare sizes
# for contract in $contracts; do
# pr_runtime=$(jq -r --arg contract "$contract" '.[$contract].runtime_size // 0' pr_sizes.json)
# pr_init=$(jq -r --arg contract "$contract" '.[$contract].init_size // 0' pr_sizes.json)
# target_runtime=$(jq -r --arg contract "$contract" '.[$contract].runtime_size // 0' target_sizes.json)
# target_init=$(jq -r --arg contract "$contract" '.[$contract].init_size // 0' target_sizes.json)
# runtime_diff=$((pr_runtime - target_runtime))
# init_diff=$((pr_init - target_init))
# if [ "$runtime_diff" -ne 0 ] || [ "$init_diff" -ne 0 ]; then
# echo -e "\033[1;36m📝 $contract:\033[0m"
# if [ "$runtime_diff" -ne 0 ]; then
# if [ "$runtime_diff" -gt 0 ]; then
# echo -e " Runtime: \033[1;31m+$runtime_diff bytes\033[0m 📈"
# else
# echo -e " Runtime: \033[1;32m$runtime_diff bytes\033[0m 📉"
# fi
# fi
# if [ "$init_diff" -ne 0 ]; then
# if [ "$init_diff" -gt 0 ]; then
# echo -e " Init: \033[1;31m+$init_diff bytes\033[0m 📈"
# else
# echo -e " Init: \033[1;32m$init_diff bytes\033[0m 📉"
# fi
# fi
# has_differences=1
# fi
# done
# if [ "$has_differences" -eq 0 ]; then
# echo -e "\033[1;32m✨ No contract size changes detected ✨\033[0m"
# fi