Skip to content

Commit 7630552

Browse files
redsun82Copilot
andcommitted
Bazel skill: apply the repository doc register
No em dashes or contractions, matching the agent-facing docs already in the repo. Also drops a few facts that would go stale without anything catching them: the registry overlay glob, the platform count, and the claim that nothing loads defs.bzl. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 49f4967 commit 7630552

1 file changed

Lines changed: 44 additions & 46 deletions

File tree

‎.github/skills/bazel/SKILL.md‎

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: bazel
3-
description: Conventions for editing Bazel files in the github/codeql repository — the shared `misc/bazel` helpers, `codeql_platform_select` and the `{CODEQL_PLATFORM}` packaging placeholder, adding `MODULE.bazel` dependencies, and the `semmle_code` stub that keeps the standalone build working. Use when editing any `BUILD.bazel`, `*.bzl`, `MODULE.bazel` or `.bazelrc` here, and before validating such an edit.
3+
description: Conventions for editing Bazel files in the github/codeql repository: the shared `misc/bazel` helpers, `codeql_platform_select` and the `{CODEQL_PLATFORM}` packaging placeholder, adding `MODULE.bazel` dependencies, and the `semmle_code` stub that keeps the standalone build working. Use when editing any `BUILD.bazel`, `*.bzl`, `MODULE.bazel` or `.bazelrc` here, and before validating such an edit.
44
---
55

66
# Bazel in the codeql repository
@@ -12,11 +12,11 @@ also consumed by an internal module that depends on it; standalone builds replac
1212

1313
Things that will waste your time or produce a wrong edit here. Read this section even if you skip the rest.
1414

15-
* **`//...` does not work.** `bazel build //...`, and even `bazel query //...`, fail at the repo root — the patched
16-
modules under `misc/bazel/registry/modules/*/*/overlay` are real packages referencing repos that are not visible from
17-
the main repo, and [`.bazelrc`](../../../.bazelrc) notes that transitions break `...` builds separately. **Validate
18-
the specific target or package you changed**, not a recursive pattern. The error names an unrelated directory and is
19-
very easy to misdiagnose.
15+
* **`//...` does not work.** `bazel build //...`, and even `bazel query //...`, fail at the repo root: the patched
16+
modules under [`misc/bazel/registry`](../../../misc/bazel/registry) are real packages referencing repos that are not
17+
visible from the main repo, and [`.bazelrc`](../../../.bazelrc) notes separately that transitions break `...` builds.
18+
The error names a registry directory unrelated to your edit, so it is easy to misdiagnose. **Validate the specific
19+
target or package you changed**, not a recursive pattern.
2020
* **There is no `MODULE.bazel.lock`, deliberately.** [`.bazelrc`](../../../.bazelrc) sets `--lockfile_mode=off` because
2121
the workspace-relative module override makes a lockfile unstable. Do not add one, and do not "fix" its absence.
2222
* **`linux_arm64` vs `linux-arm64`.** The keyword argument and config setting use an underscore; the platform *string*
@@ -26,40 +26,40 @@ Things that will waste your time or produce a wrong edit here. Read this section
2626

2727
## Rules of thumb
2828

29-
* **Copy a neighbouring target rather than inventing a shape.** Note that packaging is not uniform — some packages use
30-
the `codeql_*` wrappers, others still use `pkg_files` directly — so copy the closest *working* neighbour and prefer
31-
the wrapper for new code.
29+
* **Copy a neighbouring target rather than inventing a shape.** Packaging is not uniform: some packages use the
30+
`codeql_*` wrappers, others still use `pkg_files` directly. Copy the closest *working* neighbour, and prefer the
31+
wrapper for new code.
3232
* **Pin anything fetched over the network** with `sha256` or `integrity`. Bazel only *warns* on an unpinned download, so
3333
nothing fails loudly, but the build stops being reproducible and a retagged upstream release silently changes what you
34-
build. `lfs_archive` is the exception — content is pinned by git object.
35-
* **Format with `bazel run //misc/bazel/buildifier`.** It rewrites in place, so don't hand-tune formatting. Also wired as
36-
a `pre-commit` hook ([`.pre-commit-config.yaml`](../../../.pre-commit-config.yaml)).
34+
build. `lfs_archive` is the exception: content is pinned by git object.
35+
* **Format with `bazel run //misc/bazel/buildifier`.** It rewrites in place, so do not hand-tune formatting. Also wired
36+
as a `pre-commit` hook ([`.pre-commit-config.yaml`](../../../.pre-commit-config.yaml)).
3737

