-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
367 lines (289 loc) · 13.4 KB
/
Makefile
File metadata and controls
367 lines (289 loc) · 13.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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
SHELL := /bin/bash
# =============================================================================
# Variables
# =============================================================================
.DEFAULT_GOAL:=help
.ONESHELL:
USING_UV = $(shell grep "tool.uv" pyproject.toml && echo "yes")
VENV_EXISTS = $(shell python3 -c "if __import__('pathlib').Path('.venv/bin/activate').exists(): print('yes')")
UV_OPTS ?=
UV ?= uv $(UV_OPTS)
.EXPORT_ALL_VARIABLES:
.PHONY: help upgrade install-prek install
.PHONY: fmt-fix test coverage check-all lint fmt-check
.PHONY: docs-install docs-clean docs-serve docs-build
.PHONY: clean run-dev-frontend run-dev-server production develop destroy
.PHONY: docker-up docker-down docker-logs docker-shell-api docker-shell-bot docker-ps
.PHONY: docker-restart docker-rebuild infra-up infra-down
.PHONY: worktree worktree-prune
.PHONY: act-list act-ci act-cd act-docs-preview
help: ## Display this help text for Makefile
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
##@ Setup & Installation
upgrade: ## Upgrade all dependencies to the latest stable versions
@echo "=> Upgrading prek"
@$(UV) run prek autoupdate
@if [ "$(USING_UV)" ]; then $(UV) lock --upgrade
@echo "Dependencies Updated"
# =============================================================================
# Developer Utils
# =============================================================================
install-uv: ## Install latest version of UV
@echo "=> Installing uv"
@curl -LsSf https://astral.sh/uv/install.sh | sh
@echo "=> uv installed"
install-prek: ## Install prek and install hooks
@echo "Installing prek hooks"
@$(UV) run prek install
@$(UV) run prek install --hook-type commit-msg
@$(UV) run prek install --hook-type pre-push
@echo "=> prek hooks installed"
@$(UV) run prek autoupdate
@echo "prek installed"
.PHONY: install-frontend
install-frontend: ## Install the frontend dependencies
@echo "=> Installing frontend dependencies"
@bunenv --python-virtualenv --bun=latest
@bun install
@echo "=> Frontend dependencies installed"
.PHONY: install-backend
install-backend: ## Install the backend dependencies
@echo "=> Installing backend dependencies"
@$(UV) venv && $(UV) pip install --quiet -U wheel setuptools cython pip
@$(UV) sync --all-extras --force-reinstall --dev
@echo "=> Backend dependencies installed"
.PHONY: install
install: clean destroy ## Install the project, dependencies, and prek for local development
@if ! $(UV) --version > /dev/null; then $(MAKE) install-uv; fi
@$(MAKE) install-backend
@$(MAKE) install-frontend
@echo "=> Install complete! Note: If you want to re-install re-run 'make install'"
up-container: ## Start the Byte database container
@echo "=> Starting Byte database container"
@docker compose -f docker-compose.infra.yml up -d
@echo "=> Started Byte database container"
clean-container: ## Stop, remove, and wipe the Byte database container, volume, network, and orphans
@echo "=> Stopping and removing Byte database container, volumes, networks, and orphans"
@docker compose -f docker-compose.infra.yml down -v --remove-orphans
@echo "=> Stopped and removed Byte database container, volumes, networks, and orphans"
load-container: up-container migrate ## Perform database migrations and load test data into the Byte database container
@echo "=> Loading database migrations and test data"
@cd services/api && $(UV) run python -m byte_api.scripts.migrate
@echo "rest not yet implemented"
@echo "=> Loaded database migrations and test data"
refresh-container: clean-container up-container load-container ## Refresh the Byte database container
# =============================================================================
# Tests, Linting, Coverage
# =============================================================================
##@ Code Quality
lint: ## Runs prek hooks; includes ruff linting, codespell, biome
@$(UV) run --no-sync prek run --all-files
fmt-check: ## Runs Ruff format in check mode (no changes)
@$(UV) run --no-sync ruff format --check .
fmt: ## Runs Ruff format, makes changes where necessary
@$(UV) run --no-sync ruff format .
ruff: ## Runs Ruff
@$(UV) run --no-sync ruff check . --unsafe-fixes --fix
ruff-check: ## Runs Ruff without changing files
@$(UV) run --no-sync ruff check .
ruff-noqa: ## Runs Ruff, adding noqa comments to disable warnings
@$(UV) run --no-sync ruff check . --add-noqa
type-check: ## Run ty type checker
@$(UV) run --no-sync ty check
# PYTHONDONTWRITEBYTECODE is set inline for test targets to prevent .pyc generation
# during testing, which reduces I/O overhead. It's NOT set globally to avoid affecting
# dev servers, docker builds, and other targets that benefit from .pyc caching.
test: ## Run the tests
@PYTHONDONTWRITEBYTECODE=1 $(UV) run --no-sync pytest
coverage: ## Run the tests and generate coverage report
@PYTHONDONTWRITEBYTECODE=1 $(UV) run --no-sync pytest --cov=byte_bot
@PYTHONDONTWRITEBYTECODE=1 $(UV) run --no-sync coverage html
@$(UV) run --no-sync coverage xml
check-all: lint type-check fmt test ## Run all linting, formatting, and tests
ci: check-all ## Run all checks for CI
# =============================================================================
# Docs
# =============================================================================
##@ Documentation
docs-clean: ## Dump the existing built docs
@echo "=> Cleaning documentation build assets"
@rm -rf docs/_build
@echo "=> Removed existing documentation build assets"
docs-serve: docs-clean ## Serve the docs locally
@echo "=> Serving documentation"
$(UV) run sphinx-autobuild docs docs/_build/ -j auto --watch byte_bot --watch docs --watch tests --watch CONTRIBUTING.rst --port 8002
docs: docs-clean ## Dump the existing built docs and rebuild them
@echo "=> Building documentation"
@$(UV) run sphinx-build -M html docs docs/_build/ -E -a -j auto --keep-going
# =============================================================================
# Database
# =============================================================================
##@ Database Operations
migrations: ## Generate database migrations
@echo "ATTENTION: This operation will create a new database migration for any defined models changes."
@while [ -z "$$MIGRATION_MESSAGE" ]; do read -r -p "Migration message: " MIGRATION_MESSAGE; done ;
@cd services/api && $(UV) run alembic revision --autogenerate -m "$${MIGRATION_MESSAGE}"
.PHONY: migrate
migrate: ## Apply database migrations
@echo "ATTENTION: Will apply all database migrations."
@cd services/api && $(UV) run python -m byte_api.scripts.migrate
.PHONY: db
db: ## Run the database
@docker compose -f "docker-compose.infra.yml" up -d --build
# =============================================================================
# Docker Compose Commands
# =============================================================================
##@ Docker Development
.PHONY: docker-up
docker-up: ## Start all services (PostgreSQL, API, Bot) with Docker Compose
@echo "=> Starting all services with Docker Compose"
@docker compose up -d --build
@echo "=> All services started. API: http://localhost:8000"
.PHONY: docker-down
docker-down: ## Stop all Docker Compose services
@echo "=> Stopping all Docker Compose services"
@docker compose down
@echo "=> All services stopped"
.PHONY: docker-down-volumes
docker-down-volumes: ## Stop all services and remove volumes
@echo "=> Stopping all services and removing volumes"
@docker compose down -v
@echo "=> All services stopped and volumes removed"
.PHONY: docker-logs
docker-logs: ## Follow logs from all Docker Compose services
@docker compose logs -f
.PHONY: docker-logs-api
docker-logs-api: ## Follow logs from API service
@docker compose logs -f api
.PHONY: docker-logs-bot
docker-logs-bot: ## Follow logs from bot service
@docker compose logs -f bot
.PHONY: docker-logs-postgres
docker-logs-postgres: ## Follow logs from PostgreSQL service
@docker compose logs -f postgres
.PHONY: docker-shell-api
docker-shell-api: ## Open shell in API container
@docker compose exec api /bin/bash
.PHONY: docker-shell-bot
docker-shell-bot: ## Open shell in bot container
@docker compose exec bot /bin/bash
.PHONY: docker-shell-postgres
docker-shell-postgres: ## Open PostgreSQL shell
@docker compose exec postgres psql -U byte -d byte
.PHONY: docker-restart
docker-restart: ## Restart all Docker Compose services
@echo "=> Restarting all services"
@docker compose restart
@echo "=> All services restarted"
.PHONY: docker-restart-api
docker-restart-api: ## Restart API service
@docker compose restart api
.PHONY: docker-restart-bot
docker-restart-bot: ## Restart bot service
@docker compose restart bot
.PHONY: docker-ps
docker-ps: ## Show status of Docker Compose services
@docker compose ps
.PHONY: docker-rebuild
docker-rebuild: ## Rebuild and restart all services
@echo "=> Rebuilding all services"
@docker compose up -d --build --force-recreate
@echo "=> All services rebuilt and restarted"
.PHONY: infra-up
infra-up: ## Start only PostgreSQL infrastructure
@echo "=> Starting PostgreSQL infrastructure"
@docker compose -f docker-compose.infra.yml up -d
@echo "=> PostgreSQL started on localhost:5432"
.PHONY: infra-down
infra-down: ## Stop PostgreSQL infrastructure
@echo "=> Stopping PostgreSQL infrastructure"
@docker compose -f docker-compose.infra.yml down
@echo "=> PostgreSQL stopped"
# =============================================================================
# Git Worktree Management
# =============================================================================
##@ Git Worktrees
worktree: ## Create a new git worktree for feature branch (Usage: make worktree NAME=my-feature)
@echo "=> Creating git worktree"
@if [ -z "$(NAME)" ]; then \
read -p "Feature name: " name; \
else \
name="$(NAME)"; \
fi; \
if [ -z "$$name" ]; then \
echo "ERROR: Feature name cannot be empty"; \
echo "Usage: make worktree NAME=my-feature"; \
exit 1; \
fi; \
git checkout main && git pull && \
git worktree add worktrees/$$name -b feature/$$name && \
mkdir -p worktrees/$$name/.claude && \
cp .claude/settings.local.json worktrees/$$name/.claude/settings.json && \
jq '.permissions.defaultMode = "bypassPermissions"' worktrees/$$name/.claude/settings.json > worktrees/$$name/.claude/settings.json.tmp && \
mv worktrees/$$name/.claude/settings.json.tmp worktrees/$$name/.claude/settings.json && \
if [ -f .env ]; then cp .env worktrees/$$name/.env; fi && \
echo "=> Worktree created at worktrees/$$name on branch feature/$$name" && \
echo "=> Claude settings copied with bypassPermissions mode enabled" && \
if [ -f .env ]; then echo "=> Environment variables copied from .env"; fi
worktree-prune: ## Clean up stale git worktrees
@echo "=> Pruning stale git worktrees"
@git worktree prune -v
@echo "=> Stale worktrees pruned"
# =============================================================================
# GitHub Actions Local Testing (act)
# =============================================================================
##@ Local GitHub Actions
act-list: ## List all available GitHub Actions workflows
@echo "=> Available GitHub Actions workflows:"
@act -l
act-ci: ## Test CI workflow locally using act
@echo "=> Running CI workflow locally with act"
@act -j lint -j type-check -j test -j build --container-architecture linux/amd64
act-cd: ## Test CD workflow locally using act (dry-run, no push)
@echo "=> Running CD workflow locally with act (dry-run)"
@echo "NOTE: This will not actually push/release, just test the workflow"
@act -j generate-changelog --container-architecture linux/amd64
act-docs-preview: ## Test docs-preview workflow locally using act
@echo "=> Running docs-preview workflow locally with act"
@act pull_request -j build-and-deploy-docs --container-architecture linux/amd64
# =============================================================================
# Main
# =============================================================================
##@ Main
clean: ## Autogenerated File Cleanup
@echo "=> Cleaning up autogenerated files"
@rm -rf .scannerwork/
@rm -rf .pytest_cache
@rm -rf .ruff_cache
@rm -rf .hypothesis
@rm -rf build/
@rm -rf dist/
@rm -rf .eggs/
@find . -name '*.egg-info' -exec rm -rf {} +
@find . -name '*.egg' -exec rm -rf {} +
@find . -name '*.pyc' -exec rm -rf {} +
@find . -name '*.pyo' -exec rm -rf {} +
@find . -name '*~' -exec rm -rf {} +
@find . -name '__pycache__' -exec rm -rf {} +
@find . -name '.ipynb_checkpoints' -exec rm -rf {} +
@rm -rf .coverage
@rm -rf coverage.xml
@rm -rf coverage.json
@rm -rf htmlcov/
@rm -rf .pytest_cache
@rm -rf tests/.pytest_cache
@rm -rf tests/**/.pytest_cache
$(MAKE) docs-clean
destroy: ## Destroy the virtual environment
@rm -rf .venv
run-dev-bot: ## Run the bot in dev mode
@cd services/bot && $(UV) run python -m byte_bot
run-dev-server: up-container ## Run the app in dev mode
@cd services/api && LITESTAR_APP=byte_api.app:create_app $(UV) run litestar run --reload --debug
run-dev-frontend: ## Run the app frontend in dev mode
@bunx tailwindcss -i services/api/src/byte_api/domain/web/resources/input.css -o services/api/src/byte_api/domain/web/resources/style.css --watch
run-dev: up-container ## Run the bot, web, and front end in dev mode
@echo "NOTE: Run each service separately in different terminals:"
@echo " Terminal 1: make run-dev-bot"
@echo " Terminal 2: make run-dev-server"
@echo " Terminal 3: make run-dev-frontend"