This document describes the process of contributing to the reference FVM implementation (this project).
If you have a general FVM related question or idea, please either as on the Filecoin Slack, or open a new discussion in fvm-specs.
If you'd like to report a bug or suggest an enhancement in the reference FVM implementation, please file an issue.
To make a change to the FVM.
- When in doubt, open an issue first to discuss the change.
- Make your change.
- Write a test for your change.
- Update the crate's
CHANGELOG.md
. If you're making any breaking changes, prefix change with "BREAKING:". - Finally, open a PR.
The primary crates are fvm
, fvm_shared
, fvm_sdk
, and the integration testing framework fvm_integration_tests
. These are the crates that have version.workspace = true
.
The crates in this workspace have the following structure:
All changes should be well tested.
If you're releasing any non-trivial changes to crates used by the builtin actors, please test them. This includes:
- Any crates in
ipld/
exceptcar
. shared/
(fvm_shared
).sdk/
(fvm_sdk
).
To test:
- Checkout this repo as
ref-fvm/
and the builtin-actors repo asbuiltin-actors/
in the same directory. - Uncomment the "patch" section in
builtin-actors/Cargo.toml
that starts with:[patch.crates-io] fvm_shared = { path = "../ref-fvm/shared" } ...
- Run
cargo test --all
(or, at a minimum,cargo check --all --tests --lib
.
If that works, proceed with releasing these crates.
The FVM is a workspace of crates which have different release schedules:
- The primary crates are released together.
- The
fvm_ipld_*
crates (living in ipld/) are released independently and only live in this repo for convenience. - The rest of the crates are for local testing and are not released.
Versioning of the primary crates is not strictly semver compatible:
- Major releases are used to signal when the FVM drops support for old network versions.
- Minor releases are used to signal breaking changes.
- Patch releases are used for bug fixes, new features and other non-breaking changes.
Versioning of the fvm_ipld_*
crates follows standard semver rules.
Preparing Primary Crates
To propose a new release, open a pull request with the following changes:
- Update the version in
Cargo.toml
:workspace.package→version
. - Update the version of the coupled workspace dependencies in
Cargo.toml
to match the new version (leaving semver range specifier~
intact):wokspace.dependencies→fvm→version
wokspace.dependencies→fvm_shared→version
wokspace.dependencies→fvm_sdk→version
wokspace.dependencies→fvm_integration_tests→version
- Update the lockfile with a rebuild:
cargo check --all
. - Make sure the
CHANGELOG.md
files in each offvm
,sdk
, andshared
are all up-to-date (look throughgit log -- path/to/crate
), set the release date & version, and add a new "Unreleased" section. It may be appropriate to duplicate some entries across these crates if the changes are relevant to multiple crates.
See PR #2002 for an example.
To propose a release of a crate other than fvm
, fvm_shared
, fvm_sdk
, or
fvm_integration_tests
, open a pull request with the following changes:
- Install
cargo-edit
(cargo install cargo-edit
). - Use
cargo set-version
to set the version for each crate you're releasing. This will both update the crate version, and make all other crates in the workspace depend on the latest version. - Make sure the
CHANGELOG.md
files are all up-to-date (look throughgit log -- path/to/crate
), set the release date & version, and add a new "Unreleased" section.
Once the release is prepared, it'll go through a review:
- Make sure that we're ready to release. E.g., make sure downstream can consume the release.
- Make sure that we're correctly following semver.
- Make sure that we're not missing anything in the changelogs.
Finally, an FVM "owner" will:
- Merge the release PR to master.
- For each released crate, create a git tag:
crate_name@crate_version
. - Run
cargo publish
for each released crate (in dependency order).
Example steps for an FVM "owner" to release MINOR
and PATCH
crates:
- Merge the
PATCH
release PR to master (e.g., PR #2030). - Publish all primary crates . For each crate (fvm, fvm_shared, fvm_sdk, fvm_integration_tests):
# Declare an associative array for crate_name → crate_directory
declare -A crates
crates["fvm"]="fvm"
crates["fvm_shared"]="shared"
crates["sdk"]="fvm_sdk"
crates["fvm_integration_tests"]="testing/integration"
workspace_package_version = `tomlq '.workspace.package.version' Cargo.toml`
for crate_name in "${!my_map[@]}"; do
crate_directory = ${crates[$key]}
pushd $crate_directory
cargo publish
git_tag = "$crate_name@v$workspace_package_version"
git tag $git_tag
popd
done
- After creating all tags, push them:
git push --tags