[RUM-18236] Improve api for upload of source maps by debug ID - #502
Conversation
|
💬 suggestion: Nice! Only comment about the public API. I’m not sure repeating debugId is ideal, consider a customer using both plugins: datadogWebpackPlugin({
auth: { apiKey: process.env.DATADOG_API_KEY, site: 'datadoghq.com' },
errorTracking: {
sourcemaps: {
debugId: true
},
},
rum: {
sourceCodeContext: {
debugId: true
},
},
});Could we instead expose something like this? {
auth: { apiKey: process.env.DATADOG_API_KEY, site: 'datadoghq.com' },
sourcemaps: {
debugId: true,
upload: true
}
} |
buranmert
left a comment
There was a problem hiding this comment.
i like the idea but i'm wondering how can we make sure RUM and Error Tracking plugins are used together?
(i'm not familiar with how to use build plugins, i assume the user picks whichever plugins they want to use)
| export type ServiceVersionSourcemapsOptionsWithDefaults = SourcemapsUploadOptionsWithDefaults & | ||
| Required< | ||
| Pick<ServiceVersionSourcemapsOptions, 'minifiedPathPrefix' | 'releaseVersion' | 'service'> | ||
| > & { | ||
| mode: SourcemapsUploadMode.SERVICE_VERSION; | ||
| }; | ||
|
|
||
| export type DebugIdSourcemapsOptionsWithDefaults = SourcemapsUploadOptionsWithDefaults & { | ||
| mode: SourcemapsUploadMode.DEBUG_ID; | ||
| }; |
There was a problem hiding this comment.
💬 suggestion: Why do we need a new type here? Instead of introducing a mode field, could we use debugId as the discriminant?
12:25 PM
There was a problem hiding this comment.
Done in 4cbb00d. I removed SourcemapsUploadMode and now use debugId as the discriminant in the normalized types and throughout file selection, payload creation, and upload metrics.
| return errors; | ||
| }; | ||
|
|
||
| const normalizeSourcemapsOptions = (options: Options, errors: string[]): Options => { |
There was a problem hiding this comment.
💬 suggestion: This function re-implements validation that rum/validate.ts and error-tracking/validate.ts already do (apiKey required, service/version conflicts, enable-flag conflicts), same rules, second place to keep in sync. Could we avoid repeating them
There was a problem hiding this comment.
The normalizer is still needed to translate the new top-level sourcemaps option into the existing RUM and Error Tracking plugin configurations. It only validates the top-level shape and cross-plugin contradictions; API-key and service/version/path validation remain in the plugin validators. The explicit enable:false checks must happen here because disabled plugins do not run their validators. Let me know if you would prefer this split to be made more explicit in naming or structure.
| // resolves; otherwise an error has been recorded and the caller will | ||
| // throw before the config is read. | ||
| if (releaseVersion) { | ||
| const { debugId: _debugId, ...serviceVersionOptions } = sourcemapsCfg; |
There was a problem hiding this comment.
❓ question: Couldn't we directly pass sourcemapsCfg instead of adding this spread?
There was a problem hiding this comment.
Yes, done in 4cbb00d. The service/version branch now spreads sourcemapsCfg directly, then sets the normalized debugId:false value and resolved releaseVersion.
| // throw before the config is read. | ||
| if (releaseVersion) { | ||
| if (toReturn.errors.length === 0) { | ||
| const { debugId: _debugId, ...uploadOptions } = sourcemapsCfg; |
There was a problem hiding this comment.
❓ question: Couldn't we directly pass sourcemapsCfg instead of adding this spread?
There was a problem hiding this comment.
Yes, done in 4cbb00d. The debug-ID branch now spreads sourcemapsCfg directly, preserving debugId:true.
| type DebugIdSourceCodeContextOptions = { | ||
| debugId: true; | ||
| service?: never; | ||
| version?: never; | ||
| }; | ||
|
|
||
| type ServiceVersionSourceCodeContextOptions = { | ||
| debugId?: false; | ||
| service: string; | ||
| version?: string; | ||
| debugId?: boolean; | ||
| }; |
There was a problem hiding this comment.
🔨 warning: This assumption is incorrect. A customer can provide source code context with both a debugId and service/version. The service and version identify and allow to filter events from a specific micro-frontend; they are independent of the unminification.
There was a problem hiding this comment.
Fixed in 4cbb00d. The debug-ID source-code-context variant now accepts optional service and version, validation preserves them, and the injected context serializes service, version, and ddDebugId together. The legacy service/version variant remains unchanged.
@buranmert @Aymeric replied:
|
|
|
||
| // Compute deterministic debug IDs whenever possible to prevent the backend from storing | ||
| // duplicate source maps for identical builds. | ||
| const debugId = |
There was a problem hiding this comment.
🥜 nitpick: Nested ternaries are difficult to read. Could we revert to the original code if the behavior is unchanged?
There was a problem hiding this comment.
Agreed, the behavior is unchanged. I've reverted this to the original variable declaration and if-statement form to avoid the nested ternary. Thanks!
| errors.push(`Sourcemap file not found: ${sourcemap.sourcemapFilePath}`); | ||
| } | ||
| if (debugIdRequired && !debugId) { | ||
| errors.push(`No debug ID found in minified file: ${sourcemap.minifiedFilePath}`); |
There was a problem hiding this comment.
💬 suggestion: I don’t think we should abort all uploads when a single file is missing a debug ID. To remain consistent with datadog-ci upload: if all debug IDs are missing, fail with exit code 1; if only some are missing, skip those files and upload the rest.
There was a problem hiding this comment.
Not fully fan with the validation flow in this file, but it could be improve in followup PRs
|
/code blockers |
|
View all feedbacks in Devflow UI.
Checking merge blockers for #502...
Detected 1 merge blocker(s) to address: 🟠 Pending
|
nchapma2
left a comment
There was a problem hiding this comment.
Approving for build-plugins. I don't really know this code at all and in the plugin files, it seems like we could do some cleaning up if debug-ids are the identifier going forward
|
/merge |
|
View all feedbacks in Devflow UI.
The expected merge time in
|
What and why?
Add direct debug-ID source-map uploads to Datadog Build Plugins. A build can now inject debug IDs and upload the corresponding source maps without configuring a service, release version, or minified path prefix.
The existing nested debug-ID and service/version workflows remain backward compatible.
How to use it
For Build Plugins to inject debug IDs and upload the source maps:
sourcemaps.debugId: trueinjects a debug ID into each generated JavaScript bundle.sourcemaps.upload: trueuploads the corresponding source maps during the build.uploadenables injection without direct upload, for example whendatadog-ciperforms the upload.auth.apiKeyorDATADOG_API_KEYis required only when direct upload is enabled.bailOnError,dryRun, andmaxConcurrencycan be configured alongsideupload: true.The existing
rum.sourceCodeContextanderrorTracking.sourcemapsconfigurations remain supported. They cannot be combined with the new top-levelsourcemapsoption.Existing service/version workflow
The legacy configuration continues to work unchanged:
Implementation
sourcemapsoption that distinguishes injection-only and upload-enabled configurations.SourcemapsUploadModediscriminator.Validation
sourcemaps: { debugId: true, upload: true }uploaded a source map to the staging intake withbailOnError: true.