Skip to content

fix(runnable): replay the target's env attribute when spawning built binaries#1234

Open
gregmagolan wants to merge 1 commit into
mainfrom
fix/runnable-replay-env-attribute
Open

fix(runnable): replay the target's env attribute when spawning built binaries#1234
gregmagolan wants to merge 1 commit into
mainfrom
fix/runnable-replay-env-attribute

Conversation

@gregmagolan

Copy link
Copy Markdown
Member

aspect run / format / gazelle / delivery spawn the built binary directly from its runfiles tree rather than shelling out to bazel run. That path never applied the target's env = {...} attribute — which bazel run injects at run time from the RunEnvironmentInfo provider — so any var declared in env was simply absent. A set -u script that reads one (e.g. JQ_BIN) failed with JQ_BIN: unbound variable.

The resolved env lives in neither the on-disk wrapper nor BES, so it can only be recovered via the provider. A small runenv aspect reads RunEnvironmentInfo.environment / .inherited_environment and writes them to JSON in an aspect_runenv output group. The runnable tracker collects that file from BES and spawn replays the env — environment values verbatim (already rootpath-expanded relative to the runfiles workspace dir, which is the spawn cwd), inherited_environment names copied from the process env. Target env is applied before the runfiles/BUILD_*/ASPECT_* vars so the runfiles plumbing wins on any collision.

The aspect is a no-op for rules that don't populate RunEnvironmentInfo (e.g. legacy native sh_binary, bazelbuild/bazel#23658), in which case the spawn behaves as before.


Changes are visible to end-users: yes

  • Searched for relevant documentation and updated as needed: no
  • Breaking change (forces users to change their own code or config): no
  • Suggested release notes appear below: yes

aspect run, format, gazelle, and delivery now apply a target's env attribute when running the built binary, matching bazel run. Fixes unbound variable errors for scripts that read env-injected vars under set -u.

Test plan

  • New test cases added (lib/runnable_test.axl: env collection, partial JSON, absent provider, ctx-less, and the aspect-flags helper)
  • Covered by existing test cases (aspect dev test-runnable, aspect tests axl)

…binaries

`runnable.axl` spawned built binaries directly from their runfiles tree but
never applied the target's `env = {...}` attribute, which `bazel run` injects
at run time from `RunEnvironmentInfo`. A `set -u` script reading an env-injected
var (e.g. JQ_BIN) failed with "unbound variable".

A `runenv` aspect reads each target's `RunEnvironmentInfo` and writes the
resolved env to JSON in an `aspect_runenv` output group; the runnable tracker
collects it from BES and `spawn` replays it verbatim before the runfiles/BUILD_*/
ASPECT_* vars. Wired into run, format, gazelle, and delivery phase 3. No-op for
rules without `RunEnvironmentInfo`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aspect-workflows

aspect-workflows Bot commented Jun 15, 2026

Copy link
Copy Markdown

✨ Aspect Workflows Tasks

📅 Mon Jun 15 20:36:37 UTC 2026

⚠️ 2 flagged tasks

  • ⚠️ delivery (delivery-gha-debug) · ⏱ 26.6s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (1 delivered · 2 warn · 3 skipped)
  • ⚠️ delivery (delivery-gha) · ⏱ 1m 29s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (1 delivered · 2 warn · 3 skipped)

✅ 14 successful tasks

  • ✅ build (build-gha-debug) · ⏱ 3m 42s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (165 built)
  • ✅ build (build-gha) · ⏱ 3m 46s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (165 built)
  • ✅ buildifier (buildifier-gha-debug) · ⏱ 42.8s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ buildifier (buildifier-gha) · ⏱ 54s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format (format-gha-debug) · ⏱ 2m 26s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format (format-gha) · ⏱ 2m 42s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ gazelle (gazelle-gha-debug) · ⏱ 23.9s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-from-source-gha-debug) · ⏱ 3m 2s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-from-source-gha) · ⏱ 2m 3s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-gha) · ⏱ 47.9s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ lint (lint-gha-debug) · ⏱ 42.3s · 🐙 GitHub Actions · ☑️ Check
    💬 Lint complete (clean)
  • ✅ lint (lint-gha) · ⏱ 32.1s · 🐙 GitHub Actions · ☑️ Check
    💬 Lint complete (clean)
  • ✅ test (test-gha-debug) · ⏱ 3m 56s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (25/25 passed · 25 cached)
  • ✅ test (test-gha) · ⏱ 4m 7s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (25/25 passed · 25 cached)

🔁 Reproduce

⚠️ delivery (delivery-gha-debug · delivery-gha)

# --mode=always --track-state=false for off-runner with no state backend.
aspect delivery \
  --commit-sha=b35ee2efa72559b5035e7733e951bd357ec98218 \
  --mode=always \
  --track-state=false \
  --dry-run=true

Install aspect: docs.aspect.build/cli/install


⏱ Last updated Mon Jun 15 20:43:19 UTC 2026 · 📊 GitHub API quota 1,040/15,000 (7% used, resets in 25m)
🚀 Powered by Aspect CLI (v0.0.0-dev)  |  Aspect Build · X · LinkedIn · YouTube

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant