Skip to content

feat(status): selectable template styles + DX-focused "Strata" style#1259

Open
gregmagolan wants to merge 2 commits into
mainfrom
feat/strata-template-style
Open

feat(status): selectable template styles + DX-focused "Strata" style#1259
gregmagolan wants to merge 2 commits into
mainfrom
feat/strata-template-style

Conversation

@gregmagolan

Copy link
Copy Markdown
Member

The current CI status templates were a first pass that shows everything. This PR makes the template layout selectable and adds a second, DX-focused style — Strata — that answers, in priority order: what broke → how to fix/repro it → why it was slow. The existing layout is preserved as Kilgore (the default), byte-identical to today.

Stacked on #1258 — that PR finalizes the per-failure repro data model this builds on. Review/merge #1258 first.

How it works

A style is a bundle of the three top-level Jinja2 templates a surface may need — summary + details (check surfaces) and body (the aggregated PR/MR comment) — selected by a new style arg on every status feature:

def config(ctx):
    for name in ctx.tasks:
        ctx.tasks[name].features[GithubStatusComments].args.style = "strata"
        ctx.tasks[name].features[GithubStatusChecks].args.style = "strata"

resolve_style(name, overrides) layers the existing per-key templates arg on top of the named style, so you can pick a style and replace just one slot — that's how custom variants are expressed, no new mechanism:

args.style = "strata"
args.templates = {"details": "<my jinja2>"}   # strata everywhere else, custom details

Wired into all five status features: GitHub status checks, GitHub PR comment, GitLab commit statuses, GitLab MR comment, Buildkite annotation.

What Strata looks like

Verdict-led, compact, aggregated PR comment:

## ✨ Aspect Workflows
### ❌ 1 task failed

- ❌ build (build-task) · ⏱ 42s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check<br>💬 Bazel build failed
- 🔄 test (test-task) · ⏱ 1m 18s · ✨ Aspect<br>💬 Bazel test running... (13/60 tests run)
- ✅ lint (lint-task) · ⏱ 24s · ✨ Aspect<br>💬 Lint complete (clean)

On a check surface, the body leads with a verdict heading + a KPI strip — a fenced, monospace, threshold-emoji health line that stands in for the web UI's colored tiles (markdown has no color):

🟡 Cache hit   78%     4,498 / 5,768 actions
🟢 Parallelism 6.2×    cpu 26m
🟡 Wall time   4m12s   crit path 1m50s (44%)

— then What broke (each failure's snippet open, with that failure's repro command right beneath it), then whole-run Fix / Reproduce, with the passed/cached rollup and the performance/invocation detail collapsed below. The performance block auto-expands on a "Passed, but slow" verdict.

Design synthesized from three independent design passes, drawing on BuildBuddy's results UI and the new Strata web UI in silo.


Changes are visible to end-users: yes

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

Suggested release notes

  • Status surfaces (GitHub/GitLab PR comment, GitHub status check, GitLab commit status, Buildkite annotation) now support a style arg. strata is a new DX-focused layout — a verdict + a compact cache/parallelism/wall KPI strip, failure snippets shown with their repro commands inline, and reference sections collapsed. The original full report is kilgore (default, unchanged).
  • Custom variants: layer per-key templates overrides on top of any style.

Test plan

  • New test cases added
    • lib/template_styles_test.axl — 20 unit tests: resolve_style selection + override layering, compute_strata_kpi thresholds (cache/parallelism/critical-path-share), verdict words, slow-but-passing detection, verdict-without-metrics
    • Strata render passes added to test-template-snapshots, test-pr-comment-snapshots, and the inline-snippet render test in .aspect/axl.axl
  • Covered by existing test cases (Kilgore output unchanged across all snapshot suites)
  • Full local regression green: aspect tests axl (851), test-template-styles (20), all 7 snapshot suites, test-repro-commands/test-bazel-results/test-bazel-runner, cargo test -p aspect-cli (40)
  • Live verification of the PR-comment + GitHub status-check surfaces with style = "strata" (in progress)

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

Copy link
Copy Markdown

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: 1469909f1f

ℹ️ 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".

if (data["bazel"].get("flaky_test_total", 0) or 0) > 0:
return ("⚠️", "Passed with flakes")
return ("✅", "Passed")
# Any terminal non-pass is a failure; name a timeout specifically.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle warning statuses in Strata verdict

