Skip to main content
Rosetta’s 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-defined gazelle.check target (default //:gazelle.check) and looked at its exit code + stderr.
  • configure: ran the legacy aspect-cli’s built-in bazel configure command, which embedded a prebuilt gazelle binary inside the CLI itself. No //tools/gazelle target was required because the binary shipped with the CLI.
Both migrate to aspect gazelle. The new task needs a //tools/gazelle:gazelle target wired to aspect_gazelle_prebuilt; see Setup.

Setup

Add aspect_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.
If you’d rather build gazelle from source (upstream 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 every aspect gazelle invocation picks it up. Good for settings that should apply to all invocations of a task type.
Pick whichever fits; you only need one. Where both work, the sections below show them side-by-side under After.

Scope and change detection

Nothing in Rosetta corresponds to these; they are how aspect 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:
After: CLI flag or config.axl:
The default gazelle target moved from //:gazelle.check to //tools/gazelle:gazelle:
  • Out of the root package. Defining gazelle() at //tools/gazelle instead of //:gazelle.check keeps the gazelle load(…) out of your root BUILD.bazel, so commands that touch the root package don’t fetch and analyze gazelle-only machinery.
  • No more .check suffix. The task drives gazelle in -mode=diff at runtime via a flag override, so a single target works for both apply and check semantics.
If you relied on the legacy default and your 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:
and relied on the legacy aspect-cli’s built-in gazelle, the migration is to add an 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-running bazel 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:
Why the default differs by host: locally, 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:
Most repos can leave this unset. Use --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):
This is useful for:
  • -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.
Note: flags specific to 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:
In .aspect/config.axl, set dirs as a list:
When no directories are specified (the default), gazelle walks the entire repo from the workspace root, matching the legacy behavior.

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 a gazelle.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:
After: CI configuration: