Skip to content

feat(bazel): announce version/command per spawn; unify setup phase + collapse lifecycle to one hook#1167

Merged
gregmagolan merged 1 commit into
mainfrom
feat/announce-bazel-version
May 31, 2026
Merged

feat(bazel): announce version/command per spawn; unify setup phase + collapse lifecycle to one hook#1167
gregmagolan merged 1 commit into
mainfrom
feat/announce-bazel-version

Conversation

@gregmagolan
Copy link
Copy Markdown
Member

@gregmagolan gregmagolan commented May 30, 2026

Improves pre-task / bazel-spawn diagnostics and unifies the pre-task lifecycle.

1. Announce the Bazel version and command on each spawn

Before each bazel build/test/run spawn, optionally print the detected Bazel version and the exact command line. The existing --announce-rc is renamed to --announce-bazel-rc so the three form one family, all "auto" | "true" | "false" defaulting to auto (shown on CI, quiet locally):

Flag Prints Default
--announce-bazel-rc resolved .bazelrc flags (was --announce-rc) auto
--announce-bazel-version INFO: Bazel <version> auto
--announce-bazel-command INFO: Spawning: <command> auto
  • auto → on when a CI host is detected, off locally; true/false force it.
  • The command and the rc disclosure are scrubbed through the existing redaction (stream::redaction): env-var values, request headers (header name kept, value hidden), and URL credentials become <REDACTED>.
  • --announce-bazel-rc displays each rc source path relative to the most meaningful anchor: ./ under the workspace root, ~/ under $HOME, else absolute.
  • A non-release Bazel prints Bazel development version (version-conditional flags assume latest).
  • The three flags are declared once by a shared announce_bazel_args helper that each Bazel-spawning task splats into its args.

2. Unify the pre-task lifecycle into one setup phase

setup_phase and preflight_phase are collapsed into a single setup_phase that every task opens with, locally and on CI, passing its result kind + data: append runner-job-history, open the 🔧 Setup phase mark (the task's first task_update — it inits the status surfaces and renders their first body from kind/data), parse the .bazelrc + resolve flags (when given a BazelTrait), then run the health_check hooks. Bazel work is gated on the BazelTrait argument so a non-Bazel task can use the same phase.

HealthCheckTrait is also collapsed to a single health_check hook (was pre_health_check + post_health_check). A hook reporting an unhealthy environment now fails the task from inside setup_phase: it concludes the status surface (terminal "Health check failed") then aborts with the hook's detailed reason. Previously an unhealthy Bazel server signaled the runner but let the task proceed — a latent bug this fixes.

3. Collapse the lifecycle to a single task_update hook

TaskLifecycleTrait had three hooks — task_started, task_update, task_complete. task_complete had no subscribers (dead), and task_started only ever did one-time surface init. Both are removed, leaving one hook:

  • A handler's first task_update is its cue to initialize (authenticate, create the GitHub check run / first Buildkite annotation). The first update is the 🔧 Setup phase mark from setup_phase, which also renders the first surface body.
  • The last update carries final = True; handlers conclude their surface there.
  • The task subject (target patterns / formatter target / …) rides on the TaskUpdate (new subject field, named subject end-to-end). setup_phase sets it on the first update; a later update may refine it (e.g. delivery emits its resolved targets once a query resolves). Handlers latch the last non-empty value, so the surface title updates in place. An empty subject renders empty (no //... placeholder); the per-task summary_title helpers share one truncate_for_title so a long target list is capped identically.

This removes the ordering constraint between the (now gone) task_started and the first task_update. It also drops the startup GET /rate_limit probe: the first status-check API response already seeds the same App-bucket quota state, the first call is never throttle-gated, and the cold-start floor makes a zero- vs one-observation buffer identical — so the probe only cost a startup round-trip.

4. Timing-breakdown alignment

Pad the phase label column by display width (emoji = 2 cells) instead of codepoint count, and use a single-astral setup emoji (🔧) that renders two cells like the other phase emoji.


Changes are visible to end-users: yes

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

Suggested release notes

  • Renamed --announce-rc to --announce-bazel-rc; added --announce-bazel-version and --announce-bazel-command. All three default to auto (shown on CI, quiet locally). The command and rc disclosures redact secrets and shorten rc paths.
  • The separate "Pre-flight" task phase is merged into "Setup"; all pre-task work now reports under one phase, shown locally and on CI.
  • A failed Bazel server health check now fails the task (and reports "Health check failed" on the status surface) instead of letting it proceed.

Test plan

  • Rust: engine::bazel build (19) + redaction (26), bazelrc (83, incl. path-anchor edge cases), eval::multi_phase (2), task_info.
  • AXL: full aspect tests axl; template-snapshot dev tests (bazel-results, lint, format, gazelle, delivery — incl. a long-subject title-capping assertion, bk-annotation — incl. an empty-subject scenario); test-bazel-flags (incl. announce_bazel_args), test-health-check-ready (incl. run_health_checks first-error-wins), test-rate-limit, test-github-detect.
  • Manual: local aspect <task> drives setup_phase → first task_update → terminal; 🔧 Setup row aligns with 🔨 Build; --announce-bazel-version=true prints the version line; an injected unhealthy health_check hook makes setup_phase render a "Health check failed" terminal and fail the task with the detailed reason.
  • CI

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0703f4c070

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread crates/aspect-cli/src/builtins/aspect/lib/bazel_flags.axl Outdated
Base automatically changed from fix/bazel-dev-version-assume-latest to main May 30, 2026 16:58
@gregmagolan gregmagolan force-pushed the feat/announce-bazel-version branch from 0703f4c to f4a46a9 Compare May 30, 2026 16:58
@aspect-workflows
Copy link
Copy Markdown

aspect-workflows Bot commented May 30, 2026

✨ Aspect Workflows Tasks

📅 Sun May 31 05:41:07 UTC 2026

⚠️ 2 flagged tasks

  • ⚠️ delivery (delivery-gha) · ⏱ 20.3s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (2 warn · 3 skipped)
  • ⚠️ delivery (delivery-gha-debug) · ⏱ 41.1s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (2 warn · 3 skipped)

✅ 17 successful tasks

  • ✅ build (build-gha) · ⏱ 20.9s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (154 built)
  • ✅ build (build-gha-debug) · ⏱ 1m 2s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (154 built)
  • ✅ buildifier (buildifier-gha) · ⏱ 32.6s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ buildifier (buildifier-gha-debug) · ⏱ 29.7s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ buildifier (buildifier-gha-ephemeral) · ⏱ 1m 5s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format (format-gha) · ⏱ 20.6s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format (format-gha-debug) · ⏱ 26.1s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format (format-gha-ephemeral) · ⏱ 2m 21s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ gazelle (gazelle-from-source-gha) · ⏱ 19.8s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-from-source-gha-debug) · ⏱ 49.2s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-gha) · ⏱ 11.6s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-gha-debug) · ⏱ 21.4s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-gha-ephemeral) · ⏱ 43.1s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ lint (lint-gha) · ⏱ 21s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Lint complete (clean)
  • ✅ lint (lint-gha-debug) · ⏱ 23.9s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Lint complete (clean)
  • ✅ test (test-gha) · ⏱ 20.7s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (25/25 passed · 25 cached)
  • ✅ test (test-gha-debug) · ⏱ 1m · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (25/25 passed · 25 cached)

🔁 Reproduce

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

# CI ran --mode=selective; --mode=always --track-state=false for off-runner with no state backend.
cd examples/deliverable
aspect delivery --mode=always --track-state=false --dry-run=true

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


⏱ Last updated Sun May 31 05:43:38 UTC 2026 · 📊 GitHub API quota 2,448/15,000 (16% used, resets in 27m)
🚀 Powered by Aspect CLI (v0.0.0-dev)  |  Aspect Build · X · LinkedIn · YouTube

