NativeLink
Contribute

Contribution guidelines

What NativeLink accepts, the git setup it requires, and the commit and review conventions a PR is held to.

Who this is for: anyone about to open their first pull request. What you'll have at the end: the git configuration the project requires, the commit conventions, and an accurate picture of how review works. Time: thirty minutes, most of it one-time setup.

NativeLink accepts contributions from anyone. The process is more specific than most projects' (signed commits, a fork, one commit per pull request, review in Reviewable rather than in GitHub's own UI), and the specificity is deliberate: it keeps main a linear history of signed, reviewable commits.

CONTRIBUTING.md

is the authoritative version; this page is the orientation around it.

What gets accepted

WelcomeWith a caveat
Bug fixes, with a regression test
Performance improvementsBring reproducible numbers
New stores, schedulers, worker typesOpen an issue and agree the approach first
Documentation fixes, including this pageSmaller is better
Tooling that makes development or operations easier

Three things reliably do not land: breaking changes to the Remote Execution API surface, which is an upstream spec the project tracks rather than owns; vendor-specific code paths only one deployment can use; and refactoring proposed on its own merits rather than as part of a change that needed it.

If you want to work on an existing issue, claim it by commenting first. That is the only mechanism preventing two people from writing the same patch.

Git setup, once

  1. Create distinct authentication and signing keys in your GitHub key settings. Two keys, not one reused.

  2. Fork the repository and clone your fork, not upstream:

    git clone git@github.com:yourusername/nativelink
    cd nativelink
    git remote add upstream git@github.com:TraceMachina/nativelink

    git remote -v should show origin pointing at your fork and upstream at TraceMachina/nativelink.

  3. Configure git to sign every commit and tag. In ~/.gitconfig:

    [user]
        name = Your Full Name
        email = the-email-you-use-on-github@example.com
        signingkey = ~/.ssh/your_private_signing_key
    
    [gpg]
        format = ssh   # or gpg, if you use a GPG key
    
    [commit]
        gpgsign = true
    
    [tag]
        gpgsign = true

Direct commits and human-created branches on TraceMachina/nativelink are not allowed, including for members of the organization. Everything arrives as a pull request from a fork.

The pull request loop

  1. Sync your fork, then branch:

    git switch main
    git pull -r upstream main
    git push
    git switch -c some-feature
  2. Make one commit. The title rules are enforced by review, not by a hook, and they are short: start with a capital letter, use the imperative, no trailing period, keep it as short as it can be, and put detail in the body wrapped at 72 characters.

    Add some feature          ← good
    Add some feature.         ← trailing period
    Adds some feature         ← not imperative
    Add X and also Y          ← "and" means this is two commits

    The word "and" in a title is the signal to split the commit.

  3. Push and open the PR from your fork, then click the purple Reviewable button on the GitHub page to add reviewers with +@somereviewer. Review conversation happens there.

  4. Revise with --amend, not a follow-up commit.

    git commit --amend
    git push -f

    Reviewable keeps the diff between commit versions visible, so nothing is lost by rewriting, and the branch stays one commit, which is what lands.

Before you push

bazel test //...                                  # what CI runs
pre-commit run -a                                 # hooks, vale, typos
bazel run --config=rustfmt @rules_rust//:rustfmt  # formatting

cargo test --all --profile=smol is the fast inner loop, but a green Cargo run is not a green CI: bazel test attaches rustfmt and clippy aspects that Cargo does not. See the testing guide for what the suites contain and which local failures are environmental.

What reviewers look for

One change per pull request. Small ones land; large ones get split.

A body that explains why. The diff already shows what changed. The body is where the constraint, the incident or the measurement goes.

Tests that match the change. A bug fix wants a regression test; new behaviour wants both unit and integration coverage. No coverage percentage gate; the question is whether the new path is exercised, not whether a number moved.

Conventions followed rather than argued. Most review feedback on a first contribution is about the house rules: the task macros instead of tokio::spawn, #[expect(..., reason = "…")] rather than a bare #[allow], the BUILD.bazel srcs entry. Codebase internals is the page that gets you past those in one read.

Licensing

Your contribution is licensed under the license that applies to the file or module you change. Most of the repository is FSL-1.1-Apache-2.0; a handful of files are Apache-2.0; and two areas, nativelink-util/src/metrics.rs and everything under nativelink-worker/src/persistent_worker/, are Business Source License. Copy the header from the file next to the one you are creating rather than from memory.

Meaningful contributors may be eligible for license waivers on the Business Source License modules. Raise an issue or contact the maintainers before depending on one.

Common questions

NextRepository and crate map

Where your change actually goes: twelve crates, a strict layering, and the six places the first guess is wrong.

On this page