aspect lint runs one or more aspect_rules_lint aspects as a Bazel build, reads the SARIF diagnostics they produce, and decides whether to fail the CI step based on which findings are in scope. It posts inline review comments on the diff through the GithubLintComments (GitHub) and GitlabLintComments (GitLab) features.
aspect lint doesn’t implement linting itself. It drives Bazel, which caches lint results like any other action: a file that hasn’t changed gets its lint result from the remote cache instead of running the linter again, so aspect lint //... re-lints only what changed.
Hold-the-line strategy
The default strategy,hold-the-line, makes lint practical on a large codebase that already has violations. Instead of failing on any finding anywhere, it:
- Finds the change’s changed lines, with
git diffor, as a fallback, the GitHub PR Files API. - Fails only on error-severity findings inside the diff hunks the change touched.
Configuration
Lint aspects
aspect lint needs at least one aspect_rules_lint aspect, from --aspect, Bazel’s own --aspects flag, or a --config in your .bazelrc:
config.axl so developers running aspect lint //... locally use the same set as CI:
.aspect/config.axl
config.axl, so a CI job that needs only the fast linters can pass its own --aspect.
Apply auto-fix patches
Some rules_lint linters produce fix patches. Pass--fix to apply them to the working tree:
--fix the patches are still produced for the features that use them, such as review-comment suggestions, and aren’t applied locally.
Base ref
The changed lines are diffed against the merge base with--base-ref. When it’s empty, the base comes from the CI environment (GITHUB_BASE_REF, BUILDKITE_PULL_REQUEST_BASE_BRANCH or CI_MERGE_REQUEST_TARGET_BRANCH_NAME), then the remote’s default branch, then origin/main. --merge-base=<sha> pins an explicit commit instead.
Options
It also takes the Bazel flag options common to every task that runs Bazel (
--bazel-flag, --bazel-startup-flag, --announce-bazel-*, --bes-backend, --bes-header); see aspect run.
GitHub PR annotations
GithubLintComments posts auto-fix suggestions as inline review comments on the diff line, as one-click Commit suggestion buttons. By default other findings appear as check-run annotations; set findings_destination to comments (below) to post every finding as a comment.
It needs the Aspect Workflows GitHub App and an Aspect credential. Cap the comments per run with --github-lint-comments:max-pr-comments=<n> (default 25).
GitLab MR comments
GitlabLintComments is the GitLab counterpart. It posts each finding as a discussion on the merge request diff, so reviewers see it inline in the Changes view. It needs the Aspect Workflows GitLab App and ASPECT_API_TOKEN, and posts only on merge request pipelines.
It differs from the GitHub feature:
- Suggestion blocks: auto-fix patches render as GitLab
```suggestionblocks that reviewers apply with one click. - Dedup across runs: re-running the lint task replaces a stale discussion at the same position instead of adding a duplicate.
- Thread auto-resolve: on a clean pass, discussions Aspect opened on earlier runs are marked Resolved rather than deleted, which keeps the review history. GitHub review comments have no resolve, so the GitHub feature deletes them instead.
--gitlab-lint-comments:max-pr-comments=<n> (default 25; 0 posts none). Errors are posted first, then warnings, then notes; findings past the cap are left off the MR but still count toward the lint result.
Routing findings: findings_destination
Where findings land is set by LintTrait.findings_destination, which both the GitHub and GitLab features read. The default, auto, posts auto-fix suggestions as inline comments and other findings as check-run annotations on GitHub. GitLab has no per-finding annotation surface, so there auto posts only the auto-fix suggestions.
To post every finding as an inline comment (recommended on GitLab, so non-fix findings show up too), set it to comments:
.aspect/config.axl
The config hook must be named
config (def config(ctx: ConfigContext):).
The CLI doesn’t call a function named configure.How it works
aspect lint reads two output groups from aspect_rules_lint:
rules_lint_machine: SARIF and per-target exit codes, used for the verdict and for posting findings.rules_lint_human: colored terminal output, streamed to your terminal.
- Reads every diagnostic from every SARIF file.
- Computes the change’s changed lines.
- Filters diagnostics by the strategy.
hold-the-linekeeps findings inside the displayed diff hunks, changed lines plus their surrounding context. - Posts the remaining findings, through
GithubLintCommentson GitHub orGitlabLintCommentson GitLab. - Exits 1 if any remaining finding is error severity, otherwise 0.
CI example
.github/workflows/lint.yaml

