Skip to content

build: setup bazel remote execution #14641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions .circleci/base-rbe-bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# ------------------------------
# This file is taken from the "bazel-toolchains" repository and is used in order to reduce the
# manual configuration overhead. https://github.com/bazelbuild/bazel-toolchains/tree/master/bazelrc
# ------------------------------

# Copyright 2016 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Depending on how many machines are in the remote execution instance, setting
# this higher can make builds faster by allowing more jobs to run in parallel.
# Setting it too high can result in jobs that timeout, however, while waiting
# for a remote machine to execute them.
build:remote --jobs=50

# Set several flags related to specifying the platform, toolchain and java
# properties.
# These flags are duplicated rather than imported from (for example)
# %workspace%/configs/ubuntu16_04_clang/1.1/toolchain.bazelrc to make this
# bazelrc a standalone file that can be copied more easily.
# These flags should only be used as is for the rbe-ubuntu16-04 container
# and need to be adapted to work with other toolchain containers.
build:remote --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.1:jdk8
build:remote --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.1:jdk8
build:remote --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build:remote --java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
build:remote --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.18.0/default:toolchain
build:remote --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
# Platform flags:
# The toolchain container used for execution is defined in the target indicated
# by "extra_execution_platforms", "host_platform" and "platforms".
# If you are using your own toolchain container, you need to create a platform
# target with "constraint_values" that allow for the toolchain specified with
# "extra_toolchains" to be selected (given constraints defined in
# "exec_compatible_with").
# More about platforms: https://docs.bazel.build/versions/master/platforms.html
build:remote --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.18.0/cpp:cc-toolchain-clang-x86_64-default
build:remote --extra_execution_platforms=@bazel_toolchains//configs/ubuntu16_04_clang/1.1:rbe_ubuntu1604
build:remote --host_platform=@bazel_toolchains//configs/ubuntu16_04_clang/1.1:rbe_ubuntu1604
build:remote --platforms=@bazel_toolchains//configs/ubuntu16_04_clang/1.1:rbe_ubuntu1604

# Set various strategies so that all actions execute remotely. Mixing remote
# and local execution will lead to errors unless the toolchain and remote
# machine exactly match the host machine.
build:remote --spawn_strategy=remote
build:remote --strategy=Javac=remote
build:remote --strategy=Closure=remote
build:remote --genrule_strategy=remote
build:remote --define=EXECUTOR=remote

# Enable the remote cache so action results can be shared across machines,
# developers, and workspaces.
build:remote --remote_cache=remotebuildexecution.googleapis.com

# Enable remote execution so actions are performed on the remote systems.
build:remote --remote_executor=remotebuildexecution.googleapis.com

# Enable encryption.
build:remote --tls_enabled=true

# Enforce stricter environment rules, which eliminates some non-hermetic
# behavior and therefore improves both the remote cache hit rate and the
# correctness and repeatability of the build.
build:remote --experimental_strict_action_env=true

# Set a higher timeout value, just in case.
build:remote --remote_timeout=3600

# Enable authentication. This will pick up application default credentials by
# default. You can use --auth_credentials=some_file.json to use a service
# account credential instead.
build:remote --auth_enabled=true

# Set flags for uploading to BES in order to view results in the Bazel Build
# Results UI.
build:results --bes_backend="buildeventservice.googleapis.com"
build:results --bes_timeout=60s
build:results --tls_enabled

# Output BES results url
build:results --bes_results_url="https://source.cloud.google.com/results/invocations/"

# Set flags for uploading to BES without Remote Build Execution.
build:results-local --bes_backend="buildeventservice.googleapis.com"
build:results-local --bes_timeout=60s
build:results-local --tls_enabled=true
build:results-local --auth_enabled=true
build:results-local --spawn_strategy=local
build:results-local --remote_cache=remotebuildexecution.googleapis.com
build:results-local --remote_timeout=3600
build:results-local --bes_results_url="https://source.cloud.google.com/results/invocations/"

# The following flags are only necessary for local docker sandboxing
# with the rbe-ubuntu16-04 container. Use of these flags is still experimental.
build:docker-sandbox --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.1:jdk8
build:docker-sandbox --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.1:jdk8
build:docker-sandbox --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.1/bazel_0.18.0/default:toolchain
build:docker-sandbox --experimental_docker_image=gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:9bd8ba020af33edb5f11eff0af2f63b3bcb168cd6566d7b27c6685e717787928
build:docker-sandbox --spawn_strategy=docker
build:docker-sandbox --strategy=Javac=docker
build:docker-sandbox --strategy=Closure=docker
build:docker-sandbox --genrule_strategy=docker
build:docker-sandbox --define=EXECUTOR=remote
build:docker-sandbox --experimental_docker_verbose
build:docker-sandbox --experimental_enable_docker_sandbox

# The following flags enable the remote cache so action results can be shared
# across machines, developers, and workspaces.
build:remote-cache --remote_cache=remotebuildexecution.googleapis.com
build:remote-cache --tls_enabled=true
build:remote-cache --experimental_strict_action_env=true
build:remote-cache --remote_timeout=3600
build:remote-cache --auth_enabled=true
build:remote-cache --spawn_strategy=standalone
build:remote-cache --strategy=Javac=standalone
build:remote-cache --strategy=Closure=standalone
build:remote-cache --genrule_strategy=standalone
25 changes: 25 additions & 0 deletions .circleci/bazel.rc
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,28 @@
# Save downloaded repositories in a location that can be cached by CircleCI. This helps us
# speeding up the analysis time significantly with Bazel managed node dependencies on the CI.
build --experimental_repository_cache=/home/circleci/bazel_repository_cache

########################################
# Remote Build Execution support on CI #
########################################

