Skip to content

Conversation

Elvis339
Copy link
Contributor

@Elvis339 Elvis339 commented Sep 25, 2025

Why this should be merged

Enables composable CI by allowing repositories to build AvalancheGo with custom dependency versions without complex setup. Solves the problem where teams need AvalancheGo context for testing but can't easily compose different repo versions in their CI workflows.

More context

How this works

Dual-mode GitHub Action:

  • BUILD mode: Produces avalanchego or reexecution binaries with custom Coreth/LibEVM/Firewood versions
  • SETUP mode: Prepares build environment with dependency replacements for custom workflows

Key features:

  • Checks out specified versions of AvalancheGo, Coreth, LibEVM
  • Uses local path replacements (go mod edit -replace)
  • Produces binaries via output parameter AND artifacts
  • Artifact names include full dependency matrix for traceability
  • Security: Only allows ava-labs repositories

How this was tested

BUILD and SETUP mode:

Custom Firewood action ava-labs/firewood/.github/actions/build-action@composable-ci-action

Need to be documented in RELEASES.md?

No. Internal CI change

@Elvis339 Elvis339 changed the title Composable ci action ci: composable avalanchego action Sep 25, 2025
@Elvis339 Elvis339 self-assigned this Sep 25, 2025
@Elvis339 Elvis339 marked this pull request as ready for review September 26, 2025 10:43
@Copilot Copilot AI review requested due to automatic review settings September 26, 2025 10:43
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds a new composable GitHub Action for building AvalancheGo with custom dependency versions, enabling teams to compose different repository versions in CI workflows without complex setup.

  • Introduces dual-mode GitHub Action supporting BUILD mode (creates binaries) and SETUP mode (prepares environment)
  • Implements secure dependency replacement using local path replacements with repository restrictions
  • Disables existing reexecution benchmark workflows that run on pull requests

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.github/actions/avalanchego-build-action/action.yml Main action implementation with dual-mode logic and dependency management
.github/actions/avalanchego-build-action/build_target.sh Shell script for building different target binaries (avalanchego, reexecution)
.github/actions/avalanchego-build-action/README.md Comprehensive documentation with usage examples and security model
.github/workflows/c-chain-reexecution-benchmark-gh-native.yml Disables pull request trigger for benchmark workflow
.github/workflows/c-chain-reexecution-benchmark-container.yml Disables pull request trigger for benchmark workflow
.github/actions/c-chain-reexecution-benchmark/action.yml Updates benchmark action configuration

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

- name: Setup Firewood FFI
if: inputs.firewood != ''
id: firewood
uses: ava-labs/firewood/.github/actions/build-action@composable-ci-action
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this action defined? I don't see it on Firewood main

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's defined here composable-ci-action branch. I used it to test these things can work.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit hard to verify as a reviewer since it's not on main and doesn't have a reference to the branch where it's available. How does this work for the workflow runs linked in the PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added link to Firewood action in PR description, thanks for pointing it out.

This run is using Firewood action along with AvalancheGo to run reexecution test on self-hosted runners. You can find the commit here. (I'll attach commits in the PR description as well).

The workflow in the commit proves that:

  1. Firewood build action is:
  2. AvalancheGo build action is linking dependencies and running reexecution benchmark in composable way

Comment on lines +93 to +94
go mod tidy
go mod download
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this leave a diff in the resulting checked out code that may cause future actions to find an unexpected diff and fail? Should that be documented or cleaned up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it will, it should probably be cleaned up. Will handle that case.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could probably do less here and only support setup rather than adding a script that builds different binaries once setup has completed.

with:
repository: 'ava-labs/avalanchego'
ref: ${{ inputs.avalanchego }}
path: ${{ inputs.checkout-path }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does AvalancheGo use checkout path and everything else just uses the name of the repo it's checking out?

Would it make sense to take in one parameter to use as a working directory and then check out each required remote as a subdirectory?

Copy link
Contributor Author

@Elvis339 Elvis339 Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The avalanchego checkout path is the main workspace where we build the final binary. It needs to be configurable because consumers might want to integrate it into existing directory structures.

Firewood has some storage requirements its database operations benefit from NVMe for performance, but compilation can happen anywhere. The Firewood action handles its own optimal storage detection internally.
A single working directory would force all components to use the same storage type.

The current approach lets each component use optimal storage:

  • Firewood runtime: NVMe when available (handled by its action)
  • AvalancheGo: Standard storage (sufficient for compilation)
  • Coreth/LibEVM: Handled by Go's dependency system

# Replace LibEVM if provided and not default
if [ "${{ inputs.libevm }}" != "" ] && [ "${{ inputs.libevm }}" != "main" ]; then
echo "Replacing LibEVM with local checkout: ../libevm"
go mod edit -replace github.com/ava-labs/libevm=../libevm
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given we are checking out versions that are available in GitHub, we can just use go get with the updated version rather than checking them each out locally. If we wanted to checkout and compile a specific version of Firewood, we'd need the source code, but currently this is just using the published golang ffi bindings of Firewood as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good input, I'll run go get instead of go mod edit and repo checkout.

The Firewood workflow handles building form source and using pre-built FFI.
https://github.com/ava-labs/firewood/blob/composable-ci-action/.github/actions/build-action/action.yml

Comment on lines +85 to +89
- name: Run custom build commands
run: |
cd build/avalanchego
./scripts/run_task.sh reexecute-cchain-range
./scripts/run_task.sh my-custom-task
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would not work because the current task definition uses go run, so it would not use the the compiled test binary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works here.

Copy link
Contributor

@maru-ava maru-ava left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this not implemented as a task that could be executed both locally and in CI? A task has the advantage of being easier to implement and maintain - since iteration doesn't require cycling through CI - and then it would be possible to trivially reproduce a binary without CI.

@Elvis339
Copy link
Contributor Author

Why was this not implemented as a task that could be executed both locally and in CI?

The Action approach was chosen for cross-repository consumption. But now that you mention Task I guess it could be made to to run locally and in CI and be exposed as GH action for cross-repository consumption.

required: false
default: ''

outputs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also output the artifact name (rather than solely relying on the convention described in README.md)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

5 participants