ProductReleases

Releases

Tag a release in the SDK, upload JS/TS source maps, and confirm regressions with copyable commands.

Deploy versions for a project live at /p/:projectId/releases.

What is a release?

A version string on events or artifact uploads. A row appears once events or maps carry that string.

Open a row to filter Issues to release:{version}. Symbolication is JS/TS .map files only; other languages keep raw frames.

What does a release row show?

FieldMeaning
VersionSDK release value (e.g. my-app@1.0.0)
First / last seenFrom ingested events
Issue / event countsAggregates for that version
ArtifactsUploaded files (typically .map / source archives)
New / came backNew fingerprints vs regressions vs prior resolve-in-release

Tag a release in the SDK

import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "http://YOUR_PUBLIC_KEY@localhost:8080/YOUR_PROJECT_ID",
  release: "my-app@1.0.0",
  tracesSampleRate: 0,
});

Use the same string in CI when uploading artifacts.

How do I upload JS/TS maps?

Upload with DSN auth, not the dashboard cookie.

Upload a source map

Body cap 2 MB. {version} cannot contain .. / or \\.

command

curl -sS -D - -o /tmp/epure-map.json -X POST \
"http://localhost:8080/api/${PROJECT_ID}/releases/my-app@1.0.0/files/" \
-H "X-Sentry-Auth: Sentry sentry_version=7, sentry_key=${PUBLIC}, sentry_secret=${SECRET}" \
-F "name=~/dist/app.min.js.map" \
-F "file=@./dist/app.min.js.map;type=application/json"

Expected

HTTP/1.1 201 Created

{ "id": "<artifact-uuid>", "name": "~/dist/app.min.js.map" }

Artifacts land under EPURE_ARTIFACTS_DIR (compose volume artifacts_data). Back them up if you rely on demangled stacks after a restore.

StatuserrorWhat to do
400invalid_release_versionDrop .. / \ from the version segment
400invalid_release_fileMultipart field must be file
401invalid_dsnUse DSN header, not the session cookie
403dsn_revokedCreate a new key

Confirm the release on an issue

After events land with release: "my-app@1.0.0":

List releases seen on an issue

command

curl -sS -b cookies.txt \
"http://localhost:8080/api/v1/issues/${ISSUE_ID}/releases"

Expected

{ "releases": ["my-app@1.0.0"] }

UI filter: release:my-app@1.0.0 on Issues.

What is a regression?

A resolved issue whose fingerprint comes back in a newer release.

  1. Resolve an issue in a release (e.g. my-app@1.4.0)
  2. Ship a newer release with the same fingerprint
  3. Status flips to regression (is:regression / “Came back”)
  4. Matching webhooks can fire (regression): Settings

Resolve in a release

command

curl -sS -b cookies.txt -X PATCH \
"http://localhost:8080/api/v1/issues/${ISSUE_ID}" \
-H "Content-Type: application/json" \
-d '{"status":"resolved","resolved_in_release":"my-app@1.4.0"}'

Expected

{ "id": "<issue-uuid>", "status": "resolved", "resolved_in_release": "my-app@1.4.0" }

Checklist

  • SDK sets release on every environment you care about
  • CI uploads maps for that exact version string
  • Crash in production shows original file / function / line in Issues
  • Resolve-in-release → redeploy same bug → row shows regression
Why are stacks still minified?

Sentry.init({ release }) must equal {version} in the upload URL. Check the Releases UI for artifacts. Demangle is JS/TS only, so other languages stay on raw frames. Upload auth is DSN, not the session cookie: Source maps.

Why is the release row missing?

No event or artifact carries that version string yet. Capture once with release set, or upload a map. The string must match exactly, including any my-app@ prefix you chose in Sentry.init. Then filter Issues with release:.

When does an issue become a regression?

After resolve-in-release, a newer release with the same fingerprint flips status to regression. Filter with is:regression. Webhooks subscribed to regression can fire. Snooze does not create a regression: Issues.

Next