# Load default settings for Remote Build Execution.
import %workspace%/.circleci/base-rbe-bazelrc

# Custom execution platform defined in the Angular repository. See:
# https://github.com/angular/angular/blob/master/tools/BUILD.bazel#L21
build:remote --extra_execution_platforms=@angular//tools:rbe_ubuntu1604-angular
build:remote --host_platform=@angular//tools:rbe_ubuntu1604-angular
build:remote --platforms=@angular//tools:rbe_ubuntu1604-angular

# Increase the amount of parallel jobs. The default RBE base configuration specifies a low
# number of parallel jobs, but our build and testing should be parallelizable.
build:remote --jobs=150

# Use the Angular team internal GCP instance for remote execution.
build:remote --remote_instance_name=projects/internal-200822/instances/default_instance

# We want to accept remote cached build artifacts to speed up our builds incrementally.
# TODO(devversion): Temporary disabled since we don't have much insight on possible security
# issues. Enable this once we investigated this further and talked to the RBE team.
build:remote --remote_accept_cached=false
32 changes: 24 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,37 +39,39 @@ var_6: &save_cache
- "node_modules"
- "~/bazel_repository_cache"

# Decryption token that is used to decode the GCP credentials file in ".circleci/gcp_token".
var_7: &gcp_decrypt_token "angular"

# Job step that ensures that the node module dependencies are installed and up-to-date. We use
# Yarn with the frozen lockfile option in order to make sure that lock file and package.json are
# in sync. Unlike in Travis, we don't need to manually purge the node modules if stale because
# CircleCI automatically discards the cache if the checksum of the lock file has changed.
var_7: &yarn_install
var_8: &yarn_install
run: yarn install --frozen-lockfile --non-interactive

# Copies the Bazel config which is specifically for CircleCI to a location where Bazel picks it
# up and merges it with the project-wide bazel configuration (tools/bazel.rc)
var_8: &copy_bazel_config
var_9: &copy_bazel_config
# Set up the CircleCI specific bazel configuration.
run: sudo cp ./.circleci/bazel.rc /etc/bazel.bazelrc

# Sets up a different Docker image that includes a moe recent Firefox version which
# is needed for headless testing.
var_9: &docker-firefox-image
var_10: &docker-firefox-image
# TODO(devversion): Temporarily use a image that includes Firefox 62 because the
# ngcontainer image does include an old Firefox version that does not support headless.
- image: circleci/node:11.4.0-browsers

# Attaches the release output which has been stored in the workspace to the current job.
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
var_10: &attach_release_output
var_11: &attach_release_output
attach_workspace:
at: dist/releases


# Branch filter that we can specify for jobs that should only run on publish branches. This filter
# is used to ensure that not all upstream branches will be published as Github builds
# (e.g. revert branches, feature branches)
var_11: &publish_branches_filter
var_12: &publish_branches_filter
branches:
only:
- master
Expand All @@ -83,11 +85,18 @@ var_11: &publish_branches_filter
# In order to reduce duplication we use a YAML anchor that just always excludes the "_presubmit"
# branch. We don't want to run Circle for the temporary "_presubmit" branch which is reserved
# for the caretaker.
var_12: &ignore_presubmit_branch_filter
var_13: &ignore_presubmit_branch_filter
branches:
ignore:
- "_presubmit"

# Runs a script that sets up the Bazel remote execution. This will be used by jobs that run
# Bazel primarily and should benefit from remote caching and execution.
var_14: &setup_bazel_remote_execution
run:
name: "Setup bazel RBE remote execution"
command: ./scripts/circleci/bazel/setup-remote-execution.sh

# -----------------------------
# Container version of CircleCI
# -----------------------------
Expand All @@ -105,10 +114,13 @@ jobs:
bazel_build_test:
<<: *job_defaults
resource_class: xlarge
environment:
GCP_DECRYPT_TOKEN: *gcp_decrypt_token
steps:
- *checkout_code
- *restore_cache
- *copy_bazel_config
- *setup_bazel_remote_execution

- run: bazel build src/... --build_tag_filters=-docs-package
- run: bazel test src/... --build_tag_filters=-docs-package
Expand All @@ -122,11 +134,15 @@ jobs:
# This job fails whenever an API has been updated but not explicitly approved through goldens.
# --------------------------------------------------------------------------------------------
api_golden_checks:
resource_class: xlarge
<<: *job_defaults
resource_class: xlarge
environment:
GCP_DECRYPT_TOKEN: *gcp_decrypt_token
steps:
- *checkout_code
- *restore_cache
- *copy_bazel_config
- *setup_bazel_remote_execution

- run: bazel test tools/public_api_guard/...

Expand Down
Binary file added .circleci/gcp_token
Binary file not shown.
19 changes: 19 additions & 0 deletions scripts/circleci/bazel/setup-remote-execution.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

if [[ -z "${GCP_DECRYPT_TOKEN}" ]]; then
echo "Please specify the \"GCP_DECRYPT_TOKEN\" environment variable when setting up remote " \
"execution"
exit 1
fi

# Decode the GCP token that is needed to authenticate the Bazel remote execution.
openssl aes-256-cbc -d -in .circleci/gcp_token -k ${GCP_DECRYPT_TOKEN} \
-out /home/circleci/.gcp_credentials

# Export the "GOOGLE_APPLICATION_CREDENTIALS" variable that should refer to the GCP credentials
# file. Bazel automatically picks up the credentials from that variable.
# https://github.com/bazelbuild/bazel/blob/master/third_party/grpc/include/grpc/grpc_security.h#L134-L137
echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/circleci/.gcp_credentials" >> $BASH_ENV

# Update the global Bazel configuration to always use remote execution.
sudo bash -c "echo 'build --config=remote' >> /etc/bazel.bazelrc"