- CI/CD 集成:针对 fork 的网络运行测试,并搭建 staging 环境
- 多网络测试:一步完成多个网络的配置
- 自动化部署:部署和验证合约,并附有完整的部署日志
- 构件收集:使用结构化日志跨网络跟踪部署
- 本地设置:设置 Foundry 以创建和测试工作流文件
- GitHub 设置:设置 GitHub Action,配置 GitHub secrets 和变量,并测试构建
Foundry CI/CD setup

阶段 1:本地设置
首先,使用必要的设置创建一个工作流文件。tenderly/vnet-github-action 根据给定的 network_id(Mainnet 和 Base)配置 Virtual Environments,并使用自定义的 chain_idupdate_foundry_config_and_build 修改 foundry.toml 中正确的链 ID(如果您使用自定义 chain_id 尤其重要),并传递验证信息。set_wallet_balance 向 DEPLOYER_WALLET_ADDRESS EOA 注资 100 ETH--json 选项将部署信息收集到 $BUILD_OUTPUT_FILE_1 和 $BUILD_OUTPUT_FILE_8453Tenderly/vnet-github-action 的 mode 参数取值为 CI 和 CD。CD模式使 Virtual Environment 保持活动状态,您可以使用已部署的合约。CI模式在步骤完成后暂停 Virtual Environment。您将能够检查交易,但无法发送更多的 RPC 请求。
name: Foundry CI/CD
on:
push:
pull_request:
env:
TENDERLY_ACCESS_KEY: ${{ secrets.TENDERLY_ACCESS_KEY }}
DEPLOYER_WALLET_ADDRESS: ${{ vars.DEPLOYER_WALLET_ADDRESS }}
DEBUG: tenderly/vnet-github-action@v1.0.14
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./examples/foundry
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Virtual Environment
uses: tenderly/vnet-github-action@v1.0.14
with:
mode: CD
access_key: ${{ secrets.TENDERLY_ACCESS_KEY }}
project_name: ${{ vars.TENDERLY_PROJECT_NAME }}
account_name: ${{ vars.TENDERLY_ACCOUNT_NAME }}
testnet_name: "Staging"
network_id: |
1
8453
chain_id_prefix: 7357
public_explorer: true
verification_visibility: 'src'
push_on_complete: true
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Fund Deployer Account on Mainnet
run: |
source ../../fixtures/load-fixtures.sh
update_foundry_config_and_build $TENDERLY_ACCESS_KEY $TENDERLY_FOUNDRY_VERIFICATION_URL_1 $TENDERLY_CHAIN_ID_1
set_wallet_balance $TENDERLY_ADMIN_RPC_URL_1 ${{ vars.DEPLOYER_WALLET_ADDRESS }} $HUNDRED_ETH
- name: Deploy Contracts Mainnet
run: |
forge build --sizes
forge script script/Counter.s.sol \
--private-key ${{ secrets.DEPLOYER_PRIVATE_KEY }} \
--rpc-url ${{ env.TENDERLY_PUBLIC_RPC_URL_1 }} \
--verifier-url ${{ env.TENDERLY_FOUNDRY_VERIFICATION_URL_1 }} \
--etherscan-api-key $TENDERLY_ACCESS_KEY \
--slow \
--broadcast \
--verify \
--json > $BUILD_OUTPUT_FILE_1
- name: Fund Deployer Account on Base
run: |
source ../../fixtures/load-fixtures.sh
update_foundry_config_and_build $TENDERLY_ACCESS_KEY $TENDERLY_FOUNDRY_VERIFICATION_URL_8453 $TENDERLY_CHAIN_ID_8453
set_wallet_balance $TENDERLY_ADMIN_RPC_URL_8453 ${{ vars.DEPLOYER_WALLET_ADDRESS }} $HUNDRED_ETH
- name: Deploy Contracts Base
working-directory: ./examples/foundry
run: |
forge script script/Counter.s.sol \
--private-key ${{ secrets.DEPLOYER_PRIVATE_KEY }} \
--rpc-url ${{ env.TENDERLY_PUBLIC_RPC_URL_8453 }} \
--verifier-url ${{ env.TENDERLY_FOUNDRY_VERIFICATION_URL_8453 }} \
--etherscan-api-key $TENDERLY_ACCESS_KEY \
--slow \
--broadcast \
--verify \
--json > $BUILD_OUTPUT_FILE_8453
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
cbor_metadata = true
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
[etherscan]
## placeholders must be replaced with key ("string"), chain_id (number, non-quoted), and tenderly_foundry_verification_url ("string")
unknown_chain = { key = "$TENDERLY_ACCESS_KEY", chain = 0, url = "$TENDERLY_FOUNDRY_VERIFICATION_URL" }
# Access parameters
TENDERLY_ACCESS_KEY=...
TENDERLY_PROJECT_NAME=...
TENDERLY_ACCOUNT_NAME=...
# Deployment parameters
DEPLOYER_PRIVATE_KEY=...
DEPLOYER_WALLET_ADDRESS=...
TENDERLY_ACCESS_KEY:您的 Tenderly access keyTENDERLY_ACCOUNT_NAME 和 TENDERLY_PROJECT_NAME:您的账户和项目名称DEPLOYER_PRIVATE_KEY:部署钱包的私钥DEPLOYER_WALLET_ADDRESS:与私钥对应的地址set_wallet_balance 函数用于给余额充值 (RPC_URL WALLET_ADDRESS BALANCE_HEX)update_foundry_config_and_build 函数用于替换 foundry.toml 中的占位符HUNDRED_ETH 对应 100 ETH 的 wei 值#!/bin/bash
set_wallet_balance() {
if [ "$#" -ne 3 ]; then
echo "Usage: set_wallet_balance RPC_URL WALLET_ADDRESS BALANCE_HEX"
return 1
fi
local rpc_url="$1"
local wallet_address="$2"
local balance_hex="$3"
curl --location "$rpc_url" \
--header 'Content-Type: application/json' \
--data "{
\"jsonrpc\": \"2.0\",
\"method\": \"tenderly_setBalance\",
\"params\": [\"$wallet_address\", \"$balance_hex\"],
\"id\": \"1\"
}"
}
update_foundry_config_and_build() {
if [ "$#" -ne 3 ]; then
echo "Usage: update_foundry_config_and_build ACCESS_KEY VERIFICATION_URL CHAIN_ID"
return 1
fi
local access_key="$1"
local verification_url="$2"
local chain_id="$3"
# Create temporary file and update foundry.toml
sed -e "s|\${TENDERLY_ACCESS_KEY}|$access_key|g" \
-e "s|\${TENDERLY_FOUNDRY_VERIFICATION_URL}|$verification_url|g" \
-e "s/\(unknown_chain[[:space:]]*=[[:space:]]*{[^}]*chain[[:space:]]*=[[:space:]]*\)[0-9][0-9]*/\1$chain_id/g" \
foundry.toml > foundry.toml.tmp && mv foundry.toml.tmp foundry.toml
}
# Export constant
HUNDRED_ETH="0xDE0B6B3A7640000"
export HUNDRED_ETH
TENDERLY_TESTNET_ID_{network_id}TENDERLY_ADMIN_RPC_URL_{network_id}TENDERLY_PUBLIC_RPC_URL_{network_id}TENDERLY_CHAIN_ID_{network_id}TENDERLY_TESTNET_SLUG_{network_id}TENDERLY_FOUNDRY_VERIFICATION_URL_{network_id}BUILD_OUTPUT_FILE_{network_id}您可以使用 Act 在本地测试您的 GitHub Action,而无需推送到 GitHub。
阶段 2:Github 设置
在确认本地设置有效后,使用以下步骤配置您的 GitHub 仓库。TENDERLY_PROJECT_NAME:Tenderly 项目名称TENDERLY_ACCOUNT_NAME:项目所有者的名称DEPLOYER_WALLET_ADDRESS:部署者 EOA您可以通过 GitHub UI 或使用
gh 命令行来完成此操作:# Load environment variables
source .env
# Set variables
gh variable set TENDERLY_PROJECT_NAME --body ${TENDERLY_PROJECT_NAME}
gh variable set TENDERLY_ACCOUNT_NAME --body ${TENDERLY_ACCOUNT_NAME}
gh variable set DEPLOYER_WALLET_ADDRESS --body ${DEPLOYER_WALLET_ADDRESS}
# Set secrets
gh secret set TENDERLY_ACCESS_KEY --body ${TENDERLY_ACCESS_KEY}
gh secret set DEPLOYER_PRIVATE_KEY --body ${DEPLOYER_PRIVATE_KEY}
后续步骤
- 在 Github 上探索 Foundry 示例。
- 在 Github 上探索 Hardhat 示例。
- 使用余额 fixtures。