-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathMakefile
More file actions
340 lines (279 loc) · 16.1 KB
/
Makefile
File metadata and controls
340 lines (279 loc) · 16.1 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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# Netresearch TimeTracker — Makefile helpers
# Default profile for development
COMPOSE_PROFILES ?= dev
export COMPOSE_PROFILES
.PHONY: help up down restart build bake bake-dev bake-tools bake-e2e bake-all logs sh install composer-install composer-update npm-install npm-build npm-dev npm-watch test test-unit test-integration test-controller test-api-contract test-api-functional test-api test-quick test-parallel test-parallel-safe test-parallel-all e2e e2e-up e2e-down e2e-run e2e-install coverage stan phpat cs-check cs-fix check-all fix-all db-migrate cache-clear swagger twig-lint prepare-test-sql reset-test-db tools-up tools-down validate-stack analyze-coverage rector rector-fix audit
help:
@echo "Netresearch TimeTracker — common commands"
@echo ""
@echo "Environment profiles:"
@echo " COMPOSE_PROFILES=dev # development (default)"
@echo " COMPOSE_PROFILES=tools # lightweight tools only (no DB)"
@echo " COMPOSE_PROFILES=prod # production"
@echo " COMPOSE_PROFILES=test # testing"
@echo ""
@echo "Commands:"
@echo " make up # start stack"
@echo " make down # stop stack"
@echo " make tools-up # start lightweight tools only (no DB)"
@echo " make tools-down # stop tools containers"
@echo " make restart # restart stack"
@echo " make bake # build production image"
@echo " make bake-dev # build development image"
@echo " make bake-tools # build tools image"
@echo " make bake-all # build all images"
@echo " make build # alias for bake-dev"
@echo " make logs # follow logs"
@echo " make sh # shell into app container"
@echo " make install # composer install + npm install"
@echo " make test # run tests fast without Xdebug (quiet output)"
@echo " make test-verbose # run tests with verbose output for debugging"
@echo " make test-debug # run tests with Xdebug for step debugging"
@echo " make test-parallel # run unit tests in parallel (full CPU)"
@echo " make test-parallel-safe # run unit tests in parallel (4 cores)"
@echo " make test-parallel-all # run all tests optimally (parallel + sequential)"
@echo " make e2e # run Playwright e2e tests (starts own stack)"
@echo " make e2e-up # start E2E test stack on port 8766"
@echo " make e2e-down # stop E2E test stack"
@echo " make e2e-run # run e2e tests (assumes stack running)"
@echo " make e2e-install # install Playwright browsers"
@echo " make coverage # run tests with coverage"
@echo " make reset-test-db # reset test database (for schema changes)"
@echo " make stan|phpat # static analysis & architecture (fast - no DB)"
@echo " make cs-check|cs-fix # coding standards (fast - no DB)"
@echo " make check-all # stan + phpat + cs-check + twig (fast - no DB)"
@echo " make twig-lint # lint twig templates (fast - no DB)"
@echo " make rector # rector dry-run for code improvements (fast - no DB)"
@echo " make rector-fix # rector apply fixes (fast - no DB)"
@echo " make audit # composer audit for security vulnerabilities"
@echo " make fix-all # cs-fix + rector (modern stack, fast - no DB)"
@echo " make validate-stack # validate entire modern toolchain"
@echo " make analyze-coverage # analyze test coverage report"
up: bake-dev
docker compose up -d
down:
docker compose down
tools-up: bake-tools
@echo "Starting lightweight development tools (no databases)..."
COMPOSE_PROFILES=tools docker compose up -d
tools-down:
@echo "Stopping tools containers..."
COMPOSE_PROFILES=tools docker compose down
restart: down up
# Docker Bake targets (recommended for image builds)
# docker-bake.hcl is the single source of truth for builds; compose.yml handles runtime only
bake:
@echo "Building production image with docker bake..."
docker bake app
bake-dev:
@echo "Building development image with docker bake..."
docker bake app-dev
bake-tools:
@echo "Building tools image with docker bake..."
docker bake app-tools
bake-e2e:
@echo "Building E2E test image with docker bake..."
docker bake app-e2e
bake-all:
@echo "Building all images with docker bake..."
docker bake all
# Alias for backward compatibility
build: bake-dev
logs:
docker compose logs -f | cat
sh:
docker compose exec app-dev bash
install: composer-install npm-install
composer-install:
# --ignore-platform-req=php needed until laminas-ldap adds PHP 8.5 support
# See: https://github.com/laminas/laminas-ldap/issues/62
docker compose run --rm app-dev composer install --ignore-platform-req=php
composer-update:
docker compose run --rm app-dev composer update
npm-install:
docker compose run --rm app-dev npm install --legacy-peer-deps
npm-build:
docker compose run --rm app-dev npm run build
npm-dev:
docker compose run --rm app-dev npm run dev
npm-watch:
docker compose run --rm app-dev npm run watch
# All PHPUnit tests (default for developers)
test: prepare-test-sql
@echo "Running all PHPUnit tests..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=2G -d max_execution_time=0 ./bin/phpunit
# Unit tests only (fast, no database required)
test-unit:
@echo "Running unit tests (no database)..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off app-dev php -d memory_limit=512M ./bin/phpunit --testsuite=unit
# Integration tests only (requires database)
test-integration: prepare-test-sql
@echo "Running integration tests..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=512M ./bin/phpunit --testsuite=integration
# Controller tests only (requires database)
test-controller: prepare-test-sql
@echo "Running controller tests..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=512M ./bin/phpunit --testsuite=controller
# API Contract tests (fast, validates response formats, for pre-commit)
test-api-contract: prepare-test-sql
@echo "Running API contract tests..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=512M ./bin/phpunit --testsuite=api-contract
# API Functional tests (CRUD operations with real database, for CI)
test-api-functional: prepare-test-sql
@echo "Running API functional tests..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=512M ./bin/phpunit --testsuite=api-functional
# All API tests (contract + functional)
test-api: test-api-contract test-api-functional
@echo "All API tests completed"
# Quick tests for pre-commit (unit + api-contract, fast)
test-quick: test-unit test-api-contract
@echo "Quick pre-commit tests completed"
# All tests: PHPUnit + E2E
test-all: test e2e
@echo "All tests completed (PHPUnit + E2E)"
# Test with Xdebug enabled for debugging failing tests
test-debug: prepare-test-sql
@echo "Running tests with Xdebug enabled for debugging..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=debug,develop -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=2G -d max_execution_time=0 ./bin/phpunit
# Test with verbose configuration (full output for debugging)
test-verbose: prepare-test-sql
@echo "Running tests with verbose output for debugging..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=2G -d max_execution_time=0 ./bin/phpunit --configuration=config/testing/phpunit.xml.verbose
# Parallel test execution - Full CPU utilization
test-parallel: prepare-test-sql
@echo "Running parallel tests with $$(nproc) processes..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e PARATEST_PARALLEL=1 -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev ./bin/paratest --configuration=config/testing/paratest.xml --processes=$$(nproc) --testsuite=unit-parallel --max-batch-size=50
# Safe parallel execution - Limited to 4 processes
test-parallel-safe: prepare-test-sql
@echo "Running parallel tests with 4 processes (safe mode)..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e PARATEST_PARALLEL=1 -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev ./bin/paratest --configuration=config/testing/paratest.xml --processes=4 --testsuite=unit-parallel --max-batch-size=25
# Optimal test execution - Parallel for units, sequential for controllers
test-parallel-all: prepare-test-sql
@echo "Running optimized test suite (parallel units + sequential controllers)..."
@echo "Phase 1: Parallel unit tests..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e PARATEST_PARALLEL=1 -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev ./bin/paratest --configuration=config/testing/paratest.xml --processes=$$(nproc) --testsuite=unit-parallel --max-batch-size=50
@echo "Phase 2: Sequential controller tests..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e PHP_MEMORY_LIMIT=2G -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=2G -d max_execution_time=0 ./bin/phpunit --testsuite=controller-sequential
# E2E test infrastructure
e2e-up: bake-e2e
@echo "Starting E2E test stack (app-e2e, httpd-e2e, db, ldap-dev)..."
@if [ ! -f .env.test.local ]; then \
echo "Creating .env.test.local from template..."; \
cp .env.test.local.example .env.test.local 2>/dev/null || echo "# E2E test config - auto-generated\nDATABASE_URL=\"mysql://timetracker:timetracker@db:3306/timetracker?serverVersion=8&charset=utf8mb4\"\nLDAP_HOST=\"ldap-dev\"\nLDAP_PORT=389\nLDAP_READUSER=\"cn=readuser,dc=dev,dc=local\"\nLDAP_READPASS=\"readuser\"\nLDAP_BASEDN=\"dc=dev,dc=local\"\nLDAP_USERNAMEFIELD=\"uid\"\nLDAP_USESSL=false\nLDAP_CREATE_USER=true" > .env.test.local; \
fi
COMPOSE_PROFILES=e2e docker compose up -d
@echo "Waiting for E2E stack to be ready..."
@for i in $$(seq 1 30); do \
if curl -s -o /dev/null -w '%{http_code}' http://localhost:8766/login | grep -q '200'; then \
echo "E2E stack is ready at http://localhost:8766"; \
break; \
fi; \
echo "Waiting for E2E stack... ($$i/30)"; \
sleep 2; \
done
e2e-down:
@echo "Stopping E2E test stack..."
COMPOSE_PROFILES=e2e docker compose down
# E2E tests with Playwright (starts its own stack)
e2e: e2e-up
@echo "Running Playwright e2e tests against E2E stack..."
E2E_BASE_URL=http://localhost:8766 npm run e2e || (make e2e-down && exit 1)
@echo "E2E tests completed. Stopping E2E stack..."
$(MAKE) e2e-down
# Run E2E tests without managing stack (for manual testing)
e2e-run:
@echo "Running Playwright e2e tests (assuming stack is already running)..."
E2E_BASE_URL=http://localhost:8766 npm run e2e
# Install Playwright browsers
e2e-install:
@echo "Installing Playwright browsers..."
npx playwright install chromium
# Coverage with parallel execution (using PCOV for speed)
coverage: prepare-test-sql
@echo "Running parallel test coverage with PCOV..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e PARATEST_PARALLEL=1 -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev ./bin/paratest --configuration=config/testing/paratest.xml --processes=$$(nproc) --testsuite=unit-parallel --coverage-html var/coverage-parallel
@echo "Coverage HTML: var/coverage-parallel/index.html"
# Traditional coverage (sequential, using PCOV)
coverage-sequential: prepare-test-sql
@echo "Running sequential test coverage with PCOV..."
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=off -e PHP_MEMORY_LIMIT=2G -e DATABASE_URL="mysql://unittest:unittest@db_unittest:3306/unittest?serverVersion=mariadb-12.1.2&charset=utf8mb4" app-dev php -d memory_limit=2G -d max_execution_time=0 ./bin/phpunit --coverage-html var/coverage
@echo "Coverage HTML: var/coverage/index.html"
stan:
@echo "Running PHPStan static analysis (lightweight - no DB)..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools composer analyze
phpat:
@echo "Running PHPat architecture analysis (lightweight - no DB)..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools composer analyze:arch
cs-check:
@echo "Running PHP-CS-Fixer code style check..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools composer cs-check
cs-fix:
@echo "Running PHP-CS-Fixer code style fix..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools composer cs-fix
check-all:
@echo "Running complete validation suite (lightweight - no DB)..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools composer check:all
twig-lint:
@echo "Running Twig template linting (lightweight - no DB)..."
COMPOSE_PROFILES=tools docker compose run --rm -e XDEBUG_MODE=off app-tools composer twig:lint
rector:
@echo "Running Rector (dry-run) to check for improvements..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools php -d memory_limit=1G bin/rector process src --config=config/quality/rector.php --dry-run
rector-fix:
@echo "Running Rector to apply fixes..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools php -d memory_limit=1G bin/rector process src --config=config/quality/rector.php
audit:
@echo "Running Composer audit for security vulnerabilities..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools composer audit --format=plain
fix-all:
@echo "Running modern code fixing suite (lightweight - no DB)..."
COMPOSE_PROFILES=tools docker compose run --rm app-tools composer fix:all
db-migrate:
docker compose run --rm app-dev bin/console doctrine:migrations:migrate -n
cache-clear:
docker compose run --rm app-dev bin/console cache:clear
swagger:
@echo "Open Swagger UI at http://localhost:8765/docs/swagger/index.html"
prepare-test-sql:
@echo "Generating unittest SQL file from sql/full.sql"
sed '1s/^/USE unittest;\n/' sql/full.sql > sql/unittest/001_testtables.sql
reset-test-db: prepare-test-sql
@echo "Resetting test database (for schema changes)"
docker compose down db_unittest
docker volume rm timetracker_db-unittest-data || true
@echo "Starting fresh test database..."
docker compose up -d db_unittest
@echo "Waiting for database to be ready..."
@for i in $$(seq 1 30); do \
if docker compose exec -T db_unittest mariadb -h 127.0.0.1 -uunittest -punittest -e "SELECT 1" >/dev/null 2>&1; then \
echo "Database is ready!"; \
break; \
fi; \
echo "Waiting for database... ($$i/30)"; \
sleep 2; \
done
# Validation target (replacing validate-modern-stack.sh)
validate-stack:
@echo "🔍 Validating modern toolchain..."
@echo "──────────────────────────────────"
@echo "▶ Checking composer configuration..."
@docker compose run --rm app composer validate --no-check-publish
@echo "✅ Composer configuration valid"
@echo ""
@echo "▶ Running PHPStan analysis..."
@$(MAKE) stan
@echo "✅ PHPStan analysis passed"
@echo ""
@echo "▶ Running PHP-CS-Fixer code style check..."
@$(MAKE) cs-check
@echo "✅ Code style check passed"
@echo ""
@echo "▶ Running architectural tests..."
@$(MAKE) phpat
@echo "✅ Architecture tests passed"
@echo ""
@echo "🎉 All validation checks passed!"
# Coverage analysis target (replacing analyze-coverage.php location)
analyze-coverage:
@echo "📊 Analyzing test coverage..."
@docker compose run --rm -e APP_ENV=test app php tests/tools/analyze-coverage.php