> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenderly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Foundry и Github Actions

> Настройте CI/CD-пайплайн на Virtual Environments с помощью Tenderly GitHub Action для тестирования и стейджинга Solidity смарт-контрактов через Foundry.

Узнайте, как настроить GitHub Action для организации пайплайна непрерывной интеграции и непрерывного развёртывания (CI/CD) с Foundry на Tenderly [Virtual Environments](/virtual-environments/overview).

Используйте action [Tenderly Virtual Environment Setup](https://github.com/marketplace/actions/tenderly-virtual-testnet-setup), чтобы включить автоматические сборки для тестирования и стейджинга ваших контрактов. Этот подход позволяет:

* **Интеграция CI/CD**: запускать тесты против форкнутых сетей и настраивать стейджинг-окружения
* **Тестирование в нескольких сетях**: разворачивать несколько сетей за один шаг
* **Автоматизированные развёртывания**: деплоить и верифицировать контракты с полными логами развёртывания
* **Сбор артефактов**: отслеживать развёртывания в разных сетях со структурированными логами

В этом руководстве нужно пройти два этапа:

1. Локальная настройка: настройте Foundry, создайте и протестируйте файл workflow
2. Настройка в GitHub: настройте GitHub Action, сконфигурируйте GitHub-секреты и переменные, протестируйте сборку

Для справки используйте этот пример проекта:

<Card title="Настройка CI/CD с Foundry" href="" />

<Frame caption="Непрерывная интеграция (CI) и непрерывное развёртывание (CD) с Virtual Environments">
  <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/testnets/ci.png?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=2feac85321ea229193ae44bdbc1c1c38" alt="Continuous integration (CI) and continous deployment (CD) with Virtual Environments" width="1920" height="1080" data-path="images/testnets/ci.png" />
</Frame>

## Этап 1: локальная настройка

Сначала создайте файл workflow с необходимыми настройками.

<Steps>
  ### Создайте файл workflow

  В вашем Foundry-проекте создайте новую директорию `workflows` и файл `ci-cd.yaml`:

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  mkdir -p .github/workflows
  touch .github/workflows/ci-cd.yaml
  ```

  Затем вставьте следующую конфигурацию в `ci-cd.yaml`, которая настраивает две задачи:

  * **`test`** — запускает тесты Foundry
  * **`deploy`** — деплоит контракты в стейджинговую Virtual Environment

  Этот пример workflow-файла:

  * Использует `tenderly/vnet-github-action` для развёртывания Virtual Environments по заданному `network_id` (Mainnet и Base) с пользовательским `chain_id`
  * Использует `update_foundry_config_and_build`, чтобы отредактировать `foundry.toml` с правильным chain ID (особенно важно, если вы используете пользовательский `chain_id`) и передать информацию о верификации
  * Пополняет EOA `DEPLOYER_WALLET_ADDRESS` 100 ETH с помощью `set_wallet_balance`
  * Деплоит контракты в Virtual Environment
  * Собирает информацию о развёртывании в `$BUILD_OUTPUT_FILE_1` и `$BUILD_OUTPUT_FILE_8453` соответственно, используя опцию `--json` в Foundry
  * Пушит собранную информацию о развёртывании в репозиторий

  <Note>
    Аргумент `mode` в `Tenderly/vnet-github-action` принимает значения `CI` и `CD`.

    * Режим `CD` оставляет Virtual Environment активной, и вы можете работать с задеплоенными контрактами.
    * Режим `CI` приостанавливает Virtual Environment после завершения шага. Вы сможете просматривать транзакции, но не сможете отправлять дальнейшие RPC-запросы.
  </Note>

  ```yaml title='ci-cd.yaml' showLineNumbers lines={24-25, 32-34, 38, 43, 49, 69} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  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
  ```

  ### Настройте Foundry

  Создайте или обновите файл конфигурации `foundry.toml`. Чтобы использовать автоматическую верификацию контрактов, у вас должна быть запись `unknown_chain` с `key`, `chain` и `url`.

  <Note>
    При использовании Virtual Environments с вашего локального компьютера замените `chain \= 0` на chain ID Virtual Environment, к которой вы подключились.
  </Note>

  ```toml showLineNumbers title="foundry.toml" lines={8-11} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  [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" }
  ```

  ### Подготовьте переменные окружения

  Для локального тестирования настройте файл `.env` со следующими переменными:

  ```dotenv showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  # Access parameters
  TENDERLY_ACCESS_KEY=...
  TENDERLY_PROJECT_NAME=...
  TENDERLY_ACCOUNT_NAME=...

  # Deployment parameters
  DEPLOYER_PRIVATE_KEY=...
  DEPLOYER_WALLET_ADDRESS=...
  ```

  Обязательные переменные:

  * `TENDERLY_ACCESS_KEY`: ваш [Tenderly access key](/platform/account/projects/api-tokens)
  * `TENDERLY_ACCOUNT_NAME` и `TENDERLY_PROJECT_NAME`: [имена вашего аккаунта и проекта](/platform/account/projects/api-tokens)
  * `DEPLOYER_PRIVATE_KEY`: приватный ключ для кошелька развёртывания
  * `DEPLOYER_WALLET_ADDRESS`: адрес, соответствующий приватному ключу

  ### Добавьте скрипт fixtures

  Добавьте следующий `fixtures.sh` в ваш репозиторий, чтобы легко пополнять аккаунты и адаптировать `foundry.toml`.

  Этот файл предоставляет:

  * функцию `set_wallet_balance` для пополнения баланса (RPC\_URL WALLET\_ADDRESS BALANCE\_HEX)
  * функцию `update_foundry_config_and_build` для замены placeholder'ов в `foundry.toml`
  * `HUNDRED_ETH` — значение wei, соответствующее 100 ETH

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  #!/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
  ```

  GitHub Action предоставляет RPC-ссылки и URL верификации через разные переменные окружения:

  | Переменная                                       | Описание                                                                   |
  | ------------------------------------------------ | -------------------------------------------------------------------------- |
  | `TENDERLY_TESTNET_ID_{network_id}`               | UUID Virtual Environment, уникально идентифицирующий её в Tenderly         |
  | `TENDERLY_ADMIN_RPC_URL_{network_id}`            | Эндпоинт [Admin RPC](/virtual-environments/admin-rpc) с методами чит-кодов |
  | `TENDERLY_PUBLIC_RPC_URL_{network_id}`           | Публичный RPC-эндпоинт                                                     |
  | `TENDERLY_CHAIN_ID_{network_id}`                 | Chain ID                                                                   |
  | `TENDERLY_TESTNET_SLUG_{network_id}`             | Уникальный слаг Virtual Environment                                        |
  | `TENDERLY_FOUNDRY_VERIFICATION_URL_{network_id}` | URL [верификации Foundry](/contract-verification/foundry#verifier-url)     |
  | `BUILD_OUTPUT_FILE_{network_id}`                 | Путь к файлу вывода сборки                                                 |

  ### Протестируйте GitHub Action локально

  Можно протестировать ваш GitHub Action локально с помощью [Act](https://github.com/nektos/act) без пуша на GitHub.

  Используйте файл **`.env`** для заполнения GitHub-секретов и переменных окружения так:

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  act --secret-file .env --var-file .env
  ```
</Steps>

## Этап 2: настройка GitHub

После того как локальная настройка подтверждена, настройте ваш GitHub-репозиторий, выполнив следующие шаги.

<Steps>
  ### Настройте секреты и переменные

  Настройте следующие GitHub-секреты и переменные:

  **Секреты:**

  * `TENDERLY_ACCESS_KEY`: Tenderly Access Key
  * `DEPLOYER_PRIVATE_KEY`: приватный ключ для EOA деплойера

  **Переменные:**

  * `TENDERLY_PROJECT_NAME`: имя проекта Tenderly
  * `TENDERLY_ACCOUNT_NAME`: имя владельца проекта
  * `DEPLOYER_WALLET_ADDRESS`: EOA деплойера

  Это можно сделать через [GitHub UI](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables#creating-configuration-variables-for-a-repository) или с помощью командной строки `gh`:

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  # 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}
  ```

  ### Запушьте обновления

  Наконец, закоммитьте и запушьте изменения:

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  git add .
  git commit -m "Add CI/CD workflow for Foundry"
  git push
  ```

  ### Проверьте ваш action

  Перейдите в ваш GitHub-репозиторий и посмотрите вкладку Actions. Поздравляем, вы запустили ваш CI/CD workflow с Virtual Environments и Foundry.

  ### Получите RPC-ссылку

  Чтобы получить RPC-ссылку, перейдите в **Tenderly dashboard > Virtual Environments** и найдите вашу CD Virtual Environment.
</Steps>

## Дальнейшие шаги

* Изучите [пример Foundry](https://github.com/Tenderly/vnet-github-action/tree/main/examples/foundry) на GitHub.
* Изучите [пример Hardhat](https://github.com/Tenderly/vnet-github-action/tree/main/examples/hardhat-ignition) на GitHub.
* Используйте [balance fixtures](https://github.com/Tenderly/vnet-github-action/blob/main/fixtures/load-fixtures.sh).
