Skip to main content
The Aspect Workflows GitHub App puts live Bazel build and test results on pull requests. Driven by the Aspect CLI, it posts per-task status checks and inline lint comments to your PR as your Bazel build runs. Mechanically, the App is what enables the Aspect API to call GitHub on your behalf. Install it once on your GitHub organization and link it to your Aspect account, and authenticated CLI features (GithubStatusChecks, GithubStatusComments, and GithubLintComments) start posting results to your pull requests. This page covers installing and linking the App. For the account setup and the ASPECT_API_TOKEN your CI uses, see Authenticating the Aspect CLI. On GitHub Enterprise Server, or to use a token of your own instead of the App, see Use your own GitHub token.
Using GitLab? See the GitLab App for the equivalent.

What the App enables

Once installed and linked, these CLI features can post to GitHub from your CI runs:
  • GithubStatusChecks: per-task pass/fail status checks on the commit, on pull request and push builds, updated live as tasks finish.
  • GithubStatusComments: a single PR task summary comment that aggregates every task’s live status into one comment, updated as jobs complete.
  • GithubLintComments: aspect lint findings posted as inline PR review comments, with one-click suggestion blocks. See aspect lint for behavior and config.
The App also backs up changed-file detection for aspect format and aspect lint. Both tasks prefer a local git diff against the merge base; on PR builds where git diff can’t resolve the diff base (shallow clones or fetch-depth-restricted runners), they fall back to the GitHub PR Files API.

On a pull request

A status check per task, updated as the task progresses rather than only when the job ends. Lint findings on the line that caused them. When aspect lint reports a warning or error, it lands as an annotation on the offending line:
A lint error annotated on the line that caused it in a GitHub pull request
Where the linter can suggest a fix, the annotation carries it as a suggestion the author applies with one click:
A suggested lint fix on a GitHub pull request, ready to apply
A summary comment on the pull request, with every task’s status and links straight to its logs, test results, build profile and uploaded artifacts.
These come from aspect <task>. The CLI streams structured events as each task runs, and the App turns them into checks and comments. A vanilla bazel step produces none of them.
1

Have an Aspect account with the right role

Installing the App requires an Aspect account with the Owner, Admin + Writer, Admin or GitHub Integration Admin role. If you don’t have an account yet, or need a role assigned, see the account setup notes first.
2

Install the Aspect Workflows GitHub App and link it to your Aspect account

Use the panel below to install the App on your GitHub organization. Installing through this panel auto-links the installation to your Aspect account; linking is what enables the Aspect CLI to use the App. Already installed the App separately? Use Link an existing installation in the same panel to associate it with your Aspect account.You must also be an admin of the GitHub organization where you install the App; GitHub gates app installation on that role.
3

Generate an Aspect API token for CI

With the App linked, generate an ASPECT_API_TOKEN and wire it into CI. Pick the GitHub CI role, which covers GithubStatusChecks, GithubStatusComments, and GithubLintComments.See Generate an Aspect API token for the full walkthrough and the GitHub token roles and scopes table.

Post to a pull request from outside GitHub CI

When no CI variable names the pull request, such as a GitLab pipeline for a repository mirrored from GitHub, or a local run, set ASPECT_GITHUB_PR_NUMBER. The repository comes from ASPECT_VCS_URL, GITHUB_REPOSITORY or the origin remote, and the commit from GITHUB_SHA or the CI host’s commit variable. When origin isn’t the GitHub repository, as on a mirror, set ASPECT_VCS_URL to its URL: the CLI sends a GitHub token only to the repository’s host. To test against a real PR from your machine:
It’s the GitHub counterpart of ASPECT_GITLAB_MR_IID on the GitLab App page.

Use your own GitHub token

The App exists only on github.com. On GitHub Enterprise Server or GHE.com, or to post without the App, give the CLI a token yourself. The features then need no ASPECT_API_TOKEN. On a runner with no Aspect credentials (no ASPECT_API_TOKEN and no aspect auth login), they call only your GitHub host. The CLI sends a GitHub token only to the repository’s own host:
  • The repository’s host comes from ASPECT_VCS_URL, else GITHUB_SERVER_URL, else the origin remote.
  • The API base must be a plain https:// host and path, with no user-info, query or fragment. Only github.com and GHE.com serve their API on a separate api. host; on Enterprise Server the API base’s host must equal the repository’s host.
  • Tokens minted by the Aspect App go only to api.github.com. A job’s GITHUB_TOKEN or GH_TOKEN goes only to the host that issued it: the runner’s own host on GitHub Actions, github.com elsewhere.
When the hosts differ, or nothing names the repository’s host, the features skip and log why. The token needs these permissions for each feature (a classic personal access token needs the repo scope instead): GitHub accepts check runs only from an App, so a personal access token can’t post status checks. Disable that feature with ctx.features[GithubStatusChecks].enabled = False if you use one. A task concludes its own check run, even when canceled. If a runner is killed outright, its check stays in progress until a re-run posts a newer one with the same name. With the Aspect App, Aspect Cloud marks such checks “Disconnected” instead. On GitHub Actions, pass the job’s own token and grant its permissions:
.github/workflows/ci.yaml
On another CI host, set both variables from your secret store:
When the run also has Aspect credentials with the GitHub CI roles, jobs still coordinate the summary comment through the Aspect API. Without them, or with ctx.features[GithubStatusComments].args.coordinate = False, jobs share the comment through state stored in it. Together they read and update it about once per min_poll_interval_seconds (default 20), and each job’s final update re-reads the comment to confirm its row. Those reads count against the token’s rate limit; on busy repositories, raise ctx.features[GithubStatusComments].args.min_poll_interval_seconds.

Troubleshooting

A feature that can’t authenticate logs one line naming what’s missing (no credential, or the App not installed or linked), prefixed with the feature, for example GitHub status checks: Authentication failed for <owner>/<repo> — <reason> or GitHub lint comments: Authentication failed for …. On GitHub Enterprise, a feature that skips logs one of:
  • <VAR> points at '<host>', not github.com, naming what’s missing: ASPECT_GITHUB_TOKEN, ASPECT_GITHUB_API_URL, or both.
  • <API base> is on '<host>', but <source> points at '<host>'; not sending a GitHub token there, when the API base and the repository are on different hosts. On a mirror, set ASPECT_VCS_URL to the GitHub repository’s URL.
See Use your own GitHub token. If PR comments or status checks aren’t appearing as expected, check the GitHub App installation (panel above) and your ASPECT_API_TOKEN first. A 403 / Authentication failed usually means the token’s roles don’t cover the scope a feature needs; see When a role is missing.

Support

Hit a bug or have a feature request? Open an issue on aspect-build/aspect-cli. Join the Aspect Community Slack, Aspect’s free community support. Ask in #help for general support. Join the discussion and see what others are building with the Aspect CLI and Aspect Extension Language (AXL) in the #cli and #axl channels. For Bazel and the Bazel rulesets, Bazel Slack is the best place for support and discussion. Ask about Aspect’s rules_js in #javascript and rules_py in #python.