diff --git a/.github/actions/avalanchego-setup-action/README.md b/.github/actions/avalanchego-setup-action/README.md new file mode 100644 index 000000000000..a561cf1b8d4a --- /dev/null +++ b/.github/actions/avalanchego-setup-action/README.md @@ -0,0 +1,44 @@ +# AvalancheGo Setup Action + +## Overview +This action provides composable CI capabilities for setting up AvalancheGo with custom dependency versions. + +### Why this exists? +Solves CI composability problems by enabling repositories to setup and build AvalancheGo with specific dependency versions without complex setup or cross-repository coordination. + +### Why is it needed? +Dependencies need AvalancheGo as their integration context for realistic testing. +Without this action, setting up AvalancheGo with custom dependency versions requires build knowledge and manual `go mod` manipulation. +Teams either skip proper testing or dump tests in AvalancheGo (wrong ownership). +This action makes AvalancheGo composable - any repository can pull it in as integration context with one line. + +## Security Model +- Repository Restriction: Only allows dependencies from `github.com/ava-labs/*` repositories +- No Custom Forks: Prevents supply chain attacks from malicious forks +- Commit Validation: Validates dependency versions reference ava-labs repositories only + +## Inputs + +| Input | Description | Required | Default | +|-------|-------------|----------|-----------------------| +| `checkout-path` | Directory path where AvalancheGo will be checked out | No | `'.'` | +| `avalanchego` | AvalancheGo version (commit SHA, branch, tag) | No | `'${{ github.sha }}'` | +| `firewood` | Firewood version. Consumer should run Firewood shared workflow first | No | `''` | +| `coreth` | Coreth version (commit SHA, branch, tag) | No | `''` | +| `libevm` | LibEVM version (commit SHA, branch, tag) | No | `''` | + +## Usage Examples + +```yaml +- name: Setup AvalancheGo with Firewood # This will setup go.mod + uses: ./.github/actions/avalanchego-setup-action + with: + checkout-path: "build/avalanchego" + coreth: "my-feature-branch" + libevm: "experimental-branch" + firewood: "ffi/v0.0.12" +- name: Load test # This will compile and run the load test + uses: ./.github/actions/run-monitored-tmpnet-cmd + with: + run: ./scripts/run_task.sh test-load -- --load-timeout=30m --firewood +``` diff --git a/.github/actions/avalanchego-setup-action/action.yml b/.github/actions/avalanchego-setup-action/action.yml new file mode 100644 index 000000000000..1ce539fc2b28 --- /dev/null +++ b/.github/actions/avalanchego-setup-action/action.yml @@ -0,0 +1,61 @@ +name: 'Setup AvalancheGo' +description: 'Setup AvalancheGo with custom dependencies (Firewood, Coreth, LibEVM)' + +inputs: + avalanchego: + description: 'AvalancheGo version (commit SHA, branch name, or tag)' + required: false + default: ${{ github.sha }} + checkout-path: + description: 'Path where AvalancheGo will be checked out' + required: false + default: '.' + firewood: + description: 'Firewood version (commit SHA, branch, tag, or ffi/vX.Y.Z for pre-built)' + required: false + default: '' + firewood-path: + description: 'Directory path where Firewood will be cloned/built (preferably NVMe storage)' + required: false + default: '' + coreth: + description: 'Coreth version (commit SHA, branch name, or tag)' + required: false + default: '' + libevm: + description: 'LibEVM version (commit SHA, branch name, or tag)' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Checkout AvalancheGo + uses: actions/checkout@v4 + with: + repository: 'ava-labs/avalanchego' + ref: ${{ inputs.avalanchego }} + path: ${{ inputs.checkout-path }} + - name: Update Coreth dependency + if: inputs.coreth != '' + shell: bash + working-directory: ${{ inputs.checkout-path }} + run: | + echo "Updating Coreth to version: ${{ inputs.coreth }}" + go get github.com/ava-labs/coreth@${{ inputs.coreth }} + - name: Update LibEVM dependency + if: inputs.libevm != '' + shell: bash + working-directory: ${{ inputs.checkout-path }} + run: | + echo "Updating LibEVM to version: ${{ inputs.libevm }}" + go get github.com/ava-labs/libevm@${{ inputs.libevm }} + - name: Setup Firewood FFI + if: inputs.firewood != '' + shell: bash + run: | + if [ -n "${{ inputs.firewood-path }}" ]; then + "${{ inputs.checkout-path }}/scripts/setup_firewood.sh" "${{ inputs.firewood }}" "${{ inputs.firewood-path }}" + else + "${{ inputs.checkout-path }}/scripts/setup_firewood.sh" "${{ inputs.firewood }}" + fi diff --git a/Taskfile.yml b/Taskfile.yml index 962deb68d583..50f62f8e917b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -11,6 +11,12 @@ tasks: desc: Builds avalanchego cmd: ./scripts/build.sh + build-with-firewood: + desc: Builds avalanchego with Firewood FFI (specify version with FIREWOOD_VERSION) + vars: + FIREWOOD_VERSION: '{{.FIREWOOD_VERSION | default "ffi/v0.0.12"}}' + cmd: ./scripts/build.sh -f {{.FIREWOOD_VERSION}} + build-antithesis-images-avalanchego: desc: Builds docker images for antithesis for the avalanchego test setup env: diff --git a/scripts/build.sh b/scripts/build.sh index 9ca888030cd0..d5df89a00a04 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -9,19 +9,29 @@ print_usage() { Options: - -r Build with race detector + -r Build with race detector + -f VERSION Build with Firewood FFI + VERSION format: ffi/vX.Y.Z for pre-built, commit/branch for source " } race='' -while getopts 'r' flag; do +firewood_version='' + +while getopts 'rf:' flag; do case "${flag}" in r) echo "Building with race detection enabled" race='-race' ;; - *) print_usage - exit 1 ;; + f) + firewood_version="${OPTARG}" + echo "Building with Firewood version: ${firewood_version}" + ;; + *) + print_usage + exit 1 + ;; esac done @@ -31,6 +41,10 @@ source "${REPO_ROOT}"/scripts/constants.sh # Determine the git commit hash to use for the build source "${REPO_ROOT}"/scripts/git_commit.sh +if [ -n "${firewood_version}" ]; then + "${REPO_ROOT}/scripts/setup_firewood.sh" "${firewood_version}" "${REPO_ROOT}" +fi + echo "Building AvalancheGo with [$(go version)]..." go build ${race} -o "${avalanchego_path}" \ -ldflags "-X github.com/ava-labs/avalanchego/version.GitCommit=$git_commit $static_ld_flags" \ diff --git a/scripts/setup_firewood.sh b/scripts/setup_firewood.sh new file mode 100755 index 000000000000..7cf55f63267d --- /dev/null +++ b/scripts/setup_firewood.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Setup Firewood FFI +# +# Clones Firewood repository, builds/fetches the FFI, and updates go.mod +# +# Usage: +# setup_firewood.sh [workspace] +# +# Arguments: +# version Firewood version (ffi/vX.Y.Z for pre-built, commit/branch for source) +# workspace Optional workspace path for Firewood build (default: ${AVALANCHE_PATH}/firewood-workspace) +# +# Output: +# Prints FFI path to stdout on success + +set -euo pipefail + +if [ $# -lt 1 ]; then + echo "Usage: $0 [workspace]" >&2 + exit 1 +fi + +FIREWOOD_VERSION="$1" +AVALANCHE_PATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )"; cd .. && pwd ) +FIREWOOD_CLONE_DIR="${AVALANCHE_PATH}/firewood" + +# Use provided workspace or default to avalanchego/firewood-workspace +if [ $# -ge 2 ] && [ -n "$2" ]; then + WORKSPACE_PATH="$2" +else + WORKSPACE_PATH="${AVALANCHE_PATH}/firewood-workspace" +fi + +if [ -d "${FIREWOOD_CLONE_DIR}" ]; then + echo "Removing existing Firewood directory..." >&2 + rm -rf "${FIREWOOD_CLONE_DIR}" +fi + +echo "Setting up Firewood FFI version: ${FIREWOOD_VERSION}" >&2 +echo "Using workspace: ${WORKSPACE_PATH}" >&2 + +git clone https://github.com/ava-labs/firewood "${FIREWOOD_CLONE_DIR}" \ + --quiet --depth 1 --branch composable-ci-action + +SETUP_FIREWOOD_SCRIPT="${FIREWOOD_CLONE_DIR}/benchmark/setup-scripts/build-firewood.sh" + +if [ ! -f "${SETUP_FIREWOOD_SCRIPT}" ]; then + echo "Error: Setup Firewood script not found at ${SETUP_FIREWOOD_SCRIPT}" >&2 + exit 1 +fi + +# Build or fetch Firewood FFI with custom workspace +# Capture only the last line which is the FFI path +FFI_PATH=$("${SETUP_FIREWOOD_SCRIPT}" "${FIREWOOD_VERSION}" --workspace "${WORKSPACE_PATH}" | tail -n 1) + +if [ -z "${FFI_PATH}" ]; then + echo "Error: Failed to build/fetch Firewood FFI" >&2 + exit 1 +fi + +cd "${AVALANCHE_PATH}" + +# Verify go.mod exists +if [ ! -f "go.mod" ]; then + echo "Error: go.mod not found in ${AVALANCHE_PATH}" >&2 + exit 1 +fi + +echo "Updating go.mod with FFI path: ${FFI_PATH}" >&2 +go mod edit -replace github.com/ava-labs/firewood-go-ethhash/ffi="${FFI_PATH}" + +go mod tidy +go mod download + +# Output FFI path to stdout for consumption by other scripts +echo "${FFI_PATH}"