From 54f843fc76ef2d9182c30c53f83a2084061ba4f7 Mon Sep 17 00:00:00 2001 From: Tony Redondo Date: Wed, 25 Mar 2026 19:36:21 +0100 Subject: [PATCH] feat: upgrade the script to installer v12 --- .gitignore | 3 + .gitlab-ci.yml | 212 +++++++++++++++++++++++++++++++++++++++++++++++-- README.md | 19 +++++ script.sh | 11 ++- 4 files changed, 237 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 8addcad..9d3dc4d 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ replay_pid* # Intellij .idea + +# macOS Finder metadata +.DS_Store diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 76e3284..82d1e5d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,13 +5,213 @@ default: stages: - test -test_script: +test_java_script: image: adoptopenjdk/openjdk11:latest stage: test cache: [] script: - - LANGUAGES="java" SERVICE="my-service" API_KEY="dummy" JAVA_INSTRUMENTED_BUILD_SYSTEM="all" source <(cat script.sh) - - export LOG_FILE=java-output.log - - export TRACER_INIT_LOG="CI Visibility settings" - - java -version 2>&1 | tee $LOG_FILE - - 'grep -q "$TRACER_INIT_LOG" $LOG_FILE || { echo "Error: Output does not contain tracer initialisation log: $TRACER_INIT_LOG"; exit 1; }' + - | + bash <<'BASH' + set -euo pipefail + LANGUAGES="java" SERVICE="my-service" API_KEY="dummy" JAVA_INSTRUMENTED_BUILD_SYSTEM="all" source <(cat script.sh) + export LOG_FILE="java-output.log" + export TRACER_INIT_LOG="CI Visibility settings" + java -version 2>&1 | tee "$LOG_FILE" + grep -q "$TRACER_INIT_LOG" "$LOG_FILE" || { echo "Error: Output does not contain tracer initialisation log: $TRACER_INIT_LOG"; exit 1; } + BASH + +.go_smoke_test: + stage: test + cache: [] + before_script: + - | + if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then + apt-get update + apt-get install -y curl + fi + go version + script: + - | + bash <<'BASH' + set -euo pipefail + + fail() { + echo "Error: $1" >&2 + exit 1 + } + + # Create a minimal Go module in the requested directory so the wrapper can + # exercise the live installer against representative repository layouts. + create_go_module() { + local module_dir="$1" + local module_name="$2" + local module_go="$3" + + mkdir -p "$module_dir" + printf 'module %s\n\ngo %s\n' "${module_name}" "${module_go}" > "${module_dir}/go.mod" + printf '%s\n' \ + 'package smoke' \ + '' \ + 'import "testing"' \ + '' \ + 'func TestSmoke(t *testing.T) {}' > "${module_dir}/smoke_test.go" + } + + case "${PROJECT_LAYOUT}" in + root) + create_go_module "." "example.com/test-optimization-gitlab-script-smoke" "${PROJECT_GO}" + ;; + single_nested) + create_go_module "services/payments" "example.com/test-optimization-gitlab-script-smoke/payments" "${PROJECT_GO}" + ;; + multiple_modules) + create_go_module "services/payments" "example.com/test-optimization-gitlab-script-smoke/payments" "${PROJECT_GO}" + create_go_module "services/refunds" "example.com/test-optimization-gitlab-script-smoke/refunds" "${SECOND_PROJECT_GO}" + ;; + *) + fail "Unsupported PROJECT_LAYOUT: ${PROJECT_LAYOUT}" + ;; + esac + + stdout_file="instrumentation.stdout" + stderr_file="instrumentation.stderr" + + set +e + if [ -n "${GO_MODULE_DIR:-}" ]; then + LANGUAGES="go" SERVICE="my-service" API_KEY="dummy" GO_MODULE_DIR="${GO_MODULE_DIR}" source <(cat script.sh) >"${stdout_file}" 2>"${stderr_file}" + else + LANGUAGES="go" SERVICE="my-service" API_KEY="dummy" source <(cat script.sh) >"${stdout_file}" 2>"${stderr_file}" + fi + action_exit=$? + set -e + + cat "${stdout_file}" + if [ -s "${stderr_file}" ]; then + cat "${stderr_file}" >&2 + fi + + if [ "${EXPECT_ACTION_FAILURE}" = "true" ]; then + [ "${action_exit}" -ne 0 ] || fail "Expected the wrapper to fail." + grep -Fq "${EXPECTED_FAILURE_MESSAGE}" "${stderr_file}" || fail "Missing expected failure message: ${EXPECTED_FAILURE_MESSAGE}" + exit 0 + fi + + [ "${action_exit}" -eq 0 ] || fail "Expected the wrapper to succeed." + + if [ -n "${EXPECTED_SKIP_MESSAGE:-}" ]; then + [ -z "${GOFLAGS:-}" ] || fail "GOFLAGS should stay unset when Go instrumentation is skipped." + [ -z "${DD_TRACER_VERSION_GO:-}" ] || fail "DD_TRACER_VERSION_GO should stay unset when Go instrumentation is skipped." + grep -Fq "${EXPECTED_SKIP_MESSAGE}" "${stderr_file}" || fail "Missing expected skip message: ${EXPECTED_SKIP_MESSAGE}" + exit 0 + fi + + [ -n "${GOFLAGS:-}" ] || fail "GOFLAGS was not set." + [ -n "${DD_TRACER_VERSION_GO:-}" ] || fail "DD_TRACER_VERSION_GO was not set." + echo "${GOFLAGS}" | grep -Fq "orchestrion toolexec" || fail "GOFLAGS does not include orchestrion." + [ -f "${TEST_WORKDIR}/orchestrion.tool.go" ] || fail "orchestrion.tool.go was not created in ${TEST_WORKDIR}." + + if [ "${RUN_GO_TESTS}" = "true" ]; then + ( + cd "${TEST_WORKDIR}" + DD_TRACE_DEBUG="true" go test -v ./... + ) + fi + BASH + +test_go_root_go124_success: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: root + PROJECT_GO: "1.24.0" + RUN_GO_TESTS: "true" + TEST_WORKDIR: "." + EXPECT_ACTION_FAILURE: "false" + +test_go_root_go125_success: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: root + PROJECT_GO: "1.25.0" + RUN_GO_TESTS: "true" + TEST_WORKDIR: "." + EXPECT_ACTION_FAILURE: "false" + +test_go_root_go122_skip: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: root + PROJECT_GO: "1.22.0" + RUN_GO_TESTS: "false" + TEST_WORKDIR: "." + EXPECT_ACTION_FAILURE: "false" + EXPECTED_SKIP_MESSAGE: "The project Go version (1.22.0) is lower than the minimum Go version required by dd-trace-go" + +test_go_runner_below_minimum_skip: + extends: .go_smoke_test + image: golang:1.23.12 + variables: + PROJECT_LAYOUT: root + PROJECT_GO: "1.24.0" + RUN_GO_TESTS: "false" + TEST_WORKDIR: "." + EXPECT_ACTION_FAILURE: "false" + EXPECTED_SKIP_MESSAGE: "The installed Go version (1.23.12) is lower than the minimum Go version required by dd-trace-go" + +test_go_single_nested_go124_auto_detect: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: single_nested + PROJECT_GO: "1.24.0" + RUN_GO_TESTS: "true" + TEST_WORKDIR: "services/payments" + EXPECT_ACTION_FAILURE: "false" + +test_go_single_nested_go125_auto_detect: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: single_nested + PROJECT_GO: "1.25.0" + RUN_GO_TESTS: "true" + TEST_WORKDIR: "services/payments" + EXPECT_ACTION_FAILURE: "false" + +test_go_multiple_modules_without_override_skip: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: multiple_modules + PROJECT_GO: "1.24.0" + SECOND_PROJECT_GO: "1.25.0" + RUN_GO_TESTS: "false" + TEST_WORKDIR: "." + EXPECT_ACTION_FAILURE: "false" + EXPECTED_SKIP_MESSAGE: "Set DD_CIVISIBILITY_GO_MODULE_DIR to the Go module root if this repository contains multiple Go modules." + +test_go_multiple_modules_with_override_success: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: multiple_modules + PROJECT_GO: "1.25.0" + SECOND_PROJECT_GO: "1.24.0" + GO_MODULE_DIR: "./services/payments" + RUN_GO_TESTS: "true" + TEST_WORKDIR: "services/payments" + EXPECT_ACTION_FAILURE: "false" + +test_go_missing_override_directory_skip: + extends: .go_smoke_test + image: golang:1.26.1 + variables: + PROJECT_LAYOUT: root + PROJECT_GO: "1.24.0" + GO_MODULE_DIR: "./services/does-not-exist" + RUN_GO_TESTS: "false" + TEST_WORKDIR: "." + EXPECT_ACTION_FAILURE: "false" + EXPECTED_SKIP_MESSAGE: "Error: DD_CIVISIBILITY_GO_MODULE_DIR points to a directory that does not exist: ./services/does-not-exist" diff --git a/README.md b/README.md index d3494c0..a4bcfa6 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ The script takes in the following environment variables: | PYTHON_TRACER_VERSION | The version of Datadog Python tracer to use. Defaults to the latest release. | false | | | RUBY_TRACER_VERSION | The version of datadog-ci gem to use. Defaults to the latest release. | false | | | GO_TRACER_VERSION | The version of Orchestrion automatic compile-time instrumentation of Go code (https://github.com/datadog/orchestrion) to use. Defaults to the latest release. | false | | +| GO_MODULE_DIR | Path to the Go module root directory to instrument. Use this when the repository contains multiple Go modules or the Go module is not in the repository root. | false | | | JAVA_INSTRUMENTED_BUILD_SYSTEM | If provided, only the specified build systems will be instrumented (allowed values are `gradle`,`maven`,`sbt`,`ant`,`all`). `all` is a special value that instruments every Java process. If this property is not provided, all known build systems will be instrumented (Gradle, Maven, SBT, Ant). | false | | ### Additional configuration @@ -63,6 +64,24 @@ test_node: - npm run test ``` +### Go multi-module repositories + +If your repository contains multiple Go modules, or the Go module you want to instrument is not at the repository root, set `GO_MODULE_DIR` to the module root directory that contains the target `go.mod` file: + +```yaml +test_go: + image: golang:1.25.0 + script: + - | + LANGUAGES="go" SITE="datadoghq.com" API_KEY="YOUR_API_KEY_SECRET" GO_MODULE_DIR="./services/payments" \ + SRC=$(curl -fsSL https://github.com/DataDog/test-optimization-gitlab-script/releases/download/v1.2.6/script.sh); \ + echo "$SRC" | sha256sum | grep -q '^5df7aea8a13e259c66109ecf7f88fef8ffe22369abc7425bf435b4bbfefb0376' && \ + source <(echo "$SRC") || \ + echo "ERROR: SHA256 mismatch. Datadog Test Optimization autoinstrumentation not enabled." >&2 + - cd services/payments + - go test ./... +``` + ## Limitations ### Tracing vitest tests diff --git a/script.sh b/script.sh index 078e437..dd1de91 100755 --- a/script.sh +++ b/script.sh @@ -63,6 +63,11 @@ if [ -n "$GO_TRACER_VERSION" ]; then export DD_SET_TRACER_VERSION_GO=${GO_TRACER_VERSION} fi +# $GO_MODULE_DIR or $DD_CIVISIBILITY_GO_MODULE_DIR are optional +if [ -n "$GO_MODULE_DIR" ]; then + export DD_CIVISIBILITY_GO_MODULE_DIR=${GO_MODULE_DIR} +fi + # $JAVA_INSTRUMENTED_BUILD_SYSTEM or $DD_INSTRUMENTATION_BUILD_SYSTEM_JAVA are optional if [ -n "$JAVA_INSTRUMENTED_BUILD_SYSTEM" ]; then export DD_INSTRUMENTATION_BUILD_SYSTEM_JAVA=${JAVA_INSTRUMENTED_BUILD_SYSTEM} @@ -70,8 +75,10 @@ fi export DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER="gitlab" -installation_script_url="https://install.datadoghq.com/scripts/install_test_visibility_v11.sh" -installation_script_checksum="fc64c45fd4b45b4b01773c58a3a116bef212dc4095508a6e27e19e50e901bd55" +# Keep the installer URL and checksum pinned together so the wrapper executes a +# deterministic upstream payload. +installation_script_url="https://install.datadoghq.com/scripts/install_test_visibility_v12.sh" +installation_script_checksum="91b6c7bb2c28ef5604c2a2b233da7d931a9b3b5d20b7872254ebb0e689e62f4a" script_filepath="install_test_visibility.sh" if command -v curl >/dev/null 2>&1; then