Skip to content

Commit

Permalink
feat: add write_aspect_bazelrc_presets macro
Browse files Browse the repository at this point in the history
  • Loading branch information
gregmagolan committed Feb 17, 2023
1 parent cb6e0c1 commit b299605
Show file tree
Hide file tree
Showing 22 changed files with 542 additions and 14 deletions.
28 changes: 27 additions & 1 deletion .aspect/bazelrc/BUILD.bazel
@@ -1 +1,27 @@
exports_files(glob(["*.bazelrc"]))
load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_file")

exports_files(glob([
"*.bazelrc",
"*.md",
]))

# `usage.md` & `intro.md` are also used for [docsite](https://docs.aspect.build/guides/bazelrc)
# content which is why they are separated into individual md files
genrule(
name = "gen_readme_md",
srcs = glob(["*.md"]),
outs = ["_README.md"],
cmd = """
cat .aspect/bazelrc/intro.md > $@
echo '' >> $@
cat .aspect/bazelrc/usage.md >> $@
echo '' >> $@
cat .aspect/bazelrc/automatic_updates.md >> $@
""",
)

write_source_file(
name = "update_readme_md",
in_file = "_README.md",
out_file = "README.md",
)
56 changes: 54 additions & 2 deletions .aspect/bazelrc/README.md
@@ -1,4 +1,56 @@
# Aspect Recommended Bazel Options
# Aspect bazelrc presets

The `.bazelrc` files found here are the source-of-truth for our recommended Bazel presets.

The Bazel options found here are the source-of-truth for our recommended set of settings.
They are mirrored on our docsite at https://docs.aspect.build/guides/bazelrc.

## Using Aspect bazelrc presets in your project

The `.bazelrc` file can get large, fast.
Some settings don't apply everywhere - some options are appropriate only on CI,
and some vary depending on the version of Bazel you use or languages used.

Bazel rc files can contain `import` statements, which allow you to organize the content better.

To use these presets in your project, simply vendor the `*.bazelrc` files from
https://github.com/aspect-build/bazel-lib/tree/main/.aspect/bazelrc into the
`.aspect/bazelrc` folder in your repository and `import` them in your `.bazelrc` file.

For example,

```python title=".bazelrc"
# Import Aspect bazelrc presets
import %workspace%/.aspect/bazelrc/bazel6.bazelrc
import %workspace%/.aspect/bazelrc/convenience.bazelrc
import %workspace%/.aspect/bazelrc/correctness.bazelrc
import %workspace%/.aspect/bazelrc/debug.bazelrc
import %workspace%/.aspect/bazelrc/javascript.bazelrc
import %workspace%/.aspect/bazelrc/performance.bazelrc

### YOUR PROJECT SPECIFIC OPTIONS GO HERE ###

# Load any settings & overrides specific to the current user from `.aspect/bazelrc/user.bazelrc`.
# This file should appear in `.gitignore` so that settings are not shared with team members. This
# should be last statement in this config so the user configuration is able to overwrite flags from
# this file. See https://bazel.build/configure/best-practices#bazelrc-file.
try-import %workspace%/.aspect/bazelrc/user.bazelrc
```

## Automatic updates

A convenient way to automatically keep your vendored copy up-to-date is to use the `write_aspect_bazelrc_presets` rule in `.aspect/bazelrc/BUILD.bazel`:

```python title=".aspect/bazelrc/BUILD.bazel"
"Aspect bazelrc presets; see https://docs.aspect.build/guides/bazelrc"

load("@aspect_bazel_lib//lib:bazelrc_presets.bzl", "write_aspect_bazelrc_presets")

write_aspect_bazelrc_presets(name = "update_aspect_bazelrc_presets")
```

When `@aspect_bazel_lib` is upgraded in your `WORKSPACE.bazel` or your `MODULE.bazel` file, a `diff_test`
stamped out by `write_aspect_bazelrc_presets` will fail if your vendored copy is out-of-date and print the Bazel command
to run to update it. For example, `bazel run //.aspect/bazelrc:update_aspect_bazelrc_presets`.

