-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
208 lines (163 loc) · 7.89 KB
/
Copy pathMakefile
File metadata and controls
208 lines (163 loc) · 7.89 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
.PHONY: all build test clean fmt lint lint-app lint-docs codegen codegen-proto codegen-sdk build-sdk codegen-sdk-rs build-sdk-rs check-sdk-rs app-test build-backend test-backend lint-backend
all: build
# The backend is the Elixir umbrella at elixir/ (harmont_core domain +
# harmont_api/harmont_engine/harmont_gh_app/harmont_web edges). Rust is the
# agent (agent/). The pipeline DSL (Python + TS) lives in the harmont-cli
# submodule and is built/linted/tested by its own CI (harmont-cli/.hm/ci.py).
build: codegen build-backend
cd agent && cargo build
test: app-test test-backend
cd agent && cargo test
$(MAKE) docs-test
# Skip docs-build if pnpm isn't installed locally; CI installs it via corepack.
docs-test:
@if command -v pnpm >/dev/null; then \
$(MAKE) docs-build; \
else \
echo "[docs] pnpm not installed; skipping docs-build in tests"; \
fi
# The OpenAPI spec + error catalog are generated by the Elixir umbrella. The
# committed source of truth is
# elixir/apps/harmont_api/priv/static/{openapi.json,error-catalog.json}.
# `mix api.spec` and `mix api.error_catalog` are umbrella aliases.
codegen: codegen-proto
cd elixir && mix api.spec && mix api.public_spec && mix api.error_catalog
# Regenerate the agent protobuf Elixir stubs (gitignored) from proto/agent.proto.
# `mix proto.gen` runs elixir/apps/harmont_engine/proto/gen.sh.
codegen-proto:
cd elixir && mix proto.gen
# Generate the TypeScript SDK from the committed openapi.json. The output
# (oss/harmont-cloud-sdk/src/generated) is a gitignored build artifact. Kept
# separate from `codegen` so backend codegen never requires Node.
codegen-sdk: codegen
cd oss/harmont-cloud-sdk && npm install && npm run codegen && npm run typecheck
# Build the publishable dist/ for the TypeScript SDK (codegen + tsup bundle).
.PHONY: build-sdk
build-sdk: codegen-sdk
cd oss/harmont-cloud-sdk && npm run build
# ─── Rust cloud SDK ────────────────────────────────────────────────────
# Refresh the committed spec copy and regenerate the raw (progenitor) crate.
# Requires `cargo install cargo-progenitor`. The generated src/lib.rs IS
# committed so the workspace builds without progenitor or network.
codegen-sdk-rs: codegen
cp $(ELIXIR_PRIV)/openapi.json oss/harmont-cloud-sdk-rs/openapi.json
# Sanitize: OpenApiSpex emits invalid empty `"application/json": {}` content
# objects for some 204 responses, which crash progenitor. Strip empty media
# objects. Remove once the upstream spec is fixed (tracked separately).
python3 oss/harmont-cloud-sdk-rs/scripts/sanitize-spec.py oss/harmont-cloud-sdk-rs/openapi.json
cd oss/harmont-cloud-sdk-rs && cargo progenitor \
-i openapi.json -o harmont-cloud-raw -n harmont-cloud-raw -v 0.1.0 \
--license-name MIT --include-client true
bash oss/harmont-cloud-sdk-rs/scripts/postprocess-raw.sh
check-sdk-rs:
cd oss/harmont-cloud-sdk-rs && cargo clippy --all-targets -- -D warnings && cargo test
build-sdk-rs: codegen-sdk-rs
cd oss/harmont-cloud-sdk-rs && cargo build --release
# ---- docs-site (fumadocs) ----
.PHONY: docs-install docs-generate docs-build docs-dev docs
docs-install:
cd docs-site && pnpm install --frozen-lockfile
# Source the Elixir-generated OpenAPI spec + error catalog into docs-site so the
# generator can read them without crossing package boundaries.
ELIXIR_PRIV := elixir/apps/harmont_api/priv/static
# Docs render the PUBLIC surface only (x-internal operations removed). The
# frontend still types against the full $(ELIXIR_PRIV)/openapi.json directly.
docs-site/openapi.json: $(ELIXIR_PRIV)/openapi.public.json
cp $< $@
docs-site/error-catalog.json: $(ELIXIR_PRIV)/error-catalog.json
cp $< $@
# Extract the Python DSL API via griffe. Runs inside the harmont-py package so
# `harmont` is importable; griffe is pulled ephemerally with `uv run --with`.
HARMONT_PY := harmont-cli/crates/hm-dsl-engine/harmont-py
docs-site/dsl-api.json:
cd $(HARMONT_PY) && uv run --with griffe python \
$(CURDIR)/docs-site/scripts/extract-dsl-api.py . $(CURDIR)/docs-site/dsl-api.json
# Extract the @harmont/cloud TypeScript SDK surface from the public OpenAPI
# spec (function names == operationIds). Depends on the copied openapi.json;
# the SDK codegen provides the generated client for the export cross-check.
docs-site/sdk-api.json: docs-site/openapi.json
cd oss/harmont-cloud-sdk && npm install && npm run codegen
cd docs-site && npx tsx scripts/extract-sdk-api.ts
$(ELIXIR_PRIV)/openapi.json:
cd elixir && mix api.spec
$(ELIXIR_PRIV)/openapi.public.json: $(ELIXIR_PRIV)/openapi.json
cd elixir && mix api.public_spec
$(ELIXIR_PRIV)/error-catalog.json:
cd elixir && mix api.error_catalog
# Examples were extracted to harmont-dev/harmont-cli in commit a3ade666. The
# docs Tree/RemoteCode server components read them from repoRoot()/examples;
# fetch them at the SHA pinned in docs-site/Dockerfile (keep the two in sync).
# This is a real directory target, so it fetches once; `rm -rf examples` to
# refresh.
HARMONT_CLI_SHA ?= 15b47afa0fd580e80364dbf63087060c07a7d364
examples:
@echo "[docs] fetching harmont-cli examples @ $(HARMONT_CLI_SHA)"
curl -fsSL "https://github.com/harmont-dev/harmont-cli/archive/$(HARMONT_CLI_SHA).tar.gz" \
| tar -xz --strip-components=1 "harmont-cli-$(HARMONT_CLI_SHA)/examples"
docs-generate: examples docs-site/openapi.json docs-site/error-catalog.json docs-site/dsl-api.json docs-site/sdk-api.json
cd docs-site && pnpm run generate
docs-build: docs-generate
cd docs-site && pnpm run build
# Run this in your OWN terminal -- never from an agent session.
# Picks port 4174 to avoid clashing with the frontend dev server (8765).
docs-dev: docs-generate
cd docs-site && pnpm run dev
docs: docs-build
clean:
cd elixir && mix clean
cd agent && cargo clean
rm -rf frontend/node_modules/.vite
fmt:
cd elixir && mix format
lint: lint-backend lint-app lint-docs
# The pipeline DSL (Python + TS) lives in the harmont-cli submodule and is
# linted by its own CI (harmont-cli/.hm/ci.py) — not from here. To lint it
# locally: cd harmont-cli/crates/hm-dsl-engine/harmont-py && uv run ruff check .
# The frontend is the Solid.js SPA at frontend/ (the Elm app/ was retired).
# Type-checking is the lint gate; there is no separate JS test suite.
lint-app:
@command -v npx >/dev/null || (echo "[lint-app] npx not on PATH; install Node >=18 (e.g. via fnm or nvm)" && exit 1)
cd frontend && npx tsc --noEmit
# Docs hygiene: fail if any hand-written doc references a toolchain the DSL
# no longer ships (derived from harmont-py __all__).
lint-docs:
@python3 scripts/check_docs_toolchains.py
# Development services
.PHONY: services services-down
services:
docker compose up -d
services-down:
docker compose down
# Local development
#
# The full local stack (postgres + Elixir backend + frontend) is brought up by
# scripts/dev-up.sh — run it in your OWN terminal, never from an agent session.
.PHONY: dev dev-seed dev-app dev-down
dev:
@echo "Local dev: run scripts/dev-up.sh in your own terminal."
@echo "It brings up postgres + the Elixir backend + the frontend in one shot."
@echo ""
@echo "Helpers:"
@echo " make dev-seed (one-time: creates user, org, sample data)"
@echo " make dev-down (tear everything down)"
dev-seed:
./scripts/dev-seed.sh
dev-app:
cd frontend && npm run dev
dev-down:
docker compose down
rm -f .hm-dev-env
# No JS unit-test suite; the production build (codegen + type-check + bundle) is
# the meaningful "does the frontend still work" check.
app-test:
@command -v npx >/dev/null || (echo "[app-test] npx not on PATH; install Node >=18" && exit 1)
cd frontend && npm run build
# Elixir umbrella (the backend)
# The agent proto stubs (gitignored) are regenerated from proto/agent.proto by
# `mix proto.gen` — must run before mix compile on a clean checkout.
build-backend:
cd elixir && mix deps.get && mix proto.gen && mix compile
test-backend:
cd elixir && mix test
lint-backend:
cd elixir && mix lint