To start developing on AvalancheGo, you'll need a few things installed.
- Golang version >= 1.25.8
- gcc
- g++
On MacOS, a modern version of bash is required (e.g. via homebrew with brew install bash). The version installed by default is not compatible with AvalancheGo's shell scripts.
This repository uses a Go workspace (go.work)
to unify the main module with grafted modules (coreth, subnet-evm, evm) under graft/.
This provides IDE support for navigating and refactoring across all modules seamlessly.
When go.work is present at the repository root, some go command flags are restricted:
| Flag | Workspace behavior |
|---|---|
-mod=readonly |
Implicit default and only allowed value |
-mod=mod |
Not allowed (would modify go.mod) |
-mod=vendor |
Not allowed (use go work vendor instead) |
-modfile=path |
Not allowed (workspace manages module resolution) |
These restrictions exist because the workspace manages dependencies across all member
modules. Use GOWORK=off to disable workspace mode when needed:
GOWORK=off go <command>Other behavioral changes:
| Command | Behavior Change |
|---|---|
go list -m |
Lists all workspace modules (use head -1 or specify module path for single result) |
go mod tidy |
Only affects current module; run task go-mod-tidy to tidy all modules |
go work sync |
Updates go.work.sum; prefer task sync-go-work after dependency changes |
The repo's go.work takes precedence over any workspace file in a parent directory.
To use your own workspace (e.g., with local checkouts of repos not yet in the monorepo):
export GOWORK=~/src/my-go.workSee the Go Modules Reference for full workspace documentation.
This repo uses the Task task runner to simplify usage and discoverability of development tasks. To list available tasks:
./scripts/run_task.sh- Do not open up a GitHub issue if it relates to a security vulnerability in AvalancheGo, and instead refer to our security policy.
- Changes from the community that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of
avalanchegowill generally not be accepted.
- Check that the issue you're filing doesn't already exist by searching under issues.
- If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a title and clear description with as much relevant information as possible.
- If you want to start a discussion about the development of a new feature or the modification of an existing one, start a thread under GitHub discussions.
- Post a thread about your idea and why it should be added to AvalancheGo.
- Don't start working on a pull request until you've received positive feedback from the maintainers.
- Open a new GitHub pull request containing your changes.
- Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
- The PR should be opened against the
masterbranch. - If your PR isn't ready to be reviewed just yet, you can open it as a draft to collect early feedback on your changes.
- Once the PR is ready for review, mark it as ready-for-review and request review from one of the maintainers.
- Any changes to protobuf message types require that protobuf files are regenerated.
./scripts/run_task.sh generate-protobuf💁 The general direction is to reduce usage of mocks, so use the following with moderation.
Mocks are auto-generated using mockgen and //go:generate commands in the code.
-
To re-generate all mocks, use the command below from the root of the project:
./scripts/run_task.sh generate-mocks
-
To add an interface that needs a corresponding mock generated:
-
if the file
mocks_generate_test.goexists in the package where the interface is located, either:- modify its
//go:generate go run go.uber.org/mock/mockgento generate a mock for your interface (preferred); or - add another
//go:generate go run go.uber.org/mock/mockgento generate a mock for your interface according to specific mock generation settings
- modify its
-
if the file
mocks_generate_test.godoes not exist in the package where the interface is located, create it with content (adapt as needed):// Copyright (C) 2019, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package mypackage //go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE} -destination=mocks_test.go . YourInterface
Notes:
- Ideally generate all mocks to
mocks_test.gofor the package you need to use the mocks for and do not export mocks to other packages. This reduces package dependencies, reduces production code pollution and forces to have locally defined narrow interfaces. - Prefer using reflect mode to generate mocks than source mode, unless you need a mock for an unexported interface, which should be rare.
- Ideally generate all mocks to
-
-
To remove an interface from having a corresponding mock generated:
- Edit the
mocks_generate_test.gofile in the directory where the interface is defined - If the
//go:generatemockgen command line:- generates a mock file for multiple interfaces, remove your interface from the line
- generates a mock file only for the interface, remove the entire line. If the file is empty, remove
mocks_generate_test.goas well.
- Edit the
- Build the avalanchego binary
./scripts/run_task.sh build- Run unit tests
./scripts/run_task.sh test-unit- Run the linter
./scripts/run_task.sh lint- Pull requests will generally not be approved or merged unless they pass CI.
- Ask any question about AvalancheGo under GitHub discussions.
- Please check out the
avalanche-docsrepository here.