{"id":28146488,"url":"https://github.com/aspect-build/aspect-cli","last_synced_at":"2026-07-01T23:01:44.849Z","repository":{"id":37246243,"uuid":"376383688","full_name":"aspect-build/aspect-cli","owner":"aspect-build","description":"{ Correct, Fast, Usable } -- Choose three","archived":false,"fork":false,"pushed_at":"2026-06-28T07:11:12.000Z","size":11521,"stargazers_count":158,"open_issues_count":25,"forks_count":43,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-06-28T07:20:12.638Z","etag":null,"topics":["bazel","cli"],"latest_commit_sha":null,"homepage":"https://aspect.build/","language":"Starlark","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aspect-build.png","metadata":{"funding":{"github":null,"patreon":null,"open_collective":"aspect-build","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null},"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-06-12T21:05:04.000Z","updated_at":"2026-06-28T06:26:02.000Z","dependencies_parsed_at":"2026-04-28T01:01:12.872Z","dependency_job_id":null,"html_url":"https://github.com/aspect-build/aspect-cli","commit_stats":{"total_commits":1074,"total_committers":21,"mean_commits":"51.142857142857146","dds":0.782122905027933,"last_synced_commit":"e6863d9d24b0254acdc828a916b92c0d43efa167"},"previous_names":[],"tags_count":344,"template":false,"template_full_name":null,"purl":"pkg:github/aspect-build/aspect-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Faspect-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Faspect-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Faspect-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Faspect-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aspect-build","download_url":"https://codeload.github.com/aspect-build/aspect-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspect-build%2Faspect-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35025983,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel","cli"],"created_at":"2025-05-14T23:12:38.228Z","updated_at":"2026-07-01T23:01:44.825Z","avatar_url":"https://github.com/aspect-build.png","language":"Starlark","funding_links":["https://opencollective.com/aspect-build"],"categories":["Starlark"],"sub_categories":[],"readme":"# Aspect CLI\n\n`aspect` is a free, open-source, programmable task runner built on top of Bazel. It replaces the pile of bespoke shell scripts and CI YAML that every Bazel monorepo eventually grows — format pre-submits, lint enforcement, BUILD-file generation, release-tag delivery — with a single command-line tool that behaves identically on a developer laptop and in CI.\n\n```text\n$ aspect test //...\n→ 🎬 Running `test` task\n\n→ 🔧 Setup · Running setup\n\n→ 🧪 Test · Spawning bazel test\nINFO: Bazel 9.0.1\nINFO: Analyzed 147 targets (0 packages loaded, 0 targets configured).\nINFO: Found 122 targets and 25 test targets...\nINFO: Elapsed time: 0.866s, Critical Path: 0.07s\nINFO: 1 process: 31 action cache hit, 1 internal.\nINFO: Build completed successfully, 1 total action\n\nExecuted 0 out of 25 tests: 25 tests pass.\nINFO: Build Event Protocol files produced successfully.\n\n→ ✅ Passed `test` task in 1.2s · Tests passed (cached)\n    🔧 Setup   2ms  Prepare the task environment\n    🧪 Test   1.2s  Run bazel tests\n```\n\nEvery `aspect \u003ctask\u003e` ends with that per-phase breakdown, so the slow part of a CI step is always called out by name. The same content gets posted back to your PR as Buildkite annotations, GitHub Status Checks, and a PR task summary comment (see [examples below](#see-it-in-action)). [The CLI overview](https://aspect.build/docs/cli/overview#what-youll-see) shows `aspect format`, `aspect buildifier`, and `aspect lint` runs too — including the hold-the-line output (linter surfaces findings in unmodified files; the task still passes because no *new* violations were introduced).\n\n## Configure and extend in AXL\n\n[AXL, the Aspect Extension Language](https://aspect.build/docs/cli/overview#aspect-extension-language), is how you configure built-in tasks (in `.aspect/config.axl`) and add your own (as `.aspect/*.axl` files). It's a [typed Starlark](https://github.com/facebook/starlark-rust/blob/main/docs/types.md) dialect evaluated by the [Rust Starlark](https://github.com/facebook/starlark-rust) interpreter built by the [Buck2](https://buck2.build/) team, so `.axl` files catch type errors at parse time and parse fast even on huge repos.\n\nHere's an example `.aspect/config.axl` that exercises several built-ins (for a full live config running in CI, see [`aspect-build/bazel-examples`](https://github.com/aspect-build/bazel-examples/blob/main/.aspect/config.axl)):\n\n```python\n\"\"\"Aspect CLI configuration.\"\"\"\n\nload(\"@aspect//feature/artifacts.axl\", \"ArtifactUpload\")\nload(\"@aspect//format.axl\", \"format\")\nload(\"@aspect//traits.axl\", \"BazelTrait\")\n\nbuildifier = format.alias(\n    defaults = {\n        \"formatter_target\": \"@buildifier_prebuilt//buildifier\",\n        \"formatter_args_for_tree_walk\": [\"-r\", \".\"],\n        \"run_in\": \"cwd\",\n        \"include_patterns\": [\n            \"**/BUILD\",\n            \"**/BUILD.bazel\",\n            \"**/MODULE.bazel\",\n            \"**/*.MODULE.bazel\",\n            \"**/WORKSPACE\",\n            \"**/WORKSPACE.bazel\",\n            \"**/*.axl\",\n            \"**/*.bzl\",\n            \"**/*.star\",\n        ],\n    },\n    summary = \"Format Starlark files using buildifier.\",\n)\n\ndef config(ctx: ConfigContext):\n    # Set --config=ci on all bazel commands on all CI environments.\n    if bool(ctx.std.env.var(\"CI\")):\n        ctx.traits[BazelTrait].extra_flags.extend([\n            \"--config=ci\",\n        ])\n\n    # Register the buildifier alias as a CLI command.\n    ctx.tasks.add(buildifier)\n\n    # Lint aspects — required by the built-in `aspect lint` task. Same set\n    # locally as on CI; CI invocations don't need to repeat the --aspect flags.\n    ctx.tasks[\"lint\"].args.aspects = [\n        \"//tools/lint:linters.bzl%buf\",\n        \"//tools/lint:linters.bzl%checkstyle\",\n        \"//tools/lint:linters.bzl%clippy\",\n        \"//tools/lint:linters.bzl%eslint\",\n        \"//tools/lint:linters.bzl%keep_sorted\",\n        \"//tools/lint:linters.bzl%pmd\",\n        \"//tools/lint:linters.bzl%ruff\",\n        \"//tools/lint:linters.bzl%shellcheck\",\n    ]\n\n    # Delivery.\n    ctx.tasks[\"delivery\"].args.query = \"kind(\\\"oci_push rule\\\", //...)\"\n    ctx.tasks[\"delivery\"].args.bazel_flags = [\n        \"--config=release\",\n    ]\n\n    # Enable artifact uploads for testlogs, profile, and BEP.\n    # upload_test_logs=\"failed\" — the logs from passing tests are noise;\n    # failing/flaky tests' logs are the ones anyone would actually open.\n    ctx.features[ArtifactUpload].args.upload_test_logs = \"failed\"\n    ctx.features[ArtifactUpload].args.upload_profile = True\n    ctx.features[ArtifactUpload].args.upload_bep = True\n```\n\n## Why another tool on top of Bazel?\n\n`bazel` is a build system, not a developer-workflow tool. Every Bazel monorepo eventually grows the same scaffolding by hand — format pre-submits, lint enforcement, BUILD-file generation, release-tag delivery — written in shell or YAML, copy-pasted across teams, behaving differently in CI than on a laptop.\n\n`aspect` replaces that scaffolding. It's a programmable task-runner layer on top of `bazel`: built-in tasks you tune in `.aspect/config.axl`, custom tasks you add as `.aspect/*.axl` files, and a clean fallthrough to raw `bazel` for anything `aspect` doesn't wrap. You're not switching build systems — you're extending the one you already have.\n\n**What's in the box:**\n\n- **Same command, every environment.** `aspect lint` on a laptop does the same thing as in a CI pipeline. Cuts an entire class of \"works on my machine but not in CI\" bugs.\n- **The CI scaffolding every Bazel repo eventually re-invents** — built in: hold-the-line lint (fails only on violations *you* introduced), selective delivery (re-deploys only services whose Bazel outputs actually changed), smart changed-file detection, bounded retry on transient Bazel errors, native artifact upload, and per-step status checks on GitHub, Buildkite, GitLab, and CircleCI.\n- **Custom CLI commands in ~10 lines of Starlark.** Drop a `.axl` file into `.aspect/` and `aspect \u003cname\u003e` is a real CLI command (see below). Tasks can shell out, read/write files, query the build graph, and subscribe to Bazel's Build Event Stream and Compact Execution Log.\n- **Per-repo version pin.** `.aspect/version.axl` pins the CLI version; the launcher fetches the matching binary on first invocation, so local and CI stay in sync.\n- **Standalone or with Aspect Workflows.** The CLI works on its own with any Bazel workspace. Pair it with [Aspect Workflows](https://aspect.build/docs/aspect-workflows) — Aspect's managed Bazel-CI runners, deployed in your AWS or GCP account or hosted by Aspect — for sub-minute cached builds, 2–3× faster CI, 40–80% cloud-compute savings, plus a Web UI, remote cache, and remote build execution.\n\n## Install\n\n```shell\ncurl -fsSL https://install.aspect.build | bash\n```\n\nmacOS and Linux. Apache-2.0. No Aspect account required.\n\nThe [10-minute Quickstart](https://aspect.build/docs/quickstart) walks from install to writing a custom task. Full docs: [aspect.build/docs/cli](https://aspect.build/docs/cli/overview).\n\n## Built-in tasks\n\nThree tasks work in any Bazel workspace with no extra setup — they're `bazel build` / `bazel test` / `bazel run` plus the retry, BES streaming, artifact upload, status checks, and CI-platform reporting described above:\n\n| Task | What it does |\n|---|---|\n| [`aspect build`](https://aspect.build/docs/cli/tasks/build_test) | Build Bazel targets |\n| [`aspect test`](https://aspect.build/docs/cli/tasks/build_test) | Run Bazel tests, with optional LCOV coverage |\n| [`aspect run`](https://aspect.build/docs/cli/tasks/run) | Build and run a binary target |\n\nThe remaining built-ins need both **Bazel-graph wiring** (a tool dependency in `MODULE.bazel`, plus a BUILD target or rule wired up to it) and **AXL wiring** (programmable configuration in `.aspect/config.axl`) to point the task at your repo's setup. Each task page walks through both:\n\n| Task | What it does | What it needs |\n|---|---|---|\n| [`aspect format`](https://aspect.build/docs/cli/tasks/format) | Format files changed in the PR | A `//tools:format` BUILD target (the task's default) that wraps a formatter binary — typically via [`aspect_rules_lint`](https://registry.bazel.build/modules/aspect_rules_lint) or [`buildifier_prebuilt`](https://registry.bazel.build/modules/buildifier_prebuilt), plus the matching `bazel_dep`. Override the target path with `formatter_target` in `.aspect/config.axl` if you put it somewhere else. |\n| [`aspect lint`](https://aspect.build/docs/cli/tasks/lint) | Run linters with hold-the-line strategy | [`aspect_rules_lint`](https://registry.bazel.build/modules/aspect_rules_lint) plus the linter rules of choice (eslint, ruff, golangci-lint, …); lint aspects declared in `.aspect/config.axl` |\n| [`aspect gazelle`](https://aspect.build/docs/cli/tasks/gazelle) | Generate and sync BUILD files | A `//tools:gazelle` BUILD target (the task's default) that wraps a Gazelle binary — typically via [`gazelle`](https://registry.bazel.build/modules/gazelle) or [`aspect_gazelle_prebuilt`](https://registry.bazel.build/modules/aspect_gazelle_prebuilt) (for Starlark-defined extensions), plus the matching `bazel_dep`. Override the target path with `gazelle_target` in `.aspect/config.axl` if you put it somewhere else. |\n| [`aspect delivery`](https://aspect.build/docs/cli/tasks/delivery) | Deliver only targets whose Bazel-built outputs changed | BUILD targets that implement delivery (e.g. `oci_push`, `helm_push`, custom `bazel_run`-able scripts); a `--query` (or `config.axl` equivalent) selecting which targets are deliverables |\n\n`aspect help` lists every task available in your repo (built-ins plus any custom ones you've added).\n\n## Custom tasks\n\nDrop a `.axl` file into `.aspect/`, define a task, and `aspect \u003cname\u003e` is a CLI command:\n\n```python\n# .aspect/codegen.axl\ndef _impl(ctx: TaskContext) -\u003e int:\n    return ctx.bazel.build(*ctx.args.targets).wait().code\n\ncodegen = task(\n    summary = \"Run the code generator.\",\n    implementation = _impl,\n    args = {\n        \"targets\": args.positional(default = [\"//gen/...\"]),\n    },\n)\n```\n\n```shell\naspect codegen //gen/services/...\n```\n\nTasks can shell out to any subprocess, read and write files, query the build graph, subscribe to Bazel's Build Event Stream, and declare typed arguments. [How to run and define tasks](https://aspect.build/docs/cli/guides/basic) covers the full walkthrough. The [AXL reference](https://aspect.build/docs/axl/types) documents every type and built-in.\n\n## Running in CI\n\nThe same `aspect \u003ctask\u003e` command you run locally works identically in CI. [Running tasks in CI](https://aspect.build/docs/cli/tasks-ci) has ready-to-paste YAML for GitHub Actions, Buildkite, GitLab CI, and CircleCI — for both provider-hosted runners and Aspect Workflows CI runners.\n\nOn GitHub Actions specifically, [`aspect-build/setup-aspect`](https://github.com/aspect-build/setup-aspect) handles the install, wires up GHA caching, and exchanges your `ASPECT_API_TOKEN` for a short-lived JWT — in one action step.\n\n## See it in action\n\nThe [`aspect-build/bazel-examples`](https://github.com/aspect-build/bazel-examples) repo runs `aspect \u003ctask\u003e` pipelines on every commit across all four supported CI providers. Click through to inspect a current build:\n\n| CI provider | Live pipeline |\n|---|---|\n| GitHub Actions | [Actions tab](https://github.com/aspect-build/bazel-examples/actions?query=branch%3Amain) |\n| Buildkite | [Recent builds](https://buildkite.com/aspect-build/bazel-examples/builds?branch=main) |\n| GitLab CI/CD | [Pipelines](https://gitlab.com/aspect-build/bazel-examples/-/pipelines?scope=all\u0026ref=main) |\n| CircleCI | [Pipeline runs](https://app.circleci.com/pipelines/github/aspect-build/bazel-examples?branch=main) |\n\n`aspect \u003ctask\u003e` posts task results to three surfaces:\n\n- **PR task summary comment** — a single comment summarising every task in the pipeline.\n- **GitHub Status Checks** — one check per `aspect \u003ctask\u003e` invocation, named by `--task:name`.\n- **Buildkite annotations** _(when running on Buildkite)_ — one annotation per `aspect \u003ctask\u003e` invocation, rendered at the top of the build page.\n\nLive links to each, from real runs of this repo's own CI: [What `aspect \u003ctask\u003e` reports back](https://aspect.build/docs/cli/tasks-ci#what-aspect-%3Ctask%3E-reports-back).\n\n## Comparison to older versions\n\n\u003e [!NOTE]\n\u003e This is a Rust rewrite, superseding the legacy Go version published as version 2025.41 and earlier.\n\u003e The older implementation is now in maintenance mode at [aspect-build/aspect-cli-legacy](https://github.com/aspect-build/aspect-cli-legacy).\n\nVersions before 2025.42 differed in some notable ways:\n\n- Older versions shadowed the `bazel` command in the recommended installation, using homebrew or `bazeliskrc` to override `bazel`. Now `aspect` works alongside `bazel`.\n- The plugin system used a gRPC client/server protocol. Now `aspect` uses Starlark via the Aspect Extension Language (AXL).\n- Older versions included a fully pre-compiled Gazelle binary along with some Gazelle extensions, using the `configure` command. This has moved to a standalone repo: [aspect-build/aspect-gazelle](https://github.com/aspect-build/aspect-gazelle).\n\n## Community and support\n\n- Documentation: [aspect.build/docs/cli](https://aspect.build/docs/cli/overview)\n- Quickstart: [aspect.build/docs/quickstart](https://aspect.build/docs/quickstart)\n- Slack: [slack.aspect.build](https://slack.aspect.build/)\n- Issues and discussions: this repo\n\n## License\n\n[Apache License 2.0](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspect-build%2Faspect-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faspect-build%2Faspect-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspect-build%2Faspect-cli/lists"}