-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMakefile
More file actions
318 lines (263 loc) · 11.4 KB
/
Copy pathMakefile
File metadata and controls
318 lines (263 loc) · 11.4 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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# ceps-rust-api - developer targets
SHELL := /bin/bash
.SHELLFLAGS := -eu -o pipefail -c
ROOT := $(CURDIR)
APP_NAME ?= ceps-rust-api
HUB_IMAGE ?= interchouette/ceps-rust-api
GHCR_PERSONAL_IMAGE ?= ghcr.io/groussac/ceps-rust-api
GHCR_WORKER_IMAGE ?= ghcr.io/interchouette/ceps-rust-api
GHCR_ORG_IMAGE ?= ghcr.io/interchouette-itc/ceps-rust-api
TAG ?= latest
APP_VERSION ?= $(shell awk '/^version = /{gsub(/"/, "", $$3); print $$3; exit}' Cargo.toml)
MCP_NAME ?= ceps-rust-api-mcp
MCP_HUB_IMAGE ?= interchouette/ceps-rust-api-mcp
MCP_GHCR_PERSONAL_IMAGE ?= ghcr.io/groussac/ceps-rust-api-mcp
MCP_GHCR_WORKER_IMAGE ?= ghcr.io/interchouette/ceps-rust-api-mcp
MCP_GHCR_ORG_IMAGE ?= ghcr.io/interchouette-itc/ceps-rust-api-mcp
MCP_VERSION ?= $(shell awk '/^version = /{gsub(/"/, "", $$3); print $$3; exit}' mcp/Cargo.toml)
DOCKERFILE ?= docker/Dockerfile
DOCKER_BUILDKIT ?= 1
CI ?= 0
COMPOSE ?= docker/docker-compose.yml
COMPOSE_MCP ?= docker/docker-compose.mcp.yml
# Sibling ceps-rust-ts-client checkout (canonical demo contract WASM pack).
CEPS_CLIENT_PRODUCT ?= $(ROOT)/../ceps-rust-ts-client
WASM_DIR := $(ROOT)/tests/wasm
FEATURES ?= ceps-all,swagger-ui,tx-return,sign-local,sign-kms,chain-put
CARGO_FEATURES := --features $(FEATURES)
RUST_LOG ?= info
CARGO := cargo
CLIPPY_FLAGS := -D warnings -D clippy::all
.DEFAULT_GOAL := help
.PHONY: help build build-release check test verify verify-slices lint format format-check clippy \
docker-build docker-build-dev docker-run docker-run-kms docker-stop version-show run pem-ban \
export-local-keys run-local wasm-from-ceps \
docker-push-dev-hub docker-push-dev-ghcr-personal docker-push-dev-ghcr-itc docker-push-dev \
docker-push-release-hub docker-push-release-ghcr-personal docker-push-release-ghcr-itc \
docker-push-release \
mcp-build mcp-docker-build mcp-docker-build-dev \
mcp-docker-push-dev-hub mcp-docker-push-dev-ghcr-personal mcp-docker-push-dev-ghcr-itc \
mcp-docker-push-dev \
mcp-docker-push-release-hub mcp-docker-push-release-ghcr-personal mcp-docker-push-release-ghcr-itc \
mcp-docker-push-release mcp-http mcp-http-stop run-mcp run-mcp-http
NCTL_CONTAINER ?= casper-nctl-2-docker-dev
NCTL_USERS ?= 1 2 3
help:
@echo "ceps-rust-api targets"
@echo " make build / test / verify / verify-slices / run"
@echo " make wasm-from-ceps # copy client tests/wasm into tests/wasm/"
@echo " make export-local-keys # print LOCAL_KEYS_JSON (NCTL users; lab only)"
@echo " make run-local # run with SIGN_BACKEND=local + exported keys"
@echo " make docker-build / docker-build-dev / docker-push-dev"
@echo " make mcp-build / mcp-docker-build-dev / mcp-http / run-mcp"
@echo " Features: FEATURES=$(FEATURES)"
@echo " SIGN_BACKEND: none (default) | local (lab) | local-production | kms (recommended)"
build:
$(CARGO) build -p ceps-rust-api $(CARGO_FEATURES)
build-release:
$(CARGO) build -p ceps-rust-api --release $(CARGO_FEATURES)
check:
$(CARGO) check -p ceps-rust-api $(CARGO_FEATURES)
format:
$(CARGO) fmt --all
format-check:
$(CARGO) fmt --all -- --check
clippy:
$(CARGO) clippy -p ceps-rust-api $(CARGO_FEATURES) -- $(CLIPPY_FLAGS)
lint: format-check clippy pem-ban
test: lint
$(CARGO) test -p ceps-rust-api $(CARGO_FEATURES) -- --nocapture
verify: lint test
# Same feature slices as CI (.github/workflows/ci.yml).
verify-slices:
$(CARGO) test -p ceps-rust-api --no-default-features --features cep18,tx-return,swagger-ui -- --nocapture
$(CARGO) test -p ceps-rust-api --no-default-features --features cep78,tx-return,swagger-ui -- --nocapture
$(CARGO) check -p ceps-rust-api --no-default-features --features cep85,cep95,swagger-ui
$(CARGO) test -p ceps-rust-api --no-default-features --features cep18,swagger-ui -- --nocapture
$(CARGO) test -p ceps-rust-api --no-default-features --features swagger-ui -- --nocapture
pem-ban:
@if rg -n 'secret_key\.pem|PATH_PRIVATE_KEY_|PRIVATE_KEY_|FAUCET_MODE|BOOTSTRAP_KMS' \
crates docker README.md .env.example .github 2>/dev/null ; then \
echo "pem-ban: forbidden key/PEM strings found"; exit 1; \
fi
@echo "pem-ban: ok"
run:
RUST_LOG=$(RUST_LOG) $(CARGO) run -p ceps-rust-api $(CARGO_FEATURES)
# Stage tip contract WASMs from sibling ceps-rust-ts-client/tests/wasm/
# (client owns tip staging via make wasm-from-ceps). Commit the result when refreshing.
wasm-from-ceps:
@src="$(CEPS_CLIENT_PRODUCT)/tests/wasm"; \
if [ ! -d "$$src" ]; then \
echo "wasm-from-ceps: missing $$src (set CEPS_CLIENT_PRODUCT or stage client tests/wasm first)"; \
exit 1; \
fi; \
missing=0; \
for name in cep18 cep78 cep85 cep95; do \
if [ ! -d "$$src/$$name" ]; then \
echo "wasm-from-ceps: missing $$src/$$name"; \
missing=1; \
fi; \
done; \
if [ "$$missing" -ne 0 ]; then exit 1; fi; \
mkdir -p "$(WASM_DIR)"; \
for name in cep18 cep78 cep85 cep95; do \
rm -rf "$(WASM_DIR)/$$name"; \
cp -a "$$src/$$name" "$(WASM_DIR)/$$name"; \
echo " staged $$name/ from $$src/$$name"; \
done; \
echo "wasm-from-ceps: done -> $(WASM_DIR)"
# Lab only: dump NCTL user PEMs as LOCAL_KEYS_JSON (stdout). Never faucet.
export-local-keys:
@chmod +x scripts/export-nctl-local-keys.sh
@NCTL_CONTAINER=$(NCTL_CONTAINER) NCTL_USERS="$(NCTL_USERS)" ./scripts/export-nctl-local-keys.sh
# Lab only: run API with SIGN_BACKEND=local and keys from export-local-keys.
run-local:
@chmod +x scripts/export-nctl-local-keys.sh
@RUST_LOG=$(RUST_LOG) \
SIGN_BACKEND=local \
LOCAL_KEYS_JSON="$$(NCTL_CONTAINER=$(NCTL_CONTAINER) NCTL_USERS="$(NCTL_USERS)" ./scripts/export-nctl-local-keys.sh)" \
$(CARGO) run -p ceps-rust-api $(CARGO_FEATURES)
docker-build:
DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build -f $(DOCKERFILE) \
--build-arg FEATURES=$(FEATURES) \
-t $(HUB_IMAGE):$(TAG) -t $(HUB_IMAGE):$(APP_VERSION) \
..
docker-build-dev:
DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build -f $(DOCKERFILE) \
--build-arg FEATURES=$(FEATURES) \
-t $(HUB_IMAGE):dev \
-t $(GHCR_PERSONAL_IMAGE):dev \
-t $(GHCR_WORKER_IMAGE):dev \
-t $(GHCR_ORG_IMAGE):dev \
..
docker-push-dev-hub:
docker push $(HUB_IMAGE):dev
docker-push-dev-ghcr-personal:
docker push $(GHCR_PERSONAL_IMAGE):dev
docker-push-dev-ghcr-itc:
docker push $(GHCR_WORKER_IMAGE):dev
docker push $(GHCR_ORG_IMAGE):dev
docker-push-dev:
@if [ "$(CI)" = "1" ]; then \
echo "Use docker-push-dev-hub / docker-push-dev-ghcr-* in CI"; \
exit 1; \
fi
@echo "Logging in to Docker Hub..."; \
docker login || { echo "Docker Hub login failed"; exit 1; }
$(MAKE) docker-push-dev-hub
@echo "Logging in to GHCR (personal)..."; \
docker login ghcr.io || { echo "Skipping personal GHCR"; exit 0; }
$(MAKE) docker-push-dev-ghcr-personal
@echo "Logging in to GHCR (org)..."; \
docker login ghcr.io || { echo "Skipping org GHCR"; exit 0; }
$(MAKE) docker-push-dev-ghcr-itc
docker-push-release-hub:
docker push $(HUB_IMAGE):$(APP_VERSION)
docker push $(HUB_IMAGE):latest
docker-push-release-ghcr-personal:
docker tag $(HUB_IMAGE):$(APP_VERSION) $(GHCR_PERSONAL_IMAGE):$(APP_VERSION)
docker tag $(HUB_IMAGE):latest $(GHCR_PERSONAL_IMAGE):latest
docker push $(GHCR_PERSONAL_IMAGE):$(APP_VERSION)
docker push $(GHCR_PERSONAL_IMAGE):latest
docker-push-release-ghcr-itc:
docker tag $(HUB_IMAGE):$(APP_VERSION) $(GHCR_WORKER_IMAGE):$(APP_VERSION)
docker tag $(HUB_IMAGE):latest $(GHCR_WORKER_IMAGE):latest
docker tag $(HUB_IMAGE):$(APP_VERSION) $(GHCR_ORG_IMAGE):$(APP_VERSION)
docker tag $(HUB_IMAGE):latest $(GHCR_ORG_IMAGE):latest
docker push $(GHCR_WORKER_IMAGE):$(APP_VERSION)
docker push $(GHCR_WORKER_IMAGE):latest
docker push $(GHCR_ORG_IMAGE):$(APP_VERSION)
docker push $(GHCR_ORG_IMAGE):latest
docker-push-release: docker-push-release-hub \
docker-push-release-ghcr-personal docker-push-release-ghcr-itc
docker-run:
docker compose -f $(COMPOSE) up -d
docker-run-kms:
docker compose -f $(COMPOSE) --profile kms up -d
docker-stop:
docker compose -f $(COMPOSE) --profile kms down || true
docker compose -f $(COMPOSE) down
version-show:
@echo "version=$(APP_VERSION) image=$(HUB_IMAGE):$(TAG)"
@echo "mcp_version=$(MCP_VERSION) mcp_image=$(MCP_HUB_IMAGE):$(TAG)"
# ---------------------------------------------------------------------------
# MCP sidecar (mcp/ - separate Cargo package; no dep on API lib)
# ---------------------------------------------------------------------------
mcp-build:
$(CARGO) build --manifest-path mcp/Cargo.toml --release
mcp-docker-build:
DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build --network=host \
-t $(MCP_NAME):$(TAG) \
-t $(MCP_HUB_IMAGE):$(TAG) \
-t $(MCP_HUB_IMAGE):$(MCP_VERSION) \
-f mcp/Dockerfile \
mcp
mcp-docker-build-dev:
DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build --network=host \
-t $(MCP_NAME):dev \
-t $(MCP_HUB_IMAGE):dev \
-t $(MCP_GHCR_PERSONAL_IMAGE):dev \
-t $(MCP_GHCR_WORKER_IMAGE):dev \
-t $(MCP_GHCR_ORG_IMAGE):dev \
-f mcp/Dockerfile \
mcp
mcp-docker-push-dev-hub:
docker push $(MCP_HUB_IMAGE):dev
mcp-docker-push-dev-ghcr-personal:
docker push $(MCP_GHCR_PERSONAL_IMAGE):dev
mcp-docker-push-dev-ghcr-itc:
docker push $(MCP_GHCR_WORKER_IMAGE):dev
docker push $(MCP_GHCR_ORG_IMAGE):dev
mcp-docker-push-dev:
@if [ "$(CI)" = "1" ]; then \
echo "Use mcp-docker-push-dev-hub / mcp-docker-push-dev-ghcr-* in CI"; \
exit 1; \
fi
@echo "Logging in to Docker Hub..."; \
docker login || { echo "Docker Hub login failed"; exit 1; }
$(MAKE) mcp-docker-push-dev-hub
@echo "Logging in to GHCR (personal)..."; \
docker login ghcr.io || { echo "Skipping personal GHCR"; exit 0; }
$(MAKE) mcp-docker-push-dev-ghcr-personal
@echo "Logging in to GHCR (org)..."; \
docker login ghcr.io || { echo "Skipping org GHCR"; exit 0; }
$(MAKE) mcp-docker-push-dev-ghcr-itc
mcp-docker-push-release-hub:
docker push $(MCP_HUB_IMAGE):$(MCP_VERSION)
docker push $(MCP_HUB_IMAGE):latest
mcp-docker-push-release-ghcr-personal:
docker tag $(MCP_HUB_IMAGE):$(MCP_VERSION) $(MCP_GHCR_PERSONAL_IMAGE):$(MCP_VERSION)
docker tag $(MCP_HUB_IMAGE):latest $(MCP_GHCR_PERSONAL_IMAGE):latest
docker push $(MCP_GHCR_PERSONAL_IMAGE):$(MCP_VERSION)
docker push $(MCP_GHCR_PERSONAL_IMAGE):latest
mcp-docker-push-release-ghcr-itc:
docker tag $(MCP_HUB_IMAGE):$(MCP_VERSION) $(MCP_GHCR_WORKER_IMAGE):$(MCP_VERSION)
docker tag $(MCP_HUB_IMAGE):latest $(MCP_GHCR_WORKER_IMAGE):latest
docker tag $(MCP_HUB_IMAGE):$(MCP_VERSION) $(MCP_GHCR_ORG_IMAGE):$(MCP_VERSION)
docker tag $(MCP_HUB_IMAGE):latest $(MCP_GHCR_ORG_IMAGE):latest
docker push $(MCP_GHCR_WORKER_IMAGE):$(MCP_VERSION)
docker push $(MCP_GHCR_WORKER_IMAGE):latest
docker push $(MCP_GHCR_ORG_IMAGE):$(MCP_VERSION)
docker push $(MCP_GHCR_ORG_IMAGE):latest
mcp-docker-push-release: mcp-docker-push-release-hub \
mcp-docker-push-release-ghcr-personal mcp-docker-push-release-ghcr-itc
mcp-http:
-docker pull $(MCP_HUB_IMAGE):$(MCP_VERSION)
@if ! docker image inspect $(MCP_HUB_IMAGE):$(MCP_VERSION) >/dev/null 2>&1 \
&& ! docker image inspect $(MCP_NAME):$(MCP_VERSION) >/dev/null 2>&1; then \
echo "Hub image missing; building locally…"; \
$(MAKE) mcp-docker-build; \
fi
CEPS_API_MCP_IMAGE=$(MCP_HUB_IMAGE):$(MCP_VERSION) CEPS_HOST_ROOT="$(CURDIR)" \
docker compose -f $(COMPOSE_MCP) up -d --force-recreate
mcp-http-stop:
-CEPS_HOST_ROOT="$(CURDIR)" docker compose -f $(COMPOSE_MCP) down --remove-orphans
-docker stop ceps-rust-api-mcp 2>/dev/null
-docker rm ceps-rust-api-mcp 2>/dev/null
run-mcp:
CEPS_API_ROOT="$(CURDIR)" CEPS_HOST_ROOT="$(CURDIR)" \
$(CARGO) run --manifest-path mcp/Cargo.toml --quiet --
run-mcp-http:
CEPS_API_ROOT="$(CURDIR)" CEPS_HOST_ROOT="$(CURDIR)" \
$(CARGO) run --manifest-path mcp/Cargo.toml --quiet -- \
--http --listen 127.0.0.1:4790