-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
242 lines (177 loc) · 10.9 KB
/
Makefile
File metadata and controls
242 lines (177 loc) · 10.9 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
# BESSAI Edge Gateway — Developer Makefile
# Usage: make <target> → make help for full list
.PHONY: help dev install setup onboard test test-cov test-compliance test-fast lint lint-fix type-check security audit \
all-checks simulate health up up-sim down logs build \
gen-onnx export-cmg fetch-cmg evolve train-drl train-ppo \
cert pilot compliance-report fleet \
validate-registry tf-plan helm-lint helm-template \
docs docs-serve \
changelog release-dry-run release publish-pypi \
consolidate consolidate-quick \
clean
PYTHON ?= python
COMPOSE = docker compose
VERSION ?= $(shell git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
SITE_ID ?= SITE-CL-001
PORT ?= 8000
# ── Help ───────────────────────────────────────────────────────────────────────
help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-22s\033[0m %s\n", $$1, $$2}'
# ── Development ────────────────────────────────────────────────────────────────
dev: ## Install all dev dependencies + pre-commit hooks + security hooks
pip install -e ".[dev]"
pre-commit install
git config core.hooksPath .githooks
@echo "✅ Dev environment ready (PI hooks active). Run: make simulate"
install: ## Install runtime dependencies only
pip install -e "."
setup: ## Interactive setup — generate config/.env for your site (5 questions)
@bash scripts/setup.sh
onboard: setup ## Full onboarding: generate config/.env + activate PI hooks + verify Docker
@bash scripts/install_hooks.sh
@echo ""
@echo "✅ config/.env generated and PI hooks active."
@echo "📖 Next step: make up-sim → demo local con simulador"
@echo "📖 Full guide: docs/ONBOARDING_7DAYS.md"
# ── Testing ────────────────────────────────────────────────────────────────────
test: ## Run full test suite (compliance + edge)
pytest -x --tb=short -q \
--ignore=tests/agents/ \
--ignore=tests/test_sun2000_monitor.py \
--ignore=tests/test_totp_auth.py \
--ignore=tests/test_vpp_publisher.py
test-compliance: ## NTSyCS compliance tests only (11 GAPs) — v2.14.0
pytest \
tests/test_compliance_api.py \
tests/test_cen_sc_bidder.py \
tests/test_ppo_trainer.py \
tests/test_cen_publisher.py \
tests/test_iec104_driver.py \
-v --tb=short
test-cov: ## Run tests with HTML coverage report → htmlcov/index.html
pytest --cov=src --cov-report=term-missing --cov-report=html -q
test-fast: ## Run tests excluding slow integration tests
pytest -x --tb=short -q -m "not slow"
# ── Code Quality ───────────────────────────────────────────────────────────────
lint: ## Ruff linter + formatter check (no changes)
ruff check src/ tests/
ruff format --check src/ tests/
lint-fix: ## Auto-fix all ruff issues
ruff check --fix src/ tests/
ruff format src/ tests/
type-check: ## mypy strict type checking
mypy src/
security: ## bandit security scan
bandit -r src/ -ll -x tests/
audit: ## pip-audit CVE scan against requirements.txt
pip-audit --requirement requirements.txt --vulnerability-service=osv
all-checks: lint type-check security test ## Run all quality checks (CI equivalent)
# ── Runtime ────────────────────────────────────────────────────────────────────
simulate: ## Run gateway with built-in Modbus simulator (no real hardware needed)
$(PYTHON) -m src.gateway --simulator
@echo "Simulator running. Health: http://localhost:8000/health"
health: ## Check all subsystem health (requires running instance)
@curl -s http://localhost:8000/health | python -m json.tool || echo "Gateway not running"
# ── Docker ─────────────────────────────────────────────────────────────────────
up: ## Start gateway + Prometheus + Grafana
$(COMPOSE) --profile monitoring up -d
@echo "Gateway: http://localhost:8000/health"
@echo "Grafana: http://localhost:3000 (admin / see GF_SECURITY_ADMIN_PASSWORD in config/.env)"
@echo "Prometheus: http://localhost:9090"
up-sim: ## Start gateway + simulator + full monitoring stack
$(COMPOSE) --profile simulator --profile monitoring up -d
@echo "Simulator on port 5020 (Modbus TCP)"
down: ## Stop all containers
$(COMPOSE) --profile simulator --profile monitoring down
logs: ## Follow gateway logs in real-time
$(COMPOSE) logs -f bessai-edge
build: ## Build Docker image locally for current platform
docker build -t bessai-edge:local .
# ── AI / BESSAIEvolve ─────────────────────────────────────────────────────────
scrape: ## Run full multi-source data scraper (CMg, ERNC, demand, weather, frequency)
$(PYTHON) scripts/bessai_data_scraper.py --days 30 --sources all
scrape-status: ## Show status of all locally cached data sources
$(PYTHON) scripts/bessai_data_scraper.py --status
fetch-cmg: scrape ## Alias for scrape (backwards compat)
evolve: ## Run BESSAIEvolve locally (manual trigger — reads parquet data if available)
$(PYTHON) -m src.agents.bessai_evolve --generations 5 --population 10 --eval-days 30
@echo "Results in models/evolution/"
gen-onnx: ## Generate dummy ONNX model for local testing
$(PYTHON) scripts/generate_dummy_onnx.py
export-cmg: ## Export CMg data as JSON for dashboard
$(PYTHON) scripts/export_cmg_json.py
train-drl: ## Train DRL policy (requires ray[rllib] + real CMg data)
$(PYTHON) scripts/train_drl_policy.py
train-ppo: ## BEP-0200 Phase 3: Train PPO dispatch agent (500k steps)
@mkdir -p models logs/ppo_training
$(PYTHON) -c "\
from src.core.ppo_trainer import PPOTrainer, TrainingConfig; \
cfg = TrainingConfig(total_timesteps=500_000); \
t = PPOTrainer(site_id='$(SITE_ID)', data_path='data/cen_telemetry.csv', config=cfg); \
r = t.train(); print(f'BEP-0200 Phase 3 done: {r.total_timesteps} steps, reward={r.final_mean_reward:.3f}')"
cert: ## Generate mTLS certs for CEN (SITE_ID=SITE-CL-001)
bash infrastructure/certs/gen_certs.sh $(SITE_ID)
pilot: ## Validate pilot site readiness (runs pilot_setup.py wizard)
$(PYTHON) scripts/pilot_setup.py --site-id $(SITE_ID)
compliance-report: ## Fetch compliance report from running gateway
curl -sf http://localhost:$(PORT)/compliance/report | python -m json.tool
fleet: ## Fleet VPP summary from running gateway
curl -sf http://localhost:$(PORT)/fleet/summary | python -m json.tool
# ── Hardware Registry ──────────────────────────────────────────────────────────
validate-registry: ## Validate all hardware registry JSON profiles against schema
$(PYTHON) -c "\
import json, glob, sys; \
errors = []; \
[errors.append(f) if not json.load(open(f)) else print(f'✅ {f}') \
for f in glob.glob('registry/*.json')]; \
sys.exit(1 if errors else 0)"
# ── Infrastructure ─────────────────────────────────────────────────────────────
tf-plan: ## Terraform plan (GCP) — dry run
cd infrastructure/terraform && terraform plan
helm-lint: ## Lint Helm chart
helm lint infrastructure/helm/bessai-edge/
helm-template: ## Render Helm templates to stdout
helm template bessai-edge infrastructure/helm/bessai-edge/
# ── Documentation ──────────────────────────────────────────────────────────────
docs: ## Build MkDocs documentation (HTML)
mkdocs build --strict
docs-serve: ## Serve docs locally with live reload → http://localhost:8080
mkdocs serve --dev-addr 0.0.0.0:8080
# ── Release ────────────────────────────────────────────────────────────────────
changelog: ## Preview changelog for unreleased changes (requires git-cliff)
git cliff --unreleased 2>/dev/null || echo "Install: pip install git-cliff"
release-dry-run: ## Simulate release without creating tag or publishing
@echo "Current version: $(VERSION)"
@echo "--- CHANGELOG preview ---"
@git log --oneline $(VERSION)..HEAD --no-walk=unsorted 2>/dev/null | head -20 || true
@echo "--- Build check ---"
$(PYTHON) -m build --no-isolation --outdir /tmp/bessai-dist-dry/ 2>&1 | tail -5
@echo "✅ Dry run complete. Use: make release VERSION=vX.Y.Z"
release: ## Create and push a release tag (usage: make release VERSION=v2.11.0)
@test -n "$(VERSION)" || (echo "Usage: make release VERSION=vX.Y.Z" && exit 1)
@echo "Tagging $(VERSION)..."
git tag -a $(VERSION) -m "Release $(VERSION)"
git push origin $(VERSION)
@echo "✅ Tag pushed. GitHub Actions will create the GitHub Release."
@echo " For PyPI: make publish-pypi"
publish-pypi: ## Build and publish to PyPI via Trusted Publisher (OIDC)
$(PYTHON) -m build
$(PYTHON) -m twine upload --repository pypi dist/*
@echo "✅ Published to PyPI. See: https://pypi.org/project/bessai-edge/"
# ── Utilities ──────────────────────────────────────────────────────────────────
clean: ## Remove build artifacts, caches, and temp files
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
find . -type f -name "*.pyc" -delete
rm -rf .pytest_cache .mypy_cache .ruff_cache htmlcov dist build *.egg-info
rm -rf /tmp/bessai-dist-dry/
@echo "[OK] Clean complete"
# -- Consolidation -------------------------------------------------------------
consolidate: ## Generate full project consolidation report (with live tests ~90s)
@echo "Generating CONSOLIDATION.md (live tests)..."
@PYTHONIOENCODING=utf-8 $(PYTHON) scripts/consolidate.py --out CONSOLIDATION.md
@echo "[OK] Informe disponible: CONSOLIDATION.md"
consolidate-quick: ## Generate consolidation report WITHOUT running tests (5s)
@echo "Generating CONSOLIDATION.md (skip tests)..."
@PYTHONIOENCODING=utf-8 $(PYTHON) scripts/consolidate.py --out CONSOLIDATION.md --no-tests
@echo "[OK] Informe rapido disponible: CONSOLIDATION.md"