3838
## Where new code goes
3939

4040
Bazel's own macro / rule / repository-rule distinction applies as usual. What is repo-specific:
4141

42-
| Adding… | Goes in |
42+
| Adding | Goes in |
4343
| --- | --- |
44-
| a new packaging shape | extend [`misc/bazel/pkg.bzl`](../../../misc/bazel/pkg.bzl) — don't fork `pkg_files` |
45-
| a new OS or arch split | [`misc/bazel/os.bzl`](../../../misc/bazel/os.bzl) — don't hand-roll a `select()` over `@platforms//` |
46-
| a fetch of something external | a repository rule ([`lfs.bzl`](../../../misc/bazel/lfs.bzl), [`ripunzip.bzl`](../../../misc/ripunzip/ripunzip.bzl)) — not a `genrule` |
44+
| a new packaging shape | extend [`misc/bazel/pkg.bzl`](../../../misc/bazel/pkg.bzl), do not fork `pkg_files` |
45+
| a new OS or arch split | [`misc/bazel/os.bzl`](../../../misc/bazel/os.bzl), do not hand-roll a `select()` over `@platforms//` |
46+
| a fetch of something external | a repository rule ([`lfs.bzl`](../../../misc/bazel/lfs.bzl), [`ripunzip.bzl`](../../../misc/ripunzip/ripunzip.bzl)), not a `genrule` |
4747
| a wrapper used by one language | next to that language ([`swift/rules.bzl`](../../../swift/rules.bzl)) |
4848
| a wrapper used across languages | `misc/bazel/` |
4949

5050
Prefer inline rules in `BUILD.bazel`. A `.bzl` file earns its `load()` only when the shape repeats across packages or a
5151
value must be computed: [`rust.bzl`](../../../misc/bazel/rust.bzl) is worth it because every Rust binary that ships in a
5252
pack must get the same universal-binary wrapper and symbols test, and forgetting either is a release bug. A local
53-
debugging aid opts out and declares a plain `rust_binary` — see `swift-syntax-parse` in
53+
debugging aid opts out and declares a plain `rust_binary`; see `swift-syntax-parse` in
5454
[`unified/swift-syntax-rs/BUILD.bazel`](../../../unified/swift-syntax-rs/BUILD.bazel). The `_gen_binaries` list in
55-
[`go/BUILD.bazel`](../../../go/BUILD.bazel) does not earn a `.bzl` — it is shared by two targets in one file, so a local
56-
variable does the job.
55+
[`go/BUILD.bazel`](../../../go/BUILD.bazel) does not earn a `.bzl`, because it is shared within a single file, where a
56+
local variable does the job.
5757

5858
Macros here are typically a thin public wrapper around a private rule (`codeql_csharp_binary`, `swift_cc_binary`). Keep
59-
the rule narrow and the ergonomics in the macro. Each macro decorates the caller's `name` to mint its helper targets
60-
(`internal/<name>`, `single_arch/<name>`, `bin/<name>`), but the visibility they get is that macro's choice — private,
61-
package default, or the caller's own — so read it instead of assuming. When an error names a target you cannot find in
62-
any source file, a macro minted it — grep the suffix under `misc/bazel/`.
59+
the rule narrow and the ergonomics in the macro. Each macro decorates the caller's `name` to mint its helper targets,
60+
for example `internal/<name>` or `single_arch/<name>`. Their visibility is that macro's choice (private, package
61+
default, or the caller's own), so read the macro instead of assuming. When an error names a target you cannot find in
62+
any source file, a macro minted it: grep the suffix under `misc/bazel/`.
6363

