Sentry Release Management
Overview
Manage the full Sentry release lifecycle: create versioned releases, associate commits for suspect commit detection, upload source maps for readable stack traces, and monitor release health with crash-free rates and adoption metrics. Every production deploy should create a Sentry release so errors are grouped by version and regressions are caught immediately.
Prerequisites
- Sentry CLI installed:
npm install -g @sentry/cli(v2.x) or usenpx @sentry/cli - Auth token with
project:releasesandorg:readscopes from sentry.io/settings/auth-tokens/ - Environment variables set:
SENTRY_AUTH_TOKEN,SENTRY_ORG,SENTRY_PROJECT - Source maps generated by your build (e.g.,
tsc --sourceMap, Vitebuild.sourcemap: true) - GitHub/GitLab integration installed in Sentry for automatic commit association (Settings > Integrations)
Instructions
Step 1 — Create a Release and Associate Commits
Choose a release naming convention. Sentry accepts any string, but two patterns dominate production usage:
Semver naming ties releases to your package version:
# Semver: my-app@2.1.0
VERSION="my-app@$(node -p "require('./package.json').version")"
sentry-cli releases new "$VERSION"
Commit SHA naming ties releases to exact deployments:
# SHA: my-app@a1b2c3d (short) or full 40-char SHA
VERSION="my-app@$(git rev-parse --short HEAD)"
sentry-cli releases new "$VERSION"
After creating the release, associate commits. This is what powers suspect commits — Sentry's ability to identify which commit likely caused a new issue by matching error stack frames to recently changed files:
# Auto-detect commits since last release (requires GitHub/GitLab integration)
sentry-cli releases set-commits "$VERSION" --auto
# Or specify a commit range manually
sentry-cli releases set-commits "$VERSION" \
--commit "my-org/my-repo@from_sha..to_sha"
When --auto runs, Sentry walks the git log from the previous release's last commit to the current HEAD. It stores each commit's author, changed files, and message. When a new error arrives, Sentry matches the stack trace file paths against recently changed files and suggests the author as the likely owner.
Step 2 — Upload Source Maps and Release Artifacts
Source maps let Sentry translate minified stack traces into original source code. Upload them before deploying — Sentry does not retroactively apply source maps to existing events.
# Upload all .js and .map files from dist/
sentry-cli sourcemaps upload \
--release="$VERSION" \
--url-prefix="~/static/js" \
--validate \
./dist
The --url-prefix must match how your JS files are served. The ~/ prefix is a wildcard that matches any scheme and host:
| Your script URL | Correct --url-prefix |
|-----------------|----------------------|
| https://example.com/static/js/app.js | ~/static/js |
| https://cdn.example.com/assets/bundle.js | ~/assets |
| https://example.com/app.js (root) | ~/ |
For multiple output directories (e.g., SSR apps):
sentry-cli sourcemaps upload \
--release="$VERSION" \
--url-prefix="~/" \
./dist/client ./dist/server
Managing release artifacts — list, inspect, and clean up uploaded files:
# List all artifacts for a release
sentry-cli releases files "$VERSION" list
# Delete all source maps for a release (free storage)
sentry-cli releases files "$VERSION" delete --all
# Upload a single file manually
sentry-cli releases files "$VERSION" upload ./dist/app.js.map
Build tool plugins (alternative to CLI uploads) — handle release creation, commit association, and source map upload automatically:
// vite.config.ts
import { sentryVitePlugin } from '@sentry/vite-plugin';
export default {
build: { sourcemap: true },
plugins: [
sentryVitePlugin({
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
release: { name: process.env.VERSION },
sourcemaps: {
assets: './dist/**',
filesToDeleteAfterUpload: ['./dist/**/*.map'],
},
}),
],
};
Step 3 — Finalize, Deploy, and Monitor Release Health
Finalize marks the release as complete. Until finalized, the release appears as "unreleased" in the UI:
sentry-cli releases finalize "$VERSION"
Finalizing affects three things: (1) issues resolved as "next release" are marked resolved, (2) the release becomes the baseline for future --auto commit detection, and (3) the activity timeline records the release.
Record the deployment to track which environments run which release:
sentry-cli releases deploys "$VERSION" new \
--env production \
--started $(date +%s) \
--finished $(date +%s)
# For staging
sentry-cli releases deploys "$VERSION" new --env staging
Match the SDK release — the release string in your Sentry SDK init must match the CLI version exactly, or events will not associate with the release:
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
release: process.env.SENTRY_RELEASE, // Must match CLI $VERSION exactly
environment: process.env.NODE_ENV,
});
Release health dashboard — after deployment, monitor these metrics at sentry.io/releases/:
- Crash-free rate: Percentage of sessions without a fatal error. Target > 99.5%.
- Adoption: Percentage of total sessions running this release. Tracks rollout progress.
- Sessions: Total session count. A session begins when a user starts the app and ends after inactivity or a crash.
- Error count: New errors first seen in this release versus regressions.
Enable session tracking in the SDK for release health data:
Sentry.init({
dsn: process.env.SENTRY_DSN,
release: process.env.SENTRY_RELEASE,
autoSessionTracking: true, // Enabled by default in browser SDK
});
Cleanup old releases to manage storage and reduce noise:
# Delete a release and all its artifacts
sentry-cli releases delete "$VERSION"
# List all releases via API
curl -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
"https://sentry.io/api/0/organizations/$SENTRY_ORG/releases/"
Output
- Release created with a version identifier tied to semver or git SHA
- Commits associated for suspect commit detection and suggested assignees
- Source maps uploaded and validated for deobfuscated stack traces
- Release finalized with deployment environment and timestamps recorded
- SDK
releasevalue matching CLI version for event-to-release correlation - Release health dashboard tracking crash-free rate, adoption, and session data
Error Handling
| Error | Cause | Solution |
|-------|-------|----------|
| error: API request failed: 401 | Auth token invalid, expired, or missing project:releases scope | Regenerate at sentry.io/settings/auth-tokens/ with project:releases + org:read |
| No commits found with --auto | GitHub/GitLab integration not installed in Sentry | Install at Settings > Integrations > GitHub, then grant repo access |
| Source maps not resolving | --url-prefix does not match actual script URLs | Open browser DevTools Network tab, copy the script URL, and set --url-prefix to match the path portion |
| Stack traces still minified | Source maps uploaded after errors were captured | Upload source maps before deploying — Sentry does not retroactively apply them to existing events |
| release already exists | Re-creating a release that was already finalized | Non-fatal: use set-commits and sourcemaps upload to update it, or use a new version string |
| release not found in SDK events | Sentry.init({ release }) does not match CLI version | Print both values and compare — they must be identical strings (case-sensitive) |
| Crash-free rate not appearing | Session tracking disabled | Verify autoSessionTracking: true in SDK init (default in browser SDKs, must be enabled in Node.js) |
See errors reference for additional troubleshooting.
Examples
Complete release script for CI/CD:
#!/bin/bash
# scripts/sentry-release.sh — run after build, before deploy
set -euo pipefail
VERSION="${1:-my-app@$(node -p "require('./package.json').version")}"
ENVIRONMENT="${2:-production}"
echo "Creating Sentry release: $VERSION → $ENVIRONMENT"
sentry-cli releases new "$VERSION"
sentry-cli releases set-commits "$VERSION" --auto
sentry-cli sourcemaps upload \
--release="$VERSION" \
--url-prefix="~/static/js" \
--validate \
./dist
sentry-cli releases finalize "$VERSION"
sentry-cli releases deploys "$VERSION" new --env "$ENVIRONMENT"
echo "Release $VERSION deployed to $ENVIRONMENT"
Monorepo with multiple Sentry projects:
# Each service gets its own release prefix
sentry-cli releases new "api@$SHA" --project api-backend
sentry-cli releases new "web@$SHA" --project web-frontend
# Upload source maps per project
SENTRY_PROJECT=api-backend sentry-cli sourcemaps upload --release="api@$SHA" ./api/dist
SENTRY_PROJECT=web-frontend sentry-cli sourcemaps upload --release="web@$SHA" ./web/dist
Query release health via API:
# Get release health stats
curl -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
"https://sentry.io/api/0/organizations/$SENTRY_ORG/releases/$VERSION/" \
| jq '{version: .version, dateCreated: .dateCreated, commitCount: .commitCount, newGroups: .newGroups}'
See examples reference for more patterns.
Resources
- Sentry Release Management (CLI) —
sentry-cli releasescommand reference - Source Map Uploads (CLI) — upload, validate, and debug source maps
- Vite Plugin —
@sentry/vite-pluginconfiguration - Webpack Plugin —
@sentry/webpack-pluginconfiguration - Releases Product Overview — UI walkthrough, suspect commits, suggested assignees
- Release Health — crash-free rate, adoption, and session tracking
- Sentry API: Releases — REST API for programmatic release management
Next Steps
- Set up CI/CD integration to automate releases on every deploy — use the
sentry-ci-integrationskill - Configure performance tracing alongside releases to correlate deploys with latency changes — use the
sentry-performance-tracingskill - Add deploy notifications to Slack/PagerDuty via Sentry's integration alerts
- Review release health after each deploy: aim for > 99.5% crash-free sessions before promoting to wider rollout
- Use
sentry-cli releases propose-versionin scripts to auto-generate version strings from git state