# Baron SSO용 Docker Compose 헬퍼 # 환경 변수 로드 ifneq (,$(wildcard ./.env)) include .env export endif # Compose 파일 경로 COMPOSE_INFRA := compose.infra.yaml COMPOSE_ORY := compose.ory.yaml COMPOSE_APP := docker-compose.yaml AUTH_CONFIG_ENV := .generated/auth-config.env COMPOSE_CLI_ENV_ARGS := ifneq (,$(wildcard ./.env)) COMPOSE_CLI_ENV_ARGS += --env-file .env endif COMPOSE_CLI_ENV_ARGS += --env-file $(AUTH_CONFIG_ENV) # --- 인증 설정 빌드/검증 --- build-auth-config: @echo "Building auth config..." @mkdir -p .generated @bash scripts/auth_config.sh build validate-auth-config: build-auth-config @echo "Validating auth config..." @bash scripts/auth_config.sh validate verify-auth-config: validate-auth-config @echo "Verifying auth config wiring..." @bash scripts/auth_config.sh verify # --- 기본 실행 --- # 주의: --remove-orphan 사용 금지 (다른 스택이 orphan으로 판단되어 종료될 수 있음) up-all: validate-auth-config @echo "Starting ALL stacks (infra + ory + app)..." docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_INFRA) -f $(COMPOSE_ORY) -f $(COMPOSE_APP) up -d # --- 개별 스택 실행 --- up-infra: @echo "Starting Infra stack (postgres/clickhouse/redis)..." docker compose -f $(COMPOSE_INFRA) up -d up-ory: validate-auth-config @echo "Starting Ory stack (kratos/hydra/keto/oathkeeper)..." docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_ORY) up -d up-app: validate-auth-config @echo "Starting App stack (backend/userfront/adminfront/devfront)..." docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up -d up-backend: validate-auth-config @echo "Starting Backend only..." docker compose $(COMPOSE_CLI_ENV_ARGS) -f $(COMPOSE_APP) up -d backend up-dev: up-infra up-ory @echo "Dev stack is up (infra + ory)." up-front-dev: up-infra up-ory up-backend @echo "Dev stack is up (infra + ory + backend)." # --- 종료 (Down) --- down-all: @echo "Stopping ALL stacks (infra + ory + app)..." docker compose -f $(COMPOSE_INFRA) -f $(COMPOSE_ORY) -f $(COMPOSE_APP) down down-app: @echo "Stopping App stack..." docker compose -f $(COMPOSE_APP) down down-backend: @echo "Stopping Backend only..." docker compose -f $(COMPOSE_APP) stop backend down-infra: @echo "Stopping Infra stack..." docker compose -f $(COMPOSE_INFRA) down down-ory: @echo "Stopping Ory stack..." docker compose -f $(COMPOSE_ORY) down # --- 유틸리티 --- # 인프라 상태 확인 check-infra: @echo "Checking infra status..." @if [ "$$(docker inspect -f '{{.State.Health.Status}}' baron_postgres 2>/dev/null)" != "healthy" ]; then \ echo "Error: PostgreSQL is not running or not healthy."; \ echo "Please run 'make up-infra' first."; \ exit 1; \ else \ echo "PostgreSQL is healthy."; \ fi ps: docker compose -f $(COMPOSE_INFRA) -f $(COMPOSE_ORY) -f $(COMPOSE_APP) ps logs-infra: docker compose -f $(COMPOSE_INFRA) logs -f logs-ory: docker compose -f $(COMPOSE_ORY) logs -f logs-app: docker compose -f $(COMPOSE_APP) logs -f # --- 로컬 통합 코드 체크 --- ifeq ($(CI),) PLAYWRIGHT_INSTALL_ALL := npx playwright install PLAYWRIGHT_INSTALL_CHROMIUM := npx playwright install chromium else PLAYWRIGHT_INSTALL_ALL := npx playwright install --with-deps PLAYWRIGHT_INSTALL_CHROMIUM := npx playwright install --with-deps chromium endif .PHONY: code-check code-check-lint code-check-test-jobs code-check-i18n code-check-go-lint code-check-sync-userfront-locales code-check-userfront-install code-check-userfront-lint code-check-front-lint code-check-backend-tests code-check-userfront-tests code-check-adminfront-tests code-check-devfront-tests code-check-userfront-e2e-tests CODE_CHECK_TEST_JOBS ?= 1 PLAYWRIGHT_WORKERS ?= 1 FLUTTER_TEST_CONCURRENCY ?= 1 code-check: code-check-lint code-check-test-jobs @echo "code-check complete." code-check-lint: code-check-i18n code-check-front-lint code-check-go-lint code-check-sync-userfront-locales code-check-userfront-install code-check-userfront-lint code-check-test-jobs: @echo "==> run CI-equivalent test jobs (parallel)" @$(MAKE) --no-print-directory -j$(CODE_CHECK_TEST_JOBS) --output-sync=target \ code-check-backend-tests \ code-check-userfront-tests \ code-check-userfront-e2e-tests \ code-check-adminfront-tests \ code-check-devfront-tests code-check-i18n: @echo "==> i18n resource check" @mkdir -p reports node tools/i18n-scanner/index.js node tools/i18n-scanner/report.js @cat reports/i18n-report.txt code-check-go-lint: @echo "==> go lint/format check" @if command -v golangci-lint >/dev/null 2>&1; then \ cd backend && golangci-lint fmt -E gofmt -E gofumpt -d; \ elif command -v docker >/dev/null 2>&1; then \ docker run --rm \ -v "$$(pwd)/backend:/app" \ -w /app \ golangci/golangci-lint:v2.10.1 \ golangci-lint fmt -E gofmt -E gofumpt -d; \ else \ echo "ERROR: golangci-lint not found and docker is unavailable."; \ echo "Install golangci-lint v2.10.1 or Docker to match CI lint step."; \ exit 1; \ fi code-check-sync-userfront-locales: @echo "==> sync userfront locales" /bin/sh ./scripts/sync_userfront_locales.sh code-check-userfront-install: @echo "==> install userfront dependencies" cd userfront && flutter pub get code-check-userfront-lint: @echo "==> userfront format/analyze" cd userfront && dart format --output=none --set-exit-if-changed lib test cd userfront && flutter analyze --no-fatal-warnings --no-fatal-infos code-check-front-lint: @echo "==> adminfront biome lint/format check" rm -rf adminfront/playwright-report adminfront/test-results cd adminfront && npm ci cd adminfront && npx biome check . --formatter-enabled=false --organize-imports-enabled=false cd adminfront && npx biome check . --linter-enabled=false --organize-imports-enabled=false @echo "==> devfront biome lint/format check" rm -rf devfront/playwright-report devfront/test-results cd devfront && npm ci cd devfront && npx biome check . --formatter-enabled=false --organize-imports-enabled=false cd devfront && npx biome check . --linter-enabled=false --organize-imports-enabled=false code-check-backend-tests: @echo "==> backend tests" cd backend && go test -v ./... code-check-userfront-tests: @echo "==> userfront tests (isolated workspace)" @tmp_dir="$$(mktemp -d /tmp/baron-sso-userfront-tests.XXXXXX)"; \ trap 'rm -rf "$$tmp_dir"' EXIT INT TERM; \ mkdir -p "$$tmp_dir/scripts"; \ cp scripts/sync_userfront_locales.sh "$$tmp_dir/scripts/"; \ cp -R locales "$$tmp_dir/locales"; \ if command -v rsync >/dev/null 2>&1; then \ rsync -a --delete \ --exclude '.dart_tool' \ --exclude 'build' \ --exclude '.pub-cache' \ --exclude '.flutter-plugins' \ --exclude '.flutter-plugins-dependencies' \ userfront/ "$$tmp_dir/userfront/"; \ else \ cp -R userfront "$$tmp_dir/userfront"; \ rm -rf "$$tmp_dir/userfront/.dart_tool" "$$tmp_dir/userfront/build"; \ fi; \ cd "$$tmp_dir" && /bin/sh ./scripts/sync_userfront_locales.sh; \ cd "$$tmp_dir/userfront" && flutter test --concurrency=$(FLUTTER_TEST_CONCURRENCY) code-check-adminfront-tests: @echo "==> adminfront tests" PLAYWRIGHT_WORKERS=$(PLAYWRIGHT_WORKERS) ./scripts/run_adminfront_ci_tests.sh adminfront-tests code-check-devfront-tests: @echo "==> devfront tests" @mkdir -p reports/devfront @rm -rf reports/devfront/playwright-report reports/devfront/test-results @status=0; \ (cd devfront && npm ci) || status=$$?; \ if [ $$status -eq 0 ]; then \ (cd devfront && $(PLAYWRIGHT_INSTALL_ALL)) || status=$$?; \ fi; \ if [ $$status -eq 0 ]; then \ (cd devfront && PLAYWRIGHT_WORKERS=$(PLAYWRIGHT_WORKERS) npm test) || status=$$?; \ fi; \ [ -d devfront/playwright-report ] && cp -R devfront/playwright-report reports/devfront/ || true; \ [ -d devfront/test-results ] && cp -R devfront/test-results reports/devfront/ || true; \ exit $$status code-check-userfront-e2e-tests: @echo "==> userfront wasm playwright e2e tests (isolated workspace)" @mkdir -p reports/userfront-e2e @rm -rf reports/userfront-e2e/playwright-report reports/userfront-e2e/test-results @tmp_dir="$$(mktemp -d /tmp/baron-sso-userfront-e2e-tests.XXXXXX)"; \ trap 'rm -rf "$$tmp_dir"' EXIT INT TERM; \ mkdir -p "$$tmp_dir/scripts"; \ cp scripts/sync_userfront_locales.sh "$$tmp_dir/scripts/"; \ cp -R locales "$$tmp_dir/locales"; \ if command -v rsync >/dev/null 2>&1; then \ rsync -a --delete \ --exclude '.dart_tool' \ --exclude 'build' \ --exclude '.pub-cache' \ --exclude '.flutter-plugins' \ --exclude '.flutter-plugins-dependencies' \ userfront/ "$$tmp_dir/userfront/"; \ rsync -a --delete \ --exclude 'node_modules' \ --exclude 'playwright-report' \ --exclude 'test-results' \ userfront-e2e/ "$$tmp_dir/userfront-e2e/"; \ else \ cp -R userfront "$$tmp_dir/userfront"; \ rm -rf "$$tmp_dir/userfront/.dart_tool" "$$tmp_dir/userfront/build"; \ cp -R userfront-e2e "$$tmp_dir/userfront-e2e"; \ rm -rf "$$tmp_dir/userfront-e2e/node_modules" "$$tmp_dir/userfront-e2e/playwright-report" "$$tmp_dir/userfront-e2e/test-results"; \ fi; \ status=0; \ (cd "$$tmp_dir" && /bin/sh ./scripts/sync_userfront_locales.sh) || status=$$?; \ if [ $$status -eq 0 ]; then \ (cd "$$tmp_dir/userfront-e2e" && npm ci) || status=$$?; \ fi; \ if [ $$status -eq 0 ]; then \ (cd "$$tmp_dir/userfront" && flutter build web --wasm --release) || status=$$?; \ fi; \ if [ $$status -eq 0 ]; then \ (cd "$$tmp_dir/userfront-e2e" && $(PLAYWRIGHT_INSTALL_CHROMIUM)) || status=$$?; \ fi; \ if [ $$status -eq 0 ]; then \ port="$$(node -e "const net=require('node:net'); const s=net.createServer(); s.listen(0,'127.0.0.1',()=>{console.log(s.address().port); s.close();});")"; \ echo "==> userfront-e2e using PORT=$$port"; \ (cd "$$tmp_dir/userfront-e2e" && PORT=$$port PLAYWRIGHT_WORKERS=$(PLAYWRIGHT_WORKERS) npm test) || status=$$?; \ fi; \ [ -d "$$tmp_dir/userfront-e2e/playwright-report" ] && cp -R "$$tmp_dir/userfront-e2e/playwright-report" reports/userfront-e2e/ || true; \ [ -d "$$tmp_dir/userfront-e2e/test-results" ] && cp -R "$$tmp_dir/userfront-e2e/test-results" reports/userfront-e2e/ || true; \ exit $$status