6464
## Shared helpers
6565

@@ -74,16 +74,15 @@ Frequently-used pieces, so you load the existing one instead of rewriting it. Re
7474
| `//misc/bazel:csharp.bzl` | C# binary/library/test wrappers |
7575
| `//misc/bazel:utils.bzl` | `select_os`; prefer `os.bzl`'s `os_select` in new code |
7676

77-
[`defs.bzl`](../../../defs.bzl) at the root exports `codeql_platform` for *dependent* modules — nothing in this repo
78-
loads it, and it is not the way to get the platform string here (use `os.bzl`).
77+
[`defs.bzl`](../../../defs.bzl) at the root exports `codeql_platform` for *dependent* modules. It is not the way to get
78+
the platform string here; use `os.bzl`.
7979

8080
## Platform selection
8181

82-
`codeql_platform_select` discriminates the four platforms CodeQL knows about: `linux64`, `linux_arm64`, `osx64`,
83-
`win64`. `otherwise` supplies the value for whichever of those four you leave unset — it is **not** a
84-
`//conditions:default`. **There is deliberately no fallback from `linux_arm64` to `linux64`**; if you only care about
85-
the OS, use `os_select`, which gives Linux the same value on both architectures and has a `posix` shorthand for the
86-
shared Linux/macOS value.
82+
`codeql_platform_select` discriminates the platforms CodeQL knows about: `linux64`, `linux_arm64`, `osx64` and `win64`.
83+
`otherwise` supplies the value for whichever of those you leave unset; it is **not** a `//conditions:default`. **There
84+
is deliberately no fallback from `linux_arm64` to `linux64`.** If you only care about the OS, use `os_select`, which
85+
gives Linux the same value on both architectures and has a `posix` shorthand for the shared Linux/macOS value.
8786

8887
In a macro (no `ctx`) it returns a `select()`:
8988

