-
Notifications
You must be signed in to change notification settings - Fork 633
Expand file tree
/
Copy pathMakefile
More file actions
161 lines (132 loc) · 6.68 KB
/
Copy pathMakefile
File metadata and controls
161 lines (132 loc) · 6.68 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
.PHONY: help
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
.PHONY: install-go
install-go: ## Install Go dependencies
go mod download
.PHONY: install-brew-tools
install-brew-tools: ## Install Homebrew tools if they don't exist
@command -v tilt >/dev/null 2>&1 || { echo "Installing tilt..."; brew install tilt; }
@command -v ctlptl >/dev/null 2>&1 || { echo "Installing ctlptl..."; brew install ctlptl; }
@command -v minikube >/dev/null 2>&1 || { echo "Installing minikube..."; brew install minikube; }
@command -v dprint >/dev/null 2>&1 || { echo "Installing dprint..."; brew install dprint; }
@command -v ngrok >/dev/null 2>&1 || { echo "Installing ngrok..."; brew install ngrok; }
.PHONY: install
install: install-go ## Install all dependencies
cd web && pnpm install --frozen-lockfile
.PHONY: generate-sql
generate-sql:
@rm -rf ./web/internal/db/out
@rm -f ./pkg/mysql/schema/*.sql
@mkdir -p ./pkg/mysql/schema
@cd web/internal/db && pnpm drizzle-kit generate --schema=src/schema/index.ts --dialect=mysql --out=out --name=init --breakpoints=true
@awk -v dir=./pkg/mysql/schema 'BEGIN{RS="--> statement-breakpoint"} \
/^[[:space:]]*$$/{next} \
{ gsub(/^[[:space:]]+|[[:space:]]+$$/, ""); \
table=""; \
if ($$0 ~ /^CREATE TABLE/) { s=$$0; gsub(/^CREATE TABLE `/, "", s); gsub(/`.*/, "", s); table=s } \
else if ($$0 ~ /ON `/) { s=$$0; gsub(/.*ON `/, "", s); gsub(/`.*/, "", s); table=s } \
if (table != "") { f=dir "/" table ".sql"; print $$0 "\n" >> f } }' \
./web/internal/db/out/0000_init.sql
@rm -rf ./web/internal/db/out
.PHONY: pscale-branch
pscale-branch: ## Create PlanetScale branch + run drizzle migration (BRANCH=name [FROM=staging])
@if [ -z "$(BRANCH)" ]; then echo "Error: BRANCH is required (e.g., make pscale-branch BRANCH=florian-scratch)"; exit 1; fi
@FROM="$${FROM:-staging}"; \
pscale branch create unkey "$(BRANCH)" --org unkey --from "$$FROM" --wait \
|| pscale branch show unkey "$(BRANCH)" --org unkey >/dev/null; \
PW=$$(pscale password create unkey "$(BRANCH)" "local-$$(date +%s)" --org unkey --format json); \
USER=$$(echo "$$PW" | jq -r '.username | @uri'); \
PASS=$$(echo "$$PW" | jq -r '.plain_text | @uri'); \
HOST=$$(echo "$$PW" | jq -r '.access_host_url | @uri'); \
DRIZZLE_DATABASE_URL="mysql://$$USER:$$PASS@$$HOST/unkey?ssl={}" \
pnpm --dir=web/internal/db run migrate
.PHONY: nuke-docker
nuke-docker: ## Stop all containers and clean up Docker system
docker stop $$(docker ps -aq)
docker system prune -af
docker volume prune --all -f
.PHONY: fmt-yaml
fmt-yaml: ## Format YAML files
dprint fmt --config dev/dprint.json
.PHONY: fmt
fmt: fmt-yaml ## Format code
go fmt ./...
go tool buf format -w
cd web && pnpm fmt
.PHONY: build
build: ## Build all artifacts (binaries land in ./bin)
mise run build
.PHONY: generate
generate: generate-sql ## Generate code from protobuf and other sources (NOT eBPF, see generate-bpf)
rm -rf ./gen || true
rm ./pkg/db/*_generated.go || true
go generate ./...
go run ./tools/exportoneof ./gen/proto
go fmt ./...
cd web && pnpm fmt
.PHONY: generate-bpf
generate-bpf: ## Compile the heimdall eBPF program and regenerate Go bindings (uses pinned clang/Go in docker for bytewise reproducibility across hosts)
@docker build --platform=linux/amd64 -q -t unkey-bpf-gen -f svc/heimdall/internal/network/bpf/Dockerfile.gen svc/heimdall/internal/network/bpf >/dev/null
@docker run --rm --platform=linux/amd64 -v "$$PWD:/work" -w /work unkey-bpf-gen \
go generate -tags bpf_generate ./svc/heimdall/internal/network/...
.PHONY: test
test: ## Run tests
mise run test
.PHONY: clean-docker-test
clean-docker-test: ## Clean up dangling test containers
@docker rm -vf $$(docker ps -q -f label="owner=testutil-containers") > /dev/null 2>&1 || true
.PHONY: tunnel
tunnel: ## Forward ports 80/443 to frontline for *.unkey.local (run in separate terminal)
@sudo -v && ( while sudo -n true 2>/dev/null; do sleep 50; done & ) && while true; do sudo kubectl port-forward -n frontline svc/frontline 443:443 80:80 2>/dev/null; echo "port-forward exited, reconnecting..."; sleep 1; done
.PHONY: dev
dev: ## Start dev environment
@# Make sure you have ./dev/.env.depot populated, or you will get some funny errors
@# we're working on making this optional soon
@ctlptl apply -f ./dev/cluster.yaml
@minikube addons enable metrics-server
@tilt up -f ./dev/Tiltfile
.PHONY: down
down: ## Stop tilt (keeps cluster)
@tilt down -f ./dev/Tiltfile
@minikube delete
.PHONY: dashboard
dashboard: build ## Run local development setup for dashboard
@test -f web/apps/dashboard/.env || cp web/apps/dashboard/dev/.env.template web/apps/dashboard/.env
@docker compose -f web/apps/dashboard/dev/docker-compose.yaml up -d --wait --build
@bin/unkey dev seed local
@cd web/apps/dashboard && pnpm dev
.PHONY: build-local-image
build-local-image: ## Build and push image to local registry (usage: make build-local-image DOCKERFILE=./path/to/Dockerfile NAME=myapp TAG=dev)
@if [ -z "$(DOCKERFILE)" ]; then echo "Error: DOCKERFILE is required (e.g., DOCKERFILE=./examples/demo_api/Dockerfile)"; exit 1; fi
@if [ -z "$(NAME)" ]; then echo "Error: NAME is required (e.g., NAME=demo_api)"; exit 1; fi
$(eval TAG ?= dev)
$(eval CONTEXT ?= $(dir $(DOCKERFILE)))
$(eval REGISTRY := $(shell kubectl get configmap local-registry-hosting -n kube-public -o jsonpath='{.data.localRegistryHosting\.v1}' 2>/dev/null | grep '^host:' | awk '{print $$2}'))
@if [ -z "$(REGISTRY)" ]; then echo "Error: Could not find local registry. Is minikube running with ctlptl?"; exit 1; fi
@echo "Building $(NAME):$(TAG) from $(DOCKERFILE) (context: $(CONTEXT))"
@echo "Pushing to $(REGISTRY)/$(NAME):$(TAG)"
docker build -t $(REGISTRY)/$(NAME):$(TAG) -f $(DOCKERFILE) $(CONTEXT)
docker push $(REGISTRY)/$(NAME):$(TAG)
@echo ""
@echo "Image pushed successfully!"
@echo "Use in pod spec: ctlptl-registry:5000/$(NAME):$(TAG)"
.PHONY: fuzz
fuzz: ## Run fuzz tests
@files=$$(grep -r --include='*_test.go' -l 'func Fuzz' .); \
for file in $$files; do \
funcs=$$(grep -oE 'func (Fuzz[a-zA-Z0-9_]*)' $$file | sed 's/func //'); \
for func in $$funcs; do \
echo "Fuzzing $$func in $$file"; \
parentDir=$$(dirname $$file); \
go test $$parentDir -run=^$$func$$ -fuzz=^$$func$$ -fuzztime=1m; \
done; \
done
.PHONY: unkey
unkey: ## Run unkey CLI (usage: make unkey dev seed local)
@set -a; [ -f .env ] && . ./.env; set +a; go run . $(filter-out unkey,$(MAKECMDGOALS)) $(ARGS)
# Catch-all to swallow extra args passed to unkey target (only when unkey is called)
ifneq ($(filter unkey,$(MAKECMDGOALS)),)
%:
@:
endif