Hi! Thanks for your interest in contributing to Gloo — we'd love to have your
participation! If you want help or mentorship, reach out to us in a GitHub
issue, or on the #WG-wasm
channel of the Rust Discord and introduce
yourself.
We abide by the Rust Code of Conduct and ask that you do as well.
These tools are required for building and testing Gloo:
- The Rust toolchain:
rustup
,cargo
,rustc
, etc. rustfmt
: We userustfmt
for a consistent code style across the whole code base.wasm-pack
: We usewasm-pack
to orchestrate headless browser testing.cargo readme
: We usecargo readme
to generateREADME.md
s from each crate's module documentation.
You can build every Gloo crate:
cargo build --all
Or you can build one particular crate:
cargo build -p my-particular-crate
To run headless browser tests for a particular crate:
wasm-pack test crates/my-particular-crate --headless --firefox # or --safari or --chrome
To run tests in Node.js:
wasm-pack test crates/my-particular-crate --node
You can run the non-Wasm tests (e.g. doc tests) for every Gloo crate with:
cargo test --all
Or you can run one particular crate's non-Wasm tests:
cargo test -p my-particular-crate
To (re)format the Gloo source code, run:
$ cargo fmt
To update each gloo/crates/*/README.md
to reflect the crate's top-level
documentation, go to the root of the repository and run:
./update-readmes.sh
Designing APIs for Gloo, its utility crates, and interfaces between them takes a lot of care. The design space is large, and there is a lot of prior art to consider. When coming to consensus on a design, we use a simplified, informal version of our RFC process.
When making a proposal, you must create a new pull request on this repo.
The pull request's title must start with [RFC]
.
The pull request must add a new file into the rfcs
folder. This file
contains all the information for the proposal.
It is expected that other people will write reviews pointing out various flaws, which should be fixed by adding new commits to the pull request.
Note: when fixing a bug in a semver-compatible way that doesn't add any new API surface (i.e. changes are purely internal) we can skip the design proposal part of this workflow, and jump straight to a pull request.
The graph below gives an overview of the workflow for proposing, designing, implementing, and merging new crates and APIs into Gloo. Notably, we expect a large amount of design discussion to happen up front in the issue thread for the design proposal.
Before writing pull requests, we should have a clear idea of what is required for implementation. This means there should be a skeleton of the API in the form of types and function/method signatures. We should have a clear idea of the layers of APIs we are exposing, and how they are built upon one another.
Note that exploratory implementations outside of Gloo are encouraged during this period to get a sense for the API's usage, but you shouldn't send an implementation pull request until the design has been accepted.
Before the design is accepted, at least two team members must have stated that they are in favor of accepting the design in the issue thread.
Here is an issue template you can use for proposing designs.
Here is a checklist of some general design principles that Gloo crates and APIs should follow:
-
Crate's public interface follows the Rust API Guidelines.
-
Callback-taking APIs are generic over
F: Fn(A) -> B
(orFnMut
orFnOnce
) instead of takingwasm_bindgen::Closure
s orjs_sys::Function
s directly. -
If the API can be implemented as a Future / Stream, then it should first be implemented as a callback, with the callback API put into the
callback
submodule.Then the Future / Stream should be implemented using the callback API, and should be put into the
future
orstream
submodule.Make sure that the callback and Future / Stream APIs properly support cancellation (if it is possible to do so).
-
Uses nice Rust-y types and interfaces instead of passing around untyped
JsValue
s. -
Has
fn as_raw(&self) -> &web_sys::Whatever
functions to get the underlying rawweb_sys
,js_sys
, orJsValue
type. This provides an escape hatch for dropping down to rawweb_sys
bindings when an API isn't fully supported by the crate yet.Similar for
from_raw
constructors andinto_raw
conversion methods when applicable. -
There is a loose hierarchy with "mid-level" APIs (which are essentially thin wrappers over the low-level APIs), and "high-level" APIs (which make more substantial changes).
As a general rule, the high-level APIs should be built on top of the mid-level APIs, which in turn should be built on top of the low-level APIs (e.g.
web_sys
)There are exceptions to this, but they have to be carefully decided on a case-by-case basis.
Once we've accepted a design, we can move forward with implementation and creating pull requests.
The implementation should generally be unsurprising, since we should have already worked out most of the kinks during the earlier design discussions. If there are significant new issues or concerns uncovered during implementation, then these should be brought up in the design proposal discussion thread again, and the evolved design reaffirmed with two team members signing off once again.
If there are no new concerns uncovered, then the implementation just needs to be checked over by at least one team member. They provide code review and feedback on the implementation, then the feedback is addressed and pull request updated. Once the pull request is in a good place and CI is passing, a team member may approve the pull request and merge it into Gloo. If any team member raises concerns with the implementation, they must be resolved before the pull request is merged.
Here is a checklist that all crate and API implementations in Gloo should fulfill:
-
The crate should be named
gloo-foobar
, located atgloo/crates/foobar
, and re-exported from the umbrella Gloo crate like:// gloo/src/lib.rs pub use gloo_foobar as foobar;
-
The
authors
entry ingloo/crates/foobar/Cargo.toml
is "The Rust and WebAssembly Working Group". -
Uses
unwrap_throw
andexpect_throw
instead of normalunwrap
andexpect
. -
Headless browser and/or Node.js tests via
wasm-pack test
. -
Uses
#![deny(missing_docs, missing_debug_implementations)]
. -
Crate's root module documentation has at least one realistic example.
-
Crate has at least a brief description of how to use it in the Gloo guide (the
mdbook
located atgloo/guide
).
Team members sign off on design proposals and review pull requests to Gloo.
@jstarry
@hamza1311
If you make a handful of significant contributions to Gloo and participate in design proposals, then maybe you should be a team member! Think you or someone else would be a good fit? Reach out to us!
Whenever we bump a gloo_whatever
utility crate's version, make sure to make a
corresponding version bump for every crate that transitively depends upon
gloo_whatever
. Crates that do not transitively depend on gloo_whatever
should not have their version bumped.
For example, if we start with this dependency graph:
- gloo @ 0.1.2
- gloo_foo @ 0.1.2
- gloo_bar @ 0.1.3
- gloo_qux @ 0.1.4
- gloo_bar @ 0.1.3
If we make a bug fix in gloo_bar
and bump its version from 0.1.3 to 0.1.4,
then the cascading version bumps should result in this final dependency graph:
- gloo @ 0.1.3 # `gloo` has deps updated, version bumped
- gloo_foo @ 0.1.2 # `gloo_foo` remains at 0.1.2 since no deps changed
- gloo_bar @ 0.1.4 # `gloo_bar` had bug fix -> bumped to 0.1.4
- gloo_qux @ 0.1.5 # `gloo_qux` has its dep on `gloo_bar` updated, version bumped
- gloo_bar @ 0.1.4
Historically, this versioning scheme was agreed upon in issue #66.
Here is a checklist for publishing new releases to crates.io:
-
Bump all the relevant crates' versions, as described above.
-
Write a
CHANGELOG.md
entry for the release. -
Commit the changes and send a pull request for the release.
-
Once a team member has approved the pull request, and continuous integration is green, merge the PR.
-
cargo publish
each crate that had its version bumped. -
Create a tag
X.Y.Z
for the umbrellagloo
crate's version, and push this tag to GitHub.