Skip to content

Commit

Permalink
Introduce the NativeLink Cloud flake module
Browse files Browse the repository at this point in the history
This change enables LRE by default and adds a config file that connects
Nix users to the NativeLink Cloud. This means that users running Bazel
from within the nix flake can fetch artifacts directly from CI builds.
  • Loading branch information
aaronmondal committed Sep 26, 2024
1 parent 9be5902 commit 8765a38
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 30 deletions.
3 changes: 3 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,8 @@ try-import %workspace%/lre.bazelrc
# Generated by the darwin flake module.
try-import %workspace%/darwin.bazelrc

# Generated by the nativelink flake module.
try-import %workspace%/nativelink.bazelrc

# Allow user-side customization.
try-import %workspace%/user.bazelrc
59 changes: 33 additions & 26 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,36 +66,43 @@ jobs:
//...
nativelink-dot-com-cloud-cache-legacy-dockerfile-test:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
environment: production
name: NativeLink.com Cloud / Remote Cache (Legacy Dockerfile Test)
name: NativeLink.com Cloud / Remote Cache (LRE)
env:
NL_COM_API_KEY: ${{ secrets.NATIVELINK_COM_API_HEADER || '065f02f53f26a12331d5cfd00a778fb243bfb4e857b8fcd4c99273edfb15deae' }}
steps:
- name: Checkout
uses: >- # v4.1.1
actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Setup Bazelisk
uses: >- # v0.8.1
bazel-contrib/setup-bazel@b388b84bb637e50cdae241d0f255670d4bd79f29
with:
bazelisk-cache: true

- name: Run Bazel tests
shell: bash
run: |
bazel test \
--remote_cache=grpcs://cas-tracemachina-shared.build-faster.nativelink.net \
--remote_header=x-nativelink-api-key=$NL_COM_API_KEY \
--remote_instance_name=main \
--bes_backend=grpcs://bes-tracemachina-shared.build-faster.nativelink.net \
--bes_header=x-nativelink-api-key=$NL_COM_API_KEY \
--bes_results_url=https://app.nativelink.com/a/e3b1e0e0-4b73-45d6-85bc-5cb7b02edea5/build \
--remote_header=x-nativelink-project=nativelink-ci \
--jobs=200 \
${{ github.ref == 'refs/heads/main' && ' ' || '--nogenerate_json_trace_profile --remote_upload_local_results=false' }} \
//...
- name: Checkout
uses: >- # v4.1.1
actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Free disk space
uses: >- # v2.0.0
endersonmenezes/free-disk-space@3f9ec39ebae520864ac93467ee395f5237585c21
with:
remove_android: true
remove_dotnet: true
remove_haskell: true
remove_tool_cache: false

- name: Install Nix
uses: >- # v10
DeterminateSystems/nix-installer-action@de22e16c4711fca50c816cc9081563429d1cf563
- name: Cache Nix derivations
uses: >- # v4
DeterminateSystems/magic-nix-cache-action@fc6aaceb40b9845a02b91e059ec147e78d1b4e41
- name: Run Bazel tests
run: >
nix develop --impure --command
bash -c "bazel test \
--remote_header=x-nativelink-api-key=$NL_COM_API_KEY \
--bes_backend=grpcs://bes-tracemachina-shared.build-faster.nativelink.net \
--bes_header=x-nativelink-api-key=$NL_COM_API_KEY \
--bes_results_url=https://app.nativelink.com/a/e3b1e0e0-4b73-45d6-85bc-5cb7b02edea5/build \
${{ github.ref == 'refs/heads/main' && ' ' || '--nogenerate_json_trace_profile --remote_upload_local_results=false' }} \
//..."
docker-compose-compiles-nativelink:
# The type of runner that the job will run on.
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ Pulumi.dev.yaml
lre.bazelrc
rust-project.json
darwin.bazelrc
nativelink.bazelrc
44 changes: 44 additions & 0 deletions flake-module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
lib,
flake-parts-lib,
...
}: {
options = {
perSystem = flake-parts-lib.mkPerSystemOption (
{
config,
options,
pkgs,
...
}: let
cfg = config.nativelink;
in {
options = {
nativelink = {
pkgs = lib.mkOption {
type = lib.types.uniq (lib.types.lazyAttrsOf (lib.types.raw or lib.types.unspecified));
description = "Nixpkgs to use.";
default = pkgs;
defaultText = lib.literalMD "`pkgs` (module argument)";
};
settings = lib.mkOption {
type = lib.types.submoduleWith {
modules = [./modules/nativelink.nix];
specialArgs = {inherit (cfg) pkgs;};
};
default = {};
description = "Configuration for Bazel on Darwin.";
};
installationScript = lib.mkOption {
type = lib.types.str;
description = "Create nativelink.bazelrc.";
default = cfg.settings.installationScript;
defaultText = lib.literalMD "bazelrc content";
readOnly = true;
};
};
};
}
);
};
}
14 changes: 10 additions & 4 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
inputs.git-hooks.flakeModule
./local-remote-execution/flake-module.nix
./tools/darwin/flake-module.nix
./flake-module.nix
];
perSystem = {
config,
Expand Down Expand Up @@ -420,7 +421,7 @@
if pkgs.stdenv.isDarwin
then [] # Doesn't support Darwin yet.
else lre-cc.meta.Env;
prefix = "lre";
prefix = "linux";
};
devShells.default = pkgs.mkShell {
nativeBuildInputs = let
Expand Down Expand Up @@ -482,10 +483,14 @@
# development shell.
${config.pre-commit.installationScript}
# Generate lre.bazelrc which configures LRE toolchains when running
# in the nix environment.
# Generate lre.bazelrc which configures LRE toolchains when
# running in the nix environment.
${config.local-remote-execution.installationScript}
# Generate nativelink.bazelrc which gives Bazel invocations access
# to NativeLink's read-only cache.
${config.nativelink.installationScript}
# The Bazel and Cargo builds in nix require a Clang toolchain.
# TODO(aaronmondal): The Bazel build currently uses the
# irreproducible host C++ toolchain. Provide
Expand All @@ -508,8 +513,9 @@
}
// {
flakeModule = {
default = ./local-remote-execution/flake-module.nix;
default = ./flake-module.nix;
darwin = ./tools/darwin/flake-module.nix;
local-remote-execution = ./local-remote-execution/flake-module.nix;
};
};
}
116 changes: 116 additions & 0 deletions modules/nativelink.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
config,
lib,
pkgs,
...
}: let
# These flags cause Bazel builds to connect to NativeLink's read-only cache.
#
# ```nix
# devShells.default = pkgs.mkShell {
# shellHook = ''
# # Generate the `lre.bazelrc` config file.
# ${config.nativelink.installationScript}
# '';
# };
# ```
defaultConfig = [
"--remote_cache=${config.endpoint}"
"--remote_header=x-nativelink-api-key=${config.api-key}"
"--remote_instance_name=main"
"--remote_header=x-nativelink-project=nativelink-ci"
"--nogenerate_json_trace_profile"
"--remote_upload_local_results=false"
"--experimental_remote_cache_async"
];

