dd-trace 5.53.0 → 5.54.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/LICENSE-3rdparty.csv +2 -1
- package/index.d.ts +33 -16
- package/initialize.mjs +3 -4
- package/package.json +36 -34
- package/packages/datadog-core/src/utils/src/get.js +1 -1
- package/packages/datadog-core/src/utils/src/has.js +1 -1
- package/packages/datadog-core/src/utils/src/kebabcase.js +4 -6
- package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
- package/packages/datadog-core/src/utils/src/pick.js +2 -2
- package/packages/datadog-core/src/utils/src/set.js +1 -1
- package/packages/datadog-core/src/utils/src/uniq.js +1 -1
- package/packages/datadog-instrumentations/src/amqp10.js +19 -17
- package/packages/datadog-instrumentations/src/amqplib.js +52 -35
- package/packages/datadog-instrumentations/src/apollo.js +2 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -4
- package/packages/datadog-instrumentations/src/child_process.js +1 -2
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +88 -73
- package/packages/datadog-instrumentations/src/couchbase.js +3 -3
- package/packages/datadog-instrumentations/src/cucumber.js +87 -40
- package/packages/datadog-instrumentations/src/cypress.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +1 -1
- package/packages/datadog-instrumentations/src/fs.js +1 -1
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +28 -34
- package/packages/datadog-instrumentations/src/graphql.js +7 -10
- package/packages/datadog-instrumentations/src/grpc/client.js +11 -23
- package/packages/datadog-instrumentations/src/grpc/server.js +7 -20
- package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +16 -10
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -41
- package/packages/datadog-instrumentations/src/helpers/register.js +5 -7
- package/packages/datadog-instrumentations/src/http/client.js +14 -20
- package/packages/datadog-instrumentations/src/jest.js +137 -48
- package/packages/datadog-instrumentations/src/kafkajs.js +52 -44
- package/packages/datadog-instrumentations/src/knex.js +4 -4
- package/packages/datadog-instrumentations/src/ldapjs.js +3 -4
- package/packages/datadog-instrumentations/src/mariadb.js +38 -61
- package/packages/datadog-instrumentations/src/mocha/main.js +63 -24
- package/packages/datadog-instrumentations/src/mocha/utils.js +36 -12
- package/packages/datadog-instrumentations/src/mocha/worker.js +6 -0
- package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +20 -36
- package/packages/datadog-instrumentations/src/mysql2.js +53 -47
- package/packages/datadog-instrumentations/src/net.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +1 -0
- package/packages/datadog-instrumentations/src/nyc.js +1 -1
- package/packages/datadog-instrumentations/src/openai.js +21 -23
- package/packages/datadog-instrumentations/src/oracledb.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +1 -2
- package/packages/datadog-instrumentations/src/playwright.js +112 -69
- package/packages/datadog-instrumentations/src/redis.js +3 -3
- package/packages/datadog-instrumentations/src/restify.js +2 -2
- package/packages/datadog-instrumentations/src/rhea.js +42 -54
- package/packages/datadog-instrumentations/src/router.js +22 -25
- package/packages/datadog-instrumentations/src/tedious.js +1 -1
- package/packages/datadog-instrumentations/src/vitest.js +77 -28
- package/packages/datadog-plugin-amqp10/src/consumer.js +7 -3
- package/packages/datadog-plugin-amqp10/src/producer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/client.js +6 -2
- package/packages/datadog-plugin-amqplib/src/consumer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/producer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/util.js +1 -1
- package/packages/datadog-plugin-apollo/src/gateway/request.js +5 -6
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +13 -13
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +24 -31
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +6 -6
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +4 -5
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +5 -6
- package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
- package/packages/datadog-plugin-child_process/src/index.js +4 -4
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +23 -23
- package/packages/datadog-plugin-cucumber/src/index.js +57 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +97 -27
- package/packages/datadog-plugin-cypress/src/plugin.js +11 -1
- package/packages/datadog-plugin-cypress/src/support.js +24 -5
- package/packages/datadog-plugin-express/src/code_origin.js +30 -0
- package/packages/datadog-plugin-express/src/index.js +10 -12
- package/packages/datadog-plugin-express/src/tracing.js +19 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +7 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +12 -7
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +6 -2
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +26 -9
- package/packages/datadog-plugin-graphql/src/execute.js +2 -2
- package/packages/datadog-plugin-graphql/src/index.js +7 -6
- package/packages/datadog-plugin-graphql/src/resolve.js +2 -2
- package/packages/datadog-plugin-graphql/src/tools/index.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +1 -0
- package/packages/datadog-plugin-grpc/src/client.js +2 -2
- package/packages/datadog-plugin-grpc/src/util.js +2 -2
- package/packages/datadog-plugin-http/src/client.js +18 -7
- package/packages/datadog-plugin-http2/src/client.js +20 -20
- package/packages/datadog-plugin-jest/src/index.js +23 -21
- package/packages/datadog-plugin-jest/src/util.js +8 -8
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +3 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +9 -5
- package/packages/datadog-plugin-kafkajs/src/producer.js +8 -3
- package/packages/datadog-plugin-kafkajs/src/utils.js +1 -1
- package/packages/datadog-plugin-langchain/src/handlers/chain.js +7 -7
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -2
- package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +6 -4
- package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +5 -4
- package/packages/datadog-plugin-langchain/src/tracing.js +11 -10
- package/packages/datadog-plugin-mariadb/src/index.js +3 -9
- package/packages/datadog-plugin-mocha/src/index.js +33 -13
- package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
- package/packages/datadog-plugin-mysql/src/index.js +11 -9
- package/packages/datadog-plugin-mysql2/src/index.js +16 -0
- package/packages/datadog-plugin-net/src/tcp.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +6 -5
- package/packages/datadog-plugin-openai/src/services.js +6 -10
- package/packages/datadog-plugin-openai/src/tracing.js +10 -14
- package/packages/datadog-plugin-oracledb/src/index.js +1 -1
- package/packages/datadog-plugin-playwright/src/index.js +22 -2
- package/packages/datadog-plugin-redis/src/index.js +1 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +8 -6
- package/packages/datadog-plugin-rhea/src/producer.js +5 -2
- package/packages/datadog-plugin-router/src/index.js +1 -1
- package/packages/datadog-plugin-selenium/src/index.js +1 -6
- package/packages/datadog-plugin-vitest/src/index.js +47 -31
- package/packages/datadog-shimmer/src/shimmer.js +4 -8
- package/packages/dd-trace/src/appsec/api_security_sampler.js +2 -2
- package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
- package/packages/dd-trace/src/appsec/blocking.js +6 -20
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +4 -6
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +7 -12
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +4 -6
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +4 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +9 -12
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +5 -4
- package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -3
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/index.js +1 -0
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +102 -7
- package/packages/dd-trace/src/appsec/iast/path-line.js +7 -8
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +6 -13
- package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +6 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +4 -28
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +3 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +6 -6
- package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +7 -7
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +23 -24
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +4 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +6 -11
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +9 -11
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/index.js +15 -15
- package/packages/dd-trace/src/appsec/rasp/lfi.js +2 -1
- package/packages/dd-trace/src/appsec/reporter.js +233 -40
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/appsec/stack_trace.js +2 -4
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +3 -5
- package/packages/dd-trace/src/appsec/telemetry/waf.js +3 -5
- package/packages/dd-trace/src/appsec/user_tracking.js +3 -5
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
- package/packages/dd-trace/src/azure_metadata.js +2 -7
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +1 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +0 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -1
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +1 -1
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +8 -5
- package/packages/dd-trace/src/ci-visibility/telemetry.js +4 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
- package/packages/dd-trace/src/config.js +82 -51
- package/packages/dd-trace/src/config_stable.js +3 -3
- package/packages/dd-trace/src/datastreams/encoding.js +9 -9
- package/packages/dd-trace/src/datastreams/fnv.js +1 -1
- package/packages/dd-trace/src/datastreams/pathway.js +4 -4
- package/packages/dd-trace/src/datastreams/processor.js +5 -7
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +4 -6
- package/packages/dd-trace/src/datastreams/size.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +74 -67
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +6 -8
- package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +7 -1
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +18 -38
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +8 -10
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +2 -10
- package/packages/dd-trace/src/debugger/devtools_client/state.js +10 -3
- package/packages/dd-trace/src/dogstatsd.js +5 -4
- package/packages/dd-trace/src/encode/0.4.js +9 -9
- package/packages/dd-trace/src/encode/0.5.js +1 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +3 -3
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
- package/packages/dd-trace/src/encode/tags-processors.js +1 -1
- package/packages/dd-trace/src/exporter.js +6 -6
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -5
- package/packages/dd-trace/src/exporters/common/docker.js +1 -1
- package/packages/dd-trace/src/exporters/common/form-data.js +6 -4
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/common/util.js +1 -1
- package/packages/dd-trace/src/external-logger/src/index.js +5 -5
- package/packages/dd-trace/src/flare/file.js +1 -5
- package/packages/dd-trace/src/format.js +1 -1
- package/packages/dd-trace/src/git_properties.js +1 -1
- package/packages/dd-trace/src/id.js +12 -6
- package/packages/dd-trace/src/iitm.js +10 -22
- package/packages/dd-trace/src/lambda/handler.js +6 -6
- package/packages/dd-trace/src/lambda/runtime/patch.js +4 -4
- package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +6 -6
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +2 -6
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +6 -6
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +2 -2
- package/packages/dd-trace/src/llmobs/tagger.js +110 -96
- package/packages/dd-trace/src/llmobs/util.js +9 -9
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -1
- package/packages/dd-trace/src/log/index.js +4 -4
- package/packages/dd-trace/src/log/log.js +1 -1
- package/packages/dd-trace/src/log/writer.js +2 -2
- package/packages/dd-trace/src/msgpack/chunk.js +3 -3
- package/packages/dd-trace/src/msgpack/encoder.js +28 -28
- package/packages/dd-trace/src/noop/dogstatsd.js +6 -6
- package/packages/dd-trace/src/noop/span.js +3 -5
- package/packages/dd-trace/src/noop/tracer.js +1 -2
- package/packages/dd-trace/src/opentelemetry/span_processor.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +6 -5
- package/packages/dd-trace/src/opentracing/propagation/log.js +6 -8
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +27 -23
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +8 -4
- package/packages/dd-trace/src/opentracing/span.js +9 -14
- package/packages/dd-trace/src/opentracing/tracer.js +9 -6
- package/packages/dd-trace/src/payload-tagging/index.js +1 -1
- package/packages/dd-trace/src/payload-tagging/tagging.js +6 -6
- package/packages/dd-trace/src/pkg.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +62 -10
- package/packages/dd-trace/src/plugins/consumer.js +2 -2
- package/packages/dd-trace/src/plugins/inbound.js +5 -1
- package/packages/dd-trace/src/plugins/index.js +0 -1
- package/packages/dd-trace/src/plugins/outbound.js +4 -5
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/producer.js +2 -2
- package/packages/dd-trace/src/plugins/storage.js +2 -2
- package/packages/dd-trace/src/plugins/util/ci.js +23 -15
- package/packages/dd-trace/src/plugins/util/git.js +165 -11
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -1
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +27 -10
- package/packages/dd-trace/src/plugins/util/stacktrace.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +311 -48
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/urlfilter.js +13 -17
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +12 -3
- package/packages/dd-trace/src/plugins/util/web.js +5 -4
- package/packages/dd-trace/src/priority_sampler.js +22 -22
- package/packages/dd-trace/src/profiling/config.js +44 -8
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +5 -5
- package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +37 -2
- package/packages/dd-trace/src/profiling/profilers/events.js +14 -17
- package/packages/dd-trace/src/profiling/profilers/shared.js +6 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +6 -7
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +3 -5
- package/packages/dd-trace/src/profiling/tagger.js +3 -5
- package/packages/dd-trace/src/profiling/webspan-utils.js +1 -1
- package/packages/dd-trace/src/proxy.js +7 -9
- package/packages/dd-trace/src/random_sampler.js +40 -0
- package/packages/dd-trace/src/rate_limiter.js +4 -4
- package/packages/dd-trace/src/remote_config/index.js +3 -7
- package/packages/dd-trace/src/remote_config/manager.js +25 -13
- package/packages/dd-trace/src/require-package-json.js +1 -1
- package/packages/dd-trace/src/ritm.js +4 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
- package/packages/dd-trace/src/sampler.js +33 -4
- package/packages/dd-trace/src/sampling_rule.js +12 -3
- package/packages/dd-trace/src/scope.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -3
- package/packages/dd-trace/src/span_processor.js +3 -3
- package/packages/dd-trace/src/span_sampler.js +4 -1
- package/packages/dd-trace/src/standalone/tracesource.js +1 -1
- package/packages/dd-trace/src/startup-log.js +2 -2
- package/packages/dd-trace/src/telemetry/dependencies.js +4 -4
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +9 -10
- package/packages/dd-trace/src/telemetry/metrics.js +10 -5
- package/packages/dd-trace/src/telemetry/send-data.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +23 -24
- package/packages/dd-trace/src/util.js +1 -1
- package/version.js +1 -0
- package/packages/datadog-instrumentations/src/paperplane.js +0 -77
- package/packages/datadog-plugin-paperplane/src/index.js +0 -25
- package/packages/datadog-plugin-paperplane/src/logger.js +0 -11
- package/packages/datadog-plugin-paperplane/src/server.js +0 -24
|
@@ -6,7 +6,17 @@ const log = require('../../log')
|
|
|
6
6
|
const istanbul = require('istanbul-lib-coverage')
|
|
7
7
|
const ignore = require('ignore')
|
|
8
8
|
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
getGitMetadata,
|
|
11
|
+
getGitInformationDiscrepancy,
|
|
12
|
+
getGitDiff,
|
|
13
|
+
getGitRemoteName,
|
|
14
|
+
getSourceBranch,
|
|
15
|
+
checkAndFetchBranch,
|
|
16
|
+
getLocalBranches,
|
|
17
|
+
getMergeBase,
|
|
18
|
+
getCounts
|
|
19
|
+
} = require('./git')
|
|
10
20
|
const { getUserProviderGitMetadata, validateGitRepositoryUrl, validateGitCommitSha } = require('./user-provided-git')
|
|
11
21
|
const { getCIMetadata } = require('./ci')
|
|
12
22
|
const { getRuntimeAndOSMetadata } = require('./env')
|
|
@@ -23,6 +33,11 @@ const {
|
|
|
23
33
|
CI_JOB_NAME
|
|
24
34
|
} = require('./tags')
|
|
25
35
|
const id = require('../../id')
|
|
36
|
+
const {
|
|
37
|
+
incrementCountMetric,
|
|
38
|
+
TELEMETRY_GIT_COMMIT_SHA_DISCREPANCY,
|
|
39
|
+
TELEMETRY_GIT_SHA_MATCH
|
|
40
|
+
} = require('../../ci-visibility/telemetry')
|
|
26
41
|
|
|
27
42
|
const { SPAN_TYPE, RESOURCE_NAME, SAMPLING_PRIORITY } = require('../../../../../ext/tags')
|
|
28
43
|
const { SAMPLING_RULE_DECISION } = require('../../constants')
|
|
@@ -59,7 +74,7 @@ const TEST_EARLY_FLAKE_ENABLED = 'test.early_flake.enabled'
|
|
|
59
74
|
const TEST_EARLY_FLAKE_ABORT_REASON = 'test.early_flake.abort_reason'
|
|
60
75
|
const TEST_RETRY_REASON = 'test.retry_reason'
|
|
61
76
|
const TEST_HAS_FAILED_ALL_RETRIES = 'test.has_failed_all_retries'
|
|
62
|
-
|
|
77
|
+
const TEST_IS_MODIFIED = 'test.is_modified'
|
|
63
78
|
const CI_APP_ORIGIN = 'ciapp-test'
|
|
64
79
|
|
|
65
80
|
const JEST_TEST_RUNNER = 'test.jest.test_runner'
|
|
@@ -101,18 +116,20 @@ const PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE = 90
|
|
|
101
116
|
|
|
102
117
|
// Early flake detection util strings
|
|
103
118
|
const EFD_STRING = "Retried by Datadog's Early Flake Detection"
|
|
104
|
-
const EFD_TEST_NAME_REGEX = new RegExp(EFD_STRING +
|
|
119
|
+
const EFD_TEST_NAME_REGEX = new RegExp(EFD_STRING + String.raw` \(#\d+\): `, 'g')
|
|
105
120
|
|
|
106
121
|
// Library Capabilities Tagging
|
|
107
122
|
const DD_CAPABILITIES_TEST_IMPACT_ANALYSIS = '_dd.library_capabilities.test_impact_analysis'
|
|
108
123
|
const DD_CAPABILITIES_EARLY_FLAKE_DETECTION = '_dd.library_capabilities.early_flake_detection'
|
|
109
124
|
const DD_CAPABILITIES_AUTO_TEST_RETRIES = '_dd.library_capabilities.auto_test_retries'
|
|
125
|
+
const DD_CAPABILITIES_IMPACTED_TESTS = '_dd.library_capabilities.impacted_tests'
|
|
110
126
|
const DD_CAPABILITIES_TEST_MANAGEMENT_QUARANTINE = '_dd.library_capabilities.test_management.quarantine'
|
|
111
127
|
const DD_CAPABILITIES_TEST_MANAGEMENT_DISABLE = '_dd.library_capabilities.test_management.disable'
|
|
112
128
|
const DD_CAPABILITIES_TEST_MANAGEMENT_ATTEMPT_TO_FIX = '_dd.library_capabilities.test_management.attempt_to_fix'
|
|
113
|
-
const UNSUPPORTED_TIA_FRAMEWORKS = ['playwright', 'vitest']
|
|
114
|
-
const UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE = ['cucumber', 'mocha']
|
|
115
|
-
const UNSUPPORTED_ATTEMPT_TO_FIX_FRAMEWORKS_PARALLEL_MODE = ['mocha']
|
|
129
|
+
const UNSUPPORTED_TIA_FRAMEWORKS = new Set(['playwright', 'vitest'])
|
|
130
|
+
const UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE = new Set(['cucumber', 'mocha'])
|
|
131
|
+
const UNSUPPORTED_ATTEMPT_TO_FIX_FRAMEWORKS_PARALLEL_MODE = new Set(['mocha'])
|
|
132
|
+
const NOT_SUPPORTED_GRANULARITY_IMPACTED_TESTS_FRAMEWORKS = new Set(['mocha', 'playwright', 'vitest'])
|
|
116
133
|
|
|
117
134
|
const TEST_LEVEL_EVENT_TYPES = [
|
|
118
135
|
'test',
|
|
@@ -145,7 +162,11 @@ const TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED = 'test.test_management.attempt_to_f
|
|
|
145
162
|
|
|
146
163
|
// Test Management utils strings
|
|
147
164
|
const ATTEMPT_TO_FIX_STRING = "Retried by Datadog's Test Management"
|
|
148
|
-
const ATTEMPT_TEST_NAME_REGEX = new RegExp(ATTEMPT_TO_FIX_STRING +
|
|
165
|
+
const ATTEMPT_TEST_NAME_REGEX = new RegExp(ATTEMPT_TO_FIX_STRING + String.raw` \(#\d+\): `, 'g')
|
|
166
|
+
|
|
167
|
+
// Impacted tests
|
|
168
|
+
const POSSIBLE_BASE_BRANCHES = ['main', 'master', 'preprod', 'prod', 'dev', 'development', 'trunk']
|
|
169
|
+
const BASE_LIKE_BRANCH_FILTER = /^(main|master|preprod|prod|dev|development|trunk|release\/.*|hotfix\/.*)$/
|
|
149
170
|
|
|
150
171
|
module.exports = {
|
|
151
172
|
TEST_CODE_OWNERS,
|
|
@@ -180,6 +201,7 @@ module.exports = {
|
|
|
180
201
|
TEST_EARLY_FLAKE_ABORT_REASON,
|
|
181
202
|
TEST_RETRY_REASON,
|
|
182
203
|
TEST_HAS_FAILED_ALL_RETRIES,
|
|
204
|
+
TEST_IS_MODIFIED,
|
|
183
205
|
getTestEnvironmentMetadata,
|
|
184
206
|
getTestParametersString,
|
|
185
207
|
finishAllTraceSpans,
|
|
@@ -212,6 +234,7 @@ module.exports = {
|
|
|
212
234
|
mergeCoverage,
|
|
213
235
|
fromCoverageMapToCoverage,
|
|
214
236
|
getTestLineStart,
|
|
237
|
+
getTestEndLine,
|
|
215
238
|
removeInvalidMetadata,
|
|
216
239
|
parseAnnotations,
|
|
217
240
|
EFD_STRING,
|
|
@@ -229,6 +252,7 @@ module.exports = {
|
|
|
229
252
|
DD_CAPABILITIES_TEST_IMPACT_ANALYSIS,
|
|
230
253
|
DD_CAPABILITIES_EARLY_FLAKE_DETECTION,
|
|
231
254
|
DD_CAPABILITIES_AUTO_TEST_RETRIES,
|
|
255
|
+
DD_CAPABILITIES_IMPACTED_TESTS,
|
|
232
256
|
DD_CAPABILITIES_TEST_MANAGEMENT_QUARANTINE,
|
|
233
257
|
DD_CAPABILITIES_TEST_MANAGEMENT_DISABLE,
|
|
234
258
|
DD_CAPABILITIES_TEST_MANAGEMENT_ATTEMPT_TO_FIX,
|
|
@@ -248,14 +272,20 @@ module.exports = {
|
|
|
248
272
|
TEST_MANAGEMENT_IS_QUARANTINED,
|
|
249
273
|
TEST_MANAGEMENT_ENABLED,
|
|
250
274
|
TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED,
|
|
251
|
-
getLibraryCapabilitiesTags
|
|
275
|
+
getLibraryCapabilitiesTags,
|
|
276
|
+
checkShaDiscrepancies,
|
|
277
|
+
getPullRequestDiff,
|
|
278
|
+
getPullRequestBaseBranch,
|
|
279
|
+
getModifiedTestsFromDiff,
|
|
280
|
+
isModifiedTest,
|
|
281
|
+
POSSIBLE_BASE_BRANCHES
|
|
252
282
|
}
|
|
253
283
|
|
|
254
284
|
// Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
|
|
255
285
|
function getPkgManager () {
|
|
256
286
|
try {
|
|
257
287
|
return process.env.npm_config_user_agent.split(' ')[0].replace('/', '-')
|
|
258
|
-
} catch
|
|
288
|
+
} catch {
|
|
259
289
|
return ''
|
|
260
290
|
}
|
|
261
291
|
}
|
|
@@ -264,35 +294,124 @@ function validateUrl (url) {
|
|
|
264
294
|
try {
|
|
265
295
|
const urlObject = new URL(url)
|
|
266
296
|
return (urlObject.protocol === 'https:' || urlObject.protocol === 'http:')
|
|
267
|
-
} catch
|
|
297
|
+
} catch {
|
|
268
298
|
return false
|
|
269
299
|
}
|
|
270
300
|
}
|
|
271
301
|
|
|
272
302
|
function removeInvalidMetadata (metadata) {
|
|
273
303
|
return Object.keys(metadata).reduce((filteredTags, tag) => {
|
|
274
|
-
if (tag === GIT_REPOSITORY_URL) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return filteredTags
|
|
278
|
-
}
|
|
304
|
+
if (tag === GIT_REPOSITORY_URL && !validateGitRepositoryUrl(metadata[GIT_REPOSITORY_URL])) {
|
|
305
|
+
log.error('Repository URL is not a valid repository URL: %s.', metadata[GIT_REPOSITORY_URL])
|
|
306
|
+
return filteredTags
|
|
279
307
|
}
|
|
280
|
-
if (tag === GIT_COMMIT_SHA) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return filteredTags
|
|
284
|
-
}
|
|
308
|
+
if (tag === GIT_COMMIT_SHA && !validateGitCommitSha(metadata[GIT_COMMIT_SHA])) {
|
|
309
|
+
log.error('Git commit SHA must be a full-length git SHA: %s.', metadata[GIT_COMMIT_SHA])
|
|
310
|
+
return filteredTags
|
|
285
311
|
}
|
|
286
|
-
if (tag === CI_PIPELINE_URL) {
|
|
287
|
-
|
|
288
|
-
return filteredTags
|
|
289
|
-
}
|
|
312
|
+
if (tag === CI_PIPELINE_URL && !validateUrl(metadata[CI_PIPELINE_URL])) {
|
|
313
|
+
return filteredTags
|
|
290
314
|
}
|
|
291
315
|
filteredTags[tag] = metadata[tag]
|
|
292
316
|
return filteredTags
|
|
293
317
|
}, {})
|
|
294
318
|
}
|
|
295
319
|
|
|
320
|
+
function checkShaDiscrepancies (ciMetadata, userProvidedGitMetadata) {
|
|
321
|
+
const {
|
|
322
|
+
[GIT_COMMIT_SHA]: ciCommitSHA,
|
|
323
|
+
[GIT_REPOSITORY_URL]: ciRepositoryUrl
|
|
324
|
+
} = ciMetadata
|
|
325
|
+
const {
|
|
326
|
+
[GIT_COMMIT_SHA]: userProvidedCommitSHA,
|
|
327
|
+
[GIT_REPOSITORY_URL]: userProvidedRepositoryUrl
|
|
328
|
+
} = userProvidedGitMetadata
|
|
329
|
+
const { gitRepositoryUrl, gitCommitSHA } = getGitInformationDiscrepancy()
|
|
330
|
+
|
|
331
|
+
const checkDiscrepancyAndSendMetrics = (
|
|
332
|
+
valueExpected,
|
|
333
|
+
valueDiscrepant,
|
|
334
|
+
discrepancyType,
|
|
335
|
+
expectedProvider,
|
|
336
|
+
discrepantProvider
|
|
337
|
+
) => {
|
|
338
|
+
if (valueExpected && valueDiscrepant && valueExpected !== valueDiscrepant) {
|
|
339
|
+
incrementCountMetric(
|
|
340
|
+
TELEMETRY_GIT_COMMIT_SHA_DISCREPANCY,
|
|
341
|
+
{
|
|
342
|
+
type: discrepancyType,
|
|
343
|
+
expected_provider: expectedProvider,
|
|
344
|
+
discrepant_provider: discrepantProvider
|
|
345
|
+
}
|
|
346
|
+
)
|
|
347
|
+
return true
|
|
348
|
+
}
|
|
349
|
+
return false
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const checkConfigs = [
|
|
353
|
+
// User provided vs Git metadata
|
|
354
|
+
{
|
|
355
|
+
v1: userProvidedRepositoryUrl,
|
|
356
|
+
v2: gitRepositoryUrl,
|
|
357
|
+
type: 'repository_discrepancy',
|
|
358
|
+
expected: 'user_supplied',
|
|
359
|
+
discrepant: 'git_client'
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
v1: userProvidedCommitSHA,
|
|
363
|
+
v2: gitCommitSHA,
|
|
364
|
+
type: 'commit_discrepancy',
|
|
365
|
+
expected: 'user_supplied',
|
|
366
|
+
discrepant: 'git_client'
|
|
367
|
+
},
|
|
368
|
+
// User provided vs CI metadata
|
|
369
|
+
{
|
|
370
|
+
v1: userProvidedRepositoryUrl,
|
|
371
|
+
v2: ciRepositoryUrl,
|
|
372
|
+
type: 'repository_discrepancy',
|
|
373
|
+
expected: 'user_supplied',
|
|
374
|
+
discrepant: 'ci_provider'
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
v1: userProvidedCommitSHA,
|
|
378
|
+
v2: ciCommitSHA,
|
|
379
|
+
type: 'commit_discrepancy',
|
|
380
|
+
expected: 'user_supplied',
|
|
381
|
+
discrepant: 'ci_provider'
|
|
382
|
+
},
|
|
383
|
+
// CI metadata vs Git metadata
|
|
384
|
+
{
|
|
385
|
+
v1: ciRepositoryUrl,
|
|
386
|
+
v2: gitRepositoryUrl,
|
|
387
|
+
type: 'repository_discrepancy',
|
|
388
|
+
expected: 'ci_provider',
|
|
389
|
+
discrepant: 'git_client'
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
v1: ciCommitSHA,
|
|
393
|
+
v2: gitCommitSHA,
|
|
394
|
+
type: 'commit_discrepancy',
|
|
395
|
+
expected: 'ci_provider',
|
|
396
|
+
discrepant: 'git_client'
|
|
397
|
+
}
|
|
398
|
+
]
|
|
399
|
+
|
|
400
|
+
let gitCommitShaMatch = true
|
|
401
|
+
for (const checkConfig of checkConfigs) {
|
|
402
|
+
const { v1, v2, type, expected, discrepant } = checkConfig
|
|
403
|
+
const discrepancy = checkDiscrepancyAndSendMetrics(v1, v2, type, expected, discrepant)
|
|
404
|
+
if (discrepancy) {
|
|
405
|
+
gitCommitShaMatch = false
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
incrementCountMetric(
|
|
410
|
+
TELEMETRY_GIT_SHA_MATCH,
|
|
411
|
+
{ match: gitCommitShaMatch }
|
|
412
|
+
)
|
|
413
|
+
}
|
|
414
|
+
|
|
296
415
|
function getTestEnvironmentMetadata (testFramework, config) {
|
|
297
416
|
// TODO: eventually these will come from the tracer (generally available)
|
|
298
417
|
const ciMetadata = getCIMetadata()
|
|
@@ -320,6 +439,8 @@ function getTestEnvironmentMetadata (testFramework, config) {
|
|
|
320
439
|
|
|
321
440
|
const userProvidedGitMetadata = getUserProviderGitMetadata()
|
|
322
441
|
|
|
442
|
+
checkShaDiscrepancies(ciMetadata, userProvidedGitMetadata)
|
|
443
|
+
|
|
323
444
|
const runtimeAndOSMetadata = getRuntimeAndOSMetadata()
|
|
324
445
|
|
|
325
446
|
const metadata = {
|
|
@@ -344,7 +465,7 @@ function getTestParametersString (parametersByTestName, testName) {
|
|
|
344
465
|
// test is invoked with each parameter set sequencially
|
|
345
466
|
const testParameters = parametersByTestName[testName].shift()
|
|
346
467
|
return JSON.stringify({ arguments: testParameters, metadata: {} })
|
|
347
|
-
} catch
|
|
468
|
+
} catch {
|
|
348
469
|
// We can't afford to interrupt the test if `testParameters` is not serializable to JSON,
|
|
349
470
|
// so we ignore the test parameters and move on
|
|
350
471
|
return ''
|
|
@@ -413,7 +534,7 @@ function readCodeOwners (rootDir) {
|
|
|
413
534
|
for (const location of POSSIBLE_CODEOWNERS_LOCATIONS) {
|
|
414
535
|
try {
|
|
415
536
|
return fs.readFileSync(path.join(rootDir, location)).toString()
|
|
416
|
-
} catch
|
|
537
|
+
} catch {
|
|
417
538
|
// retry with next path
|
|
418
539
|
}
|
|
419
540
|
}
|
|
@@ -467,7 +588,7 @@ function getCodeOwnersForFilename (filename, entries) {
|
|
|
467
588
|
if (isResponsible) {
|
|
468
589
|
return JSON.stringify(entry.owners)
|
|
469
590
|
}
|
|
470
|
-
} catch
|
|
591
|
+
} catch {
|
|
471
592
|
return null
|
|
472
593
|
}
|
|
473
594
|
}
|
|
@@ -619,12 +740,19 @@ function getTestLineStart (err, testSuitePath) {
|
|
|
619
740
|
const testFileLine = err.stack.split('\n').find(line => line.includes(testSuitePath))
|
|
620
741
|
try {
|
|
621
742
|
const testFileLineMatch = testFileLine.match(/at (?:(.+?)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/)
|
|
622
|
-
return parseInt(testFileLineMatch[3], 10) || null
|
|
623
|
-
} catch
|
|
743
|
+
return Number.parseInt(testFileLineMatch[3], 10) || null
|
|
744
|
+
} catch {
|
|
624
745
|
return null
|
|
625
746
|
}
|
|
626
747
|
}
|
|
627
748
|
|
|
749
|
+
// Get the end line of a test by inspecting a given function's source code
|
|
750
|
+
function getTestEndLine (testFn, startLine = 0) {
|
|
751
|
+
const source = testFn.toString()
|
|
752
|
+
const lineCount = source.split('\n').length
|
|
753
|
+
return startLine + lineCount - 1
|
|
754
|
+
}
|
|
755
|
+
|
|
628
756
|
/**
|
|
629
757
|
* Gets an object of test tags from an Playwright annotations array.
|
|
630
758
|
* @param {Object[]} annotations - Annotations from a Playwright test.
|
|
@@ -686,14 +814,14 @@ function getIsFaultyEarlyFlakeDetection (projectSuites, testsBySuiteName, faulty
|
|
|
686
814
|
)
|
|
687
815
|
}
|
|
688
816
|
|
|
689
|
-
function getTestSessionName (config,
|
|
817
|
+
function getTestSessionName (config, trimmedCommand, envTags) {
|
|
690
818
|
if (config.ciVisibilityTestSessionName) {
|
|
691
819
|
return config.ciVisibilityTestSessionName
|
|
692
820
|
}
|
|
693
821
|
if (envTags[CI_JOB_NAME]) {
|
|
694
|
-
return `${envTags[CI_JOB_NAME]}-${
|
|
822
|
+
return `${envTags[CI_JOB_NAME]}-${trimmedCommand}`
|
|
695
823
|
}
|
|
696
|
-
return
|
|
824
|
+
return trimmedCommand
|
|
697
825
|
}
|
|
698
826
|
|
|
699
827
|
// Calculate the number of a tests from the known tests response, which has a shape like:
|
|
@@ -761,28 +889,21 @@ function getFormattedError (error, repositoryRoot) {
|
|
|
761
889
|
return newError
|
|
762
890
|
}
|
|
763
891
|
|
|
764
|
-
function
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
if (isParallel && UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE.includes(testFramework)) {
|
|
770
|
-
return false
|
|
771
|
-
}
|
|
772
|
-
return true
|
|
773
|
-
}
|
|
892
|
+
function isTiaSupported (testFramework, isParallel) {
|
|
893
|
+
return !(UNSUPPORTED_TIA_FRAMEWORKS.has(testFramework) ||
|
|
894
|
+
(isParallel && UNSUPPORTED_TIA_FRAMEWORKS_PARALLEL_MODE.has(testFramework)))
|
|
895
|
+
}
|
|
774
896
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
779
|
-
return true
|
|
780
|
-
}
|
|
897
|
+
function isAttemptToFixSupported (testFramework, isParallel) {
|
|
898
|
+
return !(isParallel && UNSUPPORTED_ATTEMPT_TO_FIX_FRAMEWORKS_PARALLEL_MODE.has(testFramework))
|
|
899
|
+
}
|
|
781
900
|
|
|
901
|
+
function getLibraryCapabilitiesTags (testFramework, isParallel) {
|
|
782
902
|
return {
|
|
783
903
|
[DD_CAPABILITIES_TEST_IMPACT_ANALYSIS]: isTiaSupported(testFramework, isParallel) ? '1' : undefined,
|
|
784
904
|
[DD_CAPABILITIES_EARLY_FLAKE_DETECTION]: '1',
|
|
785
905
|
[DD_CAPABILITIES_AUTO_TEST_RETRIES]: '1',
|
|
906
|
+
[DD_CAPABILITIES_IMPACTED_TESTS]: '1',
|
|
786
907
|
[DD_CAPABILITIES_TEST_MANAGEMENT_QUARANTINE]: '1',
|
|
787
908
|
[DD_CAPABILITIES_TEST_MANAGEMENT_DISABLE]: '1',
|
|
788
909
|
[DD_CAPABILITIES_TEST_MANAGEMENT_ATTEMPT_TO_FIX]: isAttemptToFixSupported(testFramework, isParallel)
|
|
@@ -790,3 +911,145 @@ function getLibraryCapabilitiesTags (testFramework, isParallel) {
|
|
|
790
911
|
: undefined
|
|
791
912
|
}
|
|
792
913
|
}
|
|
914
|
+
|
|
915
|
+
function getPullRequestBaseBranch (pullRequestBaseBranch) {
|
|
916
|
+
const remoteName = getGitRemoteName()
|
|
917
|
+
|
|
918
|
+
const sourceBranch = getSourceBranch()
|
|
919
|
+
// TODO: We will get the default branch name from the backend in the future.
|
|
920
|
+
const POSSIBLE_DEFAULT_BRANCHES = ['main', 'master']
|
|
921
|
+
|
|
922
|
+
const candidateBranches = []
|
|
923
|
+
if (pullRequestBaseBranch) {
|
|
924
|
+
checkAndFetchBranch(pullRequestBaseBranch, remoteName)
|
|
925
|
+
candidateBranches.push(pullRequestBaseBranch)
|
|
926
|
+
} else {
|
|
927
|
+
for (const branch of POSSIBLE_BASE_BRANCHES) {
|
|
928
|
+
checkAndFetchBranch(branch, remoteName)
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
const localBranches = getLocalBranches(remoteName)
|
|
932
|
+
for (const branch of localBranches) {
|
|
933
|
+
const shortBranchName = branch.replace(new RegExp(`^${remoteName}/`), '')
|
|
934
|
+
if (branch !== sourceBranch && BASE_LIKE_BRANCH_FILTER.test(shortBranchName)) {
|
|
935
|
+
candidateBranches.push(branch)
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (candidateBranches.length === 1) {
|
|
941
|
+
return getMergeBase(candidateBranches[0], sourceBranch)
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
const metrics = {}
|
|
945
|
+
for (const candidate of candidateBranches) {
|
|
946
|
+
// Find common ancestor
|
|
947
|
+
const baseSha = getMergeBase(candidate, sourceBranch)
|
|
948
|
+
if (!baseSha) {
|
|
949
|
+
continue
|
|
950
|
+
}
|
|
951
|
+
// Count commits ahead/behind
|
|
952
|
+
const counts = getCounts(candidate, sourceBranch)
|
|
953
|
+
if (!counts) {
|
|
954
|
+
continue
|
|
955
|
+
}
|
|
956
|
+
const behind = counts.behind
|
|
957
|
+
const ahead = counts.ahead
|
|
958
|
+
metrics[candidate] = {
|
|
959
|
+
behind,
|
|
960
|
+
ahead,
|
|
961
|
+
baseSha
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
function isDefaultBranch (branch) {
|
|
966
|
+
return POSSIBLE_DEFAULT_BRANCHES.some(defaultBranch =>
|
|
967
|
+
branch === defaultBranch || branch === `${remoteName}/${defaultBranch}`
|
|
968
|
+
)
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
if (Object.keys(metrics).length === 0) {
|
|
972
|
+
return null
|
|
973
|
+
}
|
|
974
|
+
// Find branch with smallest "ahead" value, preferring default branch on tie
|
|
975
|
+
let bestBranch = null
|
|
976
|
+
let bestScore = Infinity
|
|
977
|
+
for (const branch of Object.keys(metrics)) {
|
|
978
|
+
const score = metrics[branch].ahead
|
|
979
|
+
if (score < bestScore) {
|
|
980
|
+
bestScore = score
|
|
981
|
+
bestBranch = branch
|
|
982
|
+
} else if (score === bestScore && isDefaultBranch(branch)) {
|
|
983
|
+
bestScore = score
|
|
984
|
+
bestBranch = branch
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
return bestBranch ? metrics[bestBranch].baseSha : null
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
function getPullRequestDiff (baseCommit, targetCommit) {
|
|
991
|
+
if (!baseCommit) {
|
|
992
|
+
return
|
|
993
|
+
}
|
|
994
|
+
return getGitDiff(baseCommit, targetCommit)
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
function getModifiedTestsFromDiff (diff) {
|
|
998
|
+
if (!diff) return null
|
|
999
|
+
const result = {}
|
|
1000
|
+
|
|
1001
|
+
const filesRegex = /^diff --git a\/(?<file>.+) b\/(?<file2>.+)$/g
|
|
1002
|
+
const linesRegex = /^@@ -\d+(,\d+)? \+(?<start>\d+)(,(?<count>\d+))? @@/g
|
|
1003
|
+
|
|
1004
|
+
let currentFile = null
|
|
1005
|
+
|
|
1006
|
+
// Go line by line
|
|
1007
|
+
const lines = diff.split('\n')
|
|
1008
|
+
for (const line of lines) {
|
|
1009
|
+
// Check for new file
|
|
1010
|
+
const fileMatch = filesRegex.exec(line)
|
|
1011
|
+
if (fileMatch && fileMatch.groups.file) {
|
|
1012
|
+
currentFile = fileMatch.groups.file
|
|
1013
|
+
result[currentFile] = []
|
|
1014
|
+
continue
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
// Check for changed lines
|
|
1018
|
+
const lineMatch = linesRegex.exec(line)
|
|
1019
|
+
if (lineMatch && currentFile) {
|
|
1020
|
+
const start = Number(lineMatch.groups.start)
|
|
1021
|
+
const count = lineMatch.groups.count ? Number(lineMatch.groups.count) : 1
|
|
1022
|
+
for (let j = 0; j < count; j++) {
|
|
1023
|
+
result[currentFile].push(start + j)
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// Reset regexes to allow re-use
|
|
1028
|
+
filesRegex.lastIndex = 0
|
|
1029
|
+
linesRegex.lastIndex = 0
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
if (Object.keys(result).length === 0) {
|
|
1033
|
+
return null
|
|
1034
|
+
}
|
|
1035
|
+
return result
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
function isModifiedTest (testPath, testStartLine, testEndLine, modifiedTests, testFramework) {
|
|
1039
|
+
if (modifiedTests === undefined) {
|
|
1040
|
+
return false
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
const lines = modifiedTests[testPath]
|
|
1044
|
+
if (!lines) {
|
|
1045
|
+
return false
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// For unsupported frameworks, consider the test modified if any lines were changed
|
|
1049
|
+
if (NOT_SUPPORTED_GRANULARITY_IMPACTED_TESTS_FRAMEWORKS.has(testFramework)) {
|
|
1050
|
+
return lines.length > 0
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// For supported frameworks, check if the test's line range overlaps with modified lines
|
|
1054
|
+
return lines.some(line => line >= testStartLine && line <= testEndLine)
|
|
1055
|
+
}
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
const log = require('../../log')
|
|
4
4
|
|
|
5
|
+
function applyFilter (filter, uri) {
|
|
6
|
+
if (typeof filter === 'function') {
|
|
7
|
+
return filter(uri)
|
|
8
|
+
} else if (filter instanceof RegExp) {
|
|
9
|
+
return filter.test(uri)
|
|
10
|
+
} else if (Array.isArray(filter)) {
|
|
11
|
+
return filter.some(filter => applyFilter(filter, uri))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return filter === uri
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
const urlFilter = {
|
|
6
18
|
getFilter (config) {
|
|
7
19
|
if (typeof config.filter === 'function') {
|
|
@@ -13,23 +25,7 @@ const urlFilter = {
|
|
|
13
25
|
const allowlist = config.allowlist || config.whitelist || /.*/
|
|
14
26
|
const blocklist = config.blocklist || config.blacklist || []
|
|
15
27
|
|
|
16
|
-
return uri =>
|
|
17
|
-
const allowed = applyFilter(allowlist, uri)
|
|
18
|
-
const blocked = applyFilter(blocklist, uri)
|
|
19
|
-
return allowed && !blocked
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function applyFilter (filter, uri) {
|
|
23
|
-
if (typeof filter === 'function') {
|
|
24
|
-
return filter(uri)
|
|
25
|
-
} else if (filter instanceof RegExp) {
|
|
26
|
-
return filter.test(uri)
|
|
27
|
-
} else if (filter instanceof Array) {
|
|
28
|
-
return filter.some(filter => applyFilter(filter, uri))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return filter === uri
|
|
32
|
-
}
|
|
28
|
+
return uri => applyFilter(allowlist, uri) && !applyFilter(blocklist, uri)
|
|
33
29
|
}
|
|
34
30
|
}
|
|
35
31
|
|
|
@@ -9,7 +9,10 @@ const {
|
|
|
9
9
|
GIT_COMMIT_COMMITTER_NAME,
|
|
10
10
|
GIT_COMMIT_AUTHOR_DATE,
|
|
11
11
|
GIT_COMMIT_AUTHOR_EMAIL,
|
|
12
|
-
GIT_COMMIT_AUTHOR_NAME
|
|
12
|
+
GIT_COMMIT_AUTHOR_NAME,
|
|
13
|
+
GIT_PULL_REQUEST_BASE_BRANCH,
|
|
14
|
+
GIT_PULL_REQUEST_BASE_BRANCH_SHA,
|
|
15
|
+
GIT_COMMIT_HEAD_SHA
|
|
13
16
|
} = require('./tags')
|
|
14
17
|
|
|
15
18
|
const { normalizeRef } = require('./ci')
|
|
@@ -52,7 +55,10 @@ function getUserProviderGitMetadata () {
|
|
|
52
55
|
DD_GIT_COMMIT_COMMITTER_DATE,
|
|
53
56
|
DD_GIT_COMMIT_AUTHOR_NAME,
|
|
54
57
|
DD_GIT_COMMIT_AUTHOR_EMAIL,
|
|
55
|
-
DD_GIT_COMMIT_AUTHOR_DATE
|
|
58
|
+
DD_GIT_COMMIT_AUTHOR_DATE,
|
|
59
|
+
DD_GIT_PULL_REQUEST_BASE_BRANCH,
|
|
60
|
+
DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA,
|
|
61
|
+
DD_GIT_COMMIT_HEAD_SHA
|
|
56
62
|
} = process.env
|
|
57
63
|
|
|
58
64
|
const branch = normalizeRef(DD_GIT_BRANCH)
|
|
@@ -74,7 +80,10 @@ function getUserProviderGitMetadata () {
|
|
|
74
80
|
[GIT_COMMIT_COMMITTER_EMAIL]: DD_GIT_COMMIT_COMMITTER_EMAIL,
|
|
75
81
|
[GIT_COMMIT_AUTHOR_NAME]: DD_GIT_COMMIT_AUTHOR_NAME,
|
|
76
82
|
[GIT_COMMIT_AUTHOR_EMAIL]: DD_GIT_COMMIT_AUTHOR_EMAIL,
|
|
77
|
-
[GIT_COMMIT_AUTHOR_DATE]: DD_GIT_COMMIT_AUTHOR_DATE
|
|
83
|
+
[GIT_COMMIT_AUTHOR_DATE]: DD_GIT_COMMIT_AUTHOR_DATE,
|
|
84
|
+
[GIT_PULL_REQUEST_BASE_BRANCH]: DD_GIT_PULL_REQUEST_BASE_BRANCH,
|
|
85
|
+
[GIT_PULL_REQUEST_BASE_BRANCH_SHA]: DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA,
|
|
86
|
+
[GIT_COMMIT_HEAD_SHA]: DD_GIT_COMMIT_HEAD_SHA
|
|
78
87
|
})
|
|
79
88
|
}
|
|
80
89
|
|
|
@@ -253,7 +253,7 @@ const web = {
|
|
|
253
253
|
if (!context) return null
|
|
254
254
|
if (context.middleware.length === 0) return context.span || null
|
|
255
255
|
|
|
256
|
-
return context.middleware.
|
|
256
|
+
return context.middleware.at(-1)
|
|
257
257
|
},
|
|
258
258
|
|
|
259
259
|
// Extract the parent span from the headers and start a new span as its child
|
|
@@ -500,7 +500,7 @@ function addResourceTag (context) {
|
|
|
500
500
|
if (tags['resource.name']) return
|
|
501
501
|
|
|
502
502
|
const resource = [req.method, tags[HTTP_ROUTE]]
|
|
503
|
-
.filter(
|
|
503
|
+
.filter(Boolean)
|
|
504
504
|
.join(' ')
|
|
505
505
|
|
|
506
506
|
span.setTag(RESOURCE_NAME, resource)
|
|
@@ -567,9 +567,10 @@ function getStatusValidator (config) {
|
|
|
567
567
|
return code => code < 500
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
+
const noop = () => {}
|
|
571
|
+
|
|
570
572
|
function getHooks (config) {
|
|
571
|
-
const
|
|
572
|
-
const request = (config.hooks && config.hooks.request) || noop
|
|
573
|
+
const request = config.hooks?.request ?? noop
|
|
573
574
|
|
|
574
575
|
return { request }
|
|
575
576
|
}
|