-
Notifications
You must be signed in to change notification settings - Fork 619
Expand file tree
/
Copy pathMakefile
More file actions
176 lines (145 loc) · 7.37 KB
/
Makefile
File metadata and controls
176 lines (145 loc) · 7.37 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
.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 bazel >/dev/null 2>&1 || { echo "Installing bazel..."; brew install bazelisk; }
@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)
bazel build //...
@mkdir -p bin
@cp -f "$$(bazel cquery --ui_event_filters=-info --noshow_progress //:unkey --output=files)" bin/unkey && chmod +w bin/unkey
.PHONY: bazel
bazel: ## Sync BUILD.bazel
bazel mod tidy
bazel run //:gazelle
.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
bazel run //:gazelle
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: oci-load clean-docker-test ## Run tests with bazel
bazel test //...
make clean-docker-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
@docker rm -vf $$(docker ps -q -f label="owner=dockertest") > /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: oci-load
oci-load: build ## Build and load OCI images into Docker
bazel run //:oci_load_unkey
.PHONY: dashboard
dashboard: build oci-load ## 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
@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=latest)
@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 ?= latest)
$(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, make unkey run api ARGS="--http-port=7070")
@set -a; [ -f .env ] && . ./.env; set +a; bazel run --ui_event_filters=-info --noshow_progress //:unkey -- $(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