agents: add shell scripting rule and artifact staging/Starlark rules (#4308) Capture review feedback from cross-building Linux release artifacts so agents avoid repeating shell, workflow, and Starlark pitfalls. Codify guidelines for flat artifact staging across Bazel split transitions, safe manifest iteration and `elif` usage in shell scripts, and dedicated providers, explicit `for` loops, and minimal `BUILD` exports in Starlark.
diff --git a/.agents/rules/github_actions_workflows.md b/.agents/rules/github_actions_workflows.md index d8fabb8..85ff59c 100644 --- a/.agents/rules/github_actions_workflows.md +++ b/.agents/rules/github_actions_workflows.md
@@ -47,6 +47,12 @@ binary directly from `bazel-bin/<pkg>/<target>` instead of `bazel run`, explicitly include `//<pkg>:<target>` in `bazel build` so its `.runfiles` tree is materialized. +* **Flat Staging for `actions/upload-artifact` Across Split Transitions**: + `actions/upload-artifact` strips only the longest common parent directory of + all matched `path` entries. When uploading files from multiple Bazel + configurations (`bazel-out/<cfg-1>/...`, `bazel-out/<cfg-2>/...`), stage them + into a single flat directory first (reading paths from the rule's `.txt` + manifest) so `<cfg>/...` subdirectories are not preserved in the artifact. ## Workflow Scripts & Testing * **Separate Script Files (No Inline Scripts)**: Factor non-trivial scripts
diff --git a/.agents/rules/shell.md b/.agents/rules/shell.md new file mode 100644 index 0000000..015a0a2 --- /dev/null +++ b/.agents/rules/shell.md
@@ -0,0 +1,13 @@ +--- +trigger: glob +description: Shell / Bash scripting style and portability rules +globs: "*.sh" +--- + +# Shell Scripting Rules + +* Use `elif` instead of nesting `if` inside an `else` block. +* When reading file paths from a manifest or list file, iterate line-by-line + with `while IFS= read -r file; do ...; done < "$manifest"`. Do not use + unquoted command substitution (`$(cat "$manifest")`) or suppress ShellCheck + `SC2046` assuming paths lack spaces.
diff --git a/.agents/rules/starlark.md b/.agents/rules/starlark.md index a0213ad..97ed3d2 100644 --- a/.agents/rules/starlark.md +++ b/.agents/rules/starlark.md
@@ -60,6 +60,10 @@ fields must be immutable when `depset()` is called (eager check before rule freeze). Use `tuple[T]` or `depset[T]` in providers placed into depsets; do not use mutable `list[T]`. +* **Dedicated Providers over Filtering `DefaultInfo.files`**: When a rule needs + a subset of a dependency's outputs (e.g., binaries without a sibling `.txt` + manifest), return a dedicated provider (e.g., `_ReleaseFilesInfo`) instead of + filtering `DefaultInfo.files` by filename or extension. ## Repository Rules & Code Generation * **Structured Attributes**: Pass separate typed attributes (`attr.string_list`, @@ -76,6 +80,10 @@ introduced in Bazel 8.3.0. ## Code Style & Conventions +* **Do Not Export `BUILD` Files Unnecessarily**: Do not add `BUILD` or + `BUILD.bazel` to `exports_files(...)` unless strictly required. +* **No Nested List Comprehensions**: Do not write nested list comprehensions + (`[x for y in ... for x in ...]`). Use explicit `for` loops instead. * **Direct Attribute Access**: Use normal attribute access (`x.field`) instead of `getattr(x, "field", default)` for fields defined on a provider or struct schema. When an object may be one of multiple provider/struct variants with