> ## 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.

# Build Results UI repository setup

> Set the build metadata keys the Aspect Workflows Build Results UI reads, and the Bazel flags that populate its Timing, Artifacts, and dependency views.

export const gatedAccess = (user, group) => {
  const loggedIn = !!(user && user.loggedIn);
  const groups = user && user.tenantMetadata && user.tenantMetadata.docsGroups || [];
  if (loggedIn && (!group || groups.indexOf(group) >= 0)) {
    return "entitled";
  }
  return loggedIn ? "signed-in" : "anonymous";
};

export const GatedLink = ({access, href, group, children}) => {
  const note = group ? "Aspect Enterprise customers" : "free Aspect account";
  const muted = {
    fontSize: "0.85em",
    opacity: 0.7,
    whiteSpace: "nowrap"
  };
  if (access === "entitled") {
    return <a href={href}>{children}</a>;
  }
  if (access !== "signed-in") {
    return <span>
        <a href={"/login?redirect=" + encodeURIComponent(href)}>{children}</a>
        <span style={muted}> (sign in: {note})</span>
      </span>;
  }
  return <span>
      {children}
      <span style={muted}> ({note})</span>
    </span>;
};

The Build Results UI reads build metadata to label each invocation, and Bazel flags decide how much of the profile, artifacts, and execution log reach it. Both live in your repository, the same on Aspect Cloud and Aspect Enterprise.

## Build metadata

The Build Results UI reads specific metadata keys to fill fields such as **Branch**, **Author**, **Task**, and **CI Host**, and the matching feed filters.

Aspect CLI tasks and Aspect Workflows CI runners set most of these automatically. For vanilla `bazel`, the quickest setup is to have the Aspect CLI print them. Add one line to your `.bazelrc`:

```bazel title=".bazelrc" theme={null}
build --workspace_status_command="aspect setup workspace-data"
```

If you already have a workspace status script, call it from inside that script instead, since Bazel takes one status command:

```bash theme={null}
if command -v aspect > /dev/null 2>&1; then
  aspect setup workspace-data
fi
```

It reads the commit, branch, pull request, actor, repository and CI run from the environment and prints the matching keys. See [`aspect setup workspace-data`](/docs/cli/tasks/setup_workspace_data) for the keys it emits and how it composes with your own.

