Add clang-tidy support

Change-Id: I22d989eea07efccaad624e0635ef3b783178a2f1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/examples/+/276972
Reviewed-by: Wyatt Hepler <hepler@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Ted Pudlik <tpudlik@google.com>
diff --git a/.bazelrc b/.bazelrc
index 4e0dff0..0bb8281 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -93,8 +93,16 @@
 test --test_output=errors
 
 # Use the remote cache. This will only work for users who have permission to access it.
-common:remote_cache --remote_cache=grpcs://remotebuildexecution.googleapis.com
+common:remote_cache --bes_backend="buildeventservice.googleapis.com"
+common:remote_cache --bes_instance_name=pigweed-rbe-open
+common:remote_cache --bes_results_url="https://source.cloud.google.com/results/invocations/"
+common:remote_cache --bes_timeout=600s
+common:remote_cache --experimental_remote_cache_eviction_retries=5
 common:remote_cache --google_default_credentials=true
+# Required to use buildeventservice on Bazel 8+.
+# TODO: b/345556899 -- Remove this flag when no longer required.
+common:remote_cache --legacy_important_outputs
+common:remote_cache --remote_cache=grpcs://remotebuildexecution.googleapis.com
 common:remote_cache --remote_instance_name=projects/pigweed-rbe-open/instances/default-instance
 common:remote_cache --remote_upload_local_results=false
 # TODO: https://github.com/bazelbuild/bazel/issues/24867 - This flag breaks
@@ -102,6 +110,22 @@
 # java.io.FileNotFoundException when creating runfiles trees.
 common:remote_cache --experimental_inprocess_symlink_creation=false
 
+# clang-tidy configuration
+build:clang-tidy --aspects @bazel_clang_tidy//clang_tidy:clang_tidy.bzl%clang_tidy_aspect
+build:clang-tidy --output_groups=report
+build:clang-tidy --@bazel_clang_tidy//:clang_tidy_config=//:clang_tidy_config
+# Use the clang-tidy executable from Pigweed's toolchain, and include
+# our sysroot headers.
+build:clang-tidy --@bazel_clang_tidy//:clang_tidy_executable=@pigweed//pw_toolchain/host_clang:copy_clang_tidy
+build:clang-tidy --@bazel_clang_tidy//:clang_tidy_additional_deps=@pigweed//pw_toolchain/host_clang:sysroot_root
+# Skip any targets with tags = ["noclangtidy"]. This allows a gradual
+# rollout.
+build:clang-tidy --build_tag_filters=-noclangtidy
+# We need to disable this warning to avoid spurious "#pragma once in main file"
+# warnings for header-only libraries. For another approach, see
+# https://github.com/mongodb-forks/bazel_clang_tidy/pull/2
+build:clang-tidy --copt=-Wno-pragma-once-outside-header
+
 # User bazelrc file; see
 # https://bazel.build/configure/best-practices#bazelrc-file
 #
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000..7ba62fb
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,84 @@
+# Copyright 2024 The Pigweed Authors
+#
+# 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
+#
+#     https://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.
+
+---
+UseColor: true
+
+Checks: >
+    bugprone-argument-comment,
+    bugprone-assert-side-effect,
+    bugprone-bool-pointer-implicit-conversion,
+    bugprone-dangling-handle,
+    bugprone-fold-init-type,
+    bugprone-forwarding-reference-overload,
+    bugprone-forward-declaration-namespace,
+    bugprone-inaccurate-erase,
+    bugprone-macro-repeated-side-effects,
+    bugprone-move-forwarding-reference,
+    bugprone-multiple-statement-macro,
+    bugprone-string-constructor,
+    bugprone-suspicious-memset-usage,
+    bugprone-swapped-arguments,
+    bugprone-undefined-memory-manipulation,
+    bugprone-undelegated-constructor,
+    bugprone-unused-raii,
+    bugprone-use-after-move,
+    clang-diagnostic-*,
+    -clang-analyzer-*,
+    darwin-avoid-spinlock,
+    google-build-explicit-make-pair,
+    google-build-namespaces,
+    google-default-arguments,
+    google-global-names-in-headers,
+    google-readability-function-size,
+    google-readability-namespace-comments,
+    google-runtime-operator,
+    misc-static-assert,
+    misc-unconventional-assign-operator,
+    misc-unused-using-decls,
+    modernize-avoid-bind,
+    modernize-deprecated-ios-base-aliases,
+    modernize-make-shared,
+    modernize-make-unique,
+    modernize-replace-auto-ptr,
+    modernize-replace-disallow-copy-and-assign-macro,
+    modernize-replace-random-shuffle,
+    modernize-shrink-to-fit,
+    modernize-unary-static-assert,
+    modernize-use-bool-literals,
+    modernize-use-equals-delete,
+    modernize-use-noexcept,
+    modernize-use-nullptr,
+    modernize-use-override,
+    modernize-use-transparent-functors,
+    modernize-use-uncaught-exceptions,
+    performance-faster-string-find,
+    performance-for-range-copy,
+    performance-implicit-conversion-in-loop,
+    performance-inefficient-algorithm,
+    performance-inefficient-vector-operation,
+    performance-move-constructor-init,
+    readability-container-size-empty,
+    readability-inconsistent-declaration-parameter-name,
+    readability-misleading-indentation,
+    readability-redundant-control-flow,
+    readability-redundant-smartptr-get,
+    readability-string-compare,
+WarningsAsErrors: >
+    *,
+    -clang-diagnostic-deprecated-declarations,
+    -clang-diagnostic-unused-command-line-argument
+HeaderFilterRegex: '.*'
+ExcludeHeaderFilterRegex: 'third_party/.*'
+...
diff --git a/BUILD.bazel b/BUILD.bazel
index 55b0628..b25644b 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -20,3 +20,8 @@
         ".pw_console.yaml",
     ],
 )
+
+filegroup(
+    name = "clang_tidy_config",
+    srcs = [".clang-tidy"],
+)
diff --git a/MODULE.bazel b/MODULE.bazel
index a714e9b..bc9cea8 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -59,6 +59,17 @@
     urls = ["https://github.com/STMicroelectronics/cmsis_core/archive/refs/tags/v5.4.0_cm4.tar.gz"],
 )
 
+git_repository = use_repo_rule(
+    "@bazel_tools//tools/build_defs/repo:git.bzl",
+    "git_repository",
+)
+
+git_repository(
+    name = "bazel_clang_tidy",
+    commit = "db677011c7363509a288a9fb3bf0a50830bbf791",
+    remote = "https://github.com/erenon/bazel_clang_tidy.git",
+)
+
 register_toolchains(
     # Toolchain for the Pico 2
     "@pigweed//pw_toolchain:cc_toolchain_cortex-m0",
diff --git a/pigweed.json b/pigweed.json
index 0feec3c..18cfedb 100644
--- a/pigweed.json
+++ b/pigweed.json
@@ -8,6 +8,11 @@
           [
             "build",
             "--config=presubmit"
+          ],
+          [
+            "build",
+            "--config=clang-tidy",
+            "//..."
           ]
         ]
       }