ci: connect builds to Aspect Cloud - #1546
Conversation
CI runs on stock GitHub-hosted runners, which have no remote cache of their own, and nothing here named an endpoint: `aspect auth login --with-api-token`, which setup-aspect already runs from its `aspect-api-token` input, records a credential but no endpoints, and Aspect Cloud's built-in entry ships with none. So the deployment is declared in a committed `.aspect/config.json` and found through `$ASPECT_WORKSPACE`, pinned to the checkout root because the test matrix builds from `e2e/*` and `examples/*`. That variable selects only the deployment list, not which `.aspect/config.axl` a task loads, and not which workspace is built. Aspect CLI tasks then take `--remote`; vanilla `bazel` calls take `--config=aspect-cloud` from the committed `.aspect/bazelrc`, plus a `--workspace_status_command` so they are attributed in the Web UI rather than arriving anonymous (a stopgap for `aspect setup workspace-data`, aspect-build/aspect-cli#1465). Both flags resolve to nothing without the token, which is every fork PR: those get no org secrets, so the login never runs and either one would reach Aspect Cloud with no credential. The token is `ASPECT_OSS_API_TOKEN`, matching aspect-build/rules_lint#1002 — the org-wide `ASPECT_API_TOKEN` authenticates as a tenant the OSS team cannot see, so uploads would succeed while the UI stayed empty. There is deliberately no fallback to it. `test` computes its own `REMOTE_FLAG` by reading `runs-on` back, because `--remote` is a hard failure on a self-hosted Aspect Workflows runner (`REMOTE_REFUSED_BY_ENV`): the `ASPECT_WORKFLOWS_*` environment already names that machine's deployment, and the CLI refuses to route the build off it rather than wire a second one. Without the gate the four workspaces that ask for the 32-core pool would fail outright. Requires the CLI pin to move off 2026.28.2, which predates the deployment feature and has no `--remote`. `--task-key` is gone there, and an unrecognized flag is forwarded to Bazel rather than rejected, so the three call sites move to `--task:name` or the build fails. `e2e/crossbuild` is the one sibling workspace CI drives with vanilla `bazel`. It imports the root's rc through `%workspace%/../..` rather than carrying a copy: `%workspace%` expands to an absolute path before Bazel opens the file, so that reaches the root from any working directory, unlike a bare relative path. Inside the imported file `%workspace%` re-expands to the importing workspace, which is why `.aspect/generated/` is committed there too — that is where its execution log lands, and Bazel fails the build outright rather than create the directory. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Aspect Workflows Tasks📅 Thu Sep 17 20:18:46 UTC 2026 Task Results
⏱ Last updated Thu Sep 17 20:24:04 UTC 2026 · 📊 GitHub API quota 0/7,700 (0% used, resets in 59m) |
py_binary startup benchmark
sys.path quality
Bazel analysis benchmark
py_image_layer benchmark
|
`aspect ci bazelrc` regenerates the Workflows runner's ~/.bazelrc on every job using the CLI the checkout pins, and at 2026.38.14 that rc gained an enabled `aspect-github-actions` group carrying `--color=yes` — GitHub Actions renders ANSI but gives the job no TTY, so Bazel's `--color=auto` misdetects. It applies to every vanilla `bazel` call on the runner, including the ones these e2e scripts make. This test greps the captured output for the line `hello` exactly, and forced color prefixes it with an ANSI reset, so the match failed on output that was otherwise correct. Only this script compares a whole line; the rest match substrings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Names the PR that replaces it, aspect-build/aspect-cli#1465, at the top of the file rather than mid-paragraph, so whoever opens it next sees that the whole script is temporary before reading what it does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Points CI at Aspect Cloud's remote cache and BES. The jobs run on stock GitHub-hosted runners, which have no cache of their own, and nothing here named an endpoint.
Draft: opened to exercise the one thing that cannot be validated locally — the
ASPECT_OSS_API_TOKEN→ JWT exchange.Follows aspect-build/rules_lint#1003, adapted to this repo's two differences: a self-hosted runner pool, and ~20 sibling Bazel workspaces that CI drives through the Aspect CLI rather than vanilla
bazel.What it takes
setup-aspectalready pipes itsaspect-api-tokeninput intoaspect auth login --with-api-token. That records a credential but no endpoints, and Aspect Cloud's built-in entry ships with none, so a token alone leaves--remotewith nothing to wire. The endpoints come from a committed.aspect/config.json, found through$ASPECT_WORKSPACE— pinned to the checkout root, since the test matrix builds from subdirectories. That variable selects only the deployment list, never which.aspect/config.axla task loads, nor which workspace is built.REMOTE_FLAGandBAZEL_ASPECT_FLAGSare empty when the secret is absent, which is every fork PR: forks get no org secrets, the login never runs, and either flag would reach Aspect Cloud with no credential.Why
testcomputes its ownREMOTE_FLAG--remoteis a hard failure on a self-hosted Aspect Workflows runner —REMOTE_REFUSED_BY_ENV: theASPECT_WORKFLOWS_*environment already names that machine's deployment, and the CLI refuses to route the build off it rather than wire a second one. The job'sREMOTE_FLAGtherefore reads its ownruns-oncondition back, so the four workspaces that ask for the 32-core pool keep the runner's wiring. Without the gate they would fail outright.Why the version bump
The pin was 2026.28.2, which predates the deployment feature — no
--remote, noaspect auth configure.--task-keyis gone at 2026.38.14, and an unrecognized flag is forwarded to Bazel rather than rejected, so the three call sites move to--task:nameor the build fails. Only the root pins a version; the launcher walks up, so the sibling workspaces follow it.One rc, two workspaces
e2e/crossbuildis the only sibling workspace CI builds with vanillabazel. It imports the root's rc through%workspace%/../..instead of carrying a copy —%workspace%expands to an absolute path before Bazel opens the file, so that reaches the root from any working directory, unlike a bare relative path. Inside the imported file%workspace%re-expands to the importing workspace, which is why.aspect/generated/is committed there too: that is where its execution log lands, and Bazel fails the build rather than create the directory.Verified locally
aspect build --remotefrom the repo root and frome2e/crossbuildwithASPECT_WORKSPACEat the root — the CI shape — both printUsing deployment 'aspect-cloud',Streaming build events to grpcs://bes.aspect.build, and anapp.aspect.build/i/…link.~/.aspect/config.jsonmoved aside,--remotefailsno default is setwithoutASPECT_WORKSPACEand resolves with it, confirming the committed file is what CI will read.bazel build --config=aspect-cloudstreams to Aspect Cloud from the root, and--config=aspect-cloudresolves ine2e/crossbuildand from a subdirectory of it.e2e/crossbuildbuild lands ine2e/crossbuild/.aspect/generated/, leaving the root's untouched..aspect/generated/fails the build, confirming the committed directory is load-bearing.What this PR is meant to prove
Local runs used a browser login, not the token, so CI is the first exercise of:
ASPECT_OSS_API_TOKENexchanges for a JWT. Note: setup-aspectcore.warnings rather than fails on a bad login, so check that step's output explicitly — a green setup step does not mean it worked.Using deployment 'aspect-cloud'; the vanilla-bazeljobs printStreaming build results to.REMOTE_FLAGempty.Deliberately out of scope
The
test.shscripts ine2e/*invoke plainbazelin ~20 nested workspaces. They stay off Aspect Cloud: an rc import alone would not connect them, since those scripts pass no--config=aspect-cloudand$BAZEL_ASPECT_FLAGSis not threaded into them.🤖 Generated with Claude Code