Skip to content

Source build version from shared metadata.version#326

Open
watson wants to merge 3 commits intomasterfrom
watson/DEBUG-5465/inject-version-at-runtime
Open

Source build version from shared metadata.version#326
watson wants to merge 3 commits intomasterfrom
watson/DEBUG-5465/inject-version-at-runtime

Conversation

@watson
Copy link
Copy Markdown
Contributor

@watson watson commented Apr 21, 2026

What and why?

This PR makes metadata.version the canonical place to declare the deployed build identifier across the Datadog build plugins. Three plugins now read from it:

  • Live Debugger injects the value into the bundle so the Browser Debugger SDK uses it as the default version during init() — keeping browser build lookup and source-code resolution working without extra SDK wiring.
  • Error Tracking (errorTracking.sourcemaps.releaseVersion) falls back to it when no plugin-specific value is set.
  • RUM (rum.sourceCodeContext.version) falls back to it when no plugin-specific value is set.

Users who declare the build version once at the top level no longer need to repeat it under each plugin namespace. The change is additive: existing per-plugin configurations keep working unchanged.

This builds on #325, which introduced build-time validation of the version but stopped short of using it at runtime.

How?

  • BuildMetadata (in @dd/core/types) gains an optional version?: string, alongside the existing name. The root README documents it as a top-level option, and the auto-generated configuration block template in @dd/tools is updated to include it.
  • Type-validation of metadata.* is centralized in the factory's validateOptions. Today it strictly type-checks metadata.version. A TODO flags metadata.name to be tightened in the next major — its documented default is currently null, so adding the check now would be a breaking change.
  • The Live Debugger validator keeps a plugin-specific cross-check: metadata.version must match errorTracking.sourcemaps.releaseVersion when both are explicitly configured.
  • The Live Debugger plugin builds its injected banner through a dedicated runtime-bootstrap helper. The bootstrap installs the minimal $dd_probes no-op stub, and when metadata.version is set it also exposes build metadata on a runtime-visible global so the Browser Debugger SDK can default its version from there during init().
  • SourcemapsOptions.releaseVersion is loosened from required to optional. The existing "is required" check still fires when neither sourcemaps.releaseVersion nor metadata.version resolves, with an updated message that mentions both options.

Copy link
Copy Markdown
Contributor Author

watson commented Apr 21, 2026

@watson watson marked this pull request as ready for review April 21, 2026 10:40
@watson watson requested review from a team and yoannmoinet as code owners April 21, 2026 10:40
@watson watson force-pushed the watson/DEBUG-5465/inject-version-at-runtime branch from eb80c25 to a800ced Compare April 22, 2026 14:42
watson added 2 commits April 28, 2026 06:38
Expose the configured `liveDebugger.version` in the injected runtime
bootstrap so the Browser Debugger SDK can default its runtime version
from build metadata. Move the bootstrap logic into a dedicated helper
and document the new behavior.
The deployed build identifier is a cross-plugin concern rather than a
Live Debugger one. Move it from `liveDebugger.version` onto the shared
`metadata.version` field, alongside the existing `metadata.name`.

Type-validation of the shared `metadata` block is centralized in the
factory's `validateOptions`, so consumers don't each re-implement it.
Only `metadata.version` is validated today: a TODO in factory/validate.ts
flags that `metadata.name` should also be tightened in the next major,
since the root README has long documented its default as `null`, and
adding the check now would break users who took that literally.

The Live-Debugger-specific invariant — `metadata.version` must match
`errorTracking.sourcemaps.releaseVersion` when both are configured —
stays in the live-debugger validator, since that's the plugin enforcing it.
@watson watson force-pushed the watson/DEBUG-5465/inject-version-at-runtime branch from a800ced to eeba682 Compare April 28, 2026 04:38
@watson watson changed the title Inject live-debugger build metadata for SDK init Inject build metadata for Live Debugger SDK init Apr 28, 2026
Have `errorTracking.sourcemaps.releaseVersion` and
`rum.sourceCodeContext.version` fall back to the shared `metadata.version`
when no plugin-specific value is configured. Users who declare the build
version once at the top level no longer need to repeat it under each
plugin namespace.

To support the fallback, `SourcemapsOptions.releaseVersion` is loosened
from required to optional. The existing "is required" check still fires
when neither `sourcemaps.releaseVersion` nor `metadata.version` resolves,
with an updated message that mentions both options.

Document `metadata.version` as a top-level option in the root README so it
sits alongside `metadata.name`, and update the auto-generated
configuration block template in `@dd/tools` accordingly.
@watson watson requested a review from a team as a code owner April 28, 2026 05:15
@watson watson changed the title Inject build metadata for Live Debugger SDK init Source build version from shared metadata.version Apr 28, 2026
Copy link
Copy Markdown
Member

@yoannmoinet yoannmoinet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand why the errorTracking concern is handled by the liveDebugger plugin.

I don't think these two plugins should know anything about each others.

```

Optional. When set, use an immutable deployed browser build identifier. This value should match:
If both `metadata.version` and an explicit `errorTracking.sourcemaps.releaseVersion` are configured and disagree, this plugin surfaces the mismatch as a build error.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is super relevant for the Live Debugger plugin's documentation.

Comment on lines +26 to +28
if (metadataVersion && sourcemapReleaseVersion && metadataVersion !== sourcemapReleaseVersion) {
errors.push(
`${red('version')} must match ${red('errorTracking.sourcemaps.releaseVersion')} when both Live Debugger and sourcemap upload are configured`,
`${red('metadata.version')} must match ${red('errorTracking.sourcemaps.releaseVersion')} when both Live Debugger and sourcemap upload are configured`,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to have this validation in the live debugger plugin?

I would probably see this more in the error tracking plugin instead.

Comment on lines +20 to +21
const makeConfig = (liveDebugger?: unknown, errorTracking?: unknown, metadata?: unknown): Options =>
({ liveDebugger, errorTracking, metadata }) as unknown as Options;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: not a fan of all these unknown casting.
All the types are accessible and we have a bunch of mocks to alleviate the burden of mocking these out.

Comment on lines +106 to +109
// Build the resolved config only when `releaseVersion` actually
// resolves; otherwise an error has been recorded and the caller will
// throw before the config is read.
if (releaseVersion) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this if () {} wrapping is really necessary.
It brings more confusion when reading the code than anything.

Even the comment tends to explain that it's actually unnecessary since it would throw anyways.


export type LiveDebuggerOptions = {
enable?: boolean;
version?: string;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's acceptable to remove it from the public API since the plugin didn't actually release publicly yet, but just to confirm it's not been missed.

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.

3 participants