See the [bazelrc](https://github.com/aspect-build/bazel-examples/blob/main/bazelrc/.aspect/bazelrc/BUILD.bazel) example
in our [bazel-examples](https://github.com/aspect-build/bazel-examples) repository for a working example.
18 changes: 18 additions & 0 deletions .aspect/bazelrc/automatic_updates.md
@@ -0,0 +1,18 @@
## Automatic updates

A convenient way to automatically keep your vendored copy up-to-date is to use the `write_aspect_bazelrc_presets` rule in `.aspect/bazelrc/BUILD.bazel`:

```python title=".aspect/bazelrc/BUILD.bazel"
"Aspect bazelrc presets; see https://docs.aspect.build/guides/bazelrc"

load("@aspect_bazel_lib//lib:bazelrc_presets.bzl", "write_aspect_bazelrc_presets")

write_aspect_bazelrc_presets(name = "update_aspect_bazelrc_presets")
```

When `@aspect_bazel_lib` is upgraded in your `WORKSPACE.bazel` or your `MODULE.bazel` file, a `diff_test`
stamped out by `write_aspect_bazelrc_presets` will fail if your vendored copy is out-of-date and print the Bazel command
to run to update it. For example, `bazel run //.aspect/bazelrc:update_aspect_bazelrc_presets`.

See the [bazelrc](https://github.com/aspect-build/bazel-examples/blob/main/bazelrc/.aspect/bazelrc/BUILD.bazel) example
in our [bazel-examples](https://github.com/aspect-build/bazel-examples) repository for a working example.
5 changes: 5 additions & 0 deletions .aspect/bazelrc/intro.md
@@ -0,0 +1,5 @@
# Aspect bazelrc presets

The `.bazelrc` files found here are the source-of-truth for our recommended Bazel presets.

They are mirrored on our docsite at https://docs.aspect.build/guides/bazelrc.
31 changes: 31 additions & 0 deletions .aspect/bazelrc/usage.md
@@ -0,0 +1,31 @@
## Using Aspect bazelrc presets in your project

The `.bazelrc` file can get large, fast.
Some settings don't apply everywhere - some options are appropriate only on CI,
and some vary depending on the version of Bazel you use or languages used.

Bazel rc files can contain `import` statements, which allow you to organize the content better.

To use these presets in your project, simply vendor the `*.bazelrc` files from
https://github.com/aspect-build/bazel-lib/tree/main/.aspect/bazelrc into the
`.aspect/bazelrc` folder in your repository and `import` them in your `.bazelrc` file.

For example,

```python title=".bazelrc"
# Import Aspect bazelrc presets
import %workspace%/.aspect/bazelrc/bazel6.bazelrc
import %workspace%/.aspect/bazelrc/convenience.bazelrc
import %workspace%/.aspect/bazelrc/correctness.bazelrc
import %workspace%/.aspect/bazelrc/debug.bazelrc
import %workspace%/.aspect/bazelrc/javascript.bazelrc
import %workspace%/.aspect/bazelrc/performance.bazelrc

### YOUR PROJECT SPECIFIC OPTIONS GO HERE ###

# Load any settings & overrides specific to the current user from `.aspect/bazelrc/user.bazelrc`.
# This file should appear in `.gitignore` so that settings are not shared with team members. This
# should be last statement in this config so the user configuration is able to overwrite flags from
# this file. See https://bazel.build/configure/best-practices#bazelrc-file.
try-import %workspace%/.aspect/bazelrc/user.bazelrc
```
15 changes: 4 additions & 11 deletions .bazelrc
@@ -1,25 +1,18 @@
# Bazel settings that apply to this repository.
# Settings that apply only to CI are in .aspect/bazelrc/ci.bazelrc

# Import Aspect recommended Bazel convenience settings for all projects
# Import Aspect bazelrc presets
import %workspace%/.aspect/bazelrc/convenience.bazelrc

# Import Aspect recommended Bazel correctness settings for all projects
import %workspace%/.aspect/bazelrc/correctness.bazelrc

# Import Aspect recommended Bazel performance settings for all projects
import %workspace%/.aspect/bazelrc/performance.bazelrc

# Import Aspect recommended Bazel debug settings for all projects
import %workspace%/.aspect/bazelrc/debug.bazelrc

# Import Aspect recommended Bazel javascript settings for all projects
import %workspace%/.aspect/bazelrc/javascript.bazelrc

# Import Aspect recommended Bazel 6 settings for all projects;
# using a try-import here since this repository is also tested against Bazel 5 on CI
# Use a try-import for Bazel 6 settings since this repository is also tested against Bazel 5 on CI
try-import %workspace%/.aspect/bazelrc/bazel6.bazelrc

### PROJECT SPECIFIC OPTIONS ###

# For testing our --stamp behavior.
# Normally users would use a --workspace_status_command with a script that calls `git describe`.
build --embed_label=v1.2.3
Expand Down
5 changes: 5 additions & 0 deletions docs/BUILD.bazel
Expand Up @@ -128,4 +128,9 @@ stardoc_with_diff_test(
bzl_library_target = "//lib:repositories",
)

stardoc_with_diff_test(
name = "bazelrc_presets",
bzl_library_target = "//lib:bazelrc_presets",
)

update_docs()
32 changes: 32 additions & 0 deletions docs/bazelrc_presets.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions e2e/bzlmod/.bazelignore
@@ -0,0 +1 @@
e2e/bzlmod/.aspect/bazelrc
1 change: 1 addition & 0 deletions e2e/copy_to_directory/.bazelignore
@@ -0,0 +1 @@
e2e/bzlmod/.aspect/bazelrc
1 change: 1 addition & 0 deletions e2e/workspace/.bazelignore
@@ -0,0 +1 @@
e2e/bzlmod/.aspect/bazelrc
6 changes: 6 additions & 0 deletions lib/BUILD.bazel
Expand Up @@ -230,3 +230,9 @@ bzl_library(
srcs = ["base64.bzl"],
deps = ["//lib/private/docs:base64"],
)

bzl_library(
name = "bazelrc_presets",
srcs = ["bazelrc_presets.bzl"],
deps = [":write_source_files"],
)
59 changes: 59 additions & 0 deletions lib/bazelrc_presets.bzl
@@ -0,0 +1,59 @@
"Aspect bazelrc presets; see https://docs.aspect.build/guides/bazelrc"

load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files")

ALL_PRESETS = [
"bazel5",
"bazel6",
"ci",
"convenience",
"correctness",
"debug",
"javascript",
"performance",
]

def write_aspect_bazelrc_presets(
name,
presets = ALL_PRESETS):
"""Keeps your vendored copy of Aspect recommended `.bazelrc` presets up-to-date.
This macro uses a [write_source_files](https://docs.aspect.build/rules/aspect_bazel_lib/docs/write_source_files)
rule under the hood to keep your presets up-to-date.
By default all presets are vendored but this list can be customized using
the 'presets' attribute.
See https://docs.aspect.build/guides/bazelrc for more info.
Args:
name: a unique name for this target
presets: a list of preset names to keep up-to-date
For example,
```
write_aspect_bazelrc_presets(
name = "update_aspect_bazelrc_presets",
presets = [
"bazel6",
"ci",
"convenience",
"correctness",
"debug",
"javascript",
"performance",
],
)
```
"""

files = {}
for p in presets:
files["{}.bazelrc".format(p)] = "@aspect_bazel_lib//.aspect/bazelrc:{}.bazelrc".format(p)

write_source_files(
name = name,
files = files,
)
5 changes: 5 additions & 0 deletions lib/tests/bazelrc_presets/BUILD.bazel
@@ -0,0 +1,5 @@
"Aspect bazelrc presets; see https://docs.aspect.build/guides/bazelrc"

load("@aspect_bazel_lib//lib:bazelrc_presets.bzl", "write_aspect_bazelrc_presets")

write_aspect_bazelrc_presets(name = "update_aspect_bazelrc_presets")
5 changes: 5 additions & 0 deletions lib/tests/bazelrc_presets/bazel5.bazelrc
@@ -0,0 +1,5 @@
# Performance improvement for WORKSPACE evaluation
# of slow rulesets, for example rules_k8s has been
# observed to take 10 seconds without this flag.
# See https://github.com/bazelbuild/bazel/issues/13907
common --incompatible_existing_rules_immutable_view
15 changes: 15 additions & 0 deletions lib/tests/bazelrc_presets/bazel6.bazelrc
@@ -0,0 +1,15 @@
# Speed up all builds by not checking if external repository files have been modified.
# Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java#L244
build --noexperimental_check_external_repository_files
fetch --noexperimental_check_external_repository_files
query --noexperimental_check_external_repository_files

# Directories used by sandboxed non-worker execution may be reused to avoid unnecessary setup costs.
# Save time on Sandbox creation and deletion when many of the same kind of action run during the
# build.
# Docs: https://bazel.build/reference/command-line-reference#flag--reuse_sandbox_directories
build --reuse_sandbox_directories

# Avoid this flag being enabled by remote_download_minimal or remote_download_toplevel
# See https://meroton.com/blog/bazel-6-errors-build-without-the-bytes/
build --noexperimental_action_cache_store_output_metadata
75 changes: 75 additions & 0 deletions lib/tests/bazelrc_presets/ci.bazelrc
@@ -0,0 +1,75 @@
# We recommend enforcing a policy that keeps your CI from being slowed down
# by individual test targets that should be optimized
# or split up into multiple test targets with sharding or manually.
# Set this flag to exclude targets that have their timeout set to eternal (>15m) from running on CI.
# Docs: https://bazel.build/docs/user-manual#test-timeout-filters
build --test_timeout_filters=-eternal

# Set this flag to enable re-tries of failed tests on CI.
# When any test target fails, try one or more times. This applies regardless of whether the "flaky"
# tag appears on the target definition.
# This is a tradeoff: legitimately failing tests will take longer to report,
# but we can paper over flaky tests that pass most of the time.
# The alternative is to mark every flaky test with the `flaky = True` attribute, but this requires
# the buildcop to make frequent code edits.
# Not recommended for local builds so that the flakiness is observed during development and thus
# is more likely to get fixed.
# Note that when passing after the first attempt, Bazel will give a special "FLAKY" status.
# Docs: https://bazel.build/docs/user-manual#flaky-test-attempts
build --flaky_test_attempts=2

# Announce all announces command options read from the bazelrc file(s) when starting up at the
# beginning of each Bazel invocation. This is very useful on CI to be able to inspect what Bazel rc
# settings are being applied on each run.
# Docs: https://bazel.build/docs/user-manual#announce-rc
build --announce_rc

# Add a timestamp to each message generated by Bazel specifying the time at which the message was
# displayed.
# Docs: https://bazel.build/docs/user-manual#show-timestamps
build --show_timestamps

# Only show progress every 60 seconds on CI.
# Docs: https://bazel.build/reference/command-line-reference#flag--progress_report_interval
build --progress_report_interval=60

# Only show progress every 60 seconds on CI.
# https://bazel.build/reference/command-line-reference#flag--show_progress_rate_limit
build --show_progress_rate_limit=60

# Don't use cursor controls in its screen output.
# Docs: https://bazel.build/docs/user-manual#curses
build --curses=no

# Use colors to highlight its output on the screen. Set to `no` if your CI does not display colors.
# Docs: https://bazel.build/docs/user-manual#color
build --color=yes

# The terminal width in columns. Configure this to override the default value based on what your CI system renders.
# Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/runtime/UiOptions.java#L151
build --terminal_columns=80

######################################
# Generic remote cache configuration #
######################################

# Only download remote outputs of top level targets to the local machine.
# Docs: https://bazel.build/reference/command-line-reference#flag--remote_download_toplevel
build --remote_download_toplevel

# The maximum amount of time to wait for remote execution and cache calls.
# https://bazel.build/reference/command-line-reference#flag--remote_timeout
build --remote_timeout=3600

# Upload locally executed action results to the remote cache.
# Docs: https://bazel.build/reference/command-line-reference#flag--remote_upload_local_results
build --remote_upload_local_results

# Fall back to standalone local execution strategy if remote execution fails. If the grpc remote
# cache connection fails, it will fail the build, add this so it falls back to the local cache.
# Docs: https://bazel.build/reference/command-line-reference#flag--remote_local_fallback
build --remote_local_fallback

# Fixes builds hanging on CI that get the TCP connection closed without sending RST packets.
# Docs: https://bazel.build/reference/command-line-reference#flag--grpc_keepalive_time
build --grpc_keepalive_time=30s

0 comments on commit b299605

Please sign in to comment.