To set the keys yourself, without the Aspect CLI or for keys it doesn't cover, use Bazel's
[--build\_metadata](https://bazel.build/reference/command-line-reference#common_options-flag--build_metadata)
or
[--workspace\_status\_command](https://bazel.build/reference/command-line-reference#build-flag--workspace_status_command)
flags. The UI reads a key from either source.

### Recommended keys

| Key                     | Description                                                                                                                                                        |
| :---------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ASPECT_TASK_NAME`      | The name of the Aspect CLI task. Outside a task, use the Bazel command you ran.                                                                                    |
| `ASPECT_TASK_ID`        | The unique identifier of the Aspect CLI task. Outside a task, use the Bazel command you ran.                                                                       |
| `ASPECT_TASK_URL`       | A link to the Aspect CLI task's CI job. Outside a task, link to the build you ran.                                                                                 |
| `USER`                  | The user or entity that initiated the build.                                                                                                                       |
| `BRANCH_NAME`           | The git branch name.                                                                                                                                               |
| `REPO_NAME`             | The name of the git repository.                                                                                                                                    |
| `REPO_OWNER`            | The owner/organization of the git repository.                                                                                                                      |
| `COMMIT_SHA`            | The full commit hash.                                                                                                                                              |
| `COMMIT_MESSAGE`        | The commit message.                                                                                                                                                |
| `COMMIT_AUTHOR_NAME`    | The git commit author name.                                                                                                                                        |
| `COMMIT_AUTHOR_EMAIL`   | The git commit author email.                                                                                                                                       |
| `COMMIT_AUTHOR`         | The git commit author information. Often formatted from git as: `Some User <user@company.email>`.                                                                  |
| `VCS`                   | The version control system being used. Valid options are: `GITHUB`, `GITLAB`                                                                                       |
| `CI_HOST`               | The CI provider. Valid options are: `BUILDKITE`, `CIRCLE_CI`, `GITHUB_ACTIONS`, `GITLAB`.                                                                          |
| `RUN_TYPE`              | The type of CI run. If it's unset, the UI treats the build as a local Bazel build. Valid options are: `PULL_REQUEST`, `BRANCH_PUSH`, `TAG`, `SCHEDULED`, `MANUAL`. |
| `BUILD_URL`             | A link to the CI build (if applicable).                                                                                                                            |
| `COMMIT_TAG`            | The git tag that caused a CI run (if applicable). Aspect CLI tasks record the tag as `TAG`, which the UI doesn't read, so set `COMMIT_TAG` yourself to show it.    |
| `PR_NUMBER`             | The Pull Request number (if applicable).                                                                                                                           |
| `PR_ID`                 | The Pull Request id (if applicable).                                                                                                                               |
| `PR_SOURCE_BRANCH_NAME` | The source branch from a given pull request (if applicable).                                                                                                       |
| `PR_TARGET_BRANCH_NAME` | The target branch from a given pull request (if applicable).                                                                                                       |

### Workspace status command

To set other keys, or to work without the Aspect CLI, write a `--workspace_status_command` script that generates them from your CI environment variables.

Create a script:

```bash workspace_status.sh theme={null}
#!/usr/bin/env bash
echo ASPECT_TASK_NAME "Test"
echo ASPECT_TASK_ID "test"
echo ASPECT_TASK_URL "https://ci.example.com/builds/123"
echo USER "First Last"
echo BRANCH_NAME "feature/some-branch"
echo REPO_NAME "some-repo"
echo REPO_OWNER "some-org"
echo COMMIT_SHA "b6d171bbcfb54c77ce5fc165b778d2c25bbef87b"
echo COMMIT_MESSAGE "feat: some awesome change"
echo COMMIT_AUTHOR_NAME "Some User"
echo COMMIT_AUTHOR_EMAIL "user@company.email"
echo COMMIT_AUTHOR "Some User <user@company.email>"
echo VCS "GITHUB"
echo CI_HOST "BUILDKITE"
echo RUN_TYPE "PULL_REQUEST"
echo BUILD_URL "https://ci.example.com/builds/123"
echo PR_NUMBER "456"
echo PR_ID "456"
echo PR_SOURCE_BRANCH_NAME "feature/some-source-branch"
echo PR_TARGET_BRANCH_NAME "feature/some-target-branch"
```

Configure Bazel to use this script in your `.bazelrc` or specify it via the command line:

```bash theme={null}
bazel build //... --workspace_status_command=./workspace_status.sh
```

### Build metadata flags

Set the same keys with `--build_metadata` flags instead of, or alongside, a workspace status script.

```bash theme={null}
bazel build //... \
  --build_metadata="ASPECT_TASK_NAME=Test" \
  --build_metadata="ASPECT_TASK_ID=test" \
  --build_metadata="ASPECT_TASK_URL=https://ci.example.com/builds/123" \
  --build_metadata="USER=First Last" \
  --build_metadata="BRANCH_NAME=feature/my-branch" \
  --build_metadata="REPO_NAME=some-repo" \
  --build_metadata="REPO_OWNER=some-org" \
  --build_metadata="COMMIT_SHA=b6d171bbcfb54c77ce5fc165b778d2c25bbef87b" \
  --build_metadata="COMMIT_MESSAGE=feat: some awesome change" \
  --build_metadata="COMMIT_AUTHOR_NAME=Some User" \
  --build_metadata="COMMIT_AUTHOR_EMAIL=user@company.email" \
  --build_metadata="COMMIT_AUTHOR=Some User <user@company.email>" \
  --build_metadata="VCS=GITHUB" \
  --build_metadata="CI_HOST=BUILDKITE" \
  --build_metadata="RUN_TYPE=PULL_REQUEST" \
  --build_metadata="BUILD_URL=https://ci.example.com/builds/123" \
  --build_metadata="PR_NUMBER=456" \
  --build_metadata="PR_ID=456" \
  --build_metadata="PR_SOURCE_BRANCH_NAME=feature/some-source-branch" \
  --build_metadata="PR_TARGET_BRANCH_NAME=feature/some-target-branch"
```

### Aspect CLI tasks

Aspect CLI tasks set the `ASPECT_TASK_*` keys themselves. To change the task name the UI shows,
pass [`--task:name` or `--task:friendly-name`](/docs/cli/tasks) to the task. To add another key to every task's
invocations, append a `--build_metadata` flag in `config.axl`, as in the `ALLOW_ENV` example below.

### Redacted environment variables

The Build Results UI redacts environment variables in the command line and options it displays, since flags can carry secrets.
To display specific variables, list them in the `ALLOW_ENV` key.

Set the key in your workspace status script or with a build metadata flag. The value is a comma-separated list of environment variable names or patterns. If both set it, the build metadata value wins.

#### Example using build metadata

```bash theme={null}
bazel build //... --build_metadata="ALLOW_ENV=USER,PATH,TZ,LANG,LC_*,BAZEL_*,RUST_*,JAVA_*"
```

#### Example using workspace status

```bash theme={null}
#!/usr/bin/env bash
# ... other status variables ...
echo ALLOW_ENV "USER,PATH,TZ,LANG,LC_*,BAZEL_*,RUST_*,JAVA_*"
```

#### Example using config.axl

```python .aspect/config.axl theme={null}
load("@aspect//traits.axl", "BazelTrait")

def config(ctx: ConfigContext):
    ctx.traits[BazelTrait].extra_flags.extend([
        "--build_metadata=ALLOW_ENV=USER,PATH,TZ,LANG,LC_*,BAZEL_*,RUST_*,JAVA_*",
    ])
```

## Bazel flags for the deeper views

Bazel's defaults omit much of the data the Build Results UI's deeper views are
built from. The profile is slimmed and has no target labels, artifact listings
come back empty, and the execution log, the source for per-target dependencies,
is never produced.

Enable the following flags to populate the Timing tab's profile views, the
Artifacts tab, and target dependency expansion. The execution log and profile
reach the UI through the remote cache, so the build also needs a gRPC
`--remote_cache`.

<Note>
  **Workflows 6.0 or later is required.** On 5.18 the flags are harmless but have
  nothing to populate: the legacy UI has no Artifacts tab or dependency expansion.
  See the <GatedLink access={gatedAccess(user, "workflows-subscriber")} href="/docs/aspect-workflows/enterprise/release-notes/6_0_upgrade" group="workflows-subscriber">6.0 upgrade guide</GatedLink>.
</Note>

| Flag                                                  | What it enables in the UI                                                                                                                                                              | Overhead                                                                                                                            |
| :---------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- |
| `--profile=command.profile.gz`                        | Pins the profile's file name to the one the UI ingests.                                                                                                                                | None.                                                                                                                               |
| `--noslim_profile`                                    | The complete build profile. By default Bazel slims the profile, merging or dropping short actions, which hides the true critical path.                                                 | Minor. Produces a larger profile file.                                                                                              |
| `--experimental_profile_include_target_label`         | Target labels on profile actions, so the timeline maps back to the targets that produced it.                                                                                           | Minor.                                                                                                                              |
| `--experimental_profile_include_primary_output`       | The primary output path on each profile action, so an entry names the file it produced.                                                                                                | Minor.                                                                                                                              |
| `--experimental_profile_include_target_configuration` | The configuration each profile action was built in.                                                                                                                                    | Minor.                                                                                                                              |
| `--execution_log_compact_file=exec.log.zst`           | Expandable per-target dependencies, and the remote cache hit rate on the Cache tab. Without it, a target's dependencies stay empty. The compact format is the only one the UI ingests. | Writes one zstd-compressed execution log per invocation.                                                                            |
| `--remote_build_event_upload=all`                     | Uploads every file the BEP references, not just the remotely cacheable ones, so the UI can serve them.                                                                                 | Additional CAS uploads.                                                                                                             |
| `--experimental_build_event_upload_strategy=remote`   | Uploads BEP-referenced files to the remote CAS and references them from the event stream, which is how the execution log reaches the UI.                                               | Shifts upload work to the CAS and keeps the BEP itself small.                                                                       |
| `--legacy_important_outputs`                          | The **Artifacts** tab and artifact downloads. A modern Bazel client omits `important_outputs` from the BEP, so the tab is otherwise empty.                                             | The largest of the set: it re-inflates `important_outputs` on every target-complete event. Leave it off if BEP volume is a concern. |

<Note>
  On a self-hosted Aspect Enterprise deployment, the <strong>Artifacts</strong> tab can list a target's full
  output set instead of its important outputs, which is a deployment setting. See
  <GatedLink access={gatedAccess(user, "workflows-subscriber")} href="/docs/aspect-workflows/enterprise/self-hosted/configuration/webui#artifacts-tab-output-sets" group="workflows-subscriber">Build Results UI configuration</GatedLink>.
</Note>

### Using `.bazelrc`

Add the flags to your workspace `.bazelrc`. Scoping them to a `ci` config keeps
the extra profiling work off local developer builds:

```bash title=".bazelrc" theme={null}
common:ci --profile=command.profile.gz
common:ci --noslim_profile
common:ci --experimental_profile_include_target_label
common:ci --experimental_profile_include_primary_output
common:ci --experimental_profile_include_target_configuration
common:ci --execution_log_compact_file=exec.log.zst
common:ci --remote_build_event_upload=all
common:ci --experimental_build_event_upload_strategy=remote
common:ci --legacy_important_outputs
```

Then pass `--config=ci` on CI invocations. To apply the flags everywhere,
including local builds, drop the `:ci` suffix and use plain `common` lines.

### Using `.aspect/config.axl`

If you use the Aspect CLI, set the flags in `.aspect/config.axl` instead. This
applies them only when the `CI` environment variable is set, so no `--config=ci`
plumbing is needed in your pipeline:

```python title=".aspect/config.axl" theme={null}
load("@aspect//traits.axl", "BazelTrait")

def config(ctx: ConfigContext):
    is_ci = bool(ctx.std.env.var("CI"))
    if is_ci:
        ctx.traits[BazelTrait].extra_flags.extend([
            "--profile=command.profile.gz",
            "--noslim_profile",
            "--experimental_profile_include_target_label",
            "--experimental_profile_include_primary_output",
            "--experimental_profile_include_target_configuration",
            "--execution_log_compact_file=exec.log.zst",
            "--remote_build_event_upload=all",
            "--experimental_build_event_upload_strategy=remote",
            "--legacy_important_outputs",
        ])
```

### Measuring the overhead

The cost of these flags depends on the shape of your build: the number of
targets, the size of the output set, and how much of the build is already cached.
Enable them on a branch and use the UI's **Compare** page to measure two runs of
the same task against each other. If the overhead is too high, drop
`--legacy_important_outputs` first. The profiling flags are the cheapest to keep.