# If the `nativelink.settings.prefix` is set to a nonempty string,
# prefix the Bazel build commands with that string. This will disable
# connecting to the nativelink-cloud by default and require adding
# `--config=<prefix>` to Bazel invocations.
maybePrefixedConfig =
if (config.prefix == "")
then map (x: "build " + x) defaultConfig
else map (x: "build:" + config.prefix + " " + x) defaultConfig;

configFile = pkgs.runCommand "nativelink.bazelrc" {} ''
printf '# These flags are dynamically generated by the nativelink flake module.
#
# Add `try-import %%workspace%%/nativelink.bazelrc` to your .bazelrc to
# include these flags when running Bazel in a nix environment.
${lib.concatLines maybePrefixedConfig}' >$out
'';
in {
options = {
installationScript = lib.mkOption {
type = lib.types.str;
description = lib.mkDoc ''
A bash snippet which creates a nativelink.bazelrc file in the repository.
'';
};
endpoint = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc ''
The NativeLink Cloud endpoint.
Defaults to NativeLink's shared cache.
'';
default = "grpcs://cas-tracemachina-shared.build-faster.nativelink.net";
};
api-key = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc ''
The API key to connect to the NativeLink Cloud.
You should only use read-only keys here to prevent cache-poisoning and
malicious artifact extractions.
Defaults to NativeLink's shared read-only api key.
'';
default = "065f02f53f26a12331d5cfd00a778fb243bfb4e857b8fcd4c99273edfb15deae";
};
prefix = lib.mkOption {
type = lib.types.str;
description = lib.mdDoc ''
An optional Bazel config prefix for the flags in `nativelink.bazelrc`.
If set, builds need to explicitly enable the nativelink config via
`--config=<prefix>`.
Defaults to an empty string, enabling the cache by default.
'';
default = "";
};
};

config = {
installationScript = ''
if ! type -t git >/dev/null; then
# In pure shells
echo 1>&2 "WARNING: NativeLink: git command not found; skipping installation."
elif ! ${pkgs.git}/bin/git rev-parse --git-dir &> /dev/null; then
echo 1>&2 "WARNING: NativeLink: .git not found; skipping installation."
else
GIT_WC=`${pkgs.git}/bin/git rev-parse --show-toplevel`
# These update procedures compare before they write, to avoid
# filesystem churn. This improves performance with watch tools like
# lorri and prevents installation loops by lorri.
if ! readlink "''${GIT_WC}/nativelink.bazelrc" >/dev/null \
|| [[ $(readlink "''${GIT_WC}/nativelink.bazelrc") != ${configFile} ]]; then
echo 1>&2 "NativeLink: updating $PWD repository"
[ -L nativelink.bazelrc ] && unlink nativelink.bazelrc
if [ -e "''${GIT_WC}/nativelink.bazelrc" ]; then
echo 1>&2 "NativeLink: WARNING: Refusing to install because of pre-existing nativelink.bazelrc"
echo 1>&2 " Remove the nativelink.bazelrc file and add nativelink.bazelrc to .gitignore."
else
ln -fs ${configFile} "''${GIT_WC}/nativelink.bazelrc"
fi
fi
fi
'';
};
}
Loading

0 comments on commit 8765a38

Please sign in to comment.