Revision control

Copy as Markdown

# 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.
* Handling of security vulnerabilities.
We're still evolving our policies in this area, but these are the
guidelines we've developed so far.
## Rust Code
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 maintence of our
existing dependencies:
* Check `Cargo.lock` into the repository.
* Generate built artifacts using the `--locked` flag to `cargo build`, as an additional
assurance that the existing `Cargo.lock` will be respected.
* Regularly run [cargo-audit](https://github.com/RustSec/cargo-audit) in CI to alert us to
security problems in our dependencies.
* It runs on every PR, and once per hour on the `main` branch
* Use [a home-grown tool](https://github.com/mozilla/application-services/blob/main/tools/dependency_summary.py) to generate a summary of dependency licenses
and to check them for compatibility with MPL-2.0.
* Check these summaries into the repository and have CI alert on unexpected changes,
to guard against pulling in new versions of a dependency under a different license.
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](https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/).
* 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-dilligence already applied, such as:
* Crates that are [already vendored into Firefox](https://dxr.mozilla.org/mozilla-central/source/third_party/rust).
* Crates from [rust-lang-nursery](https://github.com/rust-lang-nursery).
* Crates that appear to be widely used in the rust community.
* Check that it is clearly licensed and is [MPL-2.0 compatible](https://www.mozilla.org/en-US/MPL/license-policy/#Licenses_Compatible_with_the_MPL).
* 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.
* Dev 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 dev dependencies!
* As part of the PR that introduces the new dependency:
* Regenerate dependency summary files using the [regenerate_dependency_summaries.sh](https://github.com/mozilla/application-services/blob/main/tools/regenerate_dependency_summaries.sh).
* Explicitly describe your consideration of the above points.
Updating to new versions of existing dependencies is a normal part of software development
and is not accompanied by any particular ceremony.
## Android/Kotlin Code
We currently depend only on the following Kotlin dependencies:
We currently depend on the following **developer** dependencies in the Kotlin codebase,
but they do not get included in built distribution files:
* detekt
* ktlint
No additional Kotlin dependencies should be added to the project unless absolutely necessary.
## iOS/Swift Code
We currently do not depend on any Swift dependencies. And no Swift dependencies should be added to the project unless absolutely necessary.
## Other Code
We currently depend on local builds of the following system dependencies:
No additional system dependencies should be added to the project unless absolutely necessary.