diff --git a/.aspect/bazelrc/.gitignore b/.aspect/bazelrc/.gitignore new file mode 100644 index 0000000..f25e3eb --- /dev/null +++ b/.aspect/bazelrc/.gitignore @@ -0,0 +1 @@ +user.bazelrc \ No newline at end of file diff --git a/.aspect/bazelrc/BUILD.bazel b/.aspect/bazelrc/BUILD.bazel new file mode 100644 index 0000000..a3e6c28 --- /dev/null +++ b/.aspect/bazelrc/BUILD.bazel @@ -0,0 +1,15 @@ +"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", + presets = [ + "ci", + "convenience", + "correctness", + "debug", + "javascript", + "performance", + ], +) diff --git a/.aspect/bazelrc/bazel7.bazelrc b/.aspect/bazelrc/bazel7.bazelrc new file mode 120000 index 0000000..d358281 --- /dev/null +++ b/.aspect/bazelrc/bazel7.bazelrc @@ -0,0 +1 @@ +../../.github/workflows/bazel7.bazelrc \ No newline at end of file diff --git a/.aspect/bazelrc/ci.bazelrc b/.aspect/bazelrc/ci.bazelrc new file mode 100644 index 0000000..4d91ee0 --- /dev/null +++ b/.aspect/bazelrc/ci.bazelrc @@ -0,0 +1,73 @@ +# 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 +test --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 +test --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. +# We want to find a compromise between printing often enough to show that the build isn't stuck, +# but not so often that we produce a long log file that requires a lot of scrolling. +# https://bazel.build/reference/command-line-reference#flag--show_progress_rate_limit +build --show_progress_rate_limit=60 + +# Use cursor controls in screen output. +# Docs: https://bazel.build/docs/user-manual#curses +build --curses=yes + +# Use colors to highlight 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=143 + +###################################### +# 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 diff --git a/.aspect/bazelrc/convenience.bazelrc b/.aspect/bazelrc/convenience.bazelrc new file mode 100644 index 0000000..c674569 --- /dev/null +++ b/.aspect/bazelrc/convenience.bazelrc @@ -0,0 +1,28 @@ +# Attempt to build & test every target whose prerequisites were successfully built. +# Docs: https://bazel.build/docs/user-manual#keep-going +build --keep_going + +# Output test errors to stderr so users don't have to `cat` or open test failure log files when test +# fail. This makes the log noiser in exchange for reducing the time-to-feedback on test failures for +# users. +# Docs: https://bazel.build/docs/user-manual#test-output +test --test_output=errors + +# Show the output files created by builds that requested more than one target. This helps users +# locate the build outputs in more cases +# Docs: https://bazel.build/docs/user-manual#show-result +build --show_result=20 + +# Bazel picks up host-OS-specific config lines from bazelrc files. For example, if the host OS is +# Linux and you run bazel build, Bazel picks up lines starting with build:linux. Supported OS +# identifiers are `linux`, `macos`, `windows`, `freebsd`, and `openbsd`. Enabling this flag is +# equivalent to using `--config=linux` on Linux, `--config=windows` on Windows, etc. +# Docs: https://bazel.build/reference/command-line-reference#flag--enable_platform_specific_config +common --enable_platform_specific_config + +# Output a heap dump if an OOM is thrown during a Bazel invocation +# (including OOMs due to `--experimental_oom_more_eagerly_threshold`). +# The dump will be written to `/.heapdump.hprof`. +# You may need to configure CI to capture this artifact and upload for later use. +# Docs: https://bazel.build/reference/command-line-reference#flag--heap_dump_on_oom +common --heap_dump_on_oom diff --git a/.aspect/bazelrc/correctness.bazelrc b/.aspect/bazelrc/correctness.bazelrc new file mode 100644 index 0000000..a599f6d --- /dev/null +++ b/.aspect/bazelrc/correctness.bazelrc @@ -0,0 +1,75 @@ +# Do not upload locally executed action results to the remote cache. +# This should be the default for local builds so local builds cannot poison the remote cache. +# It should be flipped to `--remote_upload_local_results` on CI +# by using `--bazelrc=.aspect/bazelrc/ci.bazelrc`. +# Docs: https://bazel.build/reference/command-line-reference#flag--remote_upload_local_results +build --noremote_upload_local_results + +# Don't allow network access for build actions in the sandbox. +# Ensures that you don't accidentally make non-hermetic actions/tests which depend on remote +# services. +# Developers should tag targets with `tags=["requires-network"]` to opt-out of the enforcement. +# Docs: https://bazel.build/reference/command-line-reference#flag--sandbox_default_allow_network +build --sandbox_default_allow_network=false + +# Warn if a test's timeout is significantly longer than the test's actual execution time. +# Bazel's default for test_timeout is medium (5 min), but most tests should instead be short (1 min). +# While a test's timeout should be set such that it is not flaky, a test that has a highly +# over-generous timeout can hide real problems that crop up unexpectedly. +# For instance, a test that normally executes in a minute or two should not have a timeout of +# ETERNAL or LONG as these are much, much too generous. +# Docs: https://bazel.build/docs/user-manual#test-verbose-timeout-warnings +test --test_verbose_timeout_warnings + +# Allow the Bazel server to check directory sources for changes. Ensures that the Bazel server +# notices when a directory changes, if you have a directory listed in the srcs of some target. +# Recommended when using +# [copy_directory](https://github.com/aspect-build/bazel-lib/blob/main/docs/copy_directory.md) and +# [rules_js](https://github.com/aspect-build/rules_js) since npm package are source directories +# inputs to copy_directory actions. +# Docs: https://bazel.build/reference/command-line-reference#flag--host_jvm_args +startup --host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1 + +# Allow exclusive tests to run in the sandbox. Fixes a bug where Bazel doesn't enable sandboxing for +# tests with `tags=["exclusive"]`. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_exclusive_test_sandboxed +test --incompatible_exclusive_test_sandboxed + +# Use a static value for `PATH` and does not inherit `LD_LIBRARY_PATH`. Doesn't let environment +# variables like `PATH` sneak into the build, which can cause massive cache misses when they change. +# Use `--action_env=ENV_VARIABLE` if you want to inherit specific environment variables from the +# client, but note that doing so can prevent cross-user caching if a shared cache is used. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_strict_action_env +build --incompatible_strict_action_env + +# Propagate tags from a target declaration to the actions' execution requirements. +# Ensures that tags applied in your BUILD file, like `tags=["no-remote"]` +# get propagated to actions created by the rule. +# Without this option, you rely on rules authors to manually check the tags you passed +# and apply relevant ones to the actions they create. +# See https://github.com/bazelbuild/bazel/issues/8830 for details. +# Docs: https://bazel.build/reference/command-line-reference#flag--experimental_allow_tags_propagation +build --experimental_allow_tags_propagation +fetch --experimental_allow_tags_propagation +query --experimental_allow_tags_propagation + +# Do not automatically create `__init__.py` files in the runfiles of Python targets. Fixes the wrong +# default that comes from Google's internal monorepo by using `__init__.py` to delimit a Python +# package. Precisely, when a `py_binary` or `py_test` target has `legacy_create_init` set to `auto (the +# default), it is treated as false if and only if this flag is set. See +# https://github.com/bazelbuild/bazel/issues/10076. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_default_to_explicit_init_py +build --incompatible_default_to_explicit_init_py + +# Set default value of `allow_empty` to `False` in `glob()`. This prevents a common mistake when +# attempting to use `glob()` to match files in a subdirectory that is opaque to the current package +# because it contains a BUILD file. See https://github.com/bazelbuild/bazel/issues/8195. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_disallow_empty_glob +common --incompatible_disallow_empty_glob + +# Always download coverage files for tests from the remote cache. By default, coverage files are not +# downloaded on test result cahce hits when --remote_download_minimal is enabled, making it impossible +# to generate a full coverage report. +# Docs: https://bazel.build/reference/command-line-reference#flag--experimental_fetch_all_coverage_outputs +# detching remote cache results +test --experimental_fetch_all_coverage_outputs diff --git a/.aspect/bazelrc/debug.bazelrc b/.aspect/bazelrc/debug.bazelrc new file mode 100644 index 0000000..bfb0bdd --- /dev/null +++ b/.aspect/bazelrc/debug.bazelrc @@ -0,0 +1,19 @@ +############################################################ +# Use `bazel test --config=debug` to enable these settings # +############################################################ + +# Stream stdout/stderr output from each test in real-time. +# Docs: https://bazel.build/docs/user-manual#test-output +test:debug --test_output=streamed + +# Run one test at a time. +# Docs: https://bazel.build/reference/command-line-reference#flag--test_strategy +test:debug --test_strategy=exclusive + +# Prevent long running tests from timing out. +# Docs: https://bazel.build/docs/user-manual#test-timeout +test:debug --test_timeout=9999 + +# Always run tests even if they have cached results. +# Docs: https://bazel.build/docs/user-manual#cache-test-results +test:debug --nocache_test_results diff --git a/.aspect/bazelrc/javascript.bazelrc b/.aspect/bazelrc/javascript.bazelrc new file mode 100644 index 0000000..dc76864 --- /dev/null +++ b/.aspect/bazelrc/javascript.bazelrc @@ -0,0 +1,28 @@ +# Aspect recommended Bazel flags when using Aspect's JavaScript rules: https://github.com/aspect-build/rules_js +# Docs for Node.js flags: https://nodejs.org/en/docs/guides/debugging-getting-started/#command-line-options + +# Support for debugging Node.js tests. Use bazel run with `--config=debug` to turn on the NodeJS +# inspector agent. The node process will break before user code starts and wait for the debugger to +# connect. Pass the --inspect-brk option to all tests which enables the node inspector agent. See +# https://nodejs.org/de/docs/guides/debugging-getting-started/#command-line-options for more +# details. +# Docs: https://nodejs.org/en/docs/guides/debugging-getting-started/#command-line-options +run:debug -- --node_options=--inspect-brk + +# Enable runfiles on all platforms. Runfiles are on by default on Linux and MacOS but off on +# Windows. +# +# In general, rules_js and derivate rule sets assume that runfiles are enabled and do not support no +# runfiles case because it does not scale to teach all Node.js tools to use the runfiles manifest. +# +# If you are developing on Windows, you must either run bazel with administrator privileges or +# enable developer mode. If you do not you may hit this error on Windows: +# +# Bazel needs to create symlinks to build the runfiles tree. +# Creating symlinks on Windows requires one of the following: +# 1. Bazel is run with administrator privileges. +# 2. The system version is Windows 10 Creators Update (1703) or later +# and developer mode is enabled. +# +# Docs: https://bazel.build/reference/command-line-reference#flag--enable_runfiles +build --enable_runfiles diff --git a/.aspect/bazelrc/performance.bazelrc b/.aspect/bazelrc/performance.bazelrc new file mode 100644 index 0000000..26dbbe1 --- /dev/null +++ b/.aspect/bazelrc/performance.bazelrc @@ -0,0 +1,29 @@ +# Speed up all builds by not checking if output files have been modified. Lets you make changes to +# the output tree without triggering a build for local debugging. For example, you can modify +# [rules_js](https://github.com/aspect-build/rules_js) 3rd party npm packages in the output tree +# when local debugging. +# Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/pkgcache/PackageOptions.java#L185 +build --noexperimental_check_output_files +fetch --noexperimental_check_output_files +query --noexperimental_check_output_files + +# Don't apply `--noremote_upload_local_results` and `--noremote_accept_cached` to the disk cache. +# If you have both `--noremote_upload_local_results` and `--disk_cache`, then this fixes a bug where +# Bazel doesn't write to the local disk cache as it treats as a remote cache. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_remote_results_ignore_disk +build --incompatible_remote_results_ignore_disk + +# 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. +# No longer experimental in Bazel 6: https://github.com/bazelbuild/bazel/commit/c1a95501a5611878e5cc43a3cc531f2b9e47835b +# Docs: https://bazel.build/reference/command-line-reference#flag--reuse_sandbox_directories +build --experimental_reuse_sandbox_directories + +# Do not build runfiles symlink forests for external repositories under +# `.runfiles/wsname/external/repo` (in addition to `.runfiles/repo`). This reduces runfiles & +# sandbox creation times & prevents accidentally depending on this feature which may flip to off by +# default in the future. Note, some rules may fail under this flag, please file issues with the rule +# author. +# Docs: https://bazel.build/reference/command-line-reference#flag--legacy_external_runfiles +build --nolegacy_external_runfiles diff --git a/.bazelrc b/.bazelrc index edbb86b..1d5d065 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,15 +1,15 @@ -# Bazel settings that apply to this repository. -# Take care to document any settings that you expect users to apply. -# Settings that apply only to CI are in .github/workflows/ci.bazelrc +# Import Aspect bazelrc presets +try-import %workspace%/.aspect/bazelrc/bazel7.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 -# for rules_js -build --enable_runfiles +### YOUR PROJECT SPECIFIC OPTIONS GO HERE ### -# Load any settings specific to the current user. -# .bazelrc.user should appear in .gitignore so that settings are not shared with team members -# This needs to be last statement in this -# config, as the user configuration should be able to overwrite flags from this file. -# See https://docs.bazel.build/versions/master/best-practices.html#bazelrc -# (Note that we use .bazelrc.user so the file appears next to .bazelrc in directory listing, -# rather than user.bazelrc as suggested in the Bazel docs) -try-import %workspace%/.bazelrc.user \ No newline at end of file +# 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 \ No newline at end of file diff --git a/.github/workflows/BUILD.bazel b/.github/workflows/BUILD.bazel new file mode 100644 index 0000000..ad948c8 --- /dev/null +++ b/.github/workflows/BUILD.bazel @@ -0,0 +1,9 @@ +load("@aspect_bazel_lib//lib:bazelrc_presets.bzl", "write_aspect_bazelrc_presets") + +write_aspect_bazelrc_presets( + name = "update_aspect_bazelrc_presets", + presets = [ + "bazel6", + "bazel7", + ], +) diff --git a/.github/workflows/bazel6.bazelrc b/.github/workflows/bazel6.bazelrc new file mode 100644 index 0000000..11a1c67 --- /dev/null +++ b/.github/workflows/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 diff --git a/.github/workflows/bazel7.bazelrc b/.github/workflows/bazel7.bazelrc new file mode 100644 index 0000000..11a1c67 --- /dev/null +++ b/.github/workflows/bazel7.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 diff --git a/.github/workflows/buildifier.yaml b/.github/workflows/buildifier.yaml index 5e98f78..4104815 100644 --- a/.github/workflows/buildifier.yaml +++ b/.github/workflows/buildifier.yaml @@ -2,19 +2,19 @@ name: Buildifier # Controls when the action will run. on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [main] + pull_request: + branches: [main] - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: buildifier - run: bazel run //:buildifier.check + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: buildifier + run: bazel run //:buildifier.check diff --git a/.github/workflows/ci.bazelrc b/.github/workflows/ci.bazelrc index d549ad8..b33f2a6 100644 --- a/.github/workflows/ci.bazelrc +++ b/.github/workflows/ci.bazelrc @@ -1,13 +1,9 @@ -# This file contains Bazel settings to apply on CI only. -# It is referenced with a --bazelrc option in the call to bazel in ci.yaml +# Directories caches by GitHub actions +common --disk_cache=~/.cache/bazel-disk-cache +common --repository_cache=~/.cache/bazel-repository-cache # Debug where options came from -build --announce_rc -# This directory is configured in GitHub actions to be persisted between runs. -build --disk_cache=~/.cache/bazel -build --repository_cache=~/.cache/bazel-repo -# Don't rely on test logs being easily accessible from the test runner, -# though it makes the log noisier. -test --test_output=errors +common --announce_rc + # Allows tests to run bazelisk-in-bazel, since this is the cache folder used -test --test_env=XDG_CACHE_HOME \ No newline at end of file +common --test_env=XDG_CACHE_HOME \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 83d7d2e..34730ca 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,116 +18,120 @@ concurrency: cancel-in-progress: ${{ github.ref_name != 'main' }} jobs: - # matrix-prep-* steps dynamically generate a bit of JSON depending on whether our action has - # access to repository secrets. When running on a pull_request from a fork, the author is - # untrusted so the secret will be absent. Insanely complex for how simple this requirement is... - # inspired from - # https://stackoverflow.com/questions/65384420/how-to-make-a-github-action-matrix-element-conditional - - matrix-prep-bazelversion: - # Prepares the 'bazelversion' axis of the test matrix - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - id: bazel_7 - run: echo "bazelversion=$(head -n 1 .bazelversion)" >> $GITHUB_OUTPUT - outputs: - # Will look like ["", ...] - bazelversions: ${{ toJSON(steps.*.outputs.bazelversion) }} - - matrix-prep-os: - # Prepares the 'os' axis of the test matrix + # Prepares dynamic test matrix values + matrix-prep: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - id: linux - run: echo "os=ubuntu-latest" >> $GITHUB_OUTPUT - - id: macos - run: echo "os=macos-latest" >> $GITHUB_OUTPUT - # Only run on main branch (not PRs) to minimize macOS minutes (billed at 10X) - # https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes - if: github.ref == 'refs/heads/main' - - id: windows - run: echo "os=windows-latest" >> $GITHUB_OUTPUT - # Only run on main branch (or PR branches that contain 'windows') to minimize Windows minutes (billed at 2X) + - uses: actions/checkout@v4 + - id: bazel-version + name: Prepare 'bazel-version' matrix axis + run: | + v=$(head -n 1 .bazelversion) + m=${v::1} + a=( + "major:$m, version:\"$v\"" + "major:6, version:\"6.5.0\"" + ) + printf -v j '{%s},' "${a[@]}" + echo "res=[${j%,}]" | tee -a $GITHUB_OUTPUT + - id: os + name: Prepare 'os' matrix axis + # Only run MacOS and Windows on main branch (not PRs) to minimize minutes (billed at 10X and 2X respectively) # https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes - if: github.ref == 'refs/heads/main' || contains(github.head_ref, 'windows') || github.head_ref == 'bzlmod' + run: | + a=( ubuntu ) + if [[ "${{ github.ref_name }}" == "main" ]] || [[ "${{ github.head_ref }}" == *"macos"* ]]; then + a+=( macos ) + fi + if [[ "${{ github.ref_name }}" == "main" ]] || [[ "${{ github.head_ref }}" == *"windows"* ]]; then + a+=( windows ) + fi + printf -v j '"%s",' "${a[@]}" + echo "res=[${j%,}]" | tee -a $GITHUB_OUTPUT outputs: - # Will look like ["ubuntu-latest", "macos-latest"] - os: ${{ toJSON(steps.*.outputs.os) }} + bazel-version: ${{ steps.bazel-version.outputs.res }} + os: ${{ steps.os.outputs.res }} test: - # The type of runner that the job will run on - runs-on: ${{ matrix.os }} - + runs-on: ${{ matrix.os }}-latest needs: - - matrix-prep-bazelversion - - matrix-prep-os - + - matrix-prep strategy: fail-fast: false matrix: - os: ${{ fromJSON(needs.matrix-prep-os.outputs.os) }} - bzlmodEnabled: [true, false] - bazelversion: ${{ fromJSON(needs.matrix-prep-bazelversion.outputs.bazelversions) }} + bazel-version: ${{ fromJSON(needs.matrix-prep.outputs.bazel-version) }} + bzlmod: [1, 0] + os: ${{ fromJSON(needs.matrix-prep.outputs.os) }} folder: - '.' - 'e2e/loaders' - 'e2e/smoke' - 'e2e/worker' exclude: + # Don't test MacOS and Windows against secondary bazel version to minimize minutes (billed at 10X and 2X respectively) + # https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#included-storage-and-minutes + - os: macos + bazel-version: + major: 6 + - os: windows + bazel-version: + major: 6 # TODO - folder: e2e/loaders - bzlmodEnabled: true + bzlmod: 1 # TODO - folder: e2e/worker - bzlmodEnabled: true + bzlmod: 1 - # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - # Cache build and external artifacts so that the next ci build is incremental. - # Because github action caches cannot be updated after a build, we need to - # store the contents of each build in a unique cache key, then fall back to loading - # it on the next ci run. We use hashFiles(...) in the key and restore-keys- with - # the prefix to load the most recent cache for the branch on a cache miss. You - # should customize the contents of hashFiles to capture any bazel input sources, - # although this doesn't need to be perfect. If none of the input sources change - # then a cache hit will load an existing cache and bazel won't have to do any work. - # In the case of a cache miss, you want the fallback cache to contain most of the - # previously built artifacts to minimize build time. The more precise you are with - # hashFiles sources the less work bazel will have to do. - name: Mount bazel caches uses: actions/cache@v3 with: path: | - "~/.cache/bazel" - "~/.cache/bazel-repo" - key: bazel-cache-${{ hashFiles('**/BUILD.bazel', '**/*.bzl', 'WORKSPACE') }} - restore-keys: bazel-cache- + ~/.cache/bazel-disk-cache + ~/.cache/bazel-repository-cache + ~/.cache/xdg-cache + key: bazel-cache-${{ matrix.bazel-version.version }}-${{ matrix.bzlmod }}-${{ matrix.os }}-${{ matrix.folder }}-${{ hashFiles('.bazelrc', '.bazelversion', '.bazeliskrc', '**/BUILD', '**/BUILD.bazel', '**/*.bzl', 'WORKSPACE', 'WORKSPACE.bazel', 'WORKSPACE.bzlmod', 'MODULE.bazel') }} + restore-keys: bazel-cache-${{ matrix.bazel-version.version }}-${{ matrix.bzlmod }}-${{ matrix.os }}-${{ matrix.folder }}- - name: Configure Bazel version working-directory: ${{ matrix.folder }} - # Overwrite the .bazelversion instead of using USE_BAZEL_VERSION so that Bazelisk - # still bootstraps Aspect CLI from configuration in .bazeliskrc. Aspect CLI will - # then use .bazelversion to determine which Bazel version to use - run: echo "${{ matrix.bazelversion }}" > .bazelversion + shell: bash + run: | + # Overwrite the .bazelversion instead of using USE_BAZEL_VERSION so that Bazelisk + # still bootstraps Aspect CLI from configuration in .bazeliskrc. Aspect CLI will + # then use .bazelversion to determine which Bazel version to use. + echo "${{ matrix.bazel-version.version }}" > .bazelversion + # Delete all the version specific bazelrc files that are used for local development + # since the version we're testing against is dynamic. These are just symlinks and the + # root .bazelrc brings these in with try-imports. In this CI workflows, we explicitly + # bring in the version specific bazelrc file with --bazelrc when we invoke bazel. + rm ${GITHUB_WORKSPACE//\\/\/}/.aspect/bazelrc/bazel*.bazelrc - - name: Set bzlmod flag - # Store the --enable_bzlmod flag that we add to the test command below - # only when we're running bzlmod in our test matrix. - id: set_bzlmod_flag - if: matrix.bzlmodEnabled - run: echo "bzlmod_flag=--enable_bzlmod" >> $GITHUB_OUTPUT + # TODO: remove this block once we have Aspect CLI Windows releases + - name: Don't use Aspect CLI on Windows + if: matrix.os == 'windows' + working-directory: ${{ matrix.folder }} + shell: bash + run: rm -f .bazeliskrc - name: bazel test //... - env: - # Bazelisk will download bazel to here, ensure it is cached between runs. - XDG_CACHE_HOME: ~/.cache/bazel-repo working-directory: ${{ matrix.folder }} - run: bazel --bazelrc=${{ github.workspace }}/.github/workflows/ci.bazelrc --bazelrc=.bazelrc test ${{ steps.set_bzlmod_flag.outputs.bzlmod_flag }} //... + shell: bash + run: | + bazel \ + --bazelrc=${GITHUB_WORKSPACE//\\/\/}/.github/workflows/bazel${{ matrix.bazel-version.major }}.bazelrc \ + --bazelrc=${GITHUB_WORKSPACE//\\/\/}/.aspect/bazelrc/ci.bazelrc \ + --bazelrc=${GITHUB_WORKSPACE//\\/\/}/.github/workflows/ci.bazelrc \ + test \ + --test_tag_filters=-skip-on-bazel${{ matrix.bazel-version.major }} \ + --build_tag_filters=-skip-on-bazel${{ matrix.bazel-version.major }} \ + --enable_bzlmod=${{ matrix.bzlmod }} \ + //... + env: + XDG_CACHE_HOME: ~/.cache/xdg-cache # bazelisk will download bazel to here - name: run ./test.sh working-directory: ${{ matrix.folder }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 517c572..3b7520c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Mount bazel caches uses: actions/cache@v3 with: diff --git a/.gitignore b/.gitignore index 1a4a203..c9f5308 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,20 @@ bazel-* +.bazelrc.user +node_modules/ +.pnpm-* + dist -node_modules -.DS_Store aspect-build-webpack-* -.bazelrc.user -# Don't commit lockfile for now as it is unstable. Do allow for it to be -# created, however, since it gives a performance boost for local development. -# https://github.com/bazelbuild/bazel/issues/19026 -# https://github.com/bazelbuild/bazel/issues/19621 -# https://github.com/bazelbuild/bazel/issues/19971 -# https://github.com/bazelbuild/bazel/issues/20272 -# https://github.com/bazelbuild/bazel/issues/20369 +.idea/ +.ijwb/ +.DS_Store + +# Bazel's MODULE lockfile isn't ready to check in yet as of Bazel 7.1. +# Do allow for it to be created, however, since it gives a performance boost for local development. +# [Store resolved repository attributes in the Bzlmod lockfile](https://github.com/bazelbuild/bazel/issues/19026) +# [MODULE.bazel.lock file contains user specific paths](https://github.com/bazelbuild/bazel/issues/19621) +# [Consider skipping bazel_tools@_ from lockfile](https://github.com/bazelbuild/bazel/issues/19971) +# [MODULE.bazel.lock file "reads through" already-locked package manager](https://github.com/bazelbuild/bazel/issues/20272) +# [moduleFileHash in MODULE.bazel.lock causes frequent Git merge conflicts](https://github.com/bazelbuild/bazel/issues/20369) MODULE.bazel.lock diff --git a/e2e/loaders/.bazelignore b/e2e/loaders/.bazelignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/e2e/loaders/.bazelignore @@ -0,0 +1 @@ +node_modules diff --git a/e2e/loaders/.bazelrc b/e2e/loaders/.bazelrc index bb7e894..413c995 100644 --- a/e2e/loaders/.bazelrc +++ b/e2e/loaders/.bazelrc @@ -1,2 +1,15 @@ -# for rules_js -build --enable_runfiles +# Import Aspect bazelrc presets +try-import %workspace%/../../.aspect/bazelrc/bazel7.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 diff --git a/e2e/loaders/.npmrc b/e2e/loaders/.npmrc new file mode 100644 index 0000000..5de6efa --- /dev/null +++ b/e2e/loaders/.npmrc @@ -0,0 +1,4 @@ +# Disabling pnpm [hoisting](https://pnpm.io/npmrc#hoist) by setting `hoist=false` is recommended on +# projects using rules_js so that pnpm outside of Bazel lays out a node_modules tree similar to what +# rules_js lays out under Bazel (without a hidden node_modules/.pnpm/node_modules) +hoist=false diff --git a/e2e/loaders/WORKSPACE b/e2e/loaders/WORKSPACE index bec87d0..b230af8 100644 --- a/e2e/loaders/WORKSPACE +++ b/e2e/loaders/WORKSPACE @@ -25,8 +25,10 @@ load("@aspect_rules_js//npm:npm_import.bzl", "npm_translate_lock") npm_translate_lock( name = "npm", no_optional = True, - pnpm_lock = "@//:pnpm-lock.yaml", + npmrc = "//:.npmrc", + pnpm_lock = "//:pnpm-lock.yaml", pnpm_version = "6.29.1", + verify_node_modules_ignored = "//:.bazelignore", ) load("@npm//:repositories.bzl", "npm_repositories") diff --git a/e2e/smoke/.bazelrc b/e2e/smoke/.bazelrc index bb7e894..413c995 100644 --- a/e2e/smoke/.bazelrc +++ b/e2e/smoke/.bazelrc @@ -1,2 +1,15 @@ -# for rules_js -build --enable_runfiles +# Import Aspect bazelrc presets +try-import %workspace%/../../.aspect/bazelrc/bazel7.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 diff --git a/e2e/smoke/MODULE.bazel b/e2e/smoke/MODULE.bazel index d0d2a86..3736331 100644 --- a/e2e/smoke/MODULE.bazel +++ b/e2e/smoke/MODULE.bazel @@ -11,11 +11,15 @@ bazel_dep(name = "bazel_skylib", version = "1.4.1", dev_dependency = True) npm = use_extension("@aspect_rules_js//npm:extensions.bzl", "npm", dev_dependency = True) npm.npm_translate_lock( name = "v4-npm", + npmrc = "//:.npmrc", pnpm_lock = "//v4:pnpm-lock.yaml", + verify_node_modules_ignored = "//:.bazelignore", ) use_repo(npm, "v4-npm") npm.npm_translate_lock( name = "v5-npm", + npmrc = "//:.npmrc", pnpm_lock = "//v5:pnpm-lock.yaml", + verify_node_modules_ignored = "//:.bazelignore", ) use_repo(npm, "v5-npm") diff --git a/e2e/worker/.bazelrc b/e2e/worker/.bazelrc index bb7e894..413c995 100644 --- a/e2e/worker/.bazelrc +++ b/e2e/worker/.bazelrc @@ -1,2 +1,15 @@ -# for rules_js -build --enable_runfiles +# Import Aspect bazelrc presets +try-import %workspace%/../../.aspect/bazelrc/bazel7.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