Dependency Management Guidelines
This repository uses third-party code from a variety of sources, so we need to be mindful of how these dependencies will affect our consumers. Considerations include:
- General code quality.
- Licensing compatibility.
- Handling of security vulnerabilities.
- The potential for supply-chain compromise.
We're still evolving our policies in this area, but these are the guidelines we've developed so far.
Rust Code
Unlike Firefox,
we do not vendor third-party source code directly into the repository. Instead we rely on
Cargo.lock
and its hash validation to ensure that each build uses an identical copy
of all third-party crates. These are the measures we use for ongoing maintenance of our
existing dependencies:
- Check
Cargo.lock
into the repository. - Generate built artifacts using the
--locked
flag tocargo build
, as an additional assurance that the existingCargo.lock
will be respected. - Use cargo-deny for a basic license-compatibility check as part of CI, to guard against human error.
Adding a new dependency, whether we like it or not, is a big deal - that dependency and everything it brings with it will become part of Firefox-branded products that we ship to end users. We try to balance this responsibility against the many benefits of using existing code, as follows:
- In general, be conservative in adding new third-party dependencies.
- For trivial functionality, consider just writing it yourself. Remember the cautionary tale of left-pad.
- Check if we already have a crate in our dependency tree that can provide the needed functionality.
- Prefer crates that have a a high level of due-diligence already applied, such as:
- Crates that are already vendored into Firefox.
- Crates from rust-lang-nursery or rust-lang.
- Crates that appear to be widely used in the Rust community.
- Check that it is clearly licensed and is MPL-2.0 compatible.
- Take the time to investigate the crate's source and ensure it is suitably high-quality.
- Be especially wary of uses of
unsafe
, or of code that is unusually resource-intensive to build. - Development dependencies do not require as much scrutiny as dependencies that will ship in consuming applications,
but should still be given some thought.
- There is still the potential for supply-chain compromise with development dependencies!
- Be especially wary of uses of
- Explicitly describe your consideration of these points in the PR that introduces the new dependency.
Updating to new versions of existing dependencies is a normal part of software development and is not accompanied by any particular ceremony.
Dependency updates
We use Dependabot to automatically open pull requests when dependencies release a new version. All CI tasks run on those pull requests to ensure updates don't break anything.
As glean-core
is now also vendored into mozilla-central, including all of its Rust dependencies, we need to be a bit careful about these updates.
Landing upgrades of the Glean SDK itself in mozilla-central is a separate process.
See Updating the Glean SDK in the Firefox Source Docs.
Following are some guidelines to ensure compatibility with mozilla-central:
- Patch releases of dependencies should be fine in most cases.
- Minor releases should be compatible. Best to check the changelog of the updated dependency to make sure. These updates should only land in
Cargo.lock
. No updates inCargo.toml
are necessary - Major releases will always need a check against mozilla-central. See Updating the Glean SDK.
In case of uncertainty defer a decision to :janerik or :chutten.
Manual dependency updates
You can manually check for outdated dependencies using cargo-outdated.
Individual crate updates for version compatible with the requirement in Cargo.toml
can be done using:
cargo update -p $cratename
To update all transitive dependencies to the latest semver-compatible version use:
cargo update