-
Notifications
You must be signed in to change notification settings - Fork 393
Expand file tree
/
Copy pathMakefile
More file actions
323 lines (278 loc) · 11.6 KB
/
Makefile
File metadata and controls
323 lines (278 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
LATEST_VERSION := $$(sed -n 's/.*"version": "\([^"]*\)".*/\1/p' package.json)
BUILD_PLATFORMS = linux/arm64,linux/amd64
include .env
# ---------------------------------------------------------------------------
# Multi-agent / worktree isolation
# ---------------------------------------------------------------------------
# Compute a deterministic port offset (0-99) from the working directory name
# so that multiple worktrees can run integration tests in parallel without
# port conflicts. Override HDX_CI_SLOT manually if you need a specific slot.
#
# Port mapping (base + slot):
# ClickHouse HTTP : 18123 + slot
# MongoDB : 39999 + slot
# API test server : 19000 + slot
# OpAMP : 14320 + slot
# ---------------------------------------------------------------------------
HDX_CI_SLOT ?= $(shell printf '%s' "$(notdir $(CURDIR))" | cksum | awk '{print $$1 % 100}')
HDX_CI_PROJECT := int-$(HDX_CI_SLOT)
HDX_CI_CH_PORT := $(shell echo $$((18123 + $(HDX_CI_SLOT))))
HDX_CI_MONGO_PORT:= $(shell echo $$((39999 + $(HDX_CI_SLOT))))
HDX_CI_API_PORT := $(shell echo $$((19000 + $(HDX_CI_SLOT))))
HDX_CI_OPAMP_PORT:= $(shell echo $$((14320 + $(HDX_CI_SLOT))))
export HDX_CI_CH_PORT HDX_CI_MONGO_PORT HDX_CI_API_PORT HDX_CI_OPAMP_PORT
# Log directory for dev-portal visibility (integration tests)
HDX_CI_LOGS_DIR := $(HOME)/.config/hyperdx/dev-slots/$(HDX_CI_SLOT)/logs-int
HDX_CI_HISTORY_DIR := $(HOME)/.config/hyperdx/dev-slots/$(HDX_CI_SLOT)/history
# Archive integration logs to history (call at end of each test target)
# Usage: $(call archive-int-logs)
define archive-int-logs
if [ -d "$(HDX_CI_LOGS_DIR)" ] && [ -n "$$(ls -A $(HDX_CI_LOGS_DIR) 2>/dev/null)" ]; then \
_ts=$$(date -u +%Y-%m-%dT%H:%M:%SZ); \
_hist="$(HDX_CI_HISTORY_DIR)/int-$$_ts"; \
mkdir -p "$$_hist"; \
mv $(HDX_CI_LOGS_DIR)/* "$$_hist/" 2>/dev/null; \
_wt=$$(basename "$$(git rev-parse --show-toplevel 2>/dev/null || pwd)"); \
_br=$$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown"); \
printf '{"worktree":"%s","branch":"%s","worktreePath":"%s"}\n' "$$_wt" "$$_br" "$(CURDIR)" > "$$_hist/meta.json"; \
fi; \
rm -rf $(HDX_CI_LOGS_DIR) 2>/dev/null
endef
.PHONY: all
all: install-tools
.PHONY: install-tools
install-tools:
yarn setup
@echo "All tools installed"
# ---------------------------------------------------------------------------
# Dev environment with worktree isolation
# ---------------------------------------------------------------------------
# Ports are allocated in the 30100-31199 range (base + slot) to avoid
# conflicts with CI (14320-40098) and E2E (20320-21399) ports.
#
# Port mapping (base + slot):
# API server : 30100 + slot
# App (Next.js) : 30200 + slot
# OpAMP : 30300 + slot
# MongoDB : 30400 + slot
# ClickHouse HTTP : 30500 + slot
# ClickHouse Native : 30600 + slot
# OTel health : 30700 + slot
# OTel gRPC : 30800 + slot
# OTel HTTP : 30900 + slot
# OTel metrics : 31000 + slot
# OTel JSON HTTP : 31100 + slot
# ---------------------------------------------------------------------------
.PHONY: dev
dev:
yarn dev
.PHONY: dev-build
dev-build:
bash -c '. ./scripts/dev-env.sh && docker compose -p "$$HDX_DEV_PROJECT" -f docker-compose.dev.yml build'
.PHONY: dev-up
dev-up:
yarn dev
.PHONY: dev-down
dev-down:
yarn dev:down
.PHONY: dev-portal
dev-portal:
node scripts/dev-portal/server.js
.PHONY: dev-portal-stop
dev-portal-stop:
@pid=$$(lsof -ti :$${HDX_PORTAL_PORT:-9900} 2>/dev/null); \
if [ -n "$$pid" ]; then \
echo "Stopping dev portal (PID $$pid)"; \
kill $$pid 2>/dev/null || true; \
else \
echo "Dev portal is not running"; \
fi
.PHONY: dev-lint
dev-lint:
npx nx run-many -t lint:fix
.PHONY: ci-build
ci-build:
npx nx run-many -t ci:build
.PHONY: ci-lint
ci-lint:
npx nx run-many -t ci:lint
.PHONY: dev-int-down
dev-int-down:
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml down
@for port in $(HDX_CI_API_PORT) $(HDX_CI_OPAMP_PORT); do \
pids=$$(lsof -ti :$$port 2>/dev/null); \
for pid in $$pids; do \
echo "Killing process $$pid on port $$port"; \
kill $$pid 2>/dev/null || true; \
done; \
done
@$(call archive-int-logs); true
.PHONY: dev-e2e-down
dev-e2e-down:
$(eval HDX_E2E_SLOT := $(shell printf '%s' "$(notdir $(CURDIR))" | cksum | awk '{print $$1 % 100}'))
docker compose -p e2e-$(HDX_E2E_SLOT) -f packages/app/tests/e2e/docker-compose.yml down -v
@for port in $$((21000 + $(HDX_E2E_SLOT))) $$((20320 + $(HDX_E2E_SLOT))) $$((21300 + $(HDX_E2E_SLOT))) $$((21200 + $(HDX_E2E_SLOT))); do \
pids=$$(lsof -ti :$$port 2>/dev/null); \
for pid in $$pids; do \
echo "Killing process $$pid on port $$port"; \
kill $$pid 2>/dev/null || true; \
done; \
done
.PHONY: dev-clean
dev-clean: dev-down dev-int-down dev-e2e-down dev-portal-stop
@rm -rf $(HOME)/.config/hyperdx/dev-slots
@echo "All dev services cleaned up"
.PHONY: dev-int-build
dev-int-build:
npx nx run-many -t ci:build
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml build
.PHONY: dev-int
dev-int:
@echo "Using CI slot $(HDX_CI_SLOT) (project=$(HDX_CI_PROJECT) ch=$(HDX_CI_CH_PORT) mongo=$(HDX_CI_MONGO_PORT) api=$(HDX_CI_API_PORT))"
@mkdir -p $(HDX_CI_LOGS_DIR)
@bash scripts/ensure-dev-portal.sh
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml up -d
bash -c 'set -o pipefail; npx nx run @hyperdx/api:dev:int $(FILE) 2>&1 | tee $(HDX_CI_LOGS_DIR)/api-int.log'; ret=$$?; \
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml down; \
$(call archive-int-logs); \
exit $$ret
.PHONY: dev-int-common-utils
dev-int-common-utils:
@echo "Using CI slot $(HDX_CI_SLOT) (project=$(HDX_CI_PROJECT) ch=$(HDX_CI_CH_PORT) mongo=$(HDX_CI_MONGO_PORT))"
@mkdir -p $(HDX_CI_LOGS_DIR)
@bash scripts/ensure-dev-portal.sh
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml up -d
bash -c 'set -o pipefail; npx nx run @hyperdx/common-utils:dev:int $(FILE) 2>&1 | tee $(HDX_CI_LOGS_DIR)/common-utils-int.log'; ret=$$?; \
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml down; \
$(call archive-int-logs); \
exit $$ret
.PHONY: ci-int
ci-int:
@mkdir -p $(HDX_CI_LOGS_DIR)
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml up -d --quiet-pull
bash -c 'set -o pipefail; npx nx run-many -t ci:int --parallel=false 2>&1 | tee $(HDX_CI_LOGS_DIR)/ci-int.log'; ret=$$?; \
docker compose -p $(HDX_CI_PROJECT) -f ./docker-compose.ci.yml down; \
$(call archive-int-logs); \
exit $$ret
.PHONY: dev-unit
dev-unit:
npx nx run-many -t dev:unit
.PHONY: ci-unit
ci-unit:
npx nx run-many -t ci:unit
.PHONY: ci-triage
ci-triage:
node --test .github/scripts/__tests__/pr-triage-classify.test.js
# ---------------------------------------------------------------------------
# E2E tests — port isolation is handled by scripts/test-e2e.sh
# ---------------------------------------------------------------------------
# Slot for the Playwright report server (only used by the Makefile REPORT flag)
HDX_E2E_SLOT ?= $(shell printf '%s' "$(notdir $(CURDIR))" | cksum | awk '{print $$1 % 100}')
.PHONY: e2e
e2e:
./scripts/test-e2e.sh
# Remove E2E test artifacts (results, reports, auth state)
.PHONY: dev-e2e-clean
dev-e2e-clean:
rm -rf packages/app/test-results packages/app/playwright-report packages/app/blob-report packages/app/tests/e2e/.auth
# Run a specific E2E test file or grep pattern (dev mode: hot reload)
# Usage:
# make dev-e2e FILE=navigation # Match files containing "navigation"
# make dev-e2e FILE=navigation GREP="help menu" # Also filter by test name
# make dev-e2e GREP="should navigate" # Filter by test name across all files
# make dev-e2e FILE=navigation REPORT=1 # Open HTML report after tests finish
.PHONY: dev-e2e
dev-e2e:
./scripts/test-e2e.sh --dev $(if $(FILE),$(FILE)) $(if $(GREP),--grep "$(GREP)") $(ARGS); \
ret=$$?; \
$(if $(REPORT),cd packages/app && npx playwright show-report --port $$((9323 + $(HDX_E2E_SLOT)));) \
exit $$ret
# TODO: check db connections before running the migration CLIs
.PHONY: dev-migrate-db
dev-migrate-db:
@echo "Migrating Mongo db...\n"
npx nx run @hyperdx/api:dev:migrate-db
@echo "Migrating ClickHouse db...\n"
npx nx run @hyperdx/api:dev:migrate-ch
.PHONY: version
version:
sh ./version.sh
# Build targets (local builds only)
.PHONY: build-otel-collector
build-otel-collector:
docker build . -f docker/otel-collector/Dockerfile \
-t ${OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB}:${IMAGE_VERSION}${IMAGE_VERSION_SUB_TAG} \
-t ${NEXT_OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB}:${IMAGE_VERSION}${IMAGE_VERSION_SUB_TAG} \
--target prod
.PHONY: build-local
build-local:
docker build . -f ./docker/hyperdx/Dockerfile \
--build-context clickhouse=./docker/clickhouse \
--build-context otel-collector=./docker/otel-collector \
--build-context hyperdx=./docker/hyperdx \
--build-context api=./packages/api \
--build-context app=./packages/app \
--build-arg CODE_VERSION=${CODE_VERSION} \
-t ${LOCAL_IMAGE_NAME_DOCKERHUB}:${IMAGE_VERSION}${IMAGE_VERSION_SUB_TAG} \
-t ${NEXT_LOCAL_IMAGE_NAME_DOCKERHUB}:${IMAGE_VERSION}${IMAGE_VERSION_SUB_TAG} \
--target all-in-one-noauth
.PHONY: build-all-in-one
build-all-in-one:
docker build . -f ./docker/hyperdx/Dockerfile \
--build-context clickhouse=./docker/clickhouse \
--build-context otel-collector=./docker/otel-collector \
--build-context hyperdx=./docker/hyperdx \
--build-context api=./packages/api \
--build-context app=./packages/app \
--build-arg CODE_VERSION=${CODE_VERSION} \
-t ${ALL_IN_ONE_IMAGE_NAME_DOCKERHUB}:${IMAGE_VERSION}${IMAGE_VERSION_SUB_TAG} \
-t ${NEXT_ALL_IN_ONE_IMAGE_NAME_DOCKERHUB}:${IMAGE_VERSION}${IMAGE_VERSION_SUB_TAG} \
--target all-in-one-auth
.PHONY: build-app
build-app:
docker build . -f ./docker/hyperdx/Dockerfile \
--build-context hyperdx=./docker/hyperdx \
--build-context api=./packages/api \
--build-context app=./packages/app \
--build-arg CODE_VERSION=${CODE_VERSION} \
-t ${IMAGE_NAME_DOCKERHUB}:${IMAGE_VERSION}${IMAGE_VERSION_SUB_TAG} \
--target prod
.PHONY: build-otel-collector-nightly
build-otel-collector-nightly:
docker build . -f docker/otel-collector/Dockerfile \
-t ${OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB}:${IMAGE_NIGHTLY_TAG} \
-t ${NEXT_OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB}:${IMAGE_NIGHTLY_TAG} \
--target prod
.PHONY: build-app-nightly
build-app-nightly:
docker build . -f ./docker/hyperdx/Dockerfile \
--build-context hyperdx=./docker/hyperdx \
--build-context api=./packages/api \
--build-context app=./packages/app \
--build-arg CODE_VERSION=${CODE_VERSION} \
-t ${IMAGE_NAME_DOCKERHUB}:${IMAGE_NIGHTLY_TAG} \
--target prod
.PHONY: build-local-nightly
build-local-nightly:
docker build . -f ./docker/hyperdx/Dockerfile \
--build-context clickhouse=./docker/clickhouse \
--build-context otel-collector=./docker/otel-collector \
--build-context hyperdx=./docker/hyperdx \
--build-context api=./packages/api \
--build-context app=./packages/app \
--build-arg CODE_VERSION=${CODE_VERSION} \
-t ${LOCAL_IMAGE_NAME_DOCKERHUB}:${IMAGE_NIGHTLY_TAG} \
-t ${NEXT_LOCAL_IMAGE_NAME_DOCKERHUB}:${IMAGE_NIGHTLY_TAG} \
--target all-in-one-noauth
.PHONY: build-all-in-one-nightly
build-all-in-one-nightly:
docker build . -f ./docker/hyperdx/Dockerfile \
--build-context clickhouse=./docker/clickhouse \
--build-context otel-collector=./docker/otel-collector \
--build-context hyperdx=./docker/hyperdx \
--build-context api=./packages/api \
--build-context app=./packages/app \
--build-arg CODE_VERSION=${CODE_VERSION} \
-t ${ALL_IN_ONE_IMAGE_NAME_DOCKERHUB}:${IMAGE_NIGHTLY_TAG} \
-t ${NEXT_ALL_IN_ONE_IMAGE_NAME_DOCKERHUB}:${IMAGE_NIGHTLY_TAG} \
--target all-in-one-auth