Skip to main content

serviceradar-bazel-guardrails

Use before creating a worktree, script, or ad hoc orchestration, handling generated Bazel artifacts, changing native add-ons, or adding serviceradar_core tests.

来源信息

仓库
carverauto/serviceradar
最近来源活动
2026年9月27日 23:22
检测到的 SKILL.md 语言
英语
星标
919
分支
2

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
serviceradar-bazel-guardrails
description
Use before creating a worktree, script, or ad hoc orchestration, handling generated Bazel artifacts, changing native add-ons, or adding serviceradar_core tests.
user-invocable
false
metadata
{"internal":true}
# ServiceRadar Bazel Guardrails - **After `git worktree add` (or any extra checkout), symlink the gitignored Bazel rc files before any `bazel` command.** `.bazelrc` try-imports `%workspace%/.bazelrc.remote` and `.bazelrc.local`. Both are gitignored: they hold the BuildBuddy API key and the remote cache/executor overrides. `git worktree add` only checks out tracked files, so a new worktree has neither. Without them `--config=remote` / `--config=ci` cannot authenticate: Bazel prints `PERMISSION_DENIED: Missing API key` and never reaches RBE (local crawl or abort). `bb view` still works from the primary clone — that is not proof the worktree is wired for remote execution. From the checkout that already has the files: ``` ln -sfn "$PRIMARY/.bazelrc.remote" "$WT/.bazelrc.remote" test -e "$PRIMARY/.bazelrc.local" && ln -sfn "$PRIMARY/.bazelrc.local" "$WT/.bazelrc.local" test -f "$WT/.bazelrc.remote" ``` Same rule for `/tmp/...` trees, `jj workspace add`, and extra clones. Never commit those files. - **Never read generated Bazel output.** No `cp` out of `bazel-out`, no `bazel info bazel-bin` plus a path, no `bazel cquery --output=files` followed by reading the file. The output tree is a cache, not an interface: it can be wiped at any time, and its path encodes the configuration that produced it, so an artifact found under `bazel-out/rbe_platform-opt/` is whatever happened to be built with that platform and compilation mode — the same command with a different `-c` or `--config` silently reads something else, or nothing. This tree hides the path deliberately: `//.bazelrc` sets `--experimental_convenience_symlinks=clean`, so there is no `bazel-out` symlink at the workspace root. A copy that appears to do nothing there is that guard working. Do not route around it by resolving an absolute path by hand. Express the need as a target instead: a `filegroup` consumed as a declared input, or `write_source_files` from `aspect_bazel_lib` to copy an artifact back into the tree. When a generated file must be committed — protoc output embedded with `include_bytes!` so `cargo` works without Bazel, generated bindings — the pattern is a committed copy, a `diff_test` that says when it is stale, and a write-back target that makes it current. See `//config/manager_config/rust:update_embedded_instances`, which copies from runfiles. If a write-back target is missing, add one rather than doing the copy by hand. - **No shell scripts. Everything is a Bazel target.** Do not add a script under `scripts/`, and do not extend an existing one. Build, test, provisioning, teardown, packaging and publishing are Bazel targets invoked with `bazel build` / `bazel test` / `bazel run`. A script is a build system with no dependency graph, no cache, no sandbox and no remote execution — every one of them is a hole in the graph that has to be re-run, re-debugged and re-documented by hand. **The only permitted exception is a hard corner case that genuinely cannot be a Bazel action**, and it must be justified in a comment at the top of the file. Today that means credential handling that must not become an action input: Docker/registry authentication and cosign/OpenBao signing setup, plus materializing rotating SRQL fixture credentials in the Bazel client's environment before database test actions start. "It was easier" is not a corner case. Corollaries: - Work an existing script does belongs in a target. `//rust/integration-db` already replaced `scripts/{reset,drop,sweep-stale-core}-test-db.sh` — those files are dead and should be deleted, not maintained. - A test needing a file gets it as a **declared input** (`data`/`srcs`), never from a script writing it to a runner temp dir and exporting a path. That pattern is what forces `no-remote-exec` and breaks RBE. - Ordering between targets is the caller's sequence of `bazel` invocations, not a script that wraps them. Two registration gates fail **only** under `make test`/BazelCI — never under `mix test`, `go test`, `cargo test` or a PR check — so a missing entry looks green all the way to trunk unless the no-mistakes pipeline catches it first: - **Adding or changing a native add-on** (`addons/<name>/` + a Go/Rust binary) must be registered in four places, and any change to its source, config or `BUILD.bazel` requires bumping `addons/<name>/addon.yaml` `version`. - **Adding an `elixir/serviceradar_core` test file** requires a row in `elixir/serviceradar_core/test/INTEGRATION_SOURCE_DISPOSITIONS.tsv`. The no-mistakes `test-registration` gate (`.no-mistakes.yaml`) now runs this contract before push, so a missing row is caught there instead of only in BazelCI. Both procedures, with their local verification commands, are in [docs/agent-runbooks.md](docs/agent-runbooks.md).
在 GitHub 查看