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 userustfmtfor a consistent code style across the whole code base.wasm-pack: We usewasm-packto orchestrate headless browser testing.cargo readme: We usecargo readmeto generateREADME.mds 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 --headless --firefox crates/my-particular-crate # or --safari or --chromeTo run tests in Node.js:
wasm-pack test --node crates/my-particular-crateYou 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(orFnMutorFnOnce) instead of takingwasm_bindgen::Closures orjs_sys::Functions 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
callbacksubmodule.Then the Future / Stream should be implemented using the callback API, and should be put into the
futureorstreamsubmodule.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
JsValues. -
Has
fn as_raw(&self) -> &web_sys::Whateverfunctions to get the underlying rawweb_sys,js_sys, orJsValuetype. This provides an escape hatch for dropping down to rawweb_sysbindings when an API isn't fully supported by the crate yet.Similar for
from_rawconstructors andinto_rawconversion 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
authorsentry ingloo/crates/foobar/Cargo.tomlis "The Rust and WebAssembly Working Group". -
Uses
unwrap_throwandexpect_throwinstead of normalunwrapandexpect. -
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
mdbooklocated 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.mdentry 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 publisheach crate that had its version bumped. -
Create a tag
X.Y.Zfor the umbrellagloocrate's version, and push this tag to GitHub.
