diff --git a/.gitlab/generate-appsec.php b/.gitlab/generate-appsec.php index 20e07ab21ad..34bc16c6399 100644 --- a/.gitlab/generate-appsec.php +++ b/.gitlab/generate-appsec.php @@ -247,24 +247,6 @@ script: - apt update && apt install -y openjdk-17-jre - - | - echo "Installing codecov CLI" - curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&search=0x27034E7FDB850E0BBC2C62FF806BB28AED779869" | gpg --no-default-keyring --keyring trustedkeys.gpg --import - CODECOV_VERSION=0.6.1 - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/linux/codecov - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/linux/codecov.SHA256SUM - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/linux/codecov.SHA256SUM.sig - gpgv codecov.SHA256SUM.sig codecov.SHA256SUM - shasum -a 256 -c codecov.SHA256SUM - rm codecov.SHA256SUM.sig codecov.SHA256SUM - chmod +x codecov - mv codecov /usr/local/bin/codecov - - | - echo "Installing vault for codecov token" - curl -o vault.zip https://releases.hashicorp.com/vault/1.20.0/vault_1.20.0_linux_amd64.zip - unzip vault.zip - mv vault /usr/local/bin/vault - rm vault.zip - | cd appsec/tests/integration CACHE_PATH=build/php-appsec-volume-caches-${ARCH}.tar.gz @@ -280,18 +262,9 @@ mkdir -p "$CI_PROJECT_DIR"/appsec/helper-rust docker run --rm -v php-helper-rust-coverage:/vol alpine cat /vol/coverage-unit.lcov > "$CI_PROJECT_DIR"/appsec/helper-rust/coverage-unit.lcov - | - echo "Uploading helper-rust unit test coverage to codecov" cd "$CI_PROJECT_DIR" - if ! VAULT_OUTPUT=$(vault kv get --format=json kv/k8s/gitlab-runner/dd-trace-php/codecov); then - echo "ERROR: vault unreachable while fetching CODECOV_TOKEN; exiting 75 so GitLab auto-retries (see default retry.exit_codes in generate-common.php)" - exit 75 - fi - CODECOV_TOKEN=$(echo "$VAULT_OUTPUT" | jq -r .data.data.token) - if [ -z "$CODECOV_TOKEN" ] || [ "$CODECOV_TOKEN" = "null" ]; then - echo "ERROR: CODECOV_TOKEN empty/null after vault fetch; exiting 75 so GitLab auto-retries" - exit 75 - fi - codecov -t "$CODECOV_TOKEN" -n helper-rust-unit -F helper-rust-unit -v -f appsec/helper-rust/coverage-unit.lcov + DD_COVERAGE_FLAGS=helper-rust-unit \ + .gitlab/upload-code-coverage-to-datadog.sh appsec/helper-rust/coverage-unit.lcov artifacts: paths: - appsec/helper-rust/coverage-unit.lcov @@ -322,24 +295,6 @@ script: - apt update && apt install -y openjdk-17-jre - - | - echo "Installing codecov CLI" - curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&search=0x27034E7FDB850E0BBC2C62FF806BB28AED779869" | gpg --no-default-keyring --keyring trustedkeys.gpg --import - CODECOV_VERSION=0.6.1 - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/linux/codecov - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/linux/codecov.SHA256SUM - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/linux/codecov.SHA256SUM.sig - gpgv codecov.SHA256SUM.sig codecov.SHA256SUM - shasum -a 256 -c codecov.SHA256SUM - rm codecov.SHA256SUM.sig codecov.SHA256SUM - chmod +x codecov - mv codecov /usr/local/bin/codecov - - | - echo "Installing vault for codecov token" - curl -o vault.zip https://releases.hashicorp.com/vault/1.20.0/vault_1.20.0_linux_amd64.zip - unzip vault.zip - mv vault /usr/local/bin/vault - rm vault.zip - | cd appsec/tests/integration CACHE_PATH=build/php-appsec-volume-caches-${ARCH}.tar.gz @@ -359,18 +314,9 @@ mkdir -p "$CI_PROJECT_DIR"/appsec/helper-rust docker run --rm -v php-helper-rust-coverage:/vol alpine cat /vol/coverage-integration.lcov > "$CI_PROJECT_DIR"/appsec/helper-rust/coverage-integration.lcov - | - echo "Uploading helper-rust integration test coverage to codecov" cd "$CI_PROJECT_DIR" - if ! VAULT_OUTPUT=$(vault kv get --format=json kv/k8s/gitlab-runner/dd-trace-php/codecov); then - echo "ERROR: vault unreachable while fetching CODECOV_TOKEN; exiting 75 so GitLab auto-retries (see default retry.exit_codes in generate-common.php)" - exit 75 - fi - CODECOV_TOKEN=$(echo "$VAULT_OUTPUT" | jq -r .data.data.token) - if [ -z "$CODECOV_TOKEN" ] || [ "$CODECOV_TOKEN" = "null" ]; then - echo "ERROR: CODECOV_TOKEN empty/null after vault fetch; exiting 75 so GitLab auto-retries" - exit 75 - fi - codecov -t "$CODECOV_TOKEN" -n helper-rust-integration -F helper-rust-integration -v -f appsec/helper-rust/coverage-integration.lcov + DD_COVERAGE_FLAGS=helper-rust-integration \ + .gitlab/upload-code-coverage-to-datadog.sh appsec/helper-rust/coverage-integration.lcov after_script: - mkdir -p "${CI_PROJECT_DIR}/artifacts" - find appsec/tests/integration/build/test-results -name "*.xml" -exec cp --parents '{}' "${CI_PROJECT_DIR}/artifacts/" \; || true @@ -401,28 +347,7 @@ script: - | echo "Installing dependencies" - cd /tmp - curl -o vault.zip https://releases.hashicorp.com/vault/1.20.0/vault_1.20.0_linux_amd64.zip - unzip vault.zip - sudo cp -v vault /usr/local/bin - cd - - sudo sed -i 's|http://deb.debian.org/debian|http://archive.debian.org/debian|g; s|http://security.debian.org/debian-security|http://archive.debian.org/debian-security|g' /etc/apt/sources.list sudo apt-get update && sudo apt-get install -y jq gcovr llvm-20 clang-20 - - echo "Installing codecov" - - CODECOV_TOKEN=$(vault kv get --format=json kv/k8s/gitlab-runner/dd-trace-php/codecov | jq -r .data.data.token) - CODECOV_VERSION=0.6.1 - CODECOV_ARCH=linux - curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&search=0x27034E7FDB850E0BBC2C62FF806BB28AED779869" | gpg --no-default-keyring --keyring trustedkeys.gpg --import - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/${CODECOV_ARCH}/codecov - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/${CODECOV_ARCH}/codecov.SHA256SUM - curl -Os https://uploader.codecov.io/v${CODECOV_VERSION}/${CODECOV_ARCH}/codecov.SHA256SUM.sig - gpgv codecov.SHA256SUM.sig codecov.SHA256SUM - shasum -a 256 -c codecov.SHA256SUM - rm codecov.SHA256SUM.sig codecov.SHA256SUM - sudo mv codecov /usr/local/bin/codecov - sudo chmod +x /usr/local/bin/codecov - cd appsec/build - | cmake .. -DCMAKE_BUILD_TYPE=Debug -DDD_APPSEC_ENABLE_COVERAGE=ON \ @@ -445,36 +370,17 @@ llvm-cov-20 export "$CI_PROJECT_DIR"/appsec/build/ddappsec.so \ -format=lcov -instr-profile=default.profdata \ > "$CI_PROJECT_DIR"/appsec/build/coverage-ext.lcov - echo "Uploading extension coverage to codecov" - cd "$CI_PROJECT_DIR" - codecov -t "$CODECOV_TOKEN" -n appsec-extension -v -f appsec/build/coverage-ext.lcov - | cd /tmp/cov-helper llvm-profdata-20 merge -sparse *.profraw -o default.profdata llvm-cov-20 export "$CI_PROJECT_DIR"/appsec/build/tests/helper/ddappsec_helper_test \ -format=lcov -instr-profile=default.profdata \ > "$CI_PROJECT_DIR/appsec/build/coverage-helper.lcov" - echo "Uploading helper coverage to codecov" - cd "$CI_PROJECT_DIR" - codecov -t "$CODECOV_TOKEN" -n appsec-helper -v -f appsec/build/coverage-helper.lcov - | - echo "Uploading coverage to Datadog" cd "$CI_PROJECT_DIR" - - DATADOG_API_KEY=$(vault kv get --format=json kv/k8s/gitlab-runner/dd-trace-php/datadoghq-api-key | jq -r .data.data.key) - export DATADOG_API_KEY - export DD_SITE="datadoghq.com" - - # Install datadog-ci - DATADOG_CI_VERSION="v5.9.1" - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/download/${DATADOG_CI_VERSION}/datadog-ci_linux-x64" --output "/tmp/datadog-ci" - chmod +x /tmp/datadog-ci - - echo "Uploading extension coverage to Datadog" - /tmp/datadog-ci coverage upload --format=lcov appsec/build/coverage-ext.lcov || true - - echo "Uploading helper coverage to Datadog" - /tmp/datadog-ci coverage upload --format=lcov appsec/build/coverage-helper.lcov || true + .gitlab/upload-code-coverage-to-datadog.sh \ + appsec/build/coverage-ext.lcov \ + appsec/build/coverage-helper.lcov "push appsec images": diff --git a/.gitlab/upload-code-coverage-to-datadog.sh b/.gitlab/upload-code-coverage-to-datadog.sh new file mode 100755 index 00000000000..5e5d0f738dd --- /dev/null +++ b/.gitlab/upload-code-coverage-to-datadog.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if [[ $# -eq 0 ]]; then + echo "Usage: $0 [ ...]" >&2 + exit 2 +fi + +: "${CI_PROJECT_DIR:?CI_PROJECT_DIR must be set}" + +export DD_SITE="${DD_SITE:-datadoghq.com}" + +if [[ -n "${DD_API_KEY:-}" ]]; then + : +elif [[ -n "${DATADOG_API_KEY:-}" ]]; then + DD_API_KEY="${DATADOG_API_KEY}" +else + vault_version="1.20.0" + vault_path="/tmp/vault" + vault_zip="${vault_path}.zip" + + if [[ ! -x "${vault_path}" ]]; then + case "$(uname -m)" in + x86_64) + vault_arch="amd64" + datadog_ci_arch="x64" + ;; + aarch64|arm64) + vault_arch="arm64" + datadog_ci_arch="arm64" + ;; + *) + echo "ERROR: unsupported architecture for Vault: $(uname -m)" >&2 + exit 1 + ;; + esac + + if ! curl -L --fail \ + "https://releases.hashicorp.com/vault/${vault_version}/vault_${vault_version}_linux_${vault_arch}.zip" \ + --output "${vault_zip}"; then + echo "ERROR: failed to download Vault; exiting 75 so GitLab auto-retries" >&2 + exit 75 + fi + unzip -o -q "${vault_zip}" -d /tmp + chmod +x "${vault_path}" + rm -f "${vault_zip}" + fi + + if ! vault_output="$("${vault_path}" kv get --format=json \ + kv/k8s/gitlab-runner/dd-trace-php/datadoghq-api-key)"; then + echo "ERROR: Vault unreachable while fetching DD_API_KEY; exiting 75 so GitLab auto-retries" >&2 + exit 75 + fi + + DD_API_KEY="$(jq -r '.data.data.key' <<< "${vault_output}")" + if [[ -z "${DD_API_KEY}" || "${DD_API_KEY}" == "null" ]]; then + echo "ERROR: DD_API_KEY empty/null after Vault fetch; exiting 75 so GitLab auto-retries" >&2 + exit 75 + fi +fi +export DD_API_KEY + +datadog_ci_version="${DATADOG_CI_VERSION:-v5.9.1}" +datadog_ci_path="${DATADOG_CI_PATH:-/tmp/datadog-ci}" + +if [[ -z "${datadog_ci_arch:-}" ]]; then + case "$(uname -m)" in + x86_64) + datadog_ci_arch="x64" + ;; + aarch64|arm64) + datadog_ci_arch="arm64" + ;; + *) + echo "ERROR: unsupported architecture for datadog-ci: $(uname -m)" >&2 + exit 1 + ;; + esac +fi + +if [[ ! -x "${datadog_ci_path}" ]]; then + if ! curl -L --fail \ + "https://github.com/DataDog/datadog-ci/releases/download/${datadog_ci_version}/datadog-ci_linux-${datadog_ci_arch}" \ + --output "${datadog_ci_path}"; then + echo "ERROR: failed to download datadog-ci; exiting 75 so GitLab auto-retries" >&2 + exit 75 + fi + chmod +x "${datadog_ci_path}" +fi + +flags_args=() +if [[ -n "${DD_COVERAGE_FLAGS:-}" ]]; then + IFS=',' read -ra coverage_flags <<< "${DD_COVERAGE_FLAGS}" + for flag in "${coverage_flags[@]}"; do + flags_args+=(--flags "${flag}") + done +fi + +cd "${CI_PROJECT_DIR}" + +for report in "$@"; do + if [[ ! -f "${report}" ]]; then + echo "ERROR: coverage report not found: ${report}" >&2 + exit 1 + fi + + # Reports generated inside the build containers use /project as the checkout + # root. Datadog expects source paths relative to the repository root. + sed -i \ + -e 's|^SF:/project/|SF:|' \ + -e "s|^SF:${CI_PROJECT_DIR}/|SF:|" \ + "${report}" + + echo "Uploading ${report} to Datadog" + "${datadog_ci_path}" coverage upload \ + --format=lcov \ + "${flags_args[@]}" \ + "${report}" +done diff --git a/README.md b/README.md index b2540b2d6db..cdb71f3f19a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # DD Trace PHP [![CircleCI](https://circleci.com/gh/DataDog/dd-trace-php/tree/master.svg?style=svg)](https://circleci.com/gh/DataDog/dd-trace-php/tree/master) -[![CodeCov](https://codecov.io/gh/DataDog/dd-trace-php/branch/master/graph/badge.svg?token=eXio8H7vwF)](https://codecov.io/gh/DataDog/dd-trace-php) [![OpenTracing Badge](https://img.shields.io/badge/OpenTracing-enabled-blue.svg)](http://opentracing.io) [![OpenTelemetry Badge](https://img.shields.io/badge/OpenTelemetry-enabled-blue.svg)](https://opentelemetry.io) [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.0-8892BF.svg)](https://php.net/) diff --git a/appsec/helper-rust/CLAUDE.md b/appsec/helper-rust/CLAUDE.md index d0e2271bf94..edfd7e1696a 100644 --- a/appsec/helper-rust/CLAUDE.md +++ b/appsec/helper-rust/CLAUDE.md @@ -303,8 +303,8 @@ The appsec child pipeline (generated from `generate-appsec.php`) includes these | Job | Description | |-----|-------------| | `helper-rust build and test` | Builds helper-rust and runs `cargo test` + format check | -| `helper-rust code coverage` | Runs unit tests with coverage, uploads to codecov | -| `helper-rust integration coverage` | Runs integration tests with coverage-instrumented binary | +| `helper-rust code coverage` | Runs unit tests with coverage, uploads to Datadog | +| `helper-rust integration coverage` | Runs integration tests with coverage-instrumented binary, uploads to Datadog | | `appsec integration tests (helper-cpp)` | Integration tests disabling Rust helper redirection (PHP 8.3, 8.3-zts) | ### Checking Pipeline Status diff --git a/appsec/tests/integration/build.gradle b/appsec/tests/integration/build.gradle index 6ab174cb46a..ecc4d33c607 100644 --- a/appsec/tests/integration/build.gradle +++ b/appsec/tests/integration/build.gradle @@ -1039,7 +1039,9 @@ buildRunInDockerTask( curl -LsSf "https://github.com/taiki-e/cargo-llvm-cov/releases/download/v0.6.23/cargo-llvm-cov-\${LLVM_COV_ARCH}.tar.gz" | tar xzf - -C /root/.cargo/bin echo '=== Running cargo test with coverage ===' - cargo llvm-cov test --release --lcov --output-path /helper-rust-build/coverage-unit.lcov + cargo llvm-cov test --release --lcov \\ + --ignore-filename-regex='appsec/third_party/' \\ + --output-path /helper-rust-build/coverage-unit.lcov echo '=== Coverage data generated ===' """ @@ -1122,6 +1124,7 @@ buildRunInDockerTask( /helper-rust-build/libddappsec-helper.so \\ -format=lcov \\ -instr-profile=merged.profdata \\ + -ignore-filename-regex='(/root/\\.cargo/|/project/appsec/third_party/|^/rustc/|^/helper-rust-build/)' \\ > /helper-rust-build/coverage-integration.lcov echo 'Coverage report generated' else diff --git a/code-coverage.datadog.yml b/code-coverage.datadog.yml index 20f4001ff36..ee3efa4d6a8 100644 --- a/code-coverage.datadog.yml +++ b/code-coverage.datadog.yml @@ -3,6 +3,11 @@ ignore: - "appsec/build/" - "appsec/tests/" - "appsec/third_party/" +flags: + helper-rust-unit: + carryforward: true + helper-rust-integration: + carryforward: true gates: - type: total_coverage_percentage config: diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index a070a1d987e..00000000000 --- a/codecov.yml +++ /dev/null @@ -1,37 +0,0 @@ -# Validate using: cat codecov.yml | curl --data-binary @- https://codecov.io/validate -codecov: - require_ci_to_pass: false # See coverage on CI test failures - -coverage: - range: 90..100 - round: down - precision: 2 - status: # Blocking coverage targets - project: # Each PR must increase coverage - default: - target: auto - patch: # New code must be at least 90% tested - default: - target: 90% - -flags: - helper-rust-unit: - paths: - - appsec/helper-rust/ - carryforward: true - helper-rust-integration: - paths: - - appsec/helper-rust/ - carryforward: true - -comment: # See https://docs.codecov.com/docs/pull-request-comments - behavior: default - layout: "header,reach,diff,flags,files,footer" - require_changes: true - require_base: false - require_head: false - -ignore: - - appsec/build - - appsec/tests - - appsec/third_party diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt index 4f867ac0467..db324e84c9d 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_01.phpt @@ -79,7 +79,7 @@ array(2) { } } [1]=> - array(10) { + array(11) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -103,5 +103,10 @@ array(2) { ["_dd.origin"]=> string(7) "datadog" } + ["metrics"]=> + array(1) { + ["_dd.apm.enabled"]=> + float(0) + } } } diff --git a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt index 01fb43be7cc..98300bf291d 100644 --- a/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt +++ b/tests/ext/distributed_tracing/distributed_trace_asm_standalone_02.phpt @@ -75,7 +75,7 @@ array(2) { } } [1]=> - array(10) { + array(11) { ["trace_id"]=> string(2) "42" ["span_id"]=> @@ -99,5 +99,10 @@ array(2) { ["_dd.origin"]=> string(7) "datadog" } + ["metrics"]=> + array(1) { + ["_dd.apm.enabled"]=> + float(0) + } } -} \ No newline at end of file +} diff --git a/tracer/serializer.c b/tracer/serializer.c index 6247c333452..e1fc3e71721 100644 --- a/tracer/serializer.c +++ b/tracer/serializer.c @@ -1832,9 +1832,10 @@ ddog_SpanBytes *ddtrace_serialize_span_to_rust_span(ddtrace_span_data *span, ddo } ddog_add_span_metrics_str(rust_span, "_sampling_priority_v1", sampling_priority); } - if(!get_global_DD_APM_TRACING_ENABLED()) { - ddog_add_span_metrics_str(rust_span, "_dd.apm.enabled", 0); - } + } + + if (!get_global_DD_APM_TRACING_ENABLED()) { + ddog_add_span_metrics_str(rust_span, "_dd.apm.enabled", 0); } if (DATADOG_G(sidecar) && get_DD_TRACE_STATS_COMPUTATION_ENABLED() && !is_inferred_span) {