Skip to content

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

Merged
BYK merged 18 commits intomainfrom
feat/release-health
Apr 9, 2026
Merged

feat(release): surface adoption and health metrics in list and view (#463)#680
BYK merged 18 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

@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 🐛

Dashboard

  • Add --layout flag to widget add for predictable placement by BYK in #700
  • Render tracemetrics widgets in dashboard view by BYK in #695

Other

  • (init) Narrow command validation to actual shell injection vectors by betegon in #697
  • (init,feedback) Default to tracing only in feature select and attach user email to feedback by MathurAditya724 in #688

Internal Changes 🔧

  • (docs) Gitignore generated command docs, extract fragments by BYK in #696
  • (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-09 13:07 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 85.77%. Project has 1523 uncovered lines.
❌ Project coverage is 95.35%. 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.47%    95.35%    -0.12%
==========================================
  Files          224       225        +1
  Lines        32591     32782      +191
  Branches         0         0         —
==========================================
+ Hits         31115     31259      +144
- Misses        1476      1523       +47
- Partials         0         0         —

Generated by Codecov Action

@BYK BYK marked this pull request as ready for review April 7, 2026 13:39
BYK and others added 13 commits April 9, 2026 11:11
…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
Address Cursor Bugbot review — deduplicate the percentage and count
formatting helpers into a shared module imported by both list and view.
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
…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)
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.
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
…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.
…ect guarantee

Rewrite auto-detect handler to properly handle multiple detected projects,
following the issue list pattern:

- Fetch from ALL detected projects in parallel (not just the primary)
- Tag each release with targetProject for the PROJECT column
- Client-side sort by dateCreated descending after merging
- Guarantee at least 1 release per project in trimmed output
- Dynamic columns: add PROJECT column only in multi-project mode
- Smart env default still applied from primary (highest-ranked) target
- Properly show resolveAllTargets footer with all detected projects

Ranking heuristic (for env default): src/lib/app/ paths rank highest,
root-level configs rank middle, docs/test/scripts rank lowest.
…ted dashes

Address Bugbot review:
- Replace hardcoded sortByDateDesc with configurable buildMergeSorter
  that maps each --sort value to the correct release field
- Make fmtCrashFree return colorTag("muted", "—") for null values,
  consistent with other columns (ADOPTION, CRASHES)
…argets

The production environment auto-default only ran in the auto-detect
override, not for explicit targets like sentry/cli. Move the env
resolution into func() via resolveEnvForParsedTarget so it applies
to explicit mode too. Shows "Environment: production (use -e to change)"
hint when auto-defaulting.
@BYK BYK force-pushed the feat/release-health branch from 9bff128 to 10a305a Compare April 9, 2026 11:14
…shes

- Fix inline comment in func() that incorrectly claimed env default
  applies to project-search mode (it only handles explicit mode)
- Wrap fmtPct/fmtCount results with mutedIfDash in view.ts health
  table so null values show as muted "—" consistently with fmtCrashFree
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.

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 75f18af. Configure here.

@BYK BYK merged commit 74898e8 into main Apr 9, 2026
27 checks passed
@BYK BYK deleted the feat/release-health branch April 9, 2026 13: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.

Add release command group with adoption/health subcommand

1 participant