This guide explains how to configure Bazel builds to create Build Scans with Develocity.
Develocity Build Scans provide observability of build and test results in your web browser. They help collaboratively debug build problems and optimize build performance.
Develocity 2021.4 or later is required to use Build Scans for Bazel builds, with significant improvements introduced in 2023.2.
To get the full benefit of a Build Scan for Bazel your Develocity instance will need to have version 2023.2 or later, and your Bazel builds will need to be configured not only to use the remote cache, but also permitted to write to the remote cache.
Bazel Build Scan functionality is not enabled by default with Develocity. If you wish to use Bazel with Develocity, please contact your customer success representative. |
Getting set up
To publish Build Scans to your Develocity server, add the following to the .bazelrc
file in your build workspace.
common:develocity --remote_cache=grpcs://«develocity-server»
common:develocity --bes_results_url=https://«develocity-server»/build/
common:develocity --bes_backend=grpcs://«develocity-server»
common:develocity --build_event_publish_all_actions=true
common:develocity --noslim_profile
build --config=develocity
query --config=develocity
Replacing «develocity-server»
with the hostname of your server. If you use a non standard port for HTTPS traffic, this must also include the port number.
With this configuration, if you need to disable the Develocity configurations, you can comment out the last two lines. This is useful if, for example, your Develocity Server is offline or unreachable.
If your Develocity server forbids anonymous cache writes or scan publishing, the following additional steps are required:
-
Log into your Develocity server, from the upper-right corner click your user icon, then "My Settings".
-
Ensure that your user has at least "Publish build scans" and either "Read and write build cache data" or "Read build cache data and write Bazel CAS data" permissions. See Cache Permissions.
-
Select "Access keys" on the left and then generate a new access key.
-
In a
.bazelrc
file in your user’s home directory, add the following:
common:develocity --remote_cache_header=Authorization=«the access key you just generated»
common:develocity --bes_header=Authorization=«the access key you just generated»
Note: if you have an existing access key, it can be reused. Generally, it is considered best practice to use each access key for a single purpose, so that if it is revoked, there is no unexpected collateral damage.
This configuration can also be specified on the command line as part of the build invocation, or via other mechanisms that Bazel provides. Please see the Bazel documentation for more information.
At the beginning and end of your build, you will see output similar to:
INFO: Streaming build results to: https://«develocity-server»/build/66e6805b-7ce1-4e32-bc26-c0fa129c76a7
The link shown is your Build Scan link and can be used to observe the results of the build.
Using a Bazel remote cache
Bazel Build Scans provide more information when the build uses a remote cache that is also accessible by the Develocity server.
Bazel uploads build artifacts, test results and diagnostic information to the remote cache. When Build Scans are published to Develocity, such diagnostic information is read from the remote cache and included in Build Scans. This allows Build Scans to provide more information about the build. In particular, action profile information and detailed test results are included.
When viewing Build Scans, the build artifacts and diagnostic logs of targets and failed actions can be downloaded from the user interface if the remote cache is accessible.
If you’re using the remote cache that is part of Develocity, this should function automatically, though note that network connectivity from Develocity to the cache is required. If an external remote cache is used, it must support the gRPC protocol and allow anonymous read access.
Cache permissions
It is generally considered a best practice to not allow all users read/write access to the build cache due to concerns of cache poisoning. Because Bazel build scans are enriched by allowing users to upload data to the remote cache, read-only access is not appropriate. We therefore add a more granular permission - "Read build cache data and write Bazel CAS data". CAS here means "content-addressable storage", one of the two types of data a Bazel cache exposes. All files linked from a Bazel build scan are CAS data. Writes to content-addressable storage are also more secure than arbitrary writes - all keys in content-addressable storage are digests of the value they point to, making cache poisoning less of a concern. Consider granting this permission by default to developers using Bazel.
Setting the project name
Develocity allows analyzing sets of builds based on search criteria. One such criterion is the project name, which is useful to set to a well known name for the project to allow for more effective searching. This default value for this is the directory name of the build workspace. You may set it to a different value by setting both the Bazel --bes_instance_name
and --remote_instance_name
configuration options to that value.
Setting the project name to a custom value will also set that value as the project identifier in Project-level Access Control. |
Project-level access control
Project-level access control for Bazel Build Scan data is not enforced for Develocity 2023.3. Please ensure to use a later version. |
To leverage Develocity’s project-level access control, builds must specify both of the following configuration options with the desired Develocity project ID:
-
--bes_instance_name=«project-id»
-
--remote_instance_name=«project-id»
These are typically set in the workspace .bazelrc
file and checked in to version control.
Extending Build Scans
You can easily include extra information in your Build Scans in the form of tags, links and values. This is a very powerful mechanism for capturing and sharing information that is important to your build and development process.
Such information is included by using Bazel’s workspace status and/or build metadata mechanisms, with specific value name prefixes.
The workspace status mechanism is most appropriate when a tag, value or link needs to be computed. The build metadata mechanism can be used when it is static, or is specified as part of the command line invocation.
Tags, values and links use the following prefixes respectively:
-
SCAN_TAG_
-
SCAN_VALUE_
-
SCAN_LINK_
The following are examples of creating a tag, value and link using build metadata at build invocation time:
bazel build ... \
--build_metadata=SCAN_TAG_LOCAL_BUILD= \
--build_metadata=SCAN_VALUE_GIT_COMMIT_ID=$(git rev-parse HEAD) \
--build_metadata=SCAN_LINK_CI_BUILD=https://ci-server.company.com/build/${BUILD_ID}
The workspace status mechanism works by running a program that prints status item values to stdout. The following is an example of using a shell script named scan_data.sh
in the workspace directory to create a tag, value and link:
#!/bin/sh
echo SCAN_TAG_LOCAL_BUILD ""
echo "SCAN_VALUE_GIT_COMMIT_ID $(git rev-parse HEAD)"
echo "SCAN_LINK_CI_BUILD https://ci-server.company.com/build/${BUILD_ID}"
This script must be specified as a workspace status command, which is typically achieved by adding the following to the workspace .bazelrc
file.
build --workspace_status_command=$(pwd)/scan_data.sh
Appendix A: Captured information
Build Scans for Bazel work differently from those for Gradle, Maven, or sbt: those build tools rely on a plugin developed by Gradle to determine what information is captured by Develocity, but in Bazel this is all controlled by client-side settings, and built-in Bazel functionality. Because of this, we cannot directly control which information will be captured, but this document will cover the most typical cases.
In general, assume that all data sent to Develocity by way of either the Bazel JSON Trace Profile or the Build Event Protocol (BEP) will be captured by Develocity.
Enumerated below is the data that will be sent based on a few common Bazel options being set for a Java build. The exact information captured will vary based on which Bazel rules, configuration options, and client version are used.
--noslim_profile
Generating a profile is the default behavior, but by default a slim profile is generated, which contains less information. This is the information contained in a fat profile:
--build_event_publish_all_actions
By default, Bazel summarizes short actions, which makes it hard for Develocity to construct a complete build timeline.
--remote_cache
The Build Events will frequently reference files from the local filesystem (test.log
, test.xml
, failed actions, etc.) and if they are not uploaded to the remote cache, they will be unavailable for analysis.
-
Environment
-
All client environment variables are captured
-
-
Build
-
Build invocation options
-
Bazel version
-
Date & timestamps
-
Output directory on the client Machine
-
CPU Usage for both client overhead & build
-
Memory usage for both client overhead & build
-
Target names
-
Source file names
-
Remote output downloads
-
Platform information
-
Target configuration
-
Action inputs and outputs
-
Client environment variables
-