diff --git a/crates/aspect-cli/src/builtins/aspect/MODULE.aspect b/crates/aspect-cli/src/builtins/aspect/MODULE.aspect index 41516b38f..d99e68dbe 100644 --- a/crates/aspect-cli/src/builtins/aspect/MODULE.aspect +++ b/crates/aspect-cli/src/builtins/aspect/MODULE.aspect @@ -19,6 +19,8 @@ use_task("wrapper.axl", "uninstall") use_task("init.axl", "init") use_task("bazelrc.axl", "bazelrc") use_task("warming.axl", "warming") +use_task("runner_metadata.axl", "runner_metadata") +use_task("runner_health_check.axl", "runner_health_check") use_feature("feature/artifacts.axl", "ArtifactUpload") use_feature("feature/circleci_test_results.axl", "CircleCITestResults") diff --git a/crates/aspect-cli/src/builtins/aspect/runner_health_check.axl b/crates/aspect-cli/src/builtins/aspect/runner_health_check.axl new file mode 100644 index 000000000..41dabf1fc --- /dev/null +++ b/crates/aspect-cli/src/builtins/aspect/runner_health_check.axl @@ -0,0 +1,63 @@ +"""`aspect ci runner-health-check` — run just the Aspect Workflows runner health check. + +Every Bazel-calling task already runs this during its Setup phase: the `Workflows` +feature registers `agent_health_check` as a `HealthCheckTrait` hook (see +`feature/workflows.axl`), and `lib/lifecycle.axl::setup_phase` runs it before the +build. This command runs just that step on demand — it waits for cache warming to +complete, prints the last runner health check and warming status, then probes the +runner's Bazel server (`ctx.bazel.health_check()`), signaling the runner unhealthy +if the server is wedged. + +Like every Bazel-calling task it resolves its flags through `setup_bazel_command`, +which folds in the Workflows runner metadata — notably the per-runner +`--output_base` that `agent_health_check` requires so the probe targets the +project-specific Bazel server (see `assert_ctx_bazel_ready_for_health_check` in +`private/lib/health_check.axl`). It is therefore not given an `--output-base` flag +of its own. + +Exits non-zero when the Bazel server is unhealthy. Off an Aspect Workflows runner +there is no runner to check, so it prints an informational line and exits 0. +""" + +load("@aspect//bazel.axl", "BazelTrait") +load( + "./private/lib/bazel_flags.axl", + "announce_bazel_args", + "bazel_flag_args", + "setup_bazel_command", +) +load( + "./private/lib/environment.axl", + "error", + "get_workflows_environment", + "info", +) +load("./private/lib/health_check.axl", "HealthCheckTrait", "agent_health_check") + +def _impl(ctx: TaskContext) -> int: + environment = get_workflows_environment(ctx.std) + if environment.runner == None: + info(ctx.std, "Not on an Aspect Workflows runner; no runner health check to run.") + return 0 + + # Register the active run command before the health check — it carries the + # per-runner --output_base that `agent_health_check` requires (see docstring). + setup_bazel_command(ctx, "build", ctx.traits[BazelTrait]) + + health_error = agent_health_check(ctx, environment) + if health_error != None: + error(ctx.std, health_error) + return 1 + return 0 + +runner_health_check = task( + group = ["ci"], + summary = "Run the Aspect Workflows runner health check.", + description = "Run the runner health check that other tasks run during their Setup phase: wait for cache warming to complete, print the last runner health check and warming status, then probe the runner's Bazel server and signal the runner unhealthy if it is wedged. Exits non-zero when the Bazel server is unhealthy. Off a Workflows runner there is nothing to check, so it prints an informational line and exits 0.", + implementation = _impl, + traits = [ + BazelTrait, + HealthCheckTrait, + ], + args = bazel_flag_args("the health check") | announce_bazel_args("the health check"), +) diff --git a/crates/aspect-cli/src/builtins/aspect/runner_metadata.axl b/crates/aspect-cli/src/builtins/aspect/runner_metadata.axl new file mode 100644 index 000000000..c3a94db77 --- /dev/null +++ b/crates/aspect-cli/src/builtins/aspect/runner_metadata.axl @@ -0,0 +1,34 @@ +"""`aspect ci runner-metadata` — print the Aspect Workflows runner metadata table. + +Every Bazel-calling task already prints this table during its Setup phase: the +`Workflows` feature registers `print_environment_info` as a `HealthCheckTrait` +diagnostic hook (see `feature/workflows.axl`), and `lib/lifecycle.axl::setup_phase` +runs it. This command runs just that step on demand — useful for inspecting the +runner (cloud/region/instance, cache and storage paths, warming status, the +bootstrap-logs command) without kicking off a build. + +Off an Aspect Workflows runner there is no runner metadata to show, so it prints +an informational line and exits 0. +""" + +load( + "./private/lib/environment.axl", + "get_workflows_environment", + "info", + "print_environment_info", +) + +def _impl(ctx: TaskContext) -> int: + environment = get_workflows_environment(ctx.std) + if environment.runner == None: + info(ctx.std, "Not on an Aspect Workflows runner; no runner metadata available.") + return 0 + print_environment_info(ctx.std, environment) + return 0 + +runner_metadata = task( + group = ["ci"], + summary = "Print the Aspect Workflows runner metadata.", + description = "Print the Aspect Workflows runner metadata table — cloud/region/instance, cache and storage paths, warming status, and the cloud bootstrap-logs command. This is the same table shown during a task's Setup phase; this command runs just that step. Off a Workflows runner there is nothing to show, so it prints an informational line and exits 0.", + implementation = _impl, +)