xtablo-source/docs/superpowers/specs/2026-04-22-datadog-rum-sourcemaps-via-ci-design.md
2026-04-22 22:13:30 +02:00

3.8 KiB
Raw Blame History

Datadog RUM Sourcemaps Via CI Design

Goal: Deobfuscate frontend RUM and Error Tracking stack traces in Datadog for the Xtablo frontends by generating sourcemaps during build, uploading them in CI, and keeping .map files off the public CDN.

Current State

  • apps/main initializes Datadog RUM in apps/main/src/lib/rum.ts with service: "xtablo-ui" and env: import.meta.env.MODE, but no explicit release version.
  • apps/main, apps/clients, and apps/external are Vite frontends with production Cloudflare deployments.
  • None of the three Vite configs currently emit production sourcemaps.
  • On this branch there is no tracked GitHub Actions workflow yet, so CI wiring must be introduced as part of the implementation.

Decision

Use Datadogs recommended CI upload flow:

  1. Build each frontend with Vite build.sourcemap: "hidden".
  2. Upload generated sourcemaps from CI with datadog-ci sourcemaps upload.
  3. Use a release version derived from the CI commit SHA.
  4. Remove all .map files from dist/ before deploy packaging so they are never publicly served.

This keeps sourcemaps private while still enabling unminified stack traces in Datadog.

Sources:

Runtime Contract

Datadog matches sourcemaps against browser events by service and version.

  • apps/main must emit version: import.meta.env.VITE_APP_VERSION in its RUM initialization.
  • CI must upload sourcemaps for apps/main using:
    • service=xtablo-ui
    • release-version=$GITHUB_SHA
  • apps/clients and apps/external should use the same CI release version convention now, even though they do not currently emit RUM events. This keeps the deployment contract consistent and avoids another pipeline change when browser monitoring is enabled there.

Public Asset Prefixes

The Datadog upload command must use the real production asset prefixes:

  • apps/main: https://app.xtablo.com/assets
  • apps/clients: https://clients.xtablo.com/assets
  • apps/external: https://embed.xtablo.com/assets

These prefixes must match the actual URLs used by the deployed JS bundles.

Implementation Shape

Frontend code

  • apps/main/src/lib/rum.ts
    • add version: import.meta.env.VITE_APP_VERSION
  • apps/main/src/vite-env.d.ts
    • declare VITE_APP_VERSION
  • apps/clients/src/vite-env.d.ts
    • create and declare VITE_APP_VERSION
  • apps/external/src/vite-env.d.ts
    • declare VITE_APP_VERSION

Build config

  • apps/main/vite.config.ts
  • apps/clients/vite.config.ts
  • apps/external/vite.config.ts

Each should emit hidden sourcemaps for non-test builds.

CI

  • Add GitHub Actions workflow for frontend builds on self-hosted runners.
  • Add @datadog/datadog-ci as a root dev dependency so the workflow can run a pinned CLI version from the repo.
  • After each frontend build:
    • upload sourcemaps to Datadog
    • delete dist/**/*.map

Secrets And CI Inputs

The workflow needs:

  • DATADOG_API_KEY
  • DATADOG_SITE
  • release version from github.sha

The workflow should fail fast if Datadog secrets are missing on the deployment path where sourcemap upload is required.

Verification

  • Unit test for apps/main RUM init to assert version is wired from env.
  • Vite config tests or config assertions for all three apps to verify production builds use sourcemap: "hidden".
  • CI workflow smoke verification:
    • build the apps
    • run sourcemap upload
    • confirm .map files are removed from dist

Non-Goals

  • Enabling Datadog RUM in apps/clients or apps/external right now.
  • Serving sourcemaps publicly.
  • Changing app deployment hosts or CDN paths.