Skip to content

feat(release): surface adoption and health metrics in list and view (#463)#680

Open
BYK wants to merge 14 commits intomainfrom
feat/release-health
Open

feat(release): surface adoption and health metrics in list and view (#463)#680
BYK wants to merge 14 commits intomainfrom
feat/release-health

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented Apr 7, 2026

Summary

  • Add per-project health/adoption data to release list and release view commands
  • Pass health=1 to the releases API so adoption and crash-free metrics are populated
  • Add ADOPTION and CRASH-FREE columns to the list table; add per-project health breakdown to view
  • Closes Add release command group with adoption/health subcommand #463

Changes

API layer (src/lib/api/releases.ts):

  • listReleasesPaginated gains health?: boolean option
  • getRelease gains optional { health, adoptionStages, healthStatsPeriod } query params
  • Export ReleaseSortValue type for future --sort support

List command (src/commands/release/list.ts):

  • Always requests health=1 in both listForOrg and listPaginated
  • Replaces STATUS/RELEASED columns with ADOPTION/CRASH-FREE/ISSUES columns
  • Health data extracted from first project with hasHealthData: true

View command (src/commands/release/view.ts):

  • Requests health=true, adoptionStages=true on every view
  • Adds "Health by Project" table section with per-project metrics
  • Color-coded crash-free rates (green ≥99%, yellow ≥95%, red <95%)
  • Section gracefully omitted when no project has session data

Tests (test/commands/release/view.test.ts):

  • Health data rendering (human mode): checks section header, project slugs, percentages
  • Health data in JSON: verifies projects[].healthData fields pass through
  • No-health fallback: verifies section is omitted when hasHealthData: false

…463)

Add health/adoption data to the existing release commands:

- Pass `health=1` to the list endpoint so each release includes
  per-project adoption and crash-free metrics
- Add ADOPTION and CRASH-FREE columns to `release list` table
- Add `health`, `adoptionStages`, and `healthStatsPeriod` query
  options to `getRelease()` API function
- Show per-project health breakdown table in `release view`
  (crash-free users/sessions, adoption %, 24h user/session counts)
- Color-code crash-free rates (green ≥ 99%, yellow ≥ 95%, red < 95%)
- Gracefully omit health section when no project has session data
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (commands) Add buildRouteMap wrapper with standard subcommand aliases by BYK in #690

Bug Fixes 🐛

  • (init,feedback) Default to tracing only in feature select and attach user email to feedback by MathurAditya724 in #688

Internal Changes 🔧

  • (eval) Replace OpenAI with Anthropic SDK in init-eval judge by betegon in #683
  • (init) Use markdown pipeline for spinner messages by betegon in #686
  • Regenerate skill files and command docs by github-actions[bot] in 584ec0e0

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/pr-preview/pr-680/

Built to branch gh-pages at 2026-04-08 20:20 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Codecov Results 📊

134 passed | Total: 134 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

✅ Patch coverage is 84.74%. Project has 1513 uncovered lines.
❌ Project coverage is 95.38%. Comparing base (base) to head (head).

Files with missing lines (3)
File Patch % Lines
src/lib/api/releases.ts 34.09% ⚠️ 29 Missing
src/lib/sentry-urls.ts 0.00% ⚠️ 5 Missing
src/lib/formatters/numbers.ts 91.67% ⚠️ 4 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    95.44%    95.38%    -0.06%
==========================================
  Files          224       225        +1
  Lines        32538     32721      +183
  Branches         0         0         —
==========================================
+ Hits         31052     31208      +156
- Misses        1486      1513       +27
- Partials         0         0         —

Generated by Codecov Action

@BYK BYK marked this pull request as ready for review April 7, 2026 13:39
Address Cursor Bugbot review — deduplicate the percentage and count
formatting helpers into a shared module imported by both list and view.
BYK and others added 4 commits April 7, 2026 14:12
Support sorting releases by: date (default), sessions, users,
crash_free_sessions, crash_free_users. Switches from buildOrgListCommand
to buildListCommand to support the custom flag (-s alias).
…ses and session sparklines

- Extract compactFormatter, formatNumber, fmtPct, fmtCount, appendUnitSuffix,
  formatWithUnit, formatCompactWithUnit into src/lib/formatters/numbers.ts
- Update dashboard.ts to import from shared module (no behavior change)
- Delete src/commands/release/format.ts — replaced by shared module
- Add sort aliases: stable_sessions/cfs → crash_free_sessions,
  stable_users/cfu → crash_free_users
- Add SESSIONS sparkline column to release list table using health stats
  time-series data (same [timestamp, count] format as issue stats)
- Drop COMMITS column from list to make room for sparkline
BYK and others added 2 commits April 8, 2026 18:37
…e URLs

Major enhancements to `release list` to match the Sentry releases page:

API layer:
- Add project (numeric ID[]), environment (string[]), statsPeriod,
  and status query params to listReleasesPaginated
- Add listReleasesForProject helper that resolves slug → numeric ID
- Add buildReleaseUrl to sentry-urls.ts (URI-encoded versions)

New flags:
- --environment/-e: filter by environment (e.g., production)
- --period/-t: health stats period (default 90d, matching web UI)
- --status: open (default) or archived

Project scoping:
- Wire listForProject in OrgListConfig so DSN auto-detection and
  explicit org/project targets scope releases to the detected project

Rich styling (matching issue list patterns):
- Bold version names linked to Sentry release page
- 2-line VERSION cell: version + muted "age | deploy-env" subtitle
- Colored adoption: green ≥50%, yellow ≥10%
- Colored crash-free rate: green ≥99%, yellow ≥95%, red <95%
- Colored crashes: red when >0, green when 0
- Muted session sparklines
- Muted row separators between rows
- Right-aligned numeric columns (ADOPTION, CRASH-FREE, CRASHES, NEW ISSUES)
BYK added 2 commits April 8, 2026 18:48
Export fmtCrashFree from view.ts and import in list.ts instead of
maintaining two identical implementations (addresses Bugbot review).
The default auto-detect handler only resolves org slugs and fetches ALL
releases in the org, burying project-specific releases in noise. Override
auto-detect to use resolveAllTargets which gets org+project+projectId
from DSN detection, then pass numeric project IDs to the API for scoped
results. This matches how issue list handles project-scoped auto-detect.
value: (r) => (r.dateReleased ? "Finalized" : "Unreleased"),
header: "CRASH-FREE",
value: (r) => fmtCrashFree(getHealthData(r)?.crashFreeSessions),
align: "right",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Inconsistent missing-value styling in list table columns

Low Severity

The CRASH-FREE column uses fmtCrashFree which returns a plain "—" for missing values, while the ADOPTION and CRASHES columns in the same table use colorTag("muted", "—"). This causes mismatched styling within a single row — some dashes appear dimmed and others appear at full brightness. fmtCrashFree was designed for view.ts markdown tables where plain text is fine, but in the list table context it breaks the visual consistency established by the other columns.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 71591f1. Configure here.

BYK and others added 2 commits April 8, 2026 19:05
Environment filtering:
- Support multiple -e flags: -e production -e development
- Support comma-separated: -e production,development
- Variadic flag via Stricli variadic: true

Smart production default:
- When no --environment is passed and a single project is auto-detected,
  call listProjectEnvironments to check if "production" or "prod" exists
- Auto-select it as the default, matching the Sentry web UI behavior
- Show "Environment: production (use -e to change)" hint so it is clear
- One lightweight API call (project environments list), cached by region

API layer:
- Add listProjectEnvironments using @sentry/api listAProject_sEnvironments
- Returns Array<{ id, name, isHidden }> for visible environments
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 82e0bd2. Configure here.

return colorTag("yellow", formatted);
}
return colorTag("red", formatted);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing muted styling for null crash-free values in list

Low Severity

In the per-project health table, fmtCrashFree returns a plain em-dash ("—") for null/undefined values. This creates a visual inconsistency, as adjacent columns (e.g., ADOPTION, USERS) render their missing data placeholders as a muted em-dash. The CRASH-FREE column's dash appears unstyled, contrasting with the muted dashes in neighboring columns.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 82e0bd2. Configure here.

…ection

When multiple DSNs are detected (e.g., cli from src/lib/constants.ts and
cli-website from docs/sentry.client.config.js), rank targets by source
path: src/lib/app/ and .env files get priority 0, root-level configs
get priority 1, docs/test/scripts get priority 2. Picks only the top-
ranked target for auto-detect, preventing mixed releases from unrelated
projects.
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.

Add release command group with adoption/health subcommand

1 participant