Skip to content

Commit bb8d3eb

Browse files
merge from main
2 parents 56c396c + 0dd6fae commit bb8d3eb

22 files changed

Lines changed: 564 additions & 105 deletions

.devcontainer/devcontainer.mk

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# DO NOT EDIT. Synced from DataDog/dd-repo-tools by the
2+
# dd-repo-tools devcontainer-bundle campaigner — edits here will be
3+
# overwritten on the next run.
4+
# Source of truth: https://github.com/DataDog/dd-repo-tools/blob/main/shared/devcontainer/devcontainer.mk
5+
#
6+
# Inputs (set before `include`):
7+
# DEV_CONTAINER_REPO_ROOT Absolute path to the repo root.
8+
# DEV_CONTAINER_IMAGE_NAME Override image name. Defaults to
9+
# registry.ddbuild.io/ci/<repo>/devcontainer.
10+
# DEV_CONTAINER_REQUIRED_PATHS Whitespace-separated paths that must exist
11+
# (e.g. submodule checkouts). Checked at
12+
# recipe time as a prereq of devcontainer-
13+
# touching targets — missing paths fail
14+
# that invocation, not parse time.
15+
# DOCKER_BUILDX_FLAGS Extra flags appended to the local build.
16+
#
17+
# This file is the single source of truth for staging + hashing. The
18+
# GitLab template (devcontainer.yml) calls into `make` so both paths
19+
# share the same code.
20+
21+
# Recipes need bash + pipefail: the hash pipeline (find | sort | sha256sum |
22+
# cut) silently produces an empty tag on any pipe failure under POSIX sh,
23+
# which downstream becomes a malformed `image:` ref. Override after the
24+
# include if you need a different shell for your own recipes.
25+
SHELL := bash
26+
.SHELLFLAGS := -eu -o pipefail -c
27+
28+
DEV_CONTAINER_REPO_ROOT ?= $(CURDIR)
29+
_DEV_CONTAINER_REPO_NAME := $(notdir $(patsubst %/,%,$(DEV_CONTAINER_REPO_ROOT)))
30+
DEV_CONTAINER_IMAGE_NAME ?= registry.ddbuild.io/ci/$(_DEV_CONTAINER_REPO_NAME)/devcontainer
31+
32+
_DEV_CONTAINER_CONTEXT_FILES := $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/context.files
33+
_DEV_CONTAINER_CONTEXT_FILTER := $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/context.filter
34+
_DEV_CONTAINER_DOCKERFILE := $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/Dockerfile
35+
_DEV_CONTAINER_STAGED := $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/.staged
36+
37+
# uname -m -> docker --platform / conventional ARCH build-arg.
38+
_DEV_CONTAINER_UNAME_M := $(shell uname -m)
39+
ifneq ($(filter $(_DEV_CONTAINER_UNAME_M),arm64 aarch64),)
40+
_DEV_CONTAINER_PLATFORM := linux/arm64
41+
_DEV_CONTAINER_ARCH := aarch64
42+
else
43+
_DEV_CONTAINER_PLATFORM := linux/amd64
44+
_DEV_CONTAINER_ARCH := x86_64
45+
endif
46+
47+
# Pass --build-arg ARCH only if the Dockerfile actually declares it.
48+
_DEV_CONTAINER_ARCH_ARG := $(shell grep -q '^ARG ARCH' $(_DEV_CONTAINER_DOCKERFILE) 2>/dev/null && echo --build-arg ARCH=$(_DEV_CONTAINER_ARCH))
49+
50+
# Skip everything inside the container (no nested docker, no pull).
51+
_DEV_CONTAINER_INSIDE := $(shell [ -f /.dockerenv ] || [ -n "$$KUBERNETES_SERVICE_HOST" ] && echo 1)
52+
53+
# Stage .devcontainer/context.files (+ optional context.filter) into $$ctx.
54+
# Caller sets $$ctx (and arranges cleanup if needed). Verifies Dockerfile
55+
# was staged.
56+
define _dev_container_stage_into_ctx
57+
if [ ! -f "$(_DEV_CONTAINER_CONTEXT_FILES)" ]; then \
58+
echo "ERROR: $(_DEV_CONTAINER_CONTEXT_FILES) not found" >&2; exit 1; \
59+
fi; \
60+
filter_arg=; \
61+
[ -f "$(_DEV_CONTAINER_CONTEXT_FILTER)" ] && filter_arg="--filter=merge $(_DEV_CONTAINER_CONTEXT_FILTER)"; \
62+
grep -Ev '^[[:space:]]*(#|$$)' "$(_DEV_CONTAINER_CONTEXT_FILES)" | \
63+
rsync -aR --files-from=- $$filter_arg "$(DEV_CONTAINER_REPO_ROOT)/" "$$ctx/"; \
64+
if [ ! -f "$$ctx/.devcontainer/Dockerfile" ]; then \
65+
echo "ERROR: .devcontainer/Dockerfile not staged; check .devcontainer/context.files" >&2; \
66+
exit 1; \
67+
fi
68+
endef
69+
70+
# Stage into a fresh mktemp dir, cleaned up on shell exit. Sets $$ctx.
71+
define _dev_container_stage_context
72+
ctx=$$(mktemp -d); \
73+
trap 'rm -rf "$$ctx"' EXIT; \
74+
$(_dev_container_stage_into_ctx)
75+
endef
76+
77+
# Compute the 12-char tag hash from the staged tree at $$ctx.
78+
define _dev_container_compute_tag
79+
tag=$$(cd "$$ctx" && find . -type f | LC_ALL=C sort | \
80+
while IFS= read -r f; do printf -- '--- %s ---\n' "$$f"; cat "$$f"; done | \
81+
sha256sum | cut -c1-12); \
82+
[ -n "$$tag" ] || { echo "ERROR: hash pipeline produced empty tag (empty staged context?)" >&2; exit 1; }
83+
endef
84+
85+
# Git-worktree support: when .git is a gitdir pointer, make the common dir
86+
# visible inside the container so `git` calls work.
87+
_DEV_CONTAINER_GIT_COMMON_DIR := $(shell cd $(DEV_CONTAINER_REPO_ROOT) && git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)
88+
_DEV_CONTAINER_DEFAULT_GIT_DIR := $(DEV_CONTAINER_REPO_ROOT)/.git
89+
ifneq ($(_DEV_CONTAINER_GIT_COMMON_DIR),)
90+
ifneq ($(_DEV_CONTAINER_GIT_COMMON_DIR),$(_DEV_CONTAINER_DEFAULT_GIT_DIR))
91+
_DEV_CONTAINER_WORKTREE_MOUNT := -v $(_DEV_CONTAINER_GIT_COMMON_DIR):$(_DEV_CONTAINER_GIT_COMMON_DIR)
92+
endif
93+
endif
94+
95+
# Precondition check for caller-declared required paths. Wired as a
96+
# phony prereq below so it fires only when a devcontainer-touching
97+
# target is actually built — not at parse time, which would block
98+
# unrelated `make` invocations (lint, format) and CI-entrypoint
99+
# targets whose own recipe initializes the submodules before
100+
# sub-making dev-image.
101+
.PHONY: _dev-container-check-required-paths
102+
_dev-container-check-required-paths:
103+
@missing="$(strip $(foreach p,$(DEV_CONTAINER_REQUIRED_PATHS),$(if $(wildcard $(DEV_CONTAINER_REPO_ROOT)/$(p)),,$(p))))"; \
104+
if [ -n "$$missing" ]; then \
105+
echo "Missing required paths (did you init submodules?): $$missing" >&2; \
106+
exit 1; \
107+
fi
108+
109+
.PHONY: dev-image dev-image-x86_64 dev-shell dev-image-tag \
110+
.devcontainer-stage-context .devcontainer-image-hash
111+
112+
dev-image dev-image-x86_64 dev-shell dev-image-tag \
113+
.devcontainer-stage-context .devcontainer-image-hash: _dev-container-check-required-paths
114+
115+
# Stage the build context into a stable path under .devcontainer/.staged/.
116+
# Invoked from VS Code's initializeCommand (so build.context = `.staged`
117+
# gets the same narrow tree CI and `make dev-image` use) and from
118+
# devcontainer.yml's CI job. Hash-computing local targets keep using a
119+
# mktemp dir for parallel safety; this one writes to a stable path
120+
# because VS Code (and CI's downstream buildx step) need one.
121+
.devcontainer-stage-context:
122+
@rm -rf "$(_DEV_CONTAINER_STAGED)"
123+
@mkdir -p "$(_DEV_CONTAINER_STAGED)"
124+
@ctx="$(_DEV_CONTAINER_STAGED)"; $(_dev_container_stage_into_ctx)
125+
126+
# Print the 12-char hash of the already-staged .devcontainer/.staged/ tree.
127+
# Caller must have run `make .devcontainer-stage-context` first. Used by
128+
# devcontainer.yml so the tag is computed by the same code that the local
129+
# Makefile uses.
130+
.devcontainer-image-hash:
131+
@ctx="$(_DEV_CONTAINER_STAGED)"; \
132+
test -d "$$ctx" || { echo "ERROR: $$ctx not staged; run 'make .devcontainer-stage-context' first" >&2; exit 1; }; \
133+
$(_dev_container_compute_tag); \
134+
echo "$$tag"
135+
136+
# Print the full image:tag that would be used. Useful for debugging.
137+
# Works inside or outside a container (no docker required).
138+
dev-image-tag:
139+
@$(_dev_container_stage_context); \
140+
$(_dev_container_compute_tag); \
141+
echo "$(DEV_CONTAINER_IMAGE_NAME):$$tag"
142+
143+
# Shared mounts for any in-container invocation: the repo root, plus the
144+
# git common dir when running inside a worktree (so `git` works).
145+
_DEV_CONTAINER_MOUNTS := \
146+
-v $(DEV_CONTAINER_REPO_ROOT):$(DEV_CONTAINER_REPO_ROOT) \
147+
$(_DEV_CONTAINER_WORKTREE_MOUNT) \
148+
-w $(DEV_CONTAINER_REPO_ROOT)
149+
150+
# Public: prefix for running a scripted command in the devcontainer image.
151+
# Includes the resolved image ref and `-i` (so stdin pipes work) but no
152+
# `-t` (so it works under `make` / CI without a TTY). Usage:
153+
# foo: dev-image
154+
# $(IN_DEVCONTAINER) cmd args
155+
# When `make` is invoked from inside a container, IN_DEVCONTAINER is empty,
156+
# so the command runs in-place — same recipe works inside or outside.
157+
IN_DEVCONTAINER ?= docker run --rm -i $(_DEV_CONTAINER_MOUNTS) \
158+
$$(cat $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/.image-ref)
159+
160+
# linux/amd64 variant: same shape as IN_DEVCONTAINER but pinned to amd64,
161+
# for running cross-compiled x86_64 binaries (e.g. Windows test exes under
162+
# wine64) on any host. On Apple Silicon, Docker emulates via Rosetta. On
163+
# native amd64 the platform pin is a no-op and we reuse the regular image.
164+
_DEV_CONTAINER_X86_64_IMAGE_REF_FILE := $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/.image-ref-x86_64
165+
IN_DEVCONTAINER_X86_64 ?= docker run --rm -i --platform=linux/amd64 $(_DEV_CONTAINER_MOUNTS) \
166+
$$(cat $(_DEV_CONTAINER_X86_64_IMAGE_REF_FILE))
167+
168+
ifeq ($(_DEV_CONTAINER_INSIDE),1)
169+
IN_DEVCONTAINER :=
170+
IN_DEVCONTAINER_X86_64 :=
171+
endif
172+
173+
# Targets whose behaviour differs inside vs outside a container.
174+
# Inside: dev-image is a no-op (already running on it); dev-shell fails
175+
# loudly because there's no docker daemon.
176+
ifeq ($(_DEV_CONTAINER_INSIDE),1)
177+
178+
dev-image dev-image-x86_64:
179+
@:
180+
181+
dev-shell:
182+
@echo "make dev-shell: already inside the devcontainer; run /bin/sh directly" >&2; exit 1
183+
184+
else # _DEV_CONTAINER_INSIDE
185+
186+
# Pull the image if available; otherwise build locally from the staged context.
187+
dev-image:
188+
@$(_dev_container_stage_context); \
189+
$(_dev_container_compute_tag); \
190+
ref="$(DEV_CONTAINER_IMAGE_NAME):$$tag"; \
191+
if docker pull "$$ref" >/dev/null 2>&1; then \
192+
echo "Pulled $$ref"; \
193+
else \
194+
echo "Pull miss; building $$ref locally"; \
195+
docker buildx build \
196+
--platform $(_DEV_CONTAINER_PLATFORM) \
197+
--file "$$ctx/.devcontainer/Dockerfile" \
198+
--build-context repo="$$ctx" \
199+
$(_DEV_CONTAINER_ARCH_ARG) \
200+
$(DOCKER_BUILDX_FLAGS) \
201+
--load -t "$$ref" \
202+
"$$ctx"; \
203+
fi; \
204+
echo "$$ref" > $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/.image-ref
205+
206+
# Build the linux/amd64 variant. On amd64 hosts this reuses dev-image; on
207+
# arm64 hosts it produces a separate `:<tag>-x86_64` image so it doesn't
208+
# clobber the native one — built locally only (CI doesn't publish the
209+
# `-x86_64` ref), so no docker pull attempt. Buildx caches per-platform
210+
# so repeats are cheap.
211+
ifeq ($(_DEV_CONTAINER_PLATFORM),linux/amd64)
212+
dev-image-x86_64: dev-image
213+
@cp $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/.image-ref $(_DEV_CONTAINER_X86_64_IMAGE_REF_FILE)
214+
else
215+
dev-image-x86_64:
216+
@$(_dev_container_stage_context); \
217+
$(_dev_container_compute_tag); \
218+
ref="$(DEV_CONTAINER_IMAGE_NAME):$$tag-x86_64"; \
219+
docker buildx build --platform=linux/amd64 \
220+
--file "$$ctx/.devcontainer/Dockerfile" \
221+
--build-context repo="$$ctx" \
222+
--build-arg ARCH=x86_64 \
223+
$(DOCKER_BUILDX_FLAGS) \
224+
--load -t "$$ref" \
225+
"$$ctx"; \
226+
echo "$$ref" > $(_DEV_CONTAINER_X86_64_IMAGE_REF_FILE)
227+
endif
228+
229+
dev-shell: dev-image
230+
@ref=$$(cat $(DEV_CONTAINER_REPO_ROOT)/.devcontainer/.image-ref); \
231+
docker run --rm -it $(_DEV_CONTAINER_MOUNTS) "$$ref" /bin/sh
232+
233+
endif # _DEV_CONTAINER_INSIDE

.dockerignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.git/
2+
build/
3+
build-rum/
4+
!build-rum/_deps/injectbrowsersdk-src/
5+
httpd/
6+
test/integration-test/.venv/
7+
test/integration-test/.pytest_cache/
8+
test/integration-test/__pycache__/

.github/workflows/dev.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ jobs:
2323
image: datadog/docker-library:httpd-datadog-ci-bf4e353dec1442b7864fddc3c2618b8541eed4c04fe2ab88f2a4c2ebea61df91
2424
steps:
2525
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
26-
with:
27-
submodules: true
2826
- name: Add cloned repo as safe
2927
run: sh -c "git config --global --add safe.directory $PWD"
28+
- name: Init required submodules
29+
run: git submodule update --init --depth=1 deps/dd-trace-cpp deps/nginx-datadog
3030
- name: Configure
3131
run: cmake --preset=ci-dev -B build .
3232
- name: Build
@@ -71,9 +71,8 @@ jobs:
7171
llvm-profdata merge -sparse /tmp/*.profraw -o /tmp/default.profdata
7272
llvm-cov export dist/lib/mod_datadog.so -format=lcov -instr-profile=/tmp/default.profdata -ignore-filename-regex=/httpd/ > coverage.lcov
7373
- name: Upload code coverage report to Datadog
74-
# The commit hash comes from the release of the action: https://github.com/DataDog/coverage-upload-github-action/releases
74+
# See https://github.com/DataDog/coverage-upload-github-action/releases
7575
uses: DataDog/coverage-upload-github-action@2ba057033351887422f8eb0203d1990c3acbc8c5 # v1.0.4
7676
with:
77-
api_key: ${{ secrets.DD_API_KEY_CI_APP }}
7877
files: coverage.lcov
7978
format: lcov

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ jobs:
99
image: datadog/docker-library:httpd-datadog-ci-bf4e353dec1442b7864fddc3c2618b8541eed4c04fe2ab88f2a4c2ebea61df91
1010
steps:
1111
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
12-
with:
13-
submodules: true
1412
- name: Add cloned repo as safe
1513
run: sh -c "git config --global --add safe.directory $PWD"
14+
- name: Init required submodules
15+
run: git submodule update --init --depth=1 deps/dd-trace-cpp deps/nginx-datadog
1616
- name: Configure
1717
run: cmake --preset ci-release -B build .
1818
- name: Build

.github/workflows/system-tests.yml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ on:
55
push:
66
branches: [main]
77
workflow_dispatch:
8-
# schedule:
9-
# - cron: 0 4 * * *
8+
schedule:
9+
- cron: 0 4 * * *
1010

1111
concurrency:
1212
# this ensures that only one workflow runs at a time for a given branch on pull requests
@@ -23,10 +23,10 @@ jobs:
2323
image: datadog/docker-library:httpd-datadog-ci-bf4e353dec1442b7864fddc3c2618b8541eed4c04fe2ab88f2a4c2ebea61df91
2424
steps:
2525
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
26-
with:
27-
submodules: true
2826
- name: Add cloned repo as safe
2927
run: sh -c "git config --global --add safe.directory $PWD"
28+
- name: Init required submodules
29+
run: git submodule update --init --depth=1 deps/dd-trace-cpp deps/nginx-datadog
3030
- name: Configure
3131
run: cmake --preset=ci-dev -B build .
3232
- name: Build
@@ -43,20 +43,16 @@ jobs:
4343
main:
4444
needs:
4545
- build-artifacts
46-
uses: DataDog/system-tests/.github/workflows/system-tests.yml@1e5d6b7096279ca43ce4826fda3cc805635b63c1
47-
secrets:
48-
TEST_OPTIMIZATION_API_KEY: ${{ secrets.DD_API_KEY_CI_APP }}
49-
DD_API_KEY: ${{ secrets.DD_API_KEY_CI_APP }}
46+
uses: DataDog/system-tests/.github/workflows/system-tests.yml@main
5047
permissions:
5148
contents: read
5249
id-token: write
5350
with:
5451
library: cpp_httpd
55-
ref: 1e5d6b7096279ca43ce4826fda3cc805635b63c1
5652
binaries_artifact: system_tests_binaries
5753
desired_execution_time: 300 # 5 minutes
5854
scenarios_groups: tracer-release
5955
excluded_scenarios: APM_TRACING_E2E_OTEL,APM_TRACING_E2E_SINGLE_SPAN # require AWS and datadog credentials
6056
parametric_job_count: 8
61-
skip_empty_scenarios: true
57+
skip_empty_scenarios: false
6258
push_to_test_optimization: ${{ github.actor != 'dependabot[bot]' }}

0 commit comments

Comments
 (0)