.PHONY: help dev dev-persistent test lint clean docker-build docker-run k8s-status k8s-logs k8s-restart k8s-sync-content # Default target all: help help: @echo "========================================================================" @echo " pengzhan.dev — Engineering Makefile" @echo "========================================================================" @echo "Available commands:" @echo " make dev Start local server in Ephemeral Staging Mode" @echo " (Safe by default: site.db is NEVER mutated)" @echo " make dev-persistent Start local server in Persistent DB Mode" @echo " (Changes to comments & logs write to site.db)" @echo " make test Run complete automated test suite" @echo " make lint Run comprehensive project linter (JS, EJS, CSS)" @echo " make clean Remove temporary staging DBs and build caches" @echo " make docker-build Build multi-stage production Docker image" @echo " make docker-run Run production Docker container on port 3000" @echo " make k8s-status Show pods, service, ingress, and PVC in k8s" @echo " make k8s-logs Stream live logs from production pod" @echo " make k8s-restart Trigger zero-downtime rolling restart" @echo " make k8s-sync-content Sync local markdown/media into live cluster PVC" @echo "========================================================================" dev: @echo "Starting dev server in Safe Ephemeral Staging Mode..." @echo "-> Production sample-content/data/site.db is protected from writes." APP_ENV=staging node --watch --watch-path=server --watch-path=views --watch-path=public server/index.js dev-persistent: @echo "Starting dev server in Persistent DB Mode..." @echo "-> Writes will be recorded to sample-content/data/site.db." node --watch --watch-path=server --watch-path=views --watch-path=public server/index.js test: @echo "Running automated test suite..." NODE_ENV=test node test/test.js lint: @echo "Running project linter..." node scripts/lint.js clean: @echo "Cleaning temporary test and staging artifacts..." @rm -f /tmp/site.staging-*.db /tmp/site.staging-*.db-* @rm -f sample-content/data/*.db-journal sample-content/data/*.db-wal sample-content/data/*.db-shm @echo "Clean complete." docker-build: @echo "Building Docker image pengzhan.dev:latest..." docker build -t pengzhan.dev:latest . docker-run: @echo "Running Docker container on http://localhost:3000..." docker run --rm -p 3000:3000 -v $(PWD)/sample-content:/app/content pengzhan.dev:latest k8s-status: @echo "Checking Kubernetes status in namespace pengzhan-dev..." kubectl get pods,svc,ingress,pvc -n pengzhan-dev -o wide k8s-logs: @echo "Streaming logs from pengzhan-web deployment..." kubectl logs -f deployment/pengzhan-web -n pengzhan-dev k8s-restart: @echo "Triggering zero-downtime rolling restart of pengzhan-web..." kubectl rollout restart deployment/pengzhan-web -n pengzhan-dev kubectl rollout status deployment/pengzhan-web -n pengzhan-dev k8s-sync-content: @echo "Syncing local sample-content/ to Kubernetes /app/content/..." @POD=$$(kubectl get pod -n pengzhan-dev -l app=pengzhan-web -o jsonpath='{.items[0].metadata.name}'); \ if [ -z "$$POD" ]; then \ echo "Error: No running pengzhan-web pod found."; exit 1; \ fi; \ echo "-> Target pod: $$POD"; \ kubectl cp sample-content/. pengzhan-dev/$$POD:/app/content/; \ kubectl exec -n pengzhan-dev $$POD -- chmod -R 775 /app/content; \ echo "-> Sync complete. Hot-reload watcher will index new content."