> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Built-in features reference

> Reference for the Aspect CLI's built-in features: what each one does, its flags and defaults, and how to set them per invocation or per repository.

A feature is behavior that applies across tasks rather than belonging to one: status checks, artifact upload, the remote cache connection. The built-in `@aspect` module registers the features on this page, and every one is enabled by default. Most act only where they apply, such as `BuildkiteAnnotations` on Buildkite, and the upload features upload nothing until you choose what.

Run `aspect feature` to list the features active in your repository, and `aspect feature <name>` to print one feature's flags.

## Setting a feature's options

Every option has a command-line flag, `--<feature>:<option>`, that applies to one invocation:

```shell theme={null}
aspect test --artifact-upload:upload-test-logs=failed //...
aspect build --workflows:remote-exec //...
```

Set it for every invocation in `.aspect/config.axl` through `ctx.features`, using the option's underscore name:

```python title=".aspect/config.axl" theme={null}
load("@aspect//feature/artifacts.axl", "ArtifactUpload")
load("@aspect//feature/workflows.axl", "Workflows")

def config(ctx: ConfigContext):
    ctx.features[ArtifactUpload].args.upload_test_logs = "failed"
    ctx.features[Workflows].args.remote_exec = True
```

Turn a feature off with `--<feature>:enabled=false`, or `ctx.features[<Feature>].enabled = False` in `config.axl`.

Each feature loads from `@aspect//feature/<file>.axl`:

| Feature                | Load from                                     | Flag prefix                 |
| ---------------------- | --------------------------------------------- | --------------------------- |
| `ArtifactUpload`       | `@aspect//feature/artifacts.axl`              | `--artifact-upload:`        |
| `BazelFlags`           | `@aspect//feature/bazel_flags.axl`            | `--bazel-flags:`            |
| `BuildkiteAnnotations` | `@aspect//feature/buildkite_annotations.axl`  | `--buildkite-annotations:`  |
| `CircleCITestResults`  | `@aspect//feature/circleci_test_results.axl`  | `--circle-ci-test-results:` |
| `Deployment`           | `@aspect//feature/deployment.axl`             | `--deployment`, `--remote`  |
| `GithubLintComments`   | `@aspect//feature/github_lint_comments.axl`   | `--github-lint-comments:`   |
| `GithubStatusChecks`   | `@aspect//feature/github_status_checks.axl`   | `--github-status-checks:`   |
| `GithubStatusComments` | `@aspect//feature/github_status_comments.axl` | `--github-status-comments:` |
| `GitlabCommitStatuses` | `@aspect//feature/gitlab_commit_statuses.axl` | `--gitlab-commit-statuses:` |
| `GitlabLintComments`   | `@aspect//feature/gitlab_lint_comments.axl`   | `--gitlab-lint-comments:`   |
| `GitlabStatusComments` | `@aspect//feature/gitlab_status_comments.axl` | `--gitlab-status-comments:` |
| `Telemetry`            | `@aspect//feature/telemetry.axl`              | `--telemetry:`              |
| `Tips`                 | `@aspect//feature/tips.axl`                   | `--tips:`                   |
| `Workflows`            | `@aspect//feature/workflows.axl`              | `--workflows:`              |

## ArtifactUpload

Uploads build outputs to your CI provider's artifact storage: GitHub Actions, Buildkite, CircleCI or GitLab. Everything is off by default, because artifacts are visible to anyone with access to the repository's CI.

| Option              | Default | Values                                                                                                                                    |
| ------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `upload_test_logs`  | `none`  | `none`, `failed` (non-passing tests), `executed` (skips cached passes), `all`                                                             |
| `upload_build_logs` | `none`  | `none`, `failed` (stdout and stderr of every failed build action)                                                                         |
| `upload_profile`    | `False` | Bazel's JSON trace profile                                                                                                                |
| `upload_bep`        | `False` | The Build Event Protocol file, redacted at the source                                                                                     |
| `upload_exec_log`   | `False` | The compact execution log. It holds action environment variables and command lines, so enable it only where artifact access is controlled |