@@ -102,7 +101,7 @@ codeql_pkg_files(
102101
```
103102

104103
If implementation code needs to *branch* on the value rather than pass it through, pass `ctx` and add
105-
`OS_DETECTION_ATTRS` to the rule's attributes — the value is then resolved eagerly instead of being an opaque `select()`:
104+
`OS_DETECTION_ATTRS` to the rule's attributes. The value is then resolved eagerly instead of being an opaque `select()`:
106105

107106
```python
108107
load("//misc/bazel:os.bzl", "OS_DETECTION_ATTRS", "os_select")
@@ -119,15 +118,15 @@ my_rule = rule(
119118

120119
## Packs
121120

122-
A pack is the unit that becomes an extractor pack. See [`unified/BUILD.bazel`](../../../unified/BUILD.bazel) for a
123-
minimal complete example and [`pkg.bzl`](../../../misc/bazel/pkg.bzl) for the arguments. The non-obvious parts:
121+
`codeql_pack` assembles the files that become an extractor pack. See [`unified/BUILD.bazel`](../../../unified/BUILD.bazel)
122+
for a minimal complete example and [`pkg.bzl`](../../../misc/bazel/pkg.bzl) for the arguments. The non-obvious parts:
124123

125124
* **`{CODEQL_PLATFORM}` in a destination path is the routing mechanism**, not just a substitution. A path containing it
126125
is *arch-specific* and lands in the per-architecture zip; every other path is *common*. So `prefix =
127126
"tools/{CODEQL_PLATFORM}"` both places the file and marks it arch-specific. `arch_overrides` forces named
128127
destinations into the arch-specific part without a placeholder.
129128
* **`codeql_pkg_files` splits `srcs` (plain) from `exes` (mode 755)** and **rejects `attributes =`** with an explicit
130-
error — use `exes` rather than hand-rolling `pkg_attributes(mode = "755")`.
129+
error. Use `exes` rather than hand-rolling `pkg_attributes(mode = "755")`.
131130
* **`pkg_dirs` and `pkg_symlinks` are unsupported** and fail at analysis time.
132131
* `codeql_pack` also generates an installer and an `install` alias, hence `bazel run //unified:install`. Pass
133132
`installer_alias = None` if one package defines several packs.
@@ -137,23 +136,22 @@ minimal complete example and [`pkg.bzl`](../../../misc/bazel/pkg.bzl) for the ar
137136

138137
In order of preference:
139138

140-
1. **A [Bazel Central Registry](https://registry.bazel.build/) module** — a `bazel_dep` in
139+
1. **A [Bazel Central Registry](https://registry.bazel.build/) module.** Add a `bazel_dep` in
141140
[`MODULE.bazel`](../../../MODULE.bazel).
142-
2. **A patched upstream module** — add it under
143-
[`misc/bazel/registry`](../../../misc/bazel/registry), which `.bazelrc` puts ahead of the BCR. Put patches in
144-
`modules/<repo>/<version>/patches`, rename the version with a `-codeql.N` suffix, and run
145-
[`fix.py`](../../../misc/bazel/registry/fix.py) to realign the metadata.
146-
3. **A raw archive** — `http_archive` via `use_repo_rule`, or a repository rule. Copy an adjacent declaration and keep
147-
its checksum field populated.
148-
149-
Vendored Rust crates under [`misc/bazel/3rdparty`](../../../misc/bazel/3rdparty) are generated — regenerate with
141+
2. **A patched upstream module.** Add it under [`misc/bazel/registry`](../../../misc/bazel/registry), which `.bazelrc`
142+
puts ahead of the BCR. Put patches in `modules/<repo>/<version>/patches`, rename the version with a `-codeql.N`
143+
suffix, and run [`fix.py`](../../../misc/bazel/registry/fix.py) to realign the metadata.
144+
3. **A raw archive.** Use `http_archive` via `use_repo_rule`, or a repository rule. Copy an adjacent declaration and
145+
keep its checksum field populated.
146+
147+
Vendored Rust crates under [`misc/bazel/3rdparty`](../../../misc/bazel/3rdparty) are generated. Regenerate with
150148
`update_cargo_deps.sh` rather than editing, and keep the `use_repo` lists in sync (`bazel mod tidy` handles several).
151149

152150
## Building standalone
153151

154152
[`MODULE.bazel`](../../../MODULE.bazel) declares `semmle_code` with a `local_path_override` pointing at `..`, which
155-
resolves when this repo is checked out inside the internal module. [`.bazelrc`](../../../.bazelrc) — read when Bazel is
156-
invoked in *this* workspace — overrides that with a stub, and this line is the whole reason a standalone build resolves:
153+
resolves when this repo is checked out inside the internal module. [`.bazelrc`](../../../.bazelrc), which Bazel reads
154+
when invoked in *this* workspace, overrides that with a stub. This line is the whole reason a standalone build resolves:
157155

158156
```
159157
common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
@@ -165,7 +163,7 @@ Do not change either the override path or the `local_path_override`; they work a
165163
versions of the internal helpers that shared `.bzl` files load *unconditionally*. That is its only job, and it is small
166164
enough to read.
167165

168-
**Extend the stub only when a `.bzl` file every standalone target loads gains a new internal `load()`** — that breaks
166+
**Extend the stub only when a `.bzl` file every standalone target loads gains a new internal `load()`**, which breaks
169167
package loading outright, for everyone. Prefer not needing one. **Never add a stub so that an internal-only target
170168
appears to build**: some targets depend on internal libraries (`grep -rl @semmle_code --include=*.bazel` finds them) and
171169
are correctly unbuildable here. Unlike a `load()`, such a dependency only fails when that target is actually requested.

0 commit comments

Comments
 (0)