gazelle task (Workflows 5.x) ran a bazel-gazelle .check target against the repo and annotated the build with the produced diff if BUILD files were out of date. aspect gazelle replaces it, and also subsumes the older configure task (see below).
aspect gazelle builds your gazelle target and runs it once with -mode=diff to capture the unified diff that gazelle would produce. From there:
- Apply mode (default off CI): the captured diff is applied to your working tree via
git apply -p0. - Check mode (
--check-only=true, default on CI): the diff is reported without modifying the tree.
--check-only defaults to auto, which picks check mode on a recognized CI host and apply mode elsewhere. A non-empty diff is a “BUILD files out of date” verdict, and --severity decides what that verdict does: its default, auto, fails the task on CI and reports it as info off CI.
Two legacy tasks, one new task
Rosetta had two different YAML tasks that both produced “BUILD files are out of date” verdicts:gazelle: ran a user-definedgazelle.checktarget (default//:gazelle.check) and looked at its exit code + stderr.configure: ran the legacy aspect-cli’s built-inbazel configurecommand, which embedded a prebuilt gazelle binary inside the CLI itself. No//tools/gazelletarget was required because the binary shipped with the CLI.
aspect gazelle. The new task needs a //tools/gazelle:gazelle target wired to aspect_gazelle_prebuilt; see Setup.
Setup
Addaspect_gazelle_prebuilt to MODULE.bazel and define a gazelle target. We recommend the prebuilt binary (no Go toolchain required); see the aspect-gazelle release notes for the latest version.
bazel-contrib/bazel-gazelle macro + a Go toolchain), aspect gazelle works against that too.
What changed
Configuration
Most settings below can be applied either way:- CLI flag: pass the flag at invocation time (e.g.
aspect gazelle --check-only=true). Good for overrides on individual task invocations, or experimenting with a setting before committing it. .aspect/config.axl: declare it once in your repo’s AXL config so everyaspect gazelleinvocation picks it up. Good for settings that should apply to all invocations of a task type.
Scope and change detection
Nothing in Rosetta corresponds to these; they are howaspect gazelle keeps a CI run proportional to the change. aspect gazelle --scope=changed is the headline CI behavior.
See change detection for how a base is resolved and what happens when it can’t be.
Gazelle target
Before:.aspect/workflows/config.yaml:
config.axl:
The default gazelle target moved from
//:gazelle.check to //tools/gazelle:gazelle:- Out of the root package. Defining
gazelle()at//tools/gazelleinstead of//:gazelle.checkkeeps the gazelleload(…)out of your rootBUILD.bazel, so commands that touch the root package don’t fetch and analyze gazelle-only machinery. - No more
.checksuffix. The task drives gazelle in-mode=diffat runtime via a flag override, so a single target works for both apply and check semantics.
gazelle.check target lives at the root, point —gazelle-target at the apply target (//:gazelle, not //:gazelle.check). Or migrate the BUILD file to tools/gazelle/BUILD to match the new default (see Setup).Migrating from the configure task
If your repo previously had:
aspect_gazelle target backed by aspect_gazelle_prebuilt at //tools/gazelle:gazelle (see Setup) and switch to aspect gazelle. aspect_gazelle_prebuilt fetches a prebuilt gazelle binary, so you keep configure’s “no Go toolchain, no build-from-source” benefit. Once that’s wired up, aspect gazelle on CI is the direct replacement for rosetta run configure.
Mode: apply vs. check
Before: both legacy tasks always ran in diff-only mode. The user fixed any reported issues by re-runningbazel run :gazelle (for the gazelle task) or bazel configure (for configure).
After: off CI the task applies the diff for you; on CI it matches the legacy diff-only behavior and fails when anything would change:
aspect gazelle and “update my BUILDs” are usually the same intent. CI inverts that, so check mode is the default there.
Gazelle subcommand (fix vs update)
The legacy tasks always ran gazelle without an explicit subcommand (defaulting to update / fix depending on the language plugin). aspect gazelle exposes this as --gazelle-command:
--gazelle-command=fix when you want gazelle to clean up deleted files or apply language-specific migrations on top of normal rule generation.
update-repos isn’t supported here. Run it directly with bazel run //tools/gazelle:gazelle -- update-repos when you need to update Go repository rules.
Passing arbitrary gazelle flags (--gazelle-flag)
--gazelle-flag passes extra flags directly to the gazelle binary (repeatable):
-progress: print progress output (aspect-gazelle prebuilt only).-cache: enable gazelle’s build cache (aspect-gazelle prebuilt only).-r: recurse into subdirectories.- Any other upstream gazelle flag not yet exposed as a first-class task arg.
aspect_gazelle_prebuilt (like -progress and -cache) will cause errors if you’re using a from-source gazelle target that doesn’t recognize them. Don’t set those in config.axl if your target may vary.
Any -mode/--mode flag passed via --gazelle-flag is ignored; the task controls the mode.
Limiting scope with directories
Pass directories as positional arguments after all flags. Gazelle limits its walk to those subtrees:.aspect/config.axl, set dirs as a list:
Diff archival
Before: the legacy tasks attached the diff to a CI annotation (truncated to ~20 lines, with the rest in the terminal-detail block). After: on by default. When BUILD files are out of date on CI, the task uploads the diff as agazelle.patch artifact via the same uploader build/test use for test logs, on GitHub Actions, Buildkite, CircleCI, and GitLab. To turn it off:
Examples
Standard gazelle check on PRs
Before:.aspect/workflows/config.yaml:

