-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
258 lines (200 loc) · 9.21 KB
/
Makefile
File metadata and controls
258 lines (200 loc) · 9.21 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
.DEFAULT_GOAL := help
NPM ?= npm
DC ?= docker compose
COMPOSE_FILE ?= docker-compose.yml
STAGING_COMPOSE_FILE ?= docker-compose.staging.yml
POSTGRES_COMPOSE_FILE ?= docker-compose.postgres.yml
WEB_PACKAGE ?= @patchwork/web
# Immutable image versioning (#109)
GIT_SHA ?= $(shell git rev-parse --short=7 HEAD 2>/dev/null || echo unknown)
GIT_SHA_FULL ?= $(shell git rev-parse HEAD 2>/dev/null || echo unknown)
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)
BUILD_VERSION ?= 0.9.0
IMAGE_TAG ?= $(BUILD_VERSION)-$(GIT_SHA)
CI_RUN_ID ?= local
# Rollback target tag (#109)
ROLLBACK_TAG ?=
SERVICE ?=
.PHONY: \
help \
install env-init \
dev dev-web dev-api dev-api-postgres dev-indexer dev-moderation \
db-up db-down db-migrate make-db-migrate db-seed db-reset \
lint typecheck test test-phase7 test-phase8 test-phase8-e2e test-web-e2e check build \
quality \
deploy-network deploy-build deploy-up deploy-down deploy-restart deploy-ps deploy-logs deploy-pull deploy-db-migrate \
compose-config \
staging-network staging-build staging-up staging-down staging-ps staging-logs staging-smoke staging-db-migrate \
image-tag image-build rollback \
deploy-rollout-pause deploy-rollout-resume deploy-rollout-abort
help: ## Show available make targets
@awk 'BEGIN {FS = ":.*##"; printf "\nPatchwork Make targets\n\n"} /^[a-zA-Z0-9_.-]+:.*##/ {printf " %-24s %s\n", $$1, $$2} END {printf "\n"}' $(MAKEFILE_LIST)
install: ## Install all monorepo dependencies
$(NPM) ci
env-init: ## Create .env from .env.example if it does not exist
@if [ -f .env ]; then \
echo ".env already exists (no changes made)."; \
else \
cp .env.example .env; \
echo "Created .env from .env.example"; \
fi
dev: dev-web ## Start web app (default local dev surface)
dev-web: ## Start web app (Vite)
$(NPM) run dev:web
dev-api: ## Start API in fixture mode
$(NPM) run dev:api
dev-api-postgres: ## Start API in postgres mode
$(NPM) run dev:api:postgres
dev-indexer: ## Start indexer service
$(NPM) run dev:indexer
dev-moderation: ## Start moderation worker
$(NPM) run dev:moderation
db-up: ## Start local Postgres for development
$(NPM) run db:up
db-down: ## Stop local Postgres for development
$(NPM) run db:down
db-migrate: ## Run versioned API database migrations
$(NPM) run db:migrate
make-db-migrate: db-migrate ## Alias target for db-migrate
db-seed: ## Seed local Postgres with deterministic data
$(NPM) run db:seed
db-reset: db-down db-up db-seed ## Recreate and reseed local Postgres
lint: ## Run lint checks across workspaces
$(NPM) run lint
typecheck: ## Run TypeScript checks across workspaces
$(NPM) run typecheck
test: ## Run unit/integration tests across workspaces
$(NPM) run test
test-phase7: ## Run moderation/privacy regression tests
$(NPM) run test:phase7
test-phase8: ## Run phase 8 regression tests
$(NPM) run test:phase8
test-phase8-e2e: ## Run API request-to-handoff contract E2E tests
$(NPM) run test:phase8-e2e
test-web-e2e: ## Run Playwright browser E2E tests for web app
$(NPM) run test:e2e -w $(WEB_PACKAGE)
check: ## Run the default local gate (lint + typecheck + test)
$(NPM) run check
quality: check test-phase7 ## Run merge-readiness quality gate
build: ## Build all workspaces
$(NPM) run build
deploy-network: ## Ensure external Docker network "web" exists
@docker network inspect web >/dev/null 2>&1 || docker network create web
compose-config: ## Validate production compose file
$(DC) -f $(COMPOSE_FILE) config >/dev/null
deploy-build: ## Build production Docker images from compose file
$(DC) -f $(COMPOSE_FILE) build
deploy-up: deploy-network ## Start production stack (detached, with build)
$(DC) -f $(COMPOSE_FILE) up -d --build
deploy-down: ## Stop production stack
$(DC) -f $(COMPOSE_FILE) down
deploy-restart: ## Restart production stack services
$(DC) -f $(COMPOSE_FILE) restart
deploy-ps: ## Show production stack container status
$(DC) -f $(COMPOSE_FILE) ps
deploy-logs: ## Tail production stack logs
$(DC) -f $(COMPOSE_FILE) logs -f --tail=200
deploy-pull: ## Pull latest upstream images referenced by compose file
$(DC) -f $(COMPOSE_FILE) pull
deploy-db-migrate: deploy-network ## Run DB migrations via production API container
$(DC) -f $(COMPOSE_FILE) up -d postgres
$(DC) -f $(COMPOSE_FILE) run --build --rm patchwork-api npm run db:migrate -w @patchwork/api
# ---------------------------------------------------------------------------
# Staging environment (#108)
# ---------------------------------------------------------------------------
staging-network: ## Ensure external Docker network "staging-web" exists
@docker network inspect staging-web >/dev/null 2>&1 || docker network create staging-web
staging-build: ## Build staging Docker images
$(DC) -f $(STAGING_COMPOSE_FILE) build \
--build-arg GIT_SHA=$(GIT_SHA) \
--build-arg GIT_BRANCH=$(GIT_BRANCH) \
--build-arg BUILD_VERSION=$(BUILD_VERSION) \
--build-arg CI_RUN_ID=$(CI_RUN_ID)
staging-up: staging-network ## Start staging stack (detached, with build)
$(DC) -f $(STAGING_COMPOSE_FILE) up -d --build
staging-down: ## Stop staging stack
$(DC) -f $(STAGING_COMPOSE_FILE) down
staging-ps: ## Show staging stack container status
$(DC) -f $(STAGING_COMPOSE_FILE) ps
staging-logs: ## Tail staging stack logs
$(DC) -f $(STAGING_COMPOSE_FILE) logs -f --tail=200
staging-db-migrate: staging-network ## Run DB migrations via staging API container
$(DC) -f $(STAGING_COMPOSE_FILE) up -d postgres
$(DC) -f $(STAGING_COMPOSE_FILE) run --build --rm patchwork-api npm run db:migrate -w @patchwork/api
staging-smoke: ## Run smoke checks against staging endpoints
@echo "Running staging smoke checks..."
@PASS=0; FAIL=0; \
for svc in api:4000 spool:4100 thimble:4200; do \
name=$${svc%%:*}; port=$${svc##*:}; \
url="http://patchwork-staging-$${name}:$${port}/health"; \
if curl -sf --max-time 5 "$$url" > /dev/null 2>&1; then \
echo " PASS: $$name /health"; \
PASS=$$((PASS + 1)); \
else \
echo " FAIL: $$name /health"; \
FAIL=$$((FAIL + 1)); \
fi; \
done; \
echo "Smoke results: $$PASS passed, $$FAIL failed"; \
if [ "$$FAIL" -gt 0 ]; then \
echo "ERROR: Smoke checks failed -- promotion to production blocked."; \
exit 1; \
fi; \
echo "All smoke checks passed -- promotion eligible."
# ---------------------------------------------------------------------------
# Immutable image versioning (#109)
# ---------------------------------------------------------------------------
image-tag: ## Print the immutable image tag for this build
@echo "$(IMAGE_TAG)"
image-build: ## Build Docker images with immutable tags and OCI labels
docker build --target api-runtime \
--build-arg GIT_SHA=$(GIT_SHA) \
--build-arg GIT_BRANCH=$(GIT_BRANCH) \
--build-arg BUILD_VERSION=$(BUILD_VERSION) \
--build-arg CI_RUN_ID=$(CI_RUN_ID) \
-t patchwork-api:$(IMAGE_TAG) .
docker build --target indexer-runtime \
--build-arg GIT_SHA=$(GIT_SHA) \
--build-arg GIT_BRANCH=$(GIT_BRANCH) \
--build-arg BUILD_VERSION=$(BUILD_VERSION) \
--build-arg CI_RUN_ID=$(CI_RUN_ID) \
-t patchwork-spool:$(IMAGE_TAG) .
docker build --target moderation-runtime \
--build-arg GIT_SHA=$(GIT_SHA) \
--build-arg GIT_BRANCH=$(GIT_BRANCH) \
--build-arg BUILD_VERSION=$(BUILD_VERSION) \
--build-arg CI_RUN_ID=$(CI_RUN_ID) \
-t patchwork-thimble:$(IMAGE_TAG) .
docker build --target web-runtime \
--build-arg GIT_SHA=$(GIT_SHA) \
--build-arg GIT_BRANCH=$(GIT_BRANCH) \
--build-arg BUILD_VERSION=$(BUILD_VERSION) \
--build-arg CI_RUN_ID=$(CI_RUN_ID) \
-t patchwork-web:$(IMAGE_TAG) .
rollback: ## Roll back a service to a previous image tag (SERVICE=api TAG=0.9.0-abc1234)
@if [ -z "$(SERVICE)" ] || [ -z "$(ROLLBACK_TAG)" ]; then \
echo "Usage: make rollback SERVICE=<api|spool|thimble|web> ROLLBACK_TAG=<tag>"; \
exit 1; \
fi
@echo "Rolling back patchwork-$(SERVICE) to tag $(ROLLBACK_TAG)..."
docker tag patchwork-$(SERVICE):$(ROLLBACK_TAG) patchwork-$(SERVICE):rollback-target
$(DC) -f $(COMPOSE_FILE) up -d --no-build patchwork-$(SERVICE)
@echo "Rollback to $(ROLLBACK_TAG) complete. Verify with: make deploy-ps"
# ---------------------------------------------------------------------------
# Progressive delivery (#110)
# ---------------------------------------------------------------------------
deploy-rollout-pause: ## Pause the current progressive rollout for SERVICE
@if [ -z "$(SERVICE)" ]; then echo "Usage: make deploy-rollout-pause SERVICE=<service>"; exit 1; fi
@echo "Pausing rollout for $(SERVICE)..."
@echo "ACTION: Operator must pause traffic shifting for $(SERVICE) in the load balancer."
@echo "Status: PAUSED"
deploy-rollout-resume: ## Resume a paused progressive rollout for SERVICE
@if [ -z "$(SERVICE)" ]; then echo "Usage: make deploy-rollout-resume SERVICE=<service>"; exit 1; fi
@echo "Resuming rollout for $(SERVICE)..."
@echo "ACTION: Operator must resume traffic shifting for $(SERVICE) in the load balancer."
@echo "Status: IN-PROGRESS"
deploy-rollout-abort: ## Abort the current rollout and revert to previous version for SERVICE
@if [ -z "$(SERVICE)" ]; then echo "Usage: make deploy-rollout-abort SERVICE=<service>"; exit 1; fi
@echo "Aborting rollout for $(SERVICE) -- routing all traffic to previous version..."
@echo "ACTION: Operator must route 100% traffic to the previous version for $(SERVICE)."
@echo "Status: ABORTED"