@gregmagolan gregmagolan force-pushed the feat/announce-bazel-version branch from 695cdde to a07af55 Compare May 30, 2026 17:28
@gregmagolan gregmagolan changed the title feat(bazel): announce the detected Bazel version in built-in tasks feat(bazel): announce Bazel version and command on each spawn May 30, 2026
@gregmagolan gregmagolan force-pushed the feat/announce-bazel-version branch from 92548d1 to a53d925 Compare May 30, 2026 18:58
@gregmagolan gregmagolan changed the title feat(bazel): announce Bazel version and command on each spawn feat(bazel): announce Bazel version/command per spawn; unify setup + pre-flight phase May 30, 2026
@gregmagolan gregmagolan changed the title feat(bazel): announce Bazel version/command per spawn; unify setup + pre-flight phase feat(bazel): announce version/command per spawn; unify pre-task setup phase May 30, 2026
@gregmagolan gregmagolan force-pushed the feat/announce-bazel-version branch from 553b14c to 1a5ceff Compare May 31, 2026 00:24
@gregmagolan gregmagolan changed the title feat(bazel): announce version/command per spawn; unify pre-task setup phase feat(bazel): announce version/command per spawn; unify setup phase + collapse lifecycle to one hook May 31, 2026
@gregmagolan gregmagolan force-pushed the feat/announce-bazel-version branch 7 times, most recently from 03180a5 to 60be37c Compare May 31, 2026 05:20
…collapse lifecycle to one hook

Announce the detected Bazel version and exact command line before each
spawn. Rename --announce-rc to --announce-bazel-rc and add
--announce-bazel-version / --announce-bazel-command, all "auto"|"true"|
"false" defaulting to auto (on under CI, quiet locally). The command and
the rc disclosure reuse the existing stream::redaction (env values,
header values with the name kept, URL creds) and the rc paths are
shortened to ./ under the workspace root, ~/ under $HOME, else absolute.
The three flags are declared once via a shared `announce_bazel_args`
helper that every Bazel-spawning task splats into its args.

Collapse setup_phase + preflight_phase into one always-on setup_phase
that every task opens with, passing its result `kind` + `data`:
runner-job-history, the Setup phase mark (the task's first task_update —
inits the status surfaces AND renders their first body from kind+data),
.bazelrc parse + flag resolution (gated on BazelTrait), then the
health_check hooks. A health_check hook reporting an unhealthy
environment fails the task from inside setup_phase: it concludes the
surface with a "Health check failed" body, then fail()s with the hook's
detailed reason — fixing a latent bug where an unhealthy Bazel server
signaled the agent but let the task proceed.

Collapse HealthCheckTrait to a single `health_check` hook (was
pre_health_check + post_health_check, the latter unregistered).

Collapse TaskLifecycleTrait to a single task_update hook. task_complete
had no subscribers; task_started only did one-time surface init. Both are
removed: a handler's first task_update initializes, and final=True
concludes it. The task subject rides on TaskUpdate.subject; setup_phase
sets it on the first update and a later update may refine it (delivery
emits its resolved targets once a query resolves), so handlers latch the
last non-empty value and refresh the surface title in place. The
render-ctx subject field is named `subject` end-to-end; the per-task
summary_title helpers share one truncate_for_title; an empty subject
renders empty (no placeholder).

Drop the GET /rate_limit setup probe: the first status-check API response
seeds the same App-bucket quota state via record_from_headers, the first
call is never throttle-gated, and the cold-start floor makes zero-vs-one
observation identical — so the probe only added a startup round-trip.

Fix the timing-breakdown alignment to pad by display width (emoji = 2
cells) and use a single-astral setup emoji (🔧) that renders two cells
like the other phase emoji.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gregmagolan gregmagolan force-pushed the feat/announce-bazel-version branch from 60be37c to d663f85 Compare May 31, 2026 05:39
@gregmagolan gregmagolan merged commit a3a810a into main May 31, 2026
58 checks passed
@gregmagolan gregmagolan deleted the feat/announce-bazel-version branch May 31, 2026 06:18
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