When a task ends with status == "warning" (for example lint/format/gazelle/delivery warnings, or a Bazel run with only flaky tests), this code falls through to the failure verdict, so the Strata details heading renders ❌ Failed even though the status feature maps the same update to a neutral/warning result. Please handle warning before the failure fallback so Strata does not mislabel successful-with-warnings runs as failures.

Useful? React with 👍 / 👎.

Comment on lines +101 to +102
_style = resolve_style(ctx.args.style, ctx.args.templates or {})
templates = {"summary": _style["summary"], "details": _style["details"]}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep Strata templates from hiding non-Bazel details

This resolved template bundle is passed later to whichever renderer_for_kind(update.kind) is selected; check_dispatch includes lint_results, format_results, gazelle_results, and delivery_results, but STRATA_DETAILS_TEMPLATE only renders the Bazel shared fields and never the non-Bazel renderers' actionable groups/file_list/delivery sections. With style = "strata", a failing or warning format/lint/gazelle/delivery check therefore loses the details users need to fix it, so either gate this template to Bazel renderers or add per-kind Strata details templates.

Useful? React with 👍 / 👎.

gregmagolan added a commit that referenced this pull request Jun 21, 2026
Sets style="strata" on GithubStatusChecks + GithubStatusComments so PR #1259's
own CI renders the new DX-focused layout live on the PR comment + status checks.
@gregmagolan gregmagolan changed the base branch from feat/per-failure-repro-commands to main June 21, 2026 23:44
@gregmagolan

Copy link
Copy Markdown
Member Author

Temporarily retargeted the base to main (from feat/per-failure-repro-commands) so CI runs — ci-workflows.yaml only triggers on PRs into main, which the stacked base skips. This lets the repo's own CI build this branch's CLI and render the Strata PR comment + GitHub status checks live (the branch sets style="strata" in .aspect/config.axl). Will retarget back onto #1258 once the live render is captured. The diff currently shows #1258's commits too; that's expected while based on main.

@aspect-workflows

aspect-workflows Bot commented Jun 21, 2026

Copy link
Copy Markdown

✨ Aspect Workflows

🔄 Running…

  • 🔄 lint (lint-gha-debug) · ⏱ 1m 10s · 🐙 GitHub Actions · ☑️ Check
    💬 Filtering diagnostics...
  • 🔄 lint (lint-gha) · ⏱ 1m 26s · 🐙 GitHub Actions · ☑️ Check
    💬 Filtering diagnostics...
  • ⚠️ delivery (delivery-gha-debug) · ⏱ 40s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (1 delivered · 2 warn · 3 skipped)
  • ⚠️ delivery (delivery-gha) · ⏱ 34.9s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Delivery complete (1 delivered · 2 warn · 3 skipped)
  • ✅ build (build-gha-debug) · ⏱ 1m 51s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (166 built)
  • ✅ build (build-gha) · ⏱ 1m 34s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (166 built)
  • ✅ build (build-gha-ephemeral) · ⏱ 1m 19s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (9 built)
  • ✅ buildifier (buildifier-gha-debug) · ⏱ 1m 21s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ buildifier (buildifier-gha) · ⏱ 41.6s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format (format-gha-debug) · ⏱ 1m 27s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ format (format-gha) · ⏱ 1m 46s · 🐙 GitHub Actions · ☑️ Check
    💬 Format complete (clean)
  • ✅ gazelle (gazelle-gha-debug) · ⏱ 1m 9s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-from-source-gha-debug) · ⏱ 2m 18s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-from-source-gha) · ⏱ 2m 19s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ gazelle (gazelle-gha) · ⏱ 38.7s · 🐙 GitHub Actions · ☑️ Check
    💬 Gazelle complete (clean)
  • ✅ build (init-shell) · ⏱ 41.9s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel build complete (10 built)
  • ✅ test (test-gha-debug) · ⏱ 1m 43s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (26/26 passed · 25 cached)
  • ✅ test (test-gha) · ⏱ 1m 51s · ✨ Aspect · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (26/26 passed · 26 cached)
  • ✅ test (test-gha-ephemeral) · ⏱ 1m 9s · 🐙 GitHub Actions · ☑️ Check
    💬 Bazel test complete (1/1 passed)

🔁 Reproduce

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

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

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


⏱ Last updated Mon Jun 22 04:35:08 UTC 2026 · 📊 GitHub API quota 768/15,000 (5% used, resets in 56m)
🚀 Powered by Aspect CLI (v0.0.0-dev)

