-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathMakefile
More file actions
294 lines (252 loc) · 12.9 KB
/
Makefile
File metadata and controls
294 lines (252 loc) · 12.9 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
.PHONY: help start stop dev dev-docker dev-local backend migrate validate test fmt lint build build-frontend docker down clean logs health install helm-deps helm-lint helm-template helm-test load-test chaos-db chaos-redis ha-up ha-down k8s-test-up k8s-test k8s-test-down
# ── Help ──────────────────────────────────────────────────────────────────────
help:
@echo "Fluidify Regen — Make targets"
@echo ""
@echo "Quick start:"
@echo " start Build and start everything (production mode) — single command"
@echo " stop Stop everything"
@echo ""
@echo "Development:"
@echo " dev Start backend in Docker (Air hot-reload) + Vite frontend locally"
@echo " Best for active development — full HMR on :3000, API on :8080."
@echo " dev-local Validate (build + test) then start the full dev stack."
@echo " Use this in worktrees — checks pass before anything starts."
@echo " dev-docker Start everything in Docker (nginx frontend, no local Node needed)"
@echo " backend Start db + redis + api in Docker only (no frontend)"
@echo " migrate Run database migrations inside the running app container"
@echo " install Install all backend and frontend dependencies"
@echo ""
@echo "Code quality:"
@echo " validate Mirror CI locally: go build + go test + npm run build."
@echo " Run before every push. Works in git worktrees."
@echo " test Run Go and frontend test suites"
@echo " lint Run golangci-lint and eslint"
@echo " fmt Format Go and TypeScript code"
@echo ""
@echo "Build & Deploy:"
@echo " build Build frontend + copy into backend/ui/dist + compile Go binary"
@echo " build-frontend Build frontend bundle only (frontend/dist + backend/ui/dist)"
@echo " docker Build production Docker image (single binary, embedded frontend)"
@echo ""
@echo "Utilities:"
@echo " down Stop and remove all containers"
@echo " clean Remove containers, volumes, and build artifacts"
@echo " logs Tail logs from all running containers"
@echo " health Check API liveness and readiness"
@echo ""
@echo "Helm:"
@echo " helm-lint Lint the Helm chart"
@echo " helm-template Dry-run render the chart"
@echo " helm-test Run all Helm checks"
@echo ""
@echo "Reliability:"
@echo " load-test Run all k6 load test scenarios against localhost:8080"
@echo " chaos-db Run DB kill chaos test (docker-compose)"
@echo " chaos-redis Run Redis kill chaos test (docker-compose)"
@echo " ha-up Start the HA stack (Patroni+HAProxy+etcd, Redis Sentinel)"
@echo " ha-down Tear down the HA stack"
@echo ""
@echo "Kubernetes testing (requires k3d on PATH):"
@echo " k8s-test-up Create k3d cluster + build and import Docker image"
@echo " k8s-test Run full k8s test suite (setup → test → teardown)"
@echo " k8s-test-down Tear down the k3d test cluster"
# ── Quick Start ───────────────────────────────────────────────────────────────
# Single command to build and run everything in production mode.
# Builds the Docker image (frontend embedded in Go binary) and starts all services.
# Open http://localhost:8080 when ready.
start:
@echo "Building and starting Fluidify Regen..."
@docker-compose up --build -d
@echo ""
@echo " App: http://localhost:8080"
@echo ""
@echo "View logs: make logs"
@echo "Stop: make stop"
stop:
@docker-compose down
# ── Development ───────────────────────────────────────────────────────────────
# Standard development workflow:
# - db, redis, and api run in Docker with Air hot-reload (backend changes rebuild instantly)
# - Frontend runs locally with Vite for fast HMR
#
# Prerequisites: Docker running, Node.js installed locally.
dev:
@echo "Starting backend services (db + redis + api)..."
@docker-compose -f docker-compose.dev.yml up -d db redis api
@echo "Waiting for API to be ready..."
@sleep 3
@echo "API running at http://localhost:8080"
@echo ""
@if [ ! -d frontend/node_modules ]; then echo "Installing frontend dependencies..." && cd frontend && npm install --silent; fi
@echo "Starting Vite dev server at http://localhost:3000"
@echo ""
@cd frontend && npm run dev
# Full Docker dev workflow — everything in Docker (nginx frontend + Air backend hot-reload).
# Use this for local testing without Node.js, or to test nginx/proxy configuration.
dev-docker:
@echo "Starting all services in Docker (db + redis + api + nginx frontend)..."
@docker-compose -f docker-compose.dev.yml up -d
@echo ""
@echo " Frontend: http://localhost:3000"
@echo " API: http://localhost:8080"
@echo ""
@echo "View logs: make logs"
@echo "Stop: make down"
# validate: mirror CI locally — go build, go test, npm run build.
# Prerequisites (one-time WSL2 setup):
# sudo apt-get install -y gcc ← required for go-sqlite3 (CGO)
# ln -s $(pwd)/frontend/node_modules <worktree>/frontend/node_modules ← for git worktrees
validate:
@echo "── Backend: build ───────────────────────────────────────────"
@cd backend && go build ./... && echo " go build: OK"
@echo "── Backend: lint ────────────────────────────────────────────"
@PATH="$$PATH:$$(go env GOPATH)/bin" which golangci-lint > /dev/null 2>&1 || (echo " ✗ golangci-lint not found — run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest" && exit 1)
@cd backend && PATH="$$PATH:$$(go env GOPATH)/bin" golangci-lint run && echo " golangci-lint: OK"
@echo "── Backend: test ────────────────────────────────────────────"
@which gcc > /dev/null 2>&1 || (echo " ✗ gcc not found — run: sudo apt-get install -y gcc" && exit 1)
@cd backend && CGO_ENABLED=1 go test ./... && echo " go test: OK"
@echo "── Frontend: tsc + vite build ───────────────────────────────"
@cd frontend && npm run build && echo " npm build: OK"
@echo ""
@echo "✓ validate passed — safe to push"
# dev-local: validate first, then bring up the full dev stack.
# Use this in git worktrees so you never start a broken stack.
dev-local: validate
@$(MAKE) dev
# Start infra + API only (no frontend).
# Useful when working on backend with a separately running frontend, or API-only testing.
backend:
@echo "Starting backend (db + redis + api)..."
@docker-compose -f docker-compose.dev.yml up -d db redis api
@echo "API running at http://localhost:8080"
# Run migrations inside the running app container.
migrate:
@echo "Running database migrations..."
@docker-compose exec app go run cmd/regen/main.go migrate
@echo "Migrations complete"
# ── Code Quality ──────────────────────────────────────────────────────────────
test:
@echo "Running backend tests..."
@cd backend && go test -race -coverprofile=coverage.out ./...
@echo ""
@echo "Running frontend build (tsc + vite)..."
@cd frontend && npm run build
@echo ""
@echo "All checks passed"
lint:
@echo "Linting Go code..."
@cd backend && PATH="$$PATH:$$(go env GOPATH)/bin" golangci-lint run
@echo "Linting TypeScript..."
@cd frontend && npm run lint
@echo "Lint complete"
fmt:
@echo "Formatting Go code..."
@gofmt -s -w ./backend/
@echo "Formatting TypeScript..."
@cd frontend && npm run format
@echo "Format complete"
# ── Build & Deploy ────────────────────────────────────────────────────────────
# build-frontend: compile the React SPA and copy it into backend/ui/dist/ so
# the Go //go:embed picks it up for local binary builds.
build-frontend:
@echo "Building frontend bundle..."
@cd frontend && npm run build
@echo "Copying into backend/ui/dist/ for Go embed..."
@rm -rf backend/ui/dist && cp -r frontend/dist backend/ui/dist
@echo " frontend/dist/ → backend/ui/dist/"
# build: full local production build — frontend embedded in the Go binary.
# The resulting binary at backend/bin/regen serves UI + API on :8080.
build: build-frontend
@echo "Compiling Go binary with embedded frontend..."
@cd backend && CGO_ENABLED=0 GOOS=linux go build \
-ldflags="-w -s -extldflags '-static'" \
-o bin/regen \
./cmd/regen
@echo ""
@echo "Artifact: backend/bin/regen (UI + API, no CORS config needed)"
# docker: build the production image using the top-level Dockerfile.
# The image serves both UI and API from :8080 — single binary, zero config.
#
# docker run -p 8080:8080 -e DATABASE_URL=... -e REDIS_URL=... fluidify-regen
docker:
@echo "Building production Docker image..."
@docker build -t fluidify-regen .
@echo ""
@echo "Run: docker run -p 8080:8080 fluidify-regen"
# ── Utilities ─────────────────────────────────────────────────────────────────
down:
@docker-compose down
@docker-compose -f docker-compose.dev.yml down
clean:
@echo "Removing build artifacts..."
@rm -rf backend/bin backend/coverage.out frontend/dist
@rm -rf backend/ui/dist && mkdir -p backend/ui/dist && touch backend/ui/dist/.gitkeep
@echo "Removing containers and volumes..."
@docker-compose down -v
@docker-compose -f docker-compose.dev.yml down -v
@echo "Clean complete"
logs:
@docker-compose logs -f 2>/dev/null || docker-compose -f docker-compose.dev.yml logs -f
health:
@echo "Checking API health..."
@curl -sf http://localhost:8080/health && echo "" || echo "API not responding at :8080"
@echo "Checking API readiness..."
@curl -sf http://localhost:8080/ready && echo "" || echo "API not ready"
install:
@echo "Installing backend dependencies..."
@cd backend && go mod download
@echo "Installing frontend dependencies..."
@cd frontend && npm install
@echo "Done"
# ── Reliability ───────────────────────────────────────────────────────────────
load-test:
@which k6 > /dev/null 2>&1 || (echo "k6 not found. Install: brew install k6" && exit 1)
@echo "=== Webhook sustained load (5 min, 50 VUs) ==="
k6 run load-tests/webhook-sustained.js
@echo ""
@echo "=== Webhook burst / flood protection ==="
k6 run load-tests/webhook-burst.js
@echo ""
@echo "=== Concurrent API reads ==="
@echo "Note: set AUTH_TOKEN=<token> for authenticated endpoints"
k6 run load-tests/api-read.js
chaos-db:
@bash scripts/chaos/db-kill.sh
chaos-redis:
@bash scripts/chaos/redis-kill.sh
ha-up:
@echo "Starting HA stack (PostgreSQL primary+replica+PgBouncer, Redis Sentinel)..."
docker-compose -f docker-compose.ha.yml up -d
@echo "Waiting for services to be healthy..."
@sleep 10
@echo "HA stack ready."
@echo " DB (via PgBouncer): postgresql://regen:secret@localhost:5433/regen"
@echo " Redis Sentinel: localhost:26379,26380,26381 master=mymaster"
@echo " API: http://localhost:8080"
ha-down:
docker-compose -f docker-compose.ha.yml down -v
# ── Kubernetes Testing ────────────────────────────────────────────────────────
# Create k3d cluster and import the Docker image (prerequisite for k8s-test).
k8s-test-up:
@bash scripts/k8s-test/00-setup-cluster.sh
@bash scripts/k8s-test/01-install-chart.sh
# Run the full k8s test suite end-to-end (creates cluster, tests, tears down).
k8s-test:
@bash scripts/k8s-test/run-all.sh
# Tear down the k3d test cluster.
k8s-test-down:
@bash scripts/k8s-test/99-teardown.sh
# ── Helm ──────────────────────────────────────────────────────────────────────
helm-deps:
@helm dependency update deploy/helm/fluidify-regen
helm-lint: helm-deps
@helm lint deploy/helm/fluidify-regen
helm-template: helm-deps
@helm template fluidify-regen deploy/helm/fluidify-regen \
--set ingress.host=localhost \
| kubectl apply --dry-run=client -f -
helm-test: helm-lint
@helm template fluidify-regen deploy/helm/fluidify-regen \
--set ingress.host=localhost > /dev/null && \
echo "helm template: OK"