dd-trace 2.22.2 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +108 -43
  2. package/ci/init.js +6 -1
  3. package/ext/exporters.d.ts +2 -1
  4. package/ext/exporters.js +2 -1
  5. package/index.d.ts +6 -1
  6. package/package.json +2 -2
  7. package/packages/datadog-instrumentations/src/http/server.js +4 -1
  8. package/packages/datadog-instrumentations/src/jest.js +26 -9
  9. package/packages/datadog-instrumentations/src/mocha.js +12 -3
  10. package/packages/datadog-instrumentations/src/opensearch.js +1 -1
  11. package/packages/datadog-instrumentations/src/router.js +1 -1
  12. package/packages/datadog-plugin-cucumber/src/index.js +1 -1
  13. package/packages/datadog-plugin-http/src/server.js +2 -1
  14. package/packages/datadog-plugin-jest/src/index.js +21 -25
  15. package/packages/datadog-plugin-mocha/src/index.js +11 -18
  16. package/packages/datadog-plugin-mongodb-core/src/index.js +3 -3
  17. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +4 -0
  18. package/packages/dd-trace/src/appsec/index.js +6 -1
  19. package/packages/dd-trace/src/appsec/remote_config/index.js +23 -2
  20. package/packages/dd-trace/src/appsec/remote_config/manager.js +1 -1
  21. package/packages/dd-trace/src/appsec/rule_manager.js +58 -1
  22. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +62 -0
  23. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +8 -1
  24. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +11 -59
  25. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +9 -1
  26. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +196 -0
  27. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +20 -7
  28. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +22 -19
  29. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -18
  30. package/packages/dd-trace/src/config.js +10 -8
  31. package/packages/dd-trace/src/exporter.js +3 -0
  32. package/packages/dd-trace/src/exporters/agent/index.js +4 -0
  33. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +82 -0
  34. package/packages/dd-trace/src/plugin_manager.js +0 -8
  35. package/packages/dd-trace/src/plugins/ci_plugin.js +9 -50
  36. package/packages/dd-trace/src/plugins/util/ci.js +35 -2
  37. package/packages/dd-trace/src/plugins/util/test.js +4 -0
  38. package/packages/dd-trace/src/plugins/util/web.js +1 -2
  39. package/packages/dd-trace/src/profiling/exporters/agent.js +4 -0
  40. package/packages/dd-trace/src/proxy.js +4 -18
  41. package/packages/dd-trace/src/ritm.js +18 -13
  42. package/packages/dd-trace/src/telemetry/dependencies.js +11 -1