See [Artifact upload](/docs/cli/tasks/build_test#artifact-upload) for what each artifact is for.

## BazelFlags

Removes flags that Aspect would otherwise add to a task's Bazel call. It never touches flags you pass yourself.

| Option | Default | What it does                                                                                                             |
| ------ | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `omit` | none    | A flag to drop, named as Aspect spells it (`--bazel-flags:omit=--heap_dump_on_oom`). Any `=value` is ignored. Repeatable |

Endpoints, credentials and the runner's output paths can't be omitted. The rc that [`aspect setup bazelrc`](/docs/cli/tasks/setup_bazelrc) writes has its own `--omit-bazel-flag`.

## BuildkiteAnnotations

Posts each task's live status as a Buildkite annotation.

| Option                        | Default   | What it does                                                                                                                         |
| ----------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `mode`                        | `ci-only` | When to annotate: `ci-only`, `local-only` or `always`                                                                                |
| `min_update_interval_seconds` | `5`       | Minimum seconds between live refreshes, at least 1. The final result and phase changes post immediately                              |
| `expand_phases`               | none      | Phase ids (such as `build` or `test`) whose log section starts expanded. CLI flag `--buildkite-annotations:expand-phase`, repeatable |
| `metadata_keys`               | none      | Extra BES `build_metadata` keys to show in the summary. `["*"]` shows all. CLI flag `--buildkite-annotations:metadata-key`           |
| `template_preset`             | `full`    | The template bundle the annotation renders with                                                                                      |
| `templates`                   | `{}`      | Jinja2 overrides for the `title`, `summary` and `details` slots, optionally per task kind. `config.axl` only                         |

## CircleCITestResults

Uploads Bazel's JUnit results to CircleCI's **Tests** tab. Acts only on CircleCI, and uploads nothing until you choose which results.

| Option                | Default | What it does                                                                         |
| --------------------- | ------- | ------------------------------------------------------------------------------------ |
| `upload_test_results` | `none`  | `none`, `failed` (non-passing and flaky), `executed` (skips cached results) or `all` |
| `cached_as_skipped`   | `False` | Report cached tests as skipped instead of passed. Applies only with `all`            |

## Deployment

Connects a task to a deployment's remote cache, build event service and remote execution. Its flags carry no prefix.

| Flag                  | Default                | What it does                                                                                                                                                   |
| --------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--remote`            | `auto`                 | Which endpoints to connect. `auto` is the cache and BES on CI and nothing elsewhere. See [the full `--remote` table](/docs/aspect-workflows/cloud/local-setup) |
| `--deployment <name>` | the default deployment | Which configured deployment to draw endpoints from. Needs `--remote` to say what to connect                                                                    |

On an Aspect Workflows runner the [`Workflows`](#workflows) feature connects the runner's own endpoints, and an explicit `--remote` is refused.

## GithubLintComments

Posts `aspect lint` findings as GitHub pull request review comments, with fix suggestions where the linter provides them. Needs the [Aspect Workflows GitHub App](/docs/cli/authentication-github).

| Option            | Default | What it does                                                                                                                |
| ----------------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `max_pr_comments` | `25`    | Most comments per run. Errors go first, then warnings, then notes. `0` posts none; the lint verdict is unchanged either way |

## GithubStatusChecks

Reports each task's live status as a GitHub check run. Needs the [Aspect Workflows GitHub App](/docs/cli/authentication-github).

| Option                          | Default   | What it does                                                                                                                                                 |
| ------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `mode`                          | `ci-only` | When to post: `ci-only`, `local-only` or `always`                                                                                                            |
| `min_update_interval_seconds`   | `20`      | Minimum seconds between live refreshes on pull request builds. Push builds refresh every 60 seconds. The interval stretches as the GitHub API quota runs low |
| `only_annotate_changed_regions` | `True`    | Limit lint annotations to the changed regions shown in **Files changed**                                                                                     |
| `metadata_keys`                 | none      | Extra BES `build_metadata` keys to show in the summary. `["*"]` shows all. CLI flag `--github-status-checks:metadata-key`                                    |
| `template_preset`               | `full`    | The template bundle the check run renders with                                                                                                               |
| `templates`                     | `{}`      | Jinja2 overrides for the `title`, `summary` and `details` slots, optionally per task kind. `config.axl` only                                                 |

## GithubStatusComments

Keeps one comment on the pull request with every task's live status.

| Option                      | Default   | What it does                                                                     |
| --------------------------- | --------- | -------------------------------------------------------------------------------- |
| `mode`                      | `ci-only` | When to post: `ci-only`, `local-only` or `always`                                |
| `min_poll_interval_seconds` | `20`      | Minimum seconds between comment refreshes. Final results post immediately        |
| `template_preset`           | `full`    | The template bundle the comment renders with                                     |
| `templates`                 | `{}`      | A Jinja2 override for the comment `body`. `config.axl` only                      |
| `status_badges`             | `{}`      | Overrides for the status labels, such as `failed` or `passed`. `config.axl` only |

## GitlabCommitStatuses

Reports each task's live status as a GitLab commit status on merge request pipelines. Needs the [Aspect Workflows GitLab App](/docs/cli/authentication-gitlab).

| Option                        | Default   | What it does                                                                                                          |
| ----------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------- |
| `mode`                        | `ci-only` | When to post: `ci-only`, `local-only` or `always`                                                                     |
| `min_update_interval_seconds` | `20`      | Minimum seconds between live refreshes, at least 1                                                                    |
| `metadata_keys`               | none      | Extra BES `build_metadata` keys passed to the rendered output. CLI flag `--gitlab-commit-statuses:metadata-key`       |
| `template_preset`             | `full`    | The template bundle the status renders with                                                                           |
| `templates`                   | `{}`      | Jinja2 overrides. Only the rendered `title` reaches the commit status, truncated to 255 characters. `config.axl` only |

## GitlabLintComments

Posts `aspect lint` findings as discussions on the merge request diff. Needs the [Aspect Workflows GitLab App](/docs/cli/authentication-gitlab).

| Option            | Default | What it does                                                                                                                   |
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `max_pr_comments` | `25`    | Most discussions per run. Errors go first, then warnings, then notes. `0` posts none; the lint verdict is unchanged either way |

## GitlabStatusComments

Keeps one note on the merge request with every task's live status.

| Option                      | Default   | What it does                                                           |
| --------------------------- | --------- | ---------------------------------------------------------------------- |
| `mode`                      | `ci-only` | When to post: `ci-only`, `local-only` or `always`                      |
| `min_poll_interval_seconds` | `20`      | Minimum seconds between note refreshes. Final results post immediately |
| `template_preset`           | `full`    | The template bundle the note renders with                              |
| `templates`                 | `{}`      | A Jinja2 override for the note `body`. `config.axl` only               |
| `status_badges`             | `{}`      | Overrides for the status labels. `config.axl` only                     |

## Telemetry

Exports the CLI's traces and metrics over OTLP.

| Option               | Default | What it does                                                                          |
| -------------------- | ------- | ------------------------------------------------------------------------------------- |
| `discover_endpoints` | `True`  | Read endpoints from the standard `OTEL_EXPORTER_OTLP_*` environment variables         |
| `endpoint`           | none    | An OTLP endpoint as `URL[;header=value;...]`, over gRPC with every signal. Repeatable |

For per-signal routing or resource attributes, call `ctx.telemetry.exporters.add()` from `config.axl`.

## Tips

Collects and shows short, non-fatal suggestions on each task. See [Add and customize tips](/docs/cli/guides/tips).

| Option       | Default | What it does                                                                          |
| ------------ | ------- | ------------------------------------------------------------------------------------- |
| `silence`    | none    | Tip ids to suppress. Repeatable                                                       |
| `auto_print` | `True`  | Print tips to the terminal. When off, tips still appear on check runs and PR comments |

## Workflows

Configures Bazel for an Aspect Workflows runner: the runner's cache, build event service, output paths and health checks. Off a runner it connects the endpoints an `ASPECT_WORKFLOWS_*` environment names, if any.

On a runner it injects, among others:

* **`--remote_cache`** pointing at the runner's local cache daemon, and the deployment's build event service.
* **`--repository_cache`** on the runner's shared external-repository cache.
* **`--output_base`** / **`--output_user_root`** on the runner's NVMe storage, namespaced per repository so concurrent checkouts don't collide. With [runner warming](/docs/aspect-workflows/enterprise/ci-runners/warming) configured, `--output_user_root` starts pre-warmed.
* **`--disk_cache=`**, turning off any disk cache an rc sets, since the runner's cache covers it.

[`aspect setup bazelrc`](/docs/cli/tasks/setup_bazelrc) writes the same flags to an rc, so vanilla `bazel` on the runner picks them up too.

| Option                       | Default | What it does                                                                                                                                                                                                          |
| ---------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `remote_exec`                | `False` | Run actions on the runner's remote executor. CLI flag `--workflows:remote-exec`. A vanilla `bazel` call opts in with `--config=aspect-exec` instead                                                                   |
| `runner_output_base_suffix`  | empty   | Give this task its own Bazel server by suffixing the runner's `--output_base`, so a task with incompatible flags doesn't discard the shared analysis cache. `--output_user_root` stays shared. No effect off a runner |
| `bes_max_retries`            | `4`     | Reconnect attempts after a transient BES error. `0` turns retries off                                                                                                                                                 |
| `bes_retry_min_delay`        | `1s`    | Base delay for backoff between BES reconnects                                                                                                                                                                         |
| `bes_retry_max_buffer_bytes` | `0`     | Byte budget for unacknowledged BES events kept for replay. `0` uses `ASPECT_CLI_BES_RETRY_MAX_BUFFER_BYTES`, or 256 MiB when that's unset                                                                             |
| `bes_timeout`                | `0s`    | Overall BES upload deadline. `0s` means none                                                                                                                                                                          |

See [Keep incompatible tasks off each other's analysis cache](/docs/cli/tasks-ci#keep-incompatible-tasks-off-each-others-analysis-cache) for when to set `runner_output_base_suffix`.

### Opting in to remote execution

Which flag turns on remote execution depends on where the call runs:

| Where                                                                                   | Flag                                                               |
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| An `aspect` task on an Aspect Workflows runner                                          | `--workflows:remote-exec` (`--remote` is refused there)            |
| An `aspect` task anywhere else                                                          | `--remote=exec`, with `--deployment <name>` to pick the deployment |
| Vanilla `bazel` on a runner                                                             | `--config=aspect-exec`                                             |
| Vanilla `bazel` with an rc from [`aspect setup bazelrc`](/docs/cli/tasks/setup_bazelrc) | `--config=aspect-<name>-exec`                                      |
