dd-trace 6.8.0 → 6.9.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.
- package/ci/diagnose.js +27 -25
- package/ci/init.js +6 -6
- package/ci/runbook.md +114 -20
- package/ci/test-optimization-validation/approval-artifacts.js +36 -3
- package/ci/test-optimization-validation/approval.js +78 -22
- package/ci/test-optimization-validation/blocker-category.js +24 -0
- package/ci/test-optimization-validation/ci-discovery.js +23 -17
- package/ci/test-optimization-validation/ci-package-scripts.js +34 -6
- package/ci/test-optimization-validation/ci-remediation.js +1 -1
- package/ci/test-optimization-validation/cli.js +280 -52
- package/ci/test-optimization-validation/command-blocker.js +159 -20
- package/ci/test-optimization-validation/command-output-policy.js +9 -3
- package/ci/test-optimization-validation/command-runner.js +9 -7
- package/ci/test-optimization-validation/environment.js +4 -2
- package/ci/test-optimization-validation/executable.js +15 -13
- package/ci/test-optimization-validation/execution-lock.js +70 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber-validation.json +3 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +657 -5
- package/ci/test-optimization-validation/framework-adapters/vitest.js +517 -0
- package/ci/test-optimization-validation/generated-files.js +38 -28
- package/ci/test-optimization-validation/generated-test-contract.js +8 -4
- package/ci/test-optimization-validation/generated-verifier.js +24 -17
- package/ci/test-optimization-validation/literal-glob.js +52 -0
- package/ci/test-optimization-validation/manifest-loader.js +3 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +300 -50
- package/ci/test-optimization-validation/manifest-schema.js +80 -17
- package/ci/test-optimization-validation/offline-fixtures.js +13 -4
- package/ci/test-optimization-validation/package-check.js +94 -0
- package/ci/test-optimization-validation/plan-writer.js +183 -10
- package/ci/test-optimization-validation/preflight-runner.js +110 -31
- package/ci/test-optimization-validation/project-build-artifact.js +31 -0
- package/ci/test-optimization-validation/redaction.js +18 -27
- package/ci/test-optimization-validation/report-writer.js +182 -48
- package/ci/test-optimization-validation/result-semantics.js +20 -3
- package/ci/test-optimization-validation/runner-command.js +40 -20
- package/ci/test-optimization-validation/runner-contract.js +79 -43
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +59 -5
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +141 -35
- package/ci/test-optimization-validation/scenarios/helpers.js +30 -6
- package/ci/test-optimization-validation/static-diagnosis.js +10 -3
- package/ci/test-optimization-validation/test-output.js +2 -1
- package/ci/test-optimization-validation/validation-blocker.js +21 -0
- package/ci/vitest-no-worker-init-setup.mjs +30 -34
- package/index.d.ts +98 -1
- package/init.js +1 -17
- package/initialize.mjs +11 -0
- package/loader-hook.mjs +6 -4
- package/package.json +5 -3
- package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
- package/packages/datadog-esbuild/src/utils.js +16 -1
- package/packages/datadog-instrumentations/src/ai.js +61 -34
- package/packages/datadog-instrumentations/src/bluebird.js +6 -6
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +81 -5
- package/packages/datadog-instrumentations/src/cucumber.js +124 -47
- package/packages/datadog-instrumentations/src/dns.js +21 -2
- package/packages/datadog-instrumentations/src/electron.js +1 -0
- package/packages/datadog-instrumentations/src/fastify.js +3 -1
- package/packages/datadog-instrumentations/src/grpc/client.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +33 -9
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +118 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +20 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +32 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +61 -0
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +37 -6
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +979 -233
- package/packages/datadog-instrumentations/src/mocha/main.js +107 -9
- package/packages/datadog-instrumentations/src/mocha/utils.js +64 -42
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +25 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -18
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +155 -23
- package/packages/datadog-instrumentations/src/openai.js +14 -0
- package/packages/datadog-instrumentations/src/pg.js +180 -6
- package/packages/datadog-instrumentations/src/playwright.js +173 -79
- package/packages/datadog-instrumentations/src/promise-js.js +4 -4
- package/packages/datadog-instrumentations/src/promise.js +3 -3
- package/packages/datadog-instrumentations/src/router.js +195 -19
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +43 -10
- package/packages/datadog-instrumentations/src/vitest-main.js +360 -56
- package/packages/datadog-instrumentations/src/vitest-util.js +42 -7
- package/packages/datadog-instrumentations/src/vitest-worker.js +234 -17
- package/packages/datadog-instrumentations/src/webdriverio.js +194 -18
- package/packages/datadog-instrumentations/src/when.js +3 -3
- package/packages/datadog-instrumentations/src/ws.js +5 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -3
- package/packages/datadog-plugin-cucumber/src/index.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +50 -46
- package/packages/datadog-plugin-cypress/src/support.js +7 -4
- package/packages/datadog-plugin-electron/src/net.js +10 -4
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +1 -18
- package/packages/datadog-plugin-jest/src/util.js +2 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +2 -1
- package/packages/datadog-plugin-mocha/src/index.js +318 -1
- package/packages/datadog-plugin-next/src/index.js +57 -9
- package/packages/datadog-plugin-openai/src/tracing.js +4 -0
- package/packages/datadog-plugin-pg/src/index.js +65 -1
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +95 -7
- package/packages/datadog-shimmer/src/shimmer.js +6 -2
- package/packages/dd-trace/src/aiguard/sdk.js +3 -0
- package/packages/dd-trace/src/appsec/{blocking.js → blocking/index.js} +26 -6
- package/packages/dd-trace/src/appsec/handlers/auth.js +62 -0
- package/packages/dd-trace/src/appsec/handlers/http-request.js +215 -0
- package/packages/dd-trace/src/appsec/handlers/http-response.js +78 -0
- package/packages/dd-trace/src/appsec/handlers/http-shared.js +24 -0
- package/packages/dd-trace/src/appsec/handlers/payments.js +104 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +48 -476
- package/packages/dd-trace/src/appsec/sdk/track_event.js +9 -0
- package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +46 -14
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +89 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +27 -13
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +17 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +21 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -7
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -14
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +21 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
- package/packages/dd-trace/src/config/generated-config-types.d.ts +2 -0
- package/packages/dd-trace/src/config/helper.js +2 -0
- package/packages/dd-trace/src/config/index.js +16 -5
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +8 -0
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
- package/packages/dd-trace/src/guardrails/log.js +1 -10
- package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +33 -25
- package/packages/dd-trace/src/llmobs/experiments/util.js +4 -2
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +5 -5
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +149 -68
- package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +3 -0
- package/packages/dd-trace/src/llmobs/writers/util.js +2 -0
- package/packages/dd-trace/src/log/channels.js +1 -9
- package/packages/dd-trace/src/log/levels.js +12 -0
- package/packages/dd-trace/src/openfeature/writers/exposures.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +8 -4
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -1
- package/packages/dd-trace/src/opentelemetry/span.js +4 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +21 -5
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +6 -0
- package/packages/dd-trace/src/plugins/util/git.js +6 -4
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +2 -2
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
- package/packages/dd-trace/src/plugins/util/test.js +319 -75
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +23 -1
- package/packages/dd-trace/src/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
- package/packages/dd-trace/src/proxy.js +1 -0
- package/packages/dd-trace/src/ritm.js +5 -0
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +4 -2
- package/packages/dd-trace/src/sampling_rule.js +4 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +1 -1
- package/packages/dd-trace/src/telemetry/logs/index.js +3 -0
- package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
- package/vendor/dist/pprof-format/index.js +1 -1
- package/version.js +10 -8
- /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
|
@@ -12,6 +12,7 @@ const { sanitizeForReport } = require('./redaction')
|
|
|
12
12
|
const { getManifestInputFiles } = require('./runner-command')
|
|
13
13
|
|
|
14
14
|
const APPROVAL_DIGEST_PATTERN = /^[a-f0-9]{64}$/
|
|
15
|
+
const MAX_CAPTURED_PROJECT_SOURCE_BYTES = 512 * 1024
|
|
15
16
|
const OFFLINE_FIXTURE_NONCE_PATTERN = /^[a-f0-9]{32}$/
|
|
16
17
|
const PACKAGE_SNAPSHOT_EXCLUDED_NAMES = new Set(['.git', '.nyc_output', 'node_modules'])
|
|
17
18
|
|
|
@@ -105,10 +106,7 @@ function getApprovalMaterial ({
|
|
|
105
106
|
path: path.resolve(manifest.__path),
|
|
106
107
|
sha256: getManifestDigest(manifest),
|
|
107
108
|
},
|
|
108
|
-
projectFiles:
|
|
109
|
-
path: filename,
|
|
110
|
-
sha256: getFileDigest(filename),
|
|
111
|
-
})),
|
|
109
|
+
projectFiles: getApprovalProjectFiles(manifest, { includeLocal }),
|
|
112
110
|
selection: {
|
|
113
111
|
frameworks: [...selectedFrameworkIds],
|
|
114
112
|
scenario: requestedScenario,
|
|
@@ -117,6 +115,11 @@ function getApprovalMaterial ({
|
|
|
117
115
|
outputDirectory: path.resolve(out),
|
|
118
116
|
offlineFixtureNonce,
|
|
119
117
|
keepTemporaryFiles: keepTempFiles,
|
|
118
|
+
requiredCapabilities: getRequiredCapabilities({
|
|
119
|
+
manifest,
|
|
120
|
+
requestedScenario,
|
|
121
|
+
selectedFrameworkIds,
|
|
122
|
+
}),
|
|
120
123
|
verbose,
|
|
121
124
|
},
|
|
122
125
|
fixtureRecipeDigests: includeLocal
|
|
@@ -133,6 +136,51 @@ function getApprovalMaterial ({
|
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
138
|
|
|
139
|
+
// Capability metadata is approval-only; the validator does not request permissions or start prerequisites.
|
|
140
|
+
function getRequiredCapabilities ({ manifest, requestedScenario, selectedFrameworkIds = [] }) {
|
|
141
|
+
if (requestedScenario === 'ci-wiring') return []
|
|
142
|
+
const selected = new Set(selectedFrameworkIds)
|
|
143
|
+
const frameworks = (manifest.frameworks || []).filter(framework => {
|
|
144
|
+
return framework.status === 'runnable' && (selected.size === 0 || selected.has(framework.id))
|
|
145
|
+
})
|
|
146
|
+
const capabilities = new Set()
|
|
147
|
+
if (frameworks.some(framework => ['cypress', 'playwright'].includes(framework.framework) ||
|
|
148
|
+
(framework.framework === 'vitest' && framework.validation?.runnerArgs?.includes('--browser')) ||
|
|
149
|
+
framework.browserRequired === true)) {
|
|
150
|
+
capabilities.add('browser_process')
|
|
151
|
+
}
|
|
152
|
+
if (frameworks.some(framework => framework.localSocketRequired === true ||
|
|
153
|
+
(framework.validation?.fallbackTests || []).some(fallback => fallback.localSocketRequired === true))) {
|
|
154
|
+
capabilities.add('localhost_socket')
|
|
155
|
+
}
|
|
156
|
+
return [...capabilities].sort()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function getApprovalProjectFiles (manifest, { includeLocal = true } = {}) {
|
|
160
|
+
return getApprovalProjectSnapshot(manifest, { includeLocal }).projectFiles
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Hashes and static-analysis sources come from the same reads to avoid approval-time races.
|
|
164
|
+
function getApprovalProjectSnapshot (manifest, { includeLocal = true } = {}) {
|
|
165
|
+
const projectFiles = []
|
|
166
|
+
const sources = new Map()
|
|
167
|
+
for (const filename of getManifestInputFiles(manifest, { includeLocal })) {
|
|
168
|
+
const stat = fs.lstatSync(filename)
|
|
169
|
+
const contents = fs.readFileSync(filename)
|
|
170
|
+
projectFiles.push({
|
|
171
|
+
path: filename,
|
|
172
|
+
sha256: crypto.createHash('sha256').update(contents).digest('hex'),
|
|
173
|
+
})
|
|
174
|
+
sources.set(
|
|
175
|
+
filename,
|
|
176
|
+
stat.isFile() && !stat.isSymbolicLink() && contents.length <= MAX_CAPTURED_PROJECT_SOURCE_BYTES
|
|
177
|
+
? contents
|
|
178
|
+
: undefined
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
return { projectFiles, sources }
|
|
182
|
+
}
|
|
183
|
+
|
|
136
184
|
/**
|
|
137
185
|
* Serializes approval material using stable formatting suitable for independent SHA-256 tools.
|
|
138
186
|
*
|
|
@@ -192,21 +240,25 @@ function getApprovalCommand (id, command) {
|
|
|
192
240
|
*/
|
|
193
241
|
function getGeneratedFileMaterial (manifest, requestedScenario) {
|
|
194
242
|
const files = []
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
243
|
+
if (manifest.frameworks) {
|
|
244
|
+
for (const framework of manifest.frameworks) {
|
|
245
|
+
const strategy = framework.generatedTestStrategy
|
|
246
|
+
const selectedPaths = getSelectedGeneratedPaths(strategy, requestedScenario)
|
|
247
|
+
if (strategy?.files) {
|
|
248
|
+
for (const file of strategy.files) {
|
|
249
|
+
if (!selectedPaths.has(path.resolve(file.path))) continue
|
|
250
|
+
const content = `${file.contentLines.join('\n')}\n`
|
|
251
|
+
files.push(sanitizeForReport({
|
|
252
|
+
frameworkId: framework.id,
|
|
253
|
+
path: path.resolve(file.path),
|
|
254
|
+
sha256: crypto.createHash('sha256').update(content).digest('hex'),
|
|
255
|
+
content,
|
|
256
|
+
removeAfterValidation: (strategy.cleanupPaths || []).some(cleanupPath => {
|
|
257
|
+
return path.resolve(cleanupPath) === path.resolve(file.path)
|
|
258
|
+
}),
|
|
259
|
+
}))
|
|
260
|
+
}
|
|
261
|
+
}
|
|
210
262
|
}
|
|
211
263
|
}
|
|
212
264
|
return files
|
|
@@ -230,9 +282,11 @@ function getSelectedGeneratedPaths (strategy, requestedScenario) {
|
|
|
230
282
|
return path.resolve(scenario.testIdentities[0].file)
|
|
231
283
|
}))
|
|
232
284
|
const selectedPaths = new Set()
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
285
|
+
if (strategy.files) {
|
|
286
|
+
for (const file of strategy.files) {
|
|
287
|
+
const filename = path.resolve(file.path)
|
|
288
|
+
if (!requestedScenario || !scenarioPaths.has(filename)) selectedPaths.add(filename)
|
|
289
|
+
}
|
|
236
290
|
}
|
|
237
291
|
if (generatedId) {
|
|
238
292
|
const scenario = strategy.scenarios?.find(candidate => candidate.id === generatedId)
|
|
@@ -332,5 +386,7 @@ module.exports = {
|
|
|
332
386
|
assertApprovalDigest,
|
|
333
387
|
getApprovalDigest,
|
|
334
388
|
getApprovalMaterial,
|
|
389
|
+
getApprovalProjectSnapshot,
|
|
390
|
+
getRequiredCapabilities,
|
|
335
391
|
serializeApprovalMaterial,
|
|
336
392
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const BLOCKER_CATEGORIES = Object.freeze({
|
|
4
|
+
CLEAN_TEST_FAILED: 'CLEAN_TEST_FAILED',
|
|
5
|
+
EXECUTION_ENVIRONMENT_BLOCKED: 'EXECUTION_ENVIRONMENT_BLOCKED',
|
|
6
|
+
PROJECT_SETUP_REQUIRED: 'PROJECT_SETUP_REQUIRED',
|
|
7
|
+
UNSUPPORTED_VERSION: 'UNSUPPORTED_VERSION',
|
|
8
|
+
VALIDATOR_LIMITATION: 'VALIDATOR_LIMITATION',
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const BLOCKER_CATEGORY_VALUES = new Set(Object.values(BLOCKER_CATEGORIES))
|
|
12
|
+
|
|
13
|
+
function getBlockerDomain (category) {
|
|
14
|
+
const domains = {
|
|
15
|
+
[BLOCKER_CATEGORIES.CLEAN_TEST_FAILED]: 'local_runtime',
|
|
16
|
+
[BLOCKER_CATEGORIES.EXECUTION_ENVIRONMENT_BLOCKED]: 'execution_environment',
|
|
17
|
+
[BLOCKER_CATEGORIES.PROJECT_SETUP_REQUIRED]: 'project_setup',
|
|
18
|
+
[BLOCKER_CATEGORIES.UNSUPPORTED_VERSION]: 'unsupported_version',
|
|
19
|
+
[BLOCKER_CATEGORIES.VALIDATOR_LIMITATION]: 'validator_adapter',
|
|
20
|
+
}
|
|
21
|
+
return domains[category]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = { BLOCKER_CATEGORIES, BLOCKER_CATEGORY_VALUES, getBlockerDomain }
|
|
@@ -61,18 +61,22 @@ function buildCiDiscovery ({ manifest, diagnosis }) {
|
|
|
61
61
|
function getManifestWorkflowLocations (manifest) {
|
|
62
62
|
const root = manifest.repository?.root
|
|
63
63
|
const locations = []
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
if (manifest.frameworks) {
|
|
65
|
+
for (const framework of manifest.frameworks) {
|
|
66
|
+
const configFile = framework.ciWiring?.configFile
|
|
67
|
+
if (typeof configFile !== 'string') continue
|
|
68
|
+
if (!root || !path.isAbsolute(configFile)) {
|
|
69
|
+
locations.push(configFile)
|
|
70
|
+
continue
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const relative = path.relative(root, configFile)
|
|
74
|
+
const isRelativePath = relative && relative !== '..' && !relative.startsWith(`..${path.sep}`) &&
|
|
75
|
+
!path.isAbsolute(relative)
|
|
76
|
+
locations.push(isRelativePath
|
|
77
|
+
? relative.split(path.sep).join('/')
|
|
78
|
+
: configFile)
|
|
70
79
|
}
|
|
71
|
-
|
|
72
|
-
const relative = path.relative(root, configFile)
|
|
73
|
-
locations.push(relative && relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative)
|
|
74
|
-
? relative.split(path.sep).join('/')
|
|
75
|
-
: configFile)
|
|
76
80
|
}
|
|
77
81
|
return uniqueStrings(locations)
|
|
78
82
|
}
|
|
@@ -106,12 +110,14 @@ function getCiDiscoveryContradictions ({ manifest, declaredFound, staticFound })
|
|
|
106
110
|
)
|
|
107
111
|
}
|
|
108
112
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
if (manifest.frameworks) {
|
|
114
|
+
for (const framework of manifest.frameworks) {
|
|
115
|
+
if (!frameworkClaimsNoCi(framework)) continue
|
|
116
|
+
contradictions.push(
|
|
117
|
+
`framework ${framework.id || '<unknown>'} records no CI workflow, but static diagnosis found ` +
|
|
118
|
+
formatList(staticFound)
|
|
119
|
+
)
|
|
120
|
+
}
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
return contradictions
|
|
@@ -3,7 +3,21 @@
|
|
|
3
3
|
const { parseLiteralEnvironmentPrefix } = require('./literal-environment')
|
|
4
4
|
|
|
5
5
|
const MAX_SCRIPT_EXPANSIONS = 16
|
|
6
|
-
const DYNAMIC_VALUE_PATTERN = /[
|
|
6
|
+
const DYNAMIC_VALUE_PATTERN = /[$`\r\n]|%[^%\s]+%|![^!\s]+!/
|
|
7
|
+
const RESERVED_PACKAGE_MANAGER_COMMANDS = {
|
|
8
|
+
pnpm: new Set([
|
|
9
|
+
'add', 'audit', 'bin', 'c', 'config', 'create', 'deploy', 'dlx', 'env', 'exec', 'fetch', 'i', 'import', 'init',
|
|
10
|
+
'install', 'link', 'list', 'ln', 'ls', 'outdated', 'pack', 'patch', 'patch-commit', 'prune', 'publish', 'rebuild',
|
|
11
|
+
'remove', 'rm', 'root', 'self-update', 'server', 'setup', 'store', 'uninstall', 'unlink', 'up', 'update', 'view',
|
|
12
|
+
'why',
|
|
13
|
+
]),
|
|
14
|
+
yarn: new Set([
|
|
15
|
+
'add', 'audit', 'bin', 'cache', 'check', 'config', 'constraints', 'create', 'dedupe', 'dlx', 'exec', 'global',
|
|
16
|
+
'help', 'import', 'info', 'init', 'install', 'link', 'list', 'node', 'npm', 'outdated', 'owner', 'pack', 'patch',
|
|
17
|
+
'plugin', 'policies', 'publish', 'rebuild', 'remove', 'set', 'stage', 'tag', 'team', 'unlink', 'unplug', 'up',
|
|
18
|
+
'upgrade', 'version', 'versions', 'why', 'workspace', 'workspaces',
|
|
19
|
+
]),
|
|
20
|
+
}
|
|
7
21
|
|
|
8
22
|
/**
|
|
9
23
|
* Expands bounded local package-script references without executing them.
|
|
@@ -45,7 +59,7 @@ function expandCommand (command, scripts, path, stack, state) {
|
|
|
45
59
|
if (stack.has(invocation.script)) {
|
|
46
60
|
return { error: `local package-script cycle includes ${invocation.script}` }
|
|
47
61
|
}
|
|
48
|
-
const lifecycleNames = invocation.manager === 'npm'
|
|
62
|
+
const lifecycleNames = invocation.manager === 'npm' || invocation.manager === 'bun'
|
|
49
63
|
? [`pre${invocation.script}`, `post${invocation.script}`]
|
|
50
64
|
.filter(name => typeof scripts[name] === 'string')
|
|
51
65
|
: []
|
|
@@ -60,8 +74,11 @@ function expandCommand (command, scripts, path, stack, state) {
|
|
|
60
74
|
const nextStack = new Set(stack)
|
|
61
75
|
nextStack.add(invocation.script)
|
|
62
76
|
nextStack.add(scriptName)
|
|
77
|
+
const scriptCommand = scriptName === invocation.script && invocation.arguments
|
|
78
|
+
? `${scripts[scriptName]} ${invocation.arguments}`
|
|
79
|
+
: scripts[scriptName]
|
|
63
80
|
const expanded = expandCommand(
|
|
64
|
-
|
|
81
|
+
scriptCommand,
|
|
65
82
|
scripts,
|
|
66
83
|
[...path, segment],
|
|
67
84
|
nextStack,
|
|
@@ -129,13 +146,24 @@ function getPackageScriptInvocation (command) {
|
|
|
129
146
|
const literalPrefix = parseLiteralEnvironmentPrefix(command)
|
|
130
147
|
const source = command.slice(literalPrefix.length).trim()
|
|
131
148
|
.replace(/^(?:c8|nyc)(?:\.cmd)?\s+/, '')
|
|
132
|
-
const match = /^(npm(?:\.cmd)?|pnpm(?:\.cmd)?|yarn(?:pkg)?(?:\.cmd)?)\s+(?:(run|run-script)\s+)?([\w:-]+)
|
|
149
|
+
const match = /^(bun|npm(?:\.cmd)?|pnpm(?:\.cmd)?|yarn(?:pkg)?(?:\.cmd)?)\s+(?:(run|run-script)\s+)?([\w:-]+)(?:\s+(.+))?$/
|
|
133
150
|
.exec(source)
|
|
134
151
|
if (!match) return
|
|
135
152
|
|
|
136
|
-
const manager = match[1].replace(/\.cmd$/i, '')
|
|
153
|
+
const manager = match[1].replace(/\.cmd$/i, '').replace(/^yarnpkg$/, 'yarn')
|
|
137
154
|
if (manager === 'npm' && !match[2] && !['restart', 'start', 'stop', 'test'].includes(match[3])) return
|
|
138
|
-
|
|
155
|
+
if (manager === 'bun' && match[2] !== 'run') return
|
|
156
|
+
if (!match[2] && RESERVED_PACKAGE_MANAGER_COMMANDS[manager]?.has(match[3])) return
|
|
157
|
+
const args = match[4]?.trim()
|
|
158
|
+
const separatedArguments = args ? /^--(?:\s+(.+))?$/.exec(args) : undefined
|
|
159
|
+
if (['npm', 'pnpm'].includes(manager) && args && !separatedArguments) return
|
|
160
|
+
const scriptArguments = ['npm', 'pnpm'].includes(manager) ? separatedArguments?.[1]?.trim() : args
|
|
161
|
+
if (scriptArguments && !splitLiteralAndChain(scriptArguments)) return
|
|
162
|
+
return {
|
|
163
|
+
...(scriptArguments ? { arguments: scriptArguments } : {}),
|
|
164
|
+
manager,
|
|
165
|
+
script: match[3],
|
|
166
|
+
}
|
|
139
167
|
}
|
|
140
168
|
|
|
141
169
|
module.exports = { expandLocalPackageScripts }
|
|
@@ -183,7 +183,7 @@ function isDatadogModuleSpecifier (specifier, entrypoint) {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
function hasDynamicEnvironmentReference (value) {
|
|
186
|
-
return
|
|
186
|
+
return /\$[A-Za-z_{]|\$\(|%[A-Za-z_][A-Za-z0-9_]*%/.test(value)
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
function getRecommendedValues (framework) {
|