-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
185 lines (155 loc) · 6.25 KB
/
Copy pathMakefile
File metadata and controls
185 lines (155 loc) · 6.25 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
RUFF := .venv/bin/ruff
PYTEST := .venv/bin/pytest
MATURIN := .venv/bin/maturin
# Pinned so lint results don't shift when ruff changes its default rule set.
RUFF_VERSION := ruff==0.15.15
.PHONY: help build install dev test clean daemon-build daemon-release test-e2e docker-build docker-down
help:
@echo "SandD - Sandbox Daemon - Build Commands"
@echo ""
@echo " make build - Build Python package (debug mode)"
@echo " make install - Install Python package locally"
@echo " make dev - Install in development mode with hot reload"
@echo " make test - Run unit and integration tests (fast, no Docker)"
@echo " make test-e2e - Run end-to-end tests with Docker (slow)"
@echo " make daemon-build - Build daemon binary (debug)"
@echo " make daemon-release - Build daemon binary (release)"
@echo " make docker-build - Build Docker image for daemon"
@echo " make docker-down - Stop and remove Docker containers"
@echo " make clean - Clean build artifacts"
build: $(MATURIN)
$(MATURIN) build -m server/Cargo.toml
release: $(MATURIN)
$(MATURIN) develop --release -m server/Cargo.toml
dev: $(MATURIN)
$(MATURIN) develop -m server/Cargo.toml
test: lint $(PYTEST) dev
@echo "Running Rust tests (daemon)..."
cargo test --package sandd
@echo ""
@echo "Running Rust tests (server protocol)..."
cargo test --package sandbox-server --lib
@echo ""
@echo "Running Python tests (excluding e2e)..."
$(PYTEST) python/tests/ -m "not e2e"
daemon-build:
cargo build --package sandd
daemon-release:
cargo build --package sandd --release
@echo ""
@echo "SandD binary built at: ./target/release/sandd"
clean:
cargo clean
rm -rf target/
rm -rf python/sandd.egg-info/
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
test-e2e: $(PYTEST) dev
@echo "Building Docker images..."
docker compose -f hack/docker/docker-compose.e2e.yml build
@echo ""
@echo "Running E2E tests with Docker..."
$(PYTEST) python/tests/ -m e2e -v -s
@echo ""
@echo "Cleaning up containers..."
docker compose -f hack/docker/docker-compose.e2e.yml down
docker-build:
docker compose -f hack/docker/docker-compose.e2e.yml build
docker-up:
docker compose -f hack/docker/docker-compose.e2e.yml up -d
docker-down:
docker compose -f hack/docker/docker-compose.e2e.yml down
.PHONY: lint
lint: $(RUFF)
$(RUFF) check .
# `check --fix` exits non-zero when unfixable errors remain, which would stop
# make before the formatter runs -- hence the leading `-`. `make lint` is what
# gates on remaining errors.
.PHONY: format
format: $(RUFF)
-$(RUFF) check --fix .
$(RUFF) format .
$(RUFF):
@echo "Installing ruff..."
@python3 -m venv .venv || true
@.venv/bin/pip install --quiet '$(RUFF_VERSION)'
@echo "Ruff installed successfully"
$(PYTEST):
@echo "Installing pytest..."
@python3 -m venv .venv || true
@.venv/bin/pip install --quiet pytest pytest-asyncio
@echo "Pytest installed successfully"
$(MATURIN):
@echo "Installing maturin..."
@python3 -m venv .venv || true
@.venv/bin/pip install --quiet maturin
@echo "Maturin installed successfully"
.PHONY: build-wheels build-wheels-local build-wheels-linux publish-pypi
# Build wheel for current platform only
build-wheels-local: $(MATURIN)
@echo "Building wheel for current platform..."
$(MATURIN) build --release -m server/Cargo.toml
# Build Linux wheels using Docker
build-wheels-linux:
@echo "Building Linux wheels using Docker..."
@command -v docker >/dev/null 2>&1 || { echo "Error: Docker not found"; exit 1; }
@echo "Building for Linux x86_64..."
docker run --rm --platform linux/amd64 -v $$(pwd):/io ghcr.io/pyo3/maturin build --release -m /io/server/Cargo.toml
@echo "Building for Linux aarch64..."
docker run --rm --platform linux/arm64 -v $$(pwd):/io ghcr.io/pyo3/maturin build --release -m /io/server/Cargo.toml
# Build all wheels (local + Linux if Docker available)
build-wheels: build-wheels-local build-wheels-linux
# Upload wheels to PyPI
publish-pypi: $(MATURIN) build-wheels
@if [ -z "$(INFTYAI_PYPI_TOKEN)" ]; then \
echo "Error: INFTYAI_PYPI_TOKEN environment variable not set"; \
exit 1; \
fi
@if [ ! -d "target/wheels" ] || [ -z "$$(ls -A target/wheels/*.whl 2>/dev/null)" ]; then \
echo "Error: No wheels found. Run 'make build-wheels' first"; \
exit 1; \
fi
@echo "Uploading wheels to PyPI..."
@ls target/wheels/*.whl
$(MATURIN) upload target/wheels/*.whl --skip-existing --username __token__ --password $(INFTYAI_PYPI_TOKEN)
# Publish one crate unless that exact version is already on crates.io. cargo has
# no --skip-existing, and crates.io is append-only, so reruns of a partially
# completed release would otherwise fail. Args: $(1) crate name, $(2) manifest dir,
# $(3) index path (see https://doc.rust-lang.org/cargo/reference/registry-index.html).
# grep -F keeps the dots in a version literal rather than regex wildcards; the
# trailing comma anchors the field so 0.0.1 can't match inside 0.0.10.
define publish_crate_once
@VER=$$(grep -m1 '^version' $(2)/Cargo.toml | cut -d'"' -f2); \
if curl -sf "https://index.crates.io/$(3)" 2>/dev/null \
| grep -qF "\"vers\":\"$$VER\","; then \
echo "$(1) $$VER already on crates.io; skipping."; \
else \
echo "Publishing $(1) $$VER to crates.io..."; \
cargo publish --package $(1); \
fi
endef
.PHONY: publish-crate
# Publish the daemon to crates.io. sandd-protocol must go first: cargo strips the
# `path` dependency on publish and resolves it from the registry instead, so the
# protocol crate has to already be there.
publish-crate:
$(call publish_crate_once,sandd-protocol,protocol,sa/nd/sandd-protocol)
$(call publish_crate_once,sandd,sandd,sa/nd/sandd)
.PHONY: publish-crate-dry
# Same ordering, no uploads -- use this to validate manifests before a release.
publish-crate-dry:
cargo publish --package sandd-protocol --dry-run
@echo "NOTE: 'cargo publish --package sandd --dry-run' cannot succeed until"
@echo " sandd-protocol is actually on crates.io."
.PHONY: publish
# Publish everything: crates.io first, then PyPI.
publish: publish-crate publish-pypi
.PHONY: benchmark
benchmark: $(MATURIN)
@echo "Running benchmarks for sandd daemon..."
@echo ""
cargo bench --package sandd
.PHONY: benchmark-results
benchmark-results:
@echo "Benchmark results for sandd daemon:"
@echo ""
open target/criterion/report/index.html