-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMakefile
More file actions
192 lines (151 loc) · 8.82 KB
/
Copy pathMakefile
File metadata and controls
192 lines (151 loc) · 8.82 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
SHELL := /bin/bash
ROOT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
API_DIR := $(ROOT_DIR)/api
API_VENV := $(API_DIR)/venv
API_BIN := $(API_VENV)/bin
BROWSER_SERVICE_DIR := $(ROOT_DIR)/browser_service
BROWSER_SERVICE_VENV := $(BROWSER_SERVICE_DIR)/venv
BROWSER_SERVICE_BIN := $(BROWSER_SERVICE_VENV)/bin
UI_DIR := $(ROOT_DIR)/ui
DOCKER_DIR := $(ROOT_DIR)/docker
PYTHON_TARGETS := app migrations
.DEFAULT_GOAL := help
.PHONY: \
help \
install install-api install-browser-service install-ui \
config-init-prod config-init-dev \
dev dev-api dev-ui infra-up infra-down migrate migration \
lint lint-api lint-browser-service lint-ui format format-api format-ui typecheck typecheck-api typecheck-browser-service typecheck-ui \
test test-api test-browser-service test-docker-config test-e2e test-ui-unit test-ui-e2e test-ui-e2e-smoke test-ui-e2e-full test-ui-e2e-performance \
build
help: ## Show available targets.
@awk 'BEGIN { FS = ":.*##"; printf "Usage: make <target>\n\nTargets:\n" } /^[a-zA-Z0-9_.-]+:.*##/ { printf " %-18s %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
install: install-api install-browser-service install-ui ## Install all local development dependencies.
install-api: ## Create the API virtualenv and install its Python and runtime dependencies.
@test -x "$(API_BIN)/python" || python3 -m venv "$(API_VENV)"
"$(API_BIN)/pip" install -r "$(API_DIR)/requirements.txt" -r "$(API_DIR)/requirements-dev.txt"
cd "$(API_DIR)/app/gemini_cli_runtime" && npm install --omit=dev --ignore-scripts
cd "$(API_DIR)/app/openai_codex_runtime" && npm install --omit=dev --ignore-scripts
install-browser-service: ## Install browser-service Python checks in its own virtualenv (runtime browser bytes stay in Docker).
@test -x "$(BROWSER_SERVICE_BIN)/python" || python3 -m venv "$(BROWSER_SERVICE_VENV)"
"$(BROWSER_SERVICE_BIN)/pip" install -r "$(BROWSER_SERVICE_DIR)/requirements.txt" -r "$(BROWSER_SERVICE_DIR)/requirements-dev.txt"
install-ui: ## Install UI dependencies with pnpm.
cd "$(UI_DIR)" && pnpm install
config-init-prod: ## Initialize production config overrides and secrets without overwriting existing files.
@if [ -L "$(DOCKER_DIR)/config/overrides/production.yaml" ]; then \
echo "Exists as a symlink, not followed: docker/config/overrides/production.yaml"; \
elif [ -e "$(DOCKER_DIR)/config/overrides/production.yaml" ]; then \
echo "Exists, not overwritten: docker/config/overrides/production.yaml"; \
elif (set -C; cat "$(DOCKER_DIR)/config/overrides/production.example.yaml" > "$(DOCKER_DIR)/config/overrides/production.yaml"); then \
echo "Created: docker/config/overrides/production.yaml"; \
else \
echo "Failed to create without overwriting: docker/config/overrides/production.yaml" >&2; \
exit 1; \
fi
@if [ -L "$(DOCKER_DIR)/config/secrets/production.env" ]; then \
echo "Refusing to follow secrets symlink: docker/config/secrets/production.env" >&2; \
exit 1; \
elif [ -e "$(DOCKER_DIR)/config/secrets/production.env" ]; then \
echo "Exists, not overwritten: docker/config/secrets/production.env"; \
elif (set -C; cat "$(DOCKER_DIR)/config/secrets/production.example.env" > "$(DOCKER_DIR)/config/secrets/production.env"); then \
echo "Created: docker/config/secrets/production.env"; \
else \
echo "Failed to create without overwriting: docker/config/secrets/production.env" >&2; \
exit 1; \
fi; \
chmod 600 "$(DOCKER_DIR)/config/secrets/production.env"
config-init-dev: ## Initialize local development config overrides and secrets without overwriting existing files.
@if [ -L "$(DOCKER_DIR)/config/overrides/local.yaml" ]; then \
echo "Exists as a symlink, not followed: docker/config/overrides/local.yaml"; \
elif [ -e "$(DOCKER_DIR)/config/overrides/local.yaml" ]; then \
echo "Exists, not overwritten: docker/config/overrides/local.yaml"; \
elif (set -C; cat "$(DOCKER_DIR)/config/overrides/local.example.yaml" > "$(DOCKER_DIR)/config/overrides/local.yaml"); then \
echo "Created: docker/config/overrides/local.yaml"; \
else \
echo "Failed to create without overwriting: docker/config/overrides/local.yaml" >&2; \
exit 1; \
fi
@if [ -L "$(DOCKER_DIR)/config/secrets/local.env" ]; then \
echo "Refusing to follow secrets symlink: docker/config/secrets/local.env" >&2; \
exit 1; \
elif [ -e "$(DOCKER_DIR)/config/secrets/local.env" ]; then \
echo "Exists, not overwritten: docker/config/secrets/local.env"; \
elif (set -C; cat "$(DOCKER_DIR)/config/secrets/local.example.env" > "$(DOCKER_DIR)/config/secrets/local.env"); then \
echo "Created: docker/config/secrets/local.env"; \
else \
echo "Failed to create without overwriting: docker/config/secrets/local.env" >&2; \
exit 1; \
fi; \
chmod 600 "$(DOCKER_DIR)/config/secrets/local.env"
dev: infra-up migrate ## Start local infrastructure, migrate, then run the API and UI together.
@api_pid=; ui_pid=; \
cleanup() { \
trap - INT TERM EXIT; \
kill "$$api_pid" "$$ui_pid" 2>/dev/null || true; \
wait "$$api_pid" "$$ui_pid" 2>/dev/null || true; \
}; \
trap 'cleanup; exit 130' INT TERM; \
trap cleanup EXIT; \
(cd "$(API_DIR)" && ./run-dev.sh) & api_pid=$$!; \
(cd "$(UI_DIR)" && pnpm dev) & ui_pid=$$!; \
wait -n "$$api_pid" "$$ui_pid"; status=$$?; \
exit "$$status"
dev-api: ## Run the API development server.
cd "$(API_DIR)" && ./run-dev.sh
dev-ui: ## Run the UI development server.
cd "$(UI_DIR)" && pnpm dev
infra-up: ## Start local Docker development dependencies in the background.
cd "$(DOCKER_DIR)" && ./run.sh dev -d --sandbox-manager
infra-down: ## Stop local Docker development dependencies.
cd "$(DOCKER_DIR)" && ./run.sh dev down
migrate: ## Apply API database migrations.
cd "$(API_DIR)" && ./run-dev.sh upgrade
ifeq ($(filter migration,$(MAKECMDGOALS)),migration)
ifeq ($(strip $(MESSAGE)),)
$(error MESSAGE is required. Usage: make migration MESSAGE="migration message")
endif
endif
migration: ## Create an API database migration revision.
cd "$(API_DIR)" && "$(API_BIN)/alembic" revision -m "$(MESSAGE)"
lint: lint-api lint-browser-service lint-ui ## Run all lint checks.
lint-api: ## Run the existing API lint and type checks.
cd "$(API_DIR)" && ./run-linter.sh
lint-browser-service: ## Run browser-service formatting and lint checks.
"$(BROWSER_SERVICE_BIN)/python" -m black --config "$(BROWSER_SERVICE_DIR)/pyproject.toml" --check "$(BROWSER_SERVICE_DIR)/app" "$(BROWSER_SERVICE_DIR)/tests"
"$(BROWSER_SERVICE_BIN)/python" -m isort --settings-path "$(BROWSER_SERVICE_DIR)/pyproject.toml" --check-only "$(BROWSER_SERVICE_DIR)/app" "$(BROWSER_SERVICE_DIR)/tests"
"$(BROWSER_SERVICE_BIN)/python" -m flake8 --max-line-length=100 "$(BROWSER_SERVICE_DIR)/app" "$(BROWSER_SERVICE_DIR)/tests"
lint-ui: ## Run UI lint checks.
cd "$(UI_DIR)" && pnpm lint
format: format-api format-ui ## Format API and UI source files.
format-api: ## Format API app and migrations with Black and isort.
cd "$(API_DIR)" && "$(API_BIN)/black" $(PYTHON_TARGETS) && "$(API_BIN)/isort" $(PYTHON_TARGETS)
format-ui: ## Format UI files with the installed Prettier.
cd "$(UI_DIR)" && pnpm exec prettier --write .
typecheck: typecheck-api typecheck-browser-service typecheck-ui ## Run all type checks.
typecheck-api: ## Run API mypy checks.
cd "$(API_DIR)" && "$(API_BIN)/mypy" $(PYTHON_TARGETS)
typecheck-browser-service: ## Run browser-service mypy checks.
"$(BROWSER_SERVICE_BIN)/python" -m mypy --config-file "$(BROWSER_SERVICE_DIR)/pyproject.toml" "$(BROWSER_SERVICE_DIR)/app"
typecheck-ui: ## Run UI type checks.
cd "$(UI_DIR)" && pnpm typecheck
test: ## Run the repository test protocol.
"$(ROOT_DIR)/scripts/run-tests.sh"
test-api: ## Run the API pytest suite.
cd "$(API_DIR)" && "$(API_BIN)/python" -m pytest tests
test-browser-service: ## Run the browser-service pytest suite.
cd "$(ROOT_DIR)" && "$(BROWSER_SERVICE_BIN)/python" -m pytest browser_service/tests
test-docker-config: ## Run isolated layered deployment configuration tests.
cd "$(ROOT_DIR)" && ./docker/tests/test_config.sh
test-e2e: ## Run the repository test protocol including Playwright correctness tests.
"$(ROOT_DIR)/scripts/run-tests.sh" --e2e
test-ui-unit: ## Run frontend unit/component tests; pass optional Vitest CLI arguments with ARGS.
cd "$(UI_DIR)" && pnpm test:unit $(ARGS)
test-ui-e2e: test-ui-e2e-full ## Run the full frontend Playwright correctness suite (compatibility target).
test-ui-e2e-smoke: ## Run the frontend Playwright correctness smoke suite; pass optional CLI arguments with ARGS.
cd "$(UI_DIR)" && pnpm test:e2e:smoke $(ARGS)
test-ui-e2e-full: ## Run the full frontend Playwright correctness suite; pass optional CLI arguments with ARGS.
cd "$(UI_DIR)" && pnpm test:e2e:full $(ARGS)
test-ui-e2e-performance: ## Run serial frontend Playwright performance budgets; pass optional CLI arguments with ARGS.
cd "$(UI_DIR)" && pnpm exec playwright test --grep @performance $(ARGS) --workers=1
build: ## Build and start local Docker images in the background.
cd "$(DOCKER_DIR)" && ./run.sh build -d