Contributing
Design Goals
This project is developed under several assumptions,
- Most of the time spent using
wasmer-pack
will actually go into the IO before and after using it rather than running the code generator (i.e. because you have to download large inputs from a server), so performance is a non-goal for this project - The core library should be usable by itself, but everything else can be tailored to Wasmer's use cases
As such, we prefer developer experience over flexibility and raw performance.
Goal 1: Fast Compile Times
A clean build of the entire workspace shouldn't take any longer than 30 seconds and all CI jobs should finish within 5 minutes.
This isn't actually too difficult to achieve as long as you follow some guidelines:
- Don't add dependencies unless you absolutely need to
- Trim out unnecessary features
- Periodically use
cargo clean && cargo build --timings
to see where compile time is spent - Don't import crates that pull in half of crates.io
The rationale behind this is simple - a short edit-compile-test cycle is a force multiplier. If you have fast compile times then developers can recompile and re-run the test suite after every change.
On the other hand, if CI takes 30 minutes to complete, developers will avoid your project like the plague because getting even the most trivial changes merged becomes a multi-hour chore.
To help this, we have a GitHub Action which will post comments on each PR to let you know how much your changes have affected CI times.
Goal 2: It Just Works
Users of wasmer-pack
should be able to compile the project from scratch and
use the generated bindings without needing to mess around with dependencies or
configuration.
To achieve this,
- Avoid dependencies that link to native libraries because they need a working C toolchain and often require installing system libraries
- Avoid conditional compilation (including feature flags) because they tend to introduce edge cases that are hard to test and debug
- Be opinionated - don't give the end user unnecessary flags or options unless it's part of the core functionality
Release Process
This is the process if you ever need to cut a release:
-
Make a PR which mentions the new version in its title (e.g.
"Release v1.2.3" on a
releases
branch) -
Update
CHANGELOG.md
to include any user-facing changes since the last release (the[Unreleased]
link at the bottom is particularly helpful here) -
Run
cargo release
. This will...- Promote the change log's
[Unreleased]
items to a named version - Bump version numbers in all
Cargo.toml
files - Tag the commit (e.g.
v1.2.3
) - Publish to crates.io, and
- Push all commits and tags to GitHub
- Promote the change log's
-
Wait for the "Releases" job to pass. This will...
- Publish WebAssembly binaries to WAPM
- Use
cargo xtask set-generator
to make the WAPM backend generate bindings with the new version ofwasmer-pack-cli
-
Merge the "Release v1.2.3" PR into the
master
branch!
Cargo xtask
We use the cargo xtask
pattern for any project automation more
complex than 1 or 2 lines of shell. This means we get access to any library
on crates.io, and having everything in pure Rust means you don't need to
manually install anything or worry about OS-specific weirdness.
Currently, there are only a couple major tasks,
cargo xtask set-generator
calls the mutation for setting a bindings generatorcargo xtask sync-schema
will make sure theschema.graphql
file is in sync with the WAPM backend, automatically updating the file if necessary
You can run cargo xtask --help
to find out more details.