@gregmagolan gregmagolan changed the base branch from main to feat/per-failure-repro-commands June 21, 2026 23:50
@gregmagolan gregmagolan force-pushed the feat/strata-template-style branch from 1621226 to 24eb13a Compare June 21, 2026 23:52
@gregmagolan

Copy link
Copy Markdown
Member Author

✅ Verified live on this repo's own CI

Retargeted to main temporarily, set style="strata" in .aspect/config.axl, and let the repo's CI (which dogfoods the branch build) render the surfaces. Both rendered correctly, then I retargeted back onto #1258 and removed the dogfood toggle — the branch is now a single clean feature commit.

GitHub status check (a real build that ran with low parallelism — note the verdict caught it and auto-expanded the perf section):

### 🟢 Passed, but slow
🟡 Cache hit   74%     53 / 71 actions
🔴 Parallelism 1.2×    cpu 55s
🟢 Wall time   46.2s

<details>
<summary>✅ Passed · 166 built</summary>
…
<details open>
<summary>⏱ Why it ran this way — slow</summary>
  Elapsed time:  46.2s   Analysis: 2.5s   Execution: 41.2s
  Action cache:  53 of 71 cached (74%)
  + runner + mnemonic distribution tables

GitHub PR comment (a real buildifier failure — the Fix section gave the exact reformat command):

## ✨ Aspect Workflows
### ❌ 1 task failed

- ❌ buildifier (buildifier-gha) · ⏱ 44s · …<br>💬 failed in diff · Format failed (9 files need format)
- ✅ build (build-gha-debug) · 1m 2s · …<br>💬 Bazel build complete (166 built)
- ✅ test (test-gha) · 1m 8s · …<br>💬 Bazel test complete (26/26 passed · 26 cached)
  …

### 🛠️ Fix
#### ❌ buildifier (buildifier-gha)
    bazel buildifier --severity=info -- .aspect/axl.axl …

### 🔁 Reproduce
  …

The buildifier failure it surfaced was real (my new .axl files needed formatting) — fixed in this branch. The verdict heading, KPI strip with threshold emoji, "Passed, but slow" auto-expand, the compact task list, and the Fix/Reproduce sections all render as designed across both surfaces.

Base automatically changed from feat/per-failure-repro-commands to main June 22, 2026 03:35
CI status surfaces now support a `style` arg selecting how results render.
Two styles ship built-in:

- kilgore (default) — the original full report (byte-identical to before).
- strata — a DX-focused layout that answers, in order: what broke → how to
  fix/repro it → why it was slow. Leads with a verdict heading + a compact
  monospace KPI strip (cache hit %, parallelism, wall + critical-path share,
  each with a 🟢/🟡/🔴 threshold emoji standing in for the web UI's tile color),
  shows failure snippets open by default with each failure's repro command
  beneath it, and collapses the reference sections (recoverable via the Aspect
  Web UI). The performance block auto-expands on a "Passed, but slow" verdict.

Mechanism (lib/template_styles.axl): a style is a bundle of the three
top-level Jinja2 template strings (summary/details for the check surfaces,
body for the aggregated PR/MR comment) plus render knobs. resolve_style(name,
overrides) layers the existing per-key `templates` arg on top of the named
style, so users pick a style and replace just one slot for a custom variant.
The Strata strings live in lib/strata_templates.axl; both consume the same
build_details_data / _render_body data shape (no data-layer fork), with a new
compute_strata_kpi() adding the KPI strip inputs.

Wired into all five status features: GitHub status checks, GitHub PR comment,
GitLab commit statuses, GitLab MR comment, Buildkite annotation.

Tests: lib/template_styles_test.axl (20 unit tests — resolve_style selection +
override layering, KPI thresholds, verdict words, slow-but-passing detection,
verdict-without-metrics); Strata render passes added to the template +
PR-comment snapshot suites and the inline-snippet render test in .aspect/axl.axl.
Kilgore output is unchanged. Verified live on this repo's own CI (PR comment +
GitHub status checks, including the "Passed, but slow" auto-expand).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gregmagolan gregmagolan force-pushed the feat/strata-template-style branch from 24eb13a to 1e51086 Compare June 22, 2026 03:41
Flip the `style` arg default from kilgore to strata on all five status
features (GitHub/GitLab status checks + comments, Buildkite annotations).
kilgore stays available; strata is now what users get out of the box.

`DEFAULT_STYLE` names the default in one place — both the feature `default =`
literals and the `builtin_style` empty/unknown-name fallback resolve to it, so a
mis-set arg renders the default rather than the other style. Docstrings + the
`style` arg help updated to reflect the new default.
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