@@ -44,7 +44,7 @@ function getCommonRequestOptions (url) {
44
44
  * The response are the commits for which the backend already has information
45
45
  * This response is used to know which commits can be ignored from there on
46
46
  */
47
- function getCommitsToExclude ({ url, repositoryUrl }, callback) {
47
+ function getCommitsToExclude ({ url, isEvpProxy, repositoryUrl }, callback) {
48
48
  const latestCommits = getLatestCommits()
49
49
  const [headCommit] = latestCommits
50
50
 
@@ -59,6 +59,12 @@ function getCommitsToExclude ({ url, repositoryUrl }, callback) {
59
59
  path: '/api/v2/git/repository/search_commits'
60
60
  }
61
61
 
62
+ if (isEvpProxy) {
63
+ options.path = '/evp_proxy/v2/api/v2/git/repository/search_commits'
64
+ options.headers['X-Datadog-EVP-Subdomain'] = 'api'
65
+ delete options.headers['dd-api-key']
66
+ }
67
+
62
68
  const localCommitData = JSON.stringify({
63
69
  meta: {
64
70
  repository_url: repositoryUrl
@@ -87,7 +93,7 @@ function getCommitsToExclude ({ url, repositoryUrl }, callback) {
87
93
  /**
88
94
  * This function uploads a git packfile
89
95
  */
90
- function uploadPackFile ({ url, packFileToUpload, repositoryUrl, headCommit }, callback) {
96
+ function uploadPackFile ({ url, isEvpProxy, packFileToUpload, repositoryUrl, headCommit }, callback) {
91
97
  const form = new FormData()
92
98
 
93
99
  const pushedSha = JSON.stringify({
@@ -125,6 +131,13 @@ function uploadPackFile ({ url, packFileToUpload, repositoryUrl, headCommit }, c
125
131
  ...form.getHeaders()
126
132
  }
127
133
  }
134
+
135
+ if (isEvpProxy) {
136
+ options.path = '/evp_proxy/v2/api/v2/git/repository/packfile'
137
+ options.headers['X-Datadog-EVP-Subdomain'] = 'api'
138
+ delete options.headers['dd-api-key']
139
+ }
140
+
128
141
  request(form, options, (err, _, statusCode) => {
129
142
  if (err) {
130
143
  const error = new Error(`Could not upload packfiles: status code ${statusCode}: ${err.message}`)
@@ -137,16 +150,14 @@ function uploadPackFile ({ url, packFileToUpload, repositoryUrl, headCommit }, c
137
150
  /**
138
151
  * This function uploads git metadata to CI Visibility's backend.
139
152
  */
140
- function sendGitMetadata (site, callback) {
141
- const url = new URL(`https://api.${site}`)
142
-
153
+ function sendGitMetadata (url, isEvpProxy, callback) {
143
154
  const repositoryUrl = getRepositoryUrl()
144
155
 
145
156
  if (!repositoryUrl) {
146
157
  return callback(new Error('Repository URL is empty'))
147
158
  }
148
159
 
149
- getCommitsToExclude({ url, repositoryUrl }, (err, commitsToExclude, headCommit) => {
160
+ getCommitsToExclude({ url, repositoryUrl, isEvpProxy }, (err, commitsToExclude, headCommit) => {
150
161
  if (err) {
151
162
  return callback(err)
152
163
  }
@@ -172,6 +183,7 @@ function sendGitMetadata (site, callback) {
172
183
  {
173
184
  packFileToUpload: packFilesToUpload[packFileIndex++],
174
185
  url,
186
+ isEvpProxy,
175
187
  repositoryUrl,
176
188
  headCommit
177
189
  },
@@ -181,8 +193,9 @@ function sendGitMetadata (site, callback) {
181
193
 
182
194
  uploadPackFile(
183
195
  {
184
- url,
185
196
  packFileToUpload: packFilesToUpload[packFileIndex++],
197
+ url,
198
+ isEvpProxy,
186
199
  repositoryUrl,
187
200
  headCommit
188
201
  },
@@ -3,7 +3,7 @@ const id = require('../../id')
3
3
 
4
4
  function getItrConfiguration ({
5
5
  url,
6
- site,
6
+ isEvpProxy,
7
7
  env,
8
8
  service,
9
9
  repositoryUrl,
@@ -15,28 +15,31 @@ function getItrConfiguration ({
15
15
  runtimeVersion,
16
16
  branch
17
17
  }, done) {
18
- const intakeUrl = url || new URL(`https://api.${site}`)
19
-
20
- const apiKey = process.env.DATADOG_API_KEY || process.env.DD_API_KEY
21
- const appKey = process.env.DATADOG_APP_KEY ||
22
- process.env.DD_APP_KEY ||
23
- process.env.DATADOG_APPLICATION_KEY ||
24
- process.env.DD_APPLICATION_KEY
25
-
26
- if (!apiKey || !appKey) {
27
- done(new Error('App key or API key undefined'))
28
- return
29
- }
30
-
31
18
  const options = {
32
19
  path: '/api/v2/libraries/tests/services/setting',
33
20
  method: 'POST',
34
21
  headers: {
35
- 'dd-api-key': apiKey,
36
- 'dd-application-key': appKey,
37
22
  'Content-Type': 'application/json'
38
23
  },
39
- url: intakeUrl
24
+ url
25
+ }
26
+
27
+ if (isEvpProxy) {
28
+ options.path = '/evp_proxy/v2/api/v2/libraries/tests/services/setting'
29
+ options.headers['X-Datadog-EVP-Subdomain'] = 'api'
30
+ options.headers['X-Datadog-NeedsAppKey'] = 'true'
31
+ } else {
32
+ const apiKey = process.env.DATADOG_API_KEY || process.env.DD_API_KEY
33
+ const appKey = process.env.DATADOG_APP_KEY ||
34
+ process.env.DD_APP_KEY ||
35
+ process.env.DATADOG_APPLICATION_KEY ||
36
+ process.env.DD_APPLICATION_KEY
37
+
38
+ if (!apiKey || !appKey) {
39
+ return done(new Error('App key or API key undefined'))
40
+ }
41
+ options.headers['dd-api-key'] = apiKey
42
+ options.headers['dd-application-key'] = appKey
40
43
  }
41
44
 
42
45
  const data = JSON.stringify({
@@ -76,8 +79,8 @@ function getItrConfiguration ({
76
79
  } = JSON.parse(res)
77
80
 
78
81
  done(null, { isCodeCoverageEnabled, isSuitesSkippingEnabled })
79
- } catch (e) {
80
- done(e)
82
+ } catch (err) {
83
+ done(err)
81
84
  }
82
85
  }
83
86
  })
@@ -2,7 +2,7 @@ const request = require('../../exporters/common/request')
2
2
 
3
3
  function getSkippableSuites ({
4
4
  url,
5
- site,
5
+ isEvpProxy,
6
6
  env,
7
7
  service,
8
8
  repositoryUrl,
@@ -13,28 +13,32 @@ function getSkippableSuites ({
13
13
  runtimeName,
14
14
  runtimeVersion
15
15
  }, done) {
16
- const intakeUrl = url || new URL(`https://api.${site}`)
17
-
18
- const apiKey = process.env.DATADOG_API_KEY || process.env.DD_API_KEY
19
- const appKey = process.env.DATADOG_APP_KEY ||
20
- process.env.DD_APP_KEY ||
21
- process.env.DATADOG_APPLICATION_KEY ||
22
- process.env.DD_APPLICATION_KEY
23
-
24
- if (!apiKey || !appKey) {
25
- return done(new Error('API key or Application key are undefined.'))
26
- }
27
-
28
16
  const options = {
29
17
  path: '/api/v2/ci/tests/skippable',
30
18
  method: 'POST',
31
19
  headers: {
32
- 'dd-api-key': apiKey,
33
- 'dd-application-key': appKey,
34
20
  'Content-Type': 'application/json'
35
21
  },
36
22
  timeout: 15000,
37
- url: intakeUrl
23
+ url
24
+ }
25
+
26
+ if (isEvpProxy) {
27
+ options.path = '/evp_proxy/v2/api/v2/ci/tests/skippable'
28
+ options.headers['X-Datadog-EVP-Subdomain'] = 'api'
29
+ options.headers['X-Datadog-NeedsAppKey'] = 'true'
30
+ } else {
31
+ const apiKey = process.env.DATADOG_API_KEY || process.env.DD_API_KEY
32
+ const appKey = process.env.DATADOG_APP_KEY ||
33
+ process.env.DD_APP_KEY ||
34
+ process.env.DATADOG_APPLICATION_KEY ||
35
+ process.env.DD_APPLICATION_KEY
36
+
37
+ if (!apiKey || !appKey) {
38
+ return done(new Error('App key or API key undefined'))
39
+ }
40
+ options.headers['dd-api-key'] = apiKey
41
+ options.headers['dd-application-key'] = appKey
38
42
  }
39
43
 
40
44
  const data = JSON.stringify({
@@ -68,8 +72,8 @@ function getSkippableSuites ({
68
72
  .filter(({ type }) => type === 'suite')
69
73
  .map(({ attributes: { suite } }) => suite)
70
74
  done(null, skippableSuites)
71
- } catch (e) {
72
- done(e)
75
+ } catch (err) {
76
+ done(err)
73
77
  }
74
78
  }
75
79
  })
@@ -3,7 +3,6 @@
3
3
  const fs = require('fs')
4
4
  const os = require('os')
5
5
  const URL = require('url').URL
6
- const path = require('path')
7
6
  const log = require('./log')
8
7
  const pkg = require('./pkg')
9
8
  const coalesce = require('koalas')
@@ -114,8 +113,11 @@ class Config {
114
113
  process.env.DD_TRACE_URL,
115
114
  null
116
115
  )
116
+ const DD_IS_CIVISIBILITY = coalesce(
117
+ options.isCiVisibility,
118
+ false
119
+ )
117
120
  const DD_CIVISIBILITY_AGENTLESS_URL = process.env.DD_CIVISIBILITY_AGENTLESS_URL
118
- const DD_CIVISIBILITY_AGENTLESS_ENABLED = process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED
119
121
 
120
122
  const DD_CIVISIBILITY_ITR_ENABLED = coalesce(
121
123
  process.env.DD_CIVISIBILITY_ITR_ENABLED,
@@ -221,8 +223,7 @@ class Config {
221
223
 
222
224
  const DD_APPSEC_RULES = coalesce(
223
225
  appsec.rules,
224
- process.env.DD_APPSEC_RULES,
225
- path.join(__dirname, 'appsec', 'recommended.json')
226
+ process.env.DD_APPSEC_RULES
226
227
  )
227
228
  const DD_APPSEC_TRACE_RATE_LIMIT = coalesce(
228
229
  parseInt(appsec.rateLimit),
@@ -379,10 +380,11 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
379
380
  maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS
380
381
  }
381
382
 
382
- const isCiVisibilityAgentlessEnabled = isTrue(DD_CIVISIBILITY_AGENTLESS_ENABLED)
383
- this.isIntelligentTestRunnerEnabled = isCiVisibilityAgentlessEnabled && isTrue(DD_CIVISIBILITY_ITR_ENABLED)
384
- this.isGitUploadEnabled = this.isIntelligentTestRunnerEnabled ||
385
- (isCiVisibilityAgentlessEnabled && isTrue(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
383
+ this.isCiVisibility = isTrue(DD_IS_CIVISIBILITY)
384
+
385
+ this.isIntelligentTestRunnerEnabled = this.isCiVisibility && isTrue(DD_CIVISIBILITY_ITR_ENABLED)
386
+ this.isGitUploadEnabled = this.isCiVisibility &&
387
+ (this.isIntelligentTestRunnerEnabled || isTrue(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
386
388
 
387
389
  this.stats = {
388
390
  enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
@@ -3,6 +3,7 @@
3
3
  const AgentExporter = require('./exporters/agent')
4
4
  const LogExporter = require('./exporters/log')
5
5
  const AgentlessCiVisibilityExporter = require('./ci-visibility/exporters/agentless')
6
+ const AgentProxyCiVisibilityExporter = require('./ci-visibility/exporters/agent-proxy')
6
7
  const exporters = require('../../../ext/exporters')
7
8
  const fs = require('fs')
8
9
  const constants = require('./constants')
@@ -18,6 +19,8 @@ module.exports = name => {
18
19
  return AgentExporter
19
20
  case exporters.DATADOG:
20
21
  return AgentlessCiVisibilityExporter
22
+ case exporters.AGENT_PROXY:
23
+ return AgentProxyCiVisibilityExporter
21
24
  default:
22
25
  return inAWSLambda && !usingLambdaExtension ? LogExporter : AgentExporter
23
26
  }
@@ -55,6 +55,10 @@ class AgentExporter {
55
55
  }, flushInterval).unref()
56
56
  }
57
57
  }
58
+
59
+ flush (done = () => {}) {
60
+ this._writer.flush(done)
61
+ }
58
62
  }
59
63
 
60
64
  module.exports = AgentExporter
@@ -0,0 +1,82 @@
1
+ const { URL, format } = require('url')
2
+
3
+ const request = require('./request')
4
+
5
+ function fetchAgentInfo (url, callback) {
6
+ request('', {
7
+ path: '/info',
8
+ url
9
+ }, (err, res) => {
10
+ if (err) {
11
+ return callback(err)
12
+ }
13
+ try {
14
+ const response = JSON.parse(res)
15
+ return callback(null, response)
16
+ } catch (e) {
17
+ return callback(e)
18
+ }
19
+ })
20
+ }
21
+
22
+ /**
23
+ * Exporter that exposes a way to query /info endpoint from the agent and gives you the response.
24
+ * While this._writer is not initialized, exported traces are stored as is.
25
+ */
26
+ class AgentInfoExporter {
27
+ constructor (tracerConfig) {
28
+ this._config = tracerConfig
29
+ const { url, hostname, port } = this._config
30
+ this._url = url || new URL(format({
31
+ protocol: 'http:',
32
+ hostname: hostname || 'localhost',
33
+ port
34
+ }))
35
+ this._traceBuffer = []
36
+ this._isInitialized = false
37
+ }
38
+
39
+ getAgentInfo (onReceivedInfo) {
40
+ fetchAgentInfo(this._url, onReceivedInfo)
41
+ }
42
+
43
+ export (trace) {
44
+ if (!this._isInitialized) {
45
+ this._traceBuffer.push(trace)
46
+ return
47
+ }
48
+ this._export(trace)
49
+ }
50
+
51
+ _export (payload, writer = this._writer, timerKey = '_timer') {
52
+ writer.append(payload)
53
+
54
+ const { flushInterval } = this._config
55
+
56
+ if (flushInterval === 0) {
57
+ writer.flush()
58
+ } else if (flushInterval > 0 && !this[timerKey]) {
59
+ this[timerKey] = setTimeout(() => {
60
+ writer.flush()
61
+ this[timerKey] = clearTimeout(this[timerKey])
62
+ }, flushInterval).unref()
63
+ }
64
+ }
65
+
66
+ getUncodedTraces () {
67
+ return this._traceBuffer
68
+ }
69
+
70
+ exportUncodedTraces () {
71
+ this.getUncodedTraces().forEach(uncodedTrace => {
72
+ this.export(uncodedTrace)
73
+ })
74
+ this.resetUncodedTraces()
75
+ }
76
+
77
+ resetUncodedTraces () {
78
+ this._traceBuffer = []
79
+ }
80
+ }
81
+
82
+ module.exports = AgentInfoExporter
@@ -121,9 +121,7 @@ module.exports = class PluginManager {
121
121
  serviceMapping,
122
122
  clientIpHeaderDisabled,
123
123
  clientIpHeader,
124
- isIntelligentTestRunnerEnabled,
125
124
  site,
126
- experimental,
127
125
  queryStringObfuscation,
128
126
  url,
129
127
  dbmPropagationMode
@@ -147,12 +145,6 @@ module.exports = class PluginManager {
147
145
  sharedConfig.clientIpHeader = clientIpHeader
148
146
  }
149
147
 
150
- if (experimental) {
151
- sharedConfig.isAgentlessEnabled = experimental.exporter === 'datadog'
152
- }
153
-
154
- sharedConfig.isIntelligentTestRunnerEnabled = isIntelligentTestRunnerEnabled
155
-
156
148
  sharedConfig.dbmPropagationMode = dbmPropagationMode
157
149
 
158
150
  if (serviceMapping && serviceMapping[name]) {
@@ -1,5 +1,3 @@
1
- const { channel } = require('diagnostics_channel')
2
-
3
1
  const {
4
2
  getTestEnvironmentMetadata,
5
3
  getCodeOwnersFileEntries,
@@ -9,8 +7,6 @@ const {
9
7
  TEST_CODE_OWNERS,
10
8
  CI_APP_ORIGIN
11
9
  } = require('./util/test')
12
- const { getItrConfiguration } = require('../ci-visibility/intelligent-test-runner/get-itr-configuration')
13
- const { getSkippableSuites } = require('../ci-visibility/intelligent-test-runner/get-skippable-suites')
14
10
  const { COMPONENT } = require('../constants')
15
11
 
16
12
  const Plugin = require('./plugin')
@@ -19,52 +15,18 @@ module.exports = class CiPlugin extends Plugin {
19
15
  constructor (...args) {
20
16
  super(...args)
21
17
 
22
- const gitMetadataUploadFinishCh = channel('ci:git-metadata-upload:finish')
23
- // `gitMetadataPromise` is used to wait until git metadata is uploaded to
24
- // proceed with calculating the suites to skip
25
- // TODO: add timeout after which the promise is resolved
26
- const gitMetadataPromise = new Promise(resolve => {
27
- gitMetadataUploadFinishCh.subscribe(err => {
28
- resolve(err)
29
- })
30
- })
31
-
32
- this.codeOwnersEntries = getCodeOwnersFileEntries()
33
-
34
- this.addSub(`ci:${this.constructor.name}:configuration`, ({ onDone }) => {
35
- if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
36
- onDone({ config: {} })
37
- return
38
- }
39
- getItrConfiguration(this.testConfiguration, (err, config) => {
40
- if (err) {
41
- onDone({ err })
42
- } else {
43
- this.itrConfig = config
44
- onDone({ config })
18
+ this.addSub(`ci:${this.constructor.name}:itr-configuration`, ({ onDone }) => {
19
+ this.tracer._exporter.getItrConfiguration(this.testConfiguration, (err, itrConfig) => {
20
+ if (!err) {
21
+ this.itrConfig = itrConfig
45
22
  }
23
+ onDone({ err, itrConfig })
46
24
  })
47
25
  })
48
26
 
49
27
  this.addSub(`ci:${this.constructor.name}:test-suite:skippable`, ({ onDone }) => {
50
- if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
51
- return onDone({ skippableSuites: [] })
52
- }
53
- // we only request after git upload has happened, if it didn't fail
54
- gitMetadataPromise.then((gitUploadError) => {
55
- if (gitUploadError) {
56
- return onDone({ err: gitUploadError })
57
- }
58
- if (!this.itrConfig || !this.itrConfig.isSuitesSkippingEnabled) {
59
- return onDone({ skippableSuites: [] })
60
- }
61
- getSkippableSuites(this.testConfiguration, (err, skippableSuites) => {
62
- if (err) {
63
- onDone({ err })
64
- } else {
65
- onDone({ skippableSuites })
66
- }
67
- })
28
+ this.tracer._exporter.getSkippableSuites(this.testConfiguration, (err, skippableSuites) => {
29
+ onDone({ err, skippableSuites })
68
30
  })
69
31
  })
70
32
  }
@@ -72,6 +34,7 @@ module.exports = class CiPlugin extends Plugin {
72
34
  configure (config) {
73
35
  super.configure(config)
74
36
  this.testEnvironmentMetadata = getTestEnvironmentMetadata(this.constructor.name, this.config)
37
+ this.codeOwnersEntries = getCodeOwnersFileEntries()
75
38
 
76
39
  const {
77
40
  'git.repository_url': repositoryUrl,
@@ -92,11 +55,7 @@ module.exports = class CiPlugin extends Plugin {
92
55
  osArchitecture,
93
56
  runtimeName,
94
57
  runtimeVersion,
95
- branch,
96
- url: this.config.url,
97
- site: this.config.site,
98
- env: this.tracer._env,
99
- service: this.config.service || this.tracer._service
58
+ branch
100
59
  }
101
60
  }
102
61
 
@@ -18,7 +18,9 @@ const {
18
18
  CI_JOB_URL,
19
19
  CI_JOB_NAME,
20
20
  CI_STAGE_NAME,
21
- CI_ENV_VARS
21
+ CI_ENV_VARS,
22
+ GIT_COMMIT_COMMITTER_NAME,
23
+ GIT_COMMIT_COMMITTER_EMAIL
22
24
  } = require('./tags')
23
25
 
24
26
  // Receives a string with the form 'John Doe <john.doe@gmail.com>'
@@ -281,6 +283,7 @@ module.exports = {
281
283
  APPVEYOR_REPO_TAG_NAME,
282
284
  APPVEYOR_REPO_COMMIT_AUTHOR,
283
285
  APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL,
286
+ APPVEYOR_REPO_COMMIT_MESSAGE,
284
287
  APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED
285
288
  } = env
286
289
 
@@ -296,7 +299,7 @@ module.exports = {
296
299
  [CI_WORKSPACE_PATH]: APPVEYOR_BUILD_FOLDER,
297
300
  [GIT_COMMIT_AUTHOR_NAME]: APPVEYOR_REPO_COMMIT_AUTHOR,
298
301
  [GIT_COMMIT_AUTHOR_EMAIL]: APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL,
299
- [GIT_COMMIT_MESSAGE]: APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED
302
+ [GIT_COMMIT_MESSAGE]: APPVEYOR_REPO_COMMIT_MESSAGE + '\n' + APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED
300
303
  }
301
304
 
302
305
  if (APPVEYOR_REPO_PROVIDER === 'github') {
@@ -506,6 +509,36 @@ module.exports = {
506
509
  }
507
510
  }
508
511
 
512
+ if (env.BUDDY) {
513
+ const {
514
+ BUDDY_EXECUTION_BRANCH,
515
+ BUDDY_EXECUTION_ID,
516
+ BUDDY_EXECUTION_REVISION,
517
+ BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL,
518
+ BUDDY_EXECUTION_REVISION_COMMITTER_NAME,
519
+ BUDDY_EXECUTION_REVISION_MESSAGE,
520
+ BUDDY_EXECUTION_TAG,
521
+ BUDDY_EXECUTION_URL,
522
+ BUDDY_PIPELINE_ID,
523
+ BUDDY_PIPELINE_NAME,
524
+ BUDDY_SCM_URL
525
+ } = env
526
+ tags = {
527
+ [CI_PROVIDER_NAME]: 'buddy',
528
+ [CI_PIPELINE_ID]: `${BUDDY_PIPELINE_ID}/${BUDDY_EXECUTION_ID}`,
529
+ [CI_PIPELINE_NAME]: BUDDY_PIPELINE_NAME,
530
+ [CI_PIPELINE_NUMBER]: BUDDY_EXECUTION_ID,
531
+ [CI_PIPELINE_URL]: BUDDY_EXECUTION_URL,
532
+ [GIT_COMMIT_SHA]: BUDDY_EXECUTION_REVISION,
533
+ [GIT_REPOSITORY_URL]: BUDDY_SCM_URL,
534
+ [GIT_BRANCH]: BUDDY_EXECUTION_BRANCH,
535
+ [GIT_TAG]: BUDDY_EXECUTION_TAG,
536
+ [GIT_COMMIT_MESSAGE]: BUDDY_EXECUTION_REVISION_MESSAGE,
537
+ [GIT_COMMIT_COMMITTER_NAME]: BUDDY_EXECUTION_REVISION_COMMITTER_NAME,
538
+ [GIT_COMMIT_COMMITTER_EMAIL]: BUDDY_EXECUTION_REVISION_COMMITTER_EMAIL
539
+ }
540
+ }
541
+
509
542
  normalizeTag(tags, CI_WORKSPACE_PATH, resolveTilde)
510
543
  normalizeTag(tags, GIT_REPOSITORY_URL, filterSensitiveInfoFromRepository)
511
544
  normalizeTag(tags, GIT_BRANCH, normalizeRef)
@@ -46,6 +46,8 @@ const CI_APP_ORIGIN = 'ciapp-test'
46
46
  const JEST_TEST_RUNNER = 'test.jest.test_runner'
47
47
 
48
48
  const TEST_ITR_TESTS_SKIPPED = '_dd.ci.itr.tests_skipped'
49
+ const TEST_SESSION_ITR_SKIPPING_ENABLED = 'test_session.itr.tests_skipping.enabled'
50
+ const TEST_SESSION_ITR_CODE_COVERAGE_ENABLED = 'test_session.itr.code_coverage.enabled'
49
51
 
50
52
  const TEST_CODE_COVERAGE_LINES_TOTAL = 'test.codecov_lines_total'
51
53
 
@@ -78,6 +80,8 @@ module.exports = {
78
80
  TEST_SESSION_ID,
79
81
  TEST_SUITE_ID,
80
82
  TEST_ITR_TESTS_SKIPPED,
83
+ TEST_SESSION_ITR_SKIPPING_ENABLED,
84
+ TEST_SESSION_ITR_CODE_COVERAGE_ENABLED,
81
85
  TEST_CODE_COVERAGE_LINES_TOTAL,
82
86
  getCoveredFilenamesFromCoverage,
83
87
  resetCoverage,
@@ -265,8 +265,7 @@ const web = {
265
265
 
266
266
  // Extract the parent span from the headers and start a new span as its child
267
267
  startChildSpan (tracer, name, headers) {
268
- const childOf = tracer.scope().active() || tracer.extract(FORMAT_HTTP_HEADERS, headers)
269
-
268
+ const childOf = tracer.extract(FORMAT_HTTP_HEADERS, headers)
270
269
  const span = tracer.startSpan(name, { childOf })
271
270
 
272
271
  return span
@@ -6,11 +6,14 @@ const { request } = require('http')
6
6
  // TODO: avoid using dd-trace internals. Make this a separate module?
7
7
  const docker = require('../../exporters/common/docker')
8
8
  const FormData = require('../../exporters/common/form-data')
9
+ const { storage } = require('../../../../datadog-core')
9
10
  const version = require('../../../../../package.json').version
10
11
 
11
12
  const containerId = docker.id()
12
13
 
13
14
  function sendRequest (options, form, callback) {
15
+ const store = storage.getStore()
16
+ storage.enterWith({ noop: true })
14
17
  const req = request(options, res => {
15
18
  if (res.statusCode >= 400) {
16
19
  const error = new Error(`HTTP Error ${res.statusCode}`)
@@ -22,6 +25,7 @@ function sendRequest (options, form, callback) {
22
25
  })
23
26
  req.on('error', callback)
24
27
  if (form) form.pipe(req)
28
+ storage.enterWith(store)
25
29
  }
26
30
 
27
31
  function getBody (stream, callback) {
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
- const { channel } = require('diagnostics_channel')
3
-
2
+ const PluginManager = require('./plugin_manager')
4
3
  const NoopProxy = require('./noop/proxy')
5
4
  const DatadogTracer = require('./tracer')
6
5
  const Config = require('./config')
@@ -8,12 +7,8 @@ const metrics = require('./metrics')
8
7
  const log = require('./log')
9
8
  const { setStartupLogPluginManager } = require('./startup-log')
10
9
  const telemetry = require('./telemetry')
11
- const PluginManager = require('./plugin_manager')
12
- const { sendGitMetadata } = require('./ci-visibility/exporters/git/git_metadata')
13
10
  const remoteConfig = require('./appsec/remote_config')
14
11
 
15
- const gitMetadataUploadFinishCh = channel('ci:git-metadata-upload:finish')
16
-
17
12
  class Tracer extends NoopProxy {
18
13
  constructor () {
19
14
  super()
@@ -30,7 +25,9 @@ class Tracer extends NoopProxy {
30
25
  try {
31
26
  const config = new Config(options) // TODO: support dynamic config
32
27
 
33
- remoteConfig.enable(config)
28
+ if (!config.isCiVisibility) {
29
+ remoteConfig.enable(config)
30
+ }
34
31
 
35
32
  if (config.profiling.enabled) {
36
33
  // do not stop tracer initialization if the profiler fails to be imported
@@ -61,17 +58,6 @@ class Tracer extends NoopProxy {
61
58
  setStartupLogPluginManager(this._pluginManager)
62
59
  telemetry.start(config, this._pluginManager)
63
60
  }
64
-
65
- if (config.isGitUploadEnabled) {
66
- sendGitMetadata(config.site, (err) => {
67
- if (err) {
68
- log.error(`Error uploading git metadata: ${err.message}`)
69
- } else {
70
- log.debug('Successfully uploaded git metadata')
71
- }
72
- gitMetadataUploadFinishCh.publish(err)
73
- })
74
- }
75
61
  } catch (e) {
76
62
  log.error(e)
77
63
  }