feat(analytics): upload web source maps to Sentry + tie release to build (#369)

* feat(analytics): upload web source maps to Sentry + tie release to build

Web crash reports were unusable: the bundle ships minified with no source
maps uploaded, and every build reported as the frozen APP_VERSION, so a
Sentry error showed an unreadable stack under a single release.

- Add @sentry/vite-plugin: emit hidden source maps and upload them by debug
  id when SENTRY_AUTH_TOKEN is present (published Docker build only), then
  delete the maps so they never ship. No-op for dev and the source archive.
- Set the Sentry release from SENTRY_RELEASE / VITE_SENTRY_RELEASE (the Docker
  build passes the release version), falling back to APP_VERSION.
- Relax beforeSend so app bundle frames keep a host-stripped path (Sentry needs
  it to match the uploaded map) while the instance hostname, error message, and
  PII stay stripped. Filesystem paths still collapse to the basename.
- Wire the Dockerfile (sentry_auth_token build secret + SENTRY_RELEASE arg/env)
  and the release docker job.

* fix(analytics): point source map upload at the snapotter org (project node)
This commit is contained in:
SnapOtter
2026-06-29 10:47:30 +08:00
committed by GitHub
parent 9819c5885e
commit 1c202c6ef0
10 changed files with 386 additions and 10 deletions
+14 -1
View File
@@ -73,8 +73,16 @@ RUN SNAPOTTER_POSTHOG_KEY="${SNAPOTTER_POSTHOG_KEY}" \
SNAPOTTER_SENTRY_DSN="${SNAPOTTER_SENTRY_DSN}" \
node scripts/bake-analytics.mjs ${SNAPOTTER_ANALYTICS}
# Build only the web frontend (API runs from TS source via tsx)
# Build only the web frontend (API runs from TS source via tsx). When a
# SENTRY_AUTH_TOKEN build secret is supplied (the published image build does),
# the Sentry Vite plugin uploads source maps for SENTRY_RELEASE; without it the
# plugin is a no-op and no maps are emitted.
ARG SENTRY_RELEASE=
RUN --mount=type=cache,id=turbo-cache,target=/app/.turbo \
--mount=type=secret,id=sentry_auth_token,required=false \
SENTRY_AUTH_TOKEN="$(cat /run/secrets/sentry_auth_token 2>/dev/null || true)" \
SENTRY_RELEASE="${SENTRY_RELEASE}" \
VITE_SENTRY_RELEASE="${SENTRY_RELEASE}" \
pnpm --filter @snapotter/web build
# ============================================
@@ -420,6 +428,11 @@ ENV PORT=1349 \
OIDC_ENABLED=false \
EXTERNAL_URL=
# Sentry release for the API runtime, matching the source maps the web build
# uploaded. Empty for non-image builds, where the API falls back to APP_VERSION.
ARG SENTRY_RELEASE=
ENV SENTRY_RELEASE=${SENTRY_RELEASE}
# COOKIE_SECRET is intentionally not baked in: the app auto-generates and persists one
# on first boot if unset (see apps/api/src/index.ts). Override via runtime env to pin it.