Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 920fcd6a1a | |||
| bd8a7da379 |
+94
-11
@@ -1,7 +1,9 @@
|
||||
# Runs on pull requests: unit tests plus a compile check.
|
||||
# Split into separate jobs (Odin, API, Infra) so they can run concurrently,
|
||||
# and gated by changed paths so each only runs when its code changes.
|
||||
# Infra always runs regardless of what changed.
|
||||
# Infra always runs (unit tests + vet) regardless of what changed; its Pulumi
|
||||
# preview (posted as a PR comment) runs when the infra, gui, or api code
|
||||
# changed, since any of those can change what gets deployed.
|
||||
|
||||
name: CI
|
||||
|
||||
@@ -28,18 +30,31 @@ jobs:
|
||||
outputs:
|
||||
odin: ${{ steps.filter.outputs.odin }}
|
||||
api: ${{ steps.filter.outputs.api }}
|
||||
infra: ${{ steps.filter.outputs.infra }}
|
||||
preview: ${{ steps.decide.outputs.run }}
|
||||
steps:
|
||||
- uses: dorny/paths-filter@v4
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
odin:
|
||||
- 'src/**'
|
||||
- 'lib/**'
|
||||
- 'gui/**'
|
||||
- 'scripts/**'
|
||||
- 'odinfmt.json'
|
||||
api:
|
||||
- 'api/**'
|
||||
infra:
|
||||
- 'infra/**'
|
||||
|
||||
- name: Decide whether to run the infra preview
|
||||
id: decide
|
||||
run: |
|
||||
if [ "${{ steps.filter.outputs.infra }}" = "true" ] || \
|
||||
[ "${{ steps.filter.outputs.odin }}" = "true" ] || \
|
||||
[ "${{ steps.filter.outputs.api }}" = "true" ]; then
|
||||
echo "run=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "run=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
odin:
|
||||
name: Odin unit tests and build
|
||||
@@ -65,14 +80,10 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Run Odin unit tests
|
||||
run: |
|
||||
mkdir -p lib/local
|
||||
odin test src -collection:lib=lib/local
|
||||
run: make -C gui test
|
||||
|
||||
- name: Verify build
|
||||
run: |
|
||||
mkdir -p bin
|
||||
odin build src -collection:lib=lib/local -o:speed -out:bin/desi_explorer
|
||||
run: make -C gui build
|
||||
|
||||
api:
|
||||
name: API unit tests and lint
|
||||
@@ -103,8 +114,13 @@ jobs:
|
||||
cargo fmt --all --check
|
||||
|
||||
infra:
|
||||
name: Infra unit tests and vet
|
||||
name: Infra unit tests, vet, and preview
|
||||
needs: changes
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
@@ -124,3 +140,70 @@ jobs:
|
||||
run: |
|
||||
cd infra
|
||||
go vet ./...
|
||||
|
||||
# Pulumi CLI. State uses the local file backend (infra/Pulumi.yaml ->
|
||||
# file://~/.pulumi), so no Pulumi Cloud token is needed. Preview diffs
|
||||
# the current source against the last-known stack state; on an ephemeral
|
||||
# runner the self-hosted environment must persist ~/.pulumi to get a
|
||||
# meaningful diff (otherwise preview shows the pending creates).
|
||||
- name: Install Pulumi
|
||||
if: ${{ needs.changes.outputs.preview == 'true' }}
|
||||
run: |
|
||||
curl -fsSL https://get.pulumi.com | sh
|
||||
echo "$HOME/.pulumi/bin" >> "$GITHUB_PATH"
|
||||
|
||||
# The runner must reach the on-prem k3s cluster for preview to diff
|
||||
# against live state. For a self-hosted runner this is the ambient
|
||||
# kubeconfig; otherwise populate it from the KUBECONFIG secret here.
|
||||
- name: Configure kubeconfig
|
||||
if: ${{ needs.changes.outputs.preview == 'true' }}
|
||||
run: |
|
||||
mkdir -p "$HOME/.kube"
|
||||
if [ -n "$KUBECONFIG_B64" ]; then
|
||||
printf '%s' "$KUBECONFIG_B64" | base64 -d > "$HOME/.kube/config"
|
||||
fi
|
||||
env:
|
||||
KUBECONFIG_B64: ${{ secrets.KUBECONFIG }}
|
||||
|
||||
- name: Pulumi preview
|
||||
if: ${{ needs.changes.outputs.preview == 'true' }}
|
||||
working-directory: infra
|
||||
env:
|
||||
PULUMI_SKIP_UPDATE_CHECK: 'true'
|
||||
run: |
|
||||
go mod download
|
||||
pulumi preview --diff 2>&1 | tee /tmp/pulumi-preview.txt || true
|
||||
|
||||
- name: Comment preview on PR
|
||||
if: ${{ needs.changes.outputs.preview == 'true' }}
|
||||
env:
|
||||
GITEA_API: ${{ gitea.api_url }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
TOKEN: ${{ github.token }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
run: |
|
||||
python3 - <<'PY'
|
||||
import json, os, urllib.request
|
||||
|
||||
with open('/tmp/pulumi-preview.txt') as f:
|
||||
preview = f.read().strip() or '(no changes)'
|
||||
|
||||
body = "### Pulumi preview\n\n```\n" + preview + "\n```"
|
||||
payload = json.dumps({"body": body}).encode()
|
||||
|
||||
url = (
|
||||
f"{os.environ['GITEA_API']}/repos/{os.environ['REPO']}"
|
||||
f"/issues/{os.environ['PR_NUMBER']}/comments"
|
||||
)
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
data=payload,
|
||||
method='POST',
|
||||
headers={
|
||||
'Authorization': f"token {os.environ['TOKEN']}",
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
)
|
||||
urllib.request.urlopen(req)
|
||||
print('Posted Pulumi preview comment')
|
||||
PY
|
||||
|
||||
@@ -53,10 +53,8 @@ jobs:
|
||||
base: ${{ steps.prev.outputs.prev }}
|
||||
filters: |
|
||||
odin:
|
||||
- 'src/**'
|
||||
- 'lib/**'
|
||||
- 'gui/**'
|
||||
- 'scripts/**'
|
||||
- 'odinfmt.json'
|
||||
api:
|
||||
- 'api/**'
|
||||
infra:
|
||||
@@ -84,7 +82,7 @@ jobs:
|
||||
- name: Build WebAssembly
|
||||
run: |
|
||||
source /tmp/emsdk/emsdk_env.sh
|
||||
scripts/build_web.sh
|
||||
gui/scripts/build_web.sh
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
|
||||
@@ -49,8 +49,8 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p lib/local build/linux
|
||||
odin build src -o:speed -collection:lib=lib/local -out:build/linux/desi_explorer
|
||||
mkdir -p build/linux
|
||||
odin build gui/src -o:speed -collection:lib=gui/lib/local -out:build/linux/desi_explorer
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
@@ -110,10 +110,10 @@ jobs:
|
||||
# next to desi_explorer.exe.
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir -p lib/local build/windows
|
||||
odin build src -target:windows_amd64 -build-mode:obj \
|
||||
mkdir -p build/windows
|
||||
odin build gui/src -target:windows_amd64 -build-mode:obj \
|
||||
-define:RAYLIB_SHARED=true -o:speed \
|
||||
-collection:lib=lib/local -out:build/windows/desi_explorer
|
||||
-collection:lib=gui/lib/local -out:build/windows/desi_explorer
|
||||
x86_64-w64-mingw32-gcc -O2 -o build/windows/desi_explorer.exe \
|
||||
build/windows/desi_explorer.obj \
|
||||
/tmp/odin-win/dist/vendor/raylib/windows/raylibdll.lib \
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
- name: Build WebAssembly
|
||||
run: |
|
||||
source /tmp/emsdk/emsdk_env.sh
|
||||
scripts/build_web.sh
|
||||
gui/scripts/build_web.sh
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
|
||||
@@ -2,27 +2,28 @@
|
||||
|
||||
Odin + raylib interactive 3D universe map (DESI data), a Rust + axum API, with Go + Pulumi infra and Gitea Actions CI. A clean `odin build` + `cargo test` + `go test` is the verification step.
|
||||
|
||||
## Commands (root Makefile)
|
||||
- Run: `make run` (`odin run src`); Build: `make build` (`odin build src -collection:lib=lib/local -out:bin/desi_explorer`)
|
||||
- Web: `make build-web` (Emscripten/WASM -> build/web); Debug: `make build-debug`
|
||||
- Test: `make test` (runs `odin test` for src/, `go test` for infra/, and `cargo test` for api/); Clean: `make clean`
|
||||
- API: `make api-run` (`cargo run` in api/), `make api-test`, `make api-check` (`cargo fmt --check` + `clippy -D warnings`)
|
||||
## Commands
|
||||
The root `Makefile` is a lean delegator: base commands (`run`, `build`, `test`, ...) forward into the per-project Makefiles in `gui/`, `api/`, and `infra/`. Project-specific commands are reached via `make -C <dir> <target>`.
|
||||
- Run: `make run`; Build: `make build` (`-> bin/desi_explorer`); Web: `make build-web` (Emscripten/WASM -> `build/web`); Debug: `make build-debug`
|
||||
- Test: `make test` (runs `odin test` in gui/, `cargo test` in api/, `go test` in infra/); Clean: `make clean`; Format: `make fmt`
|
||||
- API: `make api-run`, `make api-test`, `make api-check` (thin passthroughs to `make -C api <target>`)
|
||||
- Setup: `make setup` (submodules + `go mod tidy` in infra/)
|
||||
- Infra: `make infra-preview`, `make infra-up`, `make infra-down`, `make infra-refresh` (Pulumi, `--cwd infra`)
|
||||
- Infra: `make infra-preview`, `make infra-up`, `make infra-down`, `make infra-refresh` (passthroughs to `make -C infra <target>`)
|
||||
- Renovate: `make renovate-validate` (npx renovate-config-validator)
|
||||
- Format Odin with `odinfmt` (config `odinfmt.json`: tabs, width 80); format Rust with `cargo fmt`
|
||||
- Format Odin with `odinfmt` (config `gui/odinfmt.json`: tabs, width 80); format Rust with `cargo fmt`
|
||||
|
||||
## Layout
|
||||
- `src/main.odin` — entrypoint; loop is `update()` → `draw()`; resizable window with an orbital `Camera3D`; point cloud generated procedurally in `make_universe`.
|
||||
- `lib/` — third-party Odin deps (submodules / vendored libs). raylib is **not** here: it ships vendored with Odin and is imported as `vendor:raylib`. `lib/local/` is the default `-collection:lib` target and is currently empty.
|
||||
- `api/` — Rust + axum backend API that will serve DESI catalog data. `src/lib.rs` exposes `routes`/`models`/`config`; `src/main.rs` is the server entrypoint (binds `API_BIND_ADDR`, default `0.0.0.0:8080`). Crate name is `desi-explorer-api` (lib `desi_explorer_api`); Rust version pinned in `api/rust-toolchain.toml`.
|
||||
- `infra/` — Go + Pulumi (`runtime: go`) targeting the on-prem k3s cluster via the default kubeconfig, mirroring the `homelab` repo's pattern. Module name is `desi-explorer-infra`.
|
||||
- `.gitea/workflows/` — `ci.yml` (PR: install Odin, Rust, `odin test` + build, `cargo test` + clippy, `go test`) and `release.yml` (tag `v*`: build native + WASM + publish a Gitea release).
|
||||
- `gui/` — the Odin + raylib renderer. `gui/src/main.odin` is the entrypoint (loop is `update()` → `draw()`; resizable window with an orbital `Camera3D`; point cloud generated procedurally in `make_universe`). `gui/lib/` holds third-party Odin deps (see below), `gui/www/` the Web GUI (WASM shell / static web assets), and `gui/scripts/` the build scripts. `gui/Makefile` owns the Odin targets.
|
||||
- `gui/lib/` — third-party Odin deps (submodules / vendored libs). raylib is **not** here: it ships vendored with Odin and is imported as `vendor:raylib`. `gui/lib/local/` is the default `-collection:lib` target and is currently empty.
|
||||
- `api/` — Rust + axum backend API that will serve DESI catalog data. `src/lib.rs` exposes `routes`/`models`/`config`; `src/main.rs` is the server entrypoint (binds `API_BIND_ADDR`, default `0.0.0.0:8080`). Crate name is `desi-explorer-api` (lib `desi_explorer_api`); Rust version pinned in `api/rust-toolchain.toml`. `api/Makefile` owns the Rust targets.
|
||||
- `infra/` — Go + Pulumi (`runtime: go`) targeting the on-prem k3s cluster via the default kubeconfig, mirroring the `homelab` repo's pattern. Module name is `desi-explorer-infra`. `infra/Makefile` owns the Pulumi/Go targets.
|
||||
- `scripts/` — repo-level build helpers (Odin toolchain install).
|
||||
- `.gitea/workflows/` — `ci.yml` (PR: `odin test` + build, `cargo test` + clippy, `go test` + vet; infra always runs tests/vet and posts a `pulumi preview --diff` as a PR comment when infra/gui/api changed) and `release.yml` (tag `v*`: build native + WASM + publish a Gitea release).
|
||||
|
||||
## Conventions
|
||||
- Odin code lives in `src/`; external deps go in `lib/` and are wired via `-collection:lib=lib/local` (or a git submodule imported by relative path).
|
||||
- Odin code lives in `gui/src/`; external deps go in `gui/lib/` and are wired via `-collection:lib=lib/local` (or a git submodule imported by relative path).
|
||||
- Everything is plain `make` — no Taskfile — so CI (Gitea Actions) can call `make` directly.
|
||||
- Keep the renderer (src/), API (api/), and infra (infra/) logically separated; the root Makefile is the only place that ties them together.
|
||||
- Keep the renderer (gui/), API (api/), and infra (infra/) logically separated; each owns its own Makefile, and the root Makefile is the only place that ties them together.
|
||||
|
||||
## Gotchas
|
||||
- Odin version is pinned in `.gitea/workflows/*.yml` (`ODIN_VERSION`) and defaults in `scripts/install_odin.sh`; bump both together when tracking a new release.
|
||||
|
||||
@@ -1,94 +1,69 @@
|
||||
# DESI Explorer — root Makefile
|
||||
#
|
||||
# Orchestrates the Odin renderer (src/) and the Go/Pulumi infrastructure
|
||||
# (infra/). Intended to be called directly by Gitea Actions CI.
|
||||
# Lean orchestrator: the "base" commands (`run`, `build`, `test`, ...) delegate
|
||||
# into the per-project Makefiles in `gui/`, `api/`, and `infra/`. Project-
|
||||
# specific commands live in those directories and are reached with
|
||||
# `make -C <dir> <target>` (or the thin passthrough targets below).
|
||||
|
||||
ODIN ?= odin
|
||||
CARGO ?= cargo
|
||||
BIN ?= bin
|
||||
BINARY := $(BIN)/desi_explorer
|
||||
ODIN_FLAGS := -collection:lib=lib/local
|
||||
WASM_DEFINE := RAYLIB_WASM_LIB=env.o
|
||||
GUI := gui
|
||||
API := api
|
||||
INFRA := infra
|
||||
|
||||
.PHONY: help setup run build build-debug build-web test clean fmt \
|
||||
api-run api-build api-test api-check api-fmt \
|
||||
infra-preview infra-up infra-down infra-refresh infra-static \
|
||||
renovate-validate
|
||||
|
||||
help: ## List available targets
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
||||
@echo ""
|
||||
@echo "Sub-project targets:"
|
||||
@echo " \033[36mmake -C gui help\033[0m Odin renderer (run, build, build-web, test, fmt, ...)"
|
||||
@echo " \033[36mmake -C api help\033[0m Rust API (run, build, test, check, fmt, ...)"
|
||||
@echo " \033[36mmake -C infra help\033[0m Infra (preview, up, down, refresh, test, ...)"
|
||||
|
||||
## ---- Setup ---------------------------------------------------------------
|
||||
|
||||
setup: ## Pull submodules + tidy Go deps
|
||||
@git submodule update --init --recursive
|
||||
@mkdir -p lib/local
|
||||
@cd infra && go mod tidy
|
||||
@$(MAKE) -C $(INFRA) tidy
|
||||
|
||||
## ---- Renderer (Odin) -----------------------------------------------------
|
||||
|
||||
run: ## Run the native app
|
||||
@mkdir -p lib/local
|
||||
$(ODIN) run src $(ODIN_FLAGS)
|
||||
run: ## Run the native app (gui/)
|
||||
@$(MAKE) -C $(GUI) run
|
||||
|
||||
build: ## Release build -> bin/desi_explorer
|
||||
@mkdir -p lib/local $(BIN)
|
||||
$(ODIN) build src $(ODIN_FLAGS) -o:speed -out:$(BINARY)
|
||||
build: ## Release build -> bin/desi_explorer (gui/)
|
||||
@$(MAKE) -C $(GUI) build
|
||||
|
||||
build-debug: ## Debug build -> bin/desi_explorer
|
||||
@mkdir -p lib/local $(BIN)
|
||||
$(ODIN) build src $(ODIN_FLAGS) -o:none -debug -out:$(BINARY)
|
||||
build-debug: ## Debug build -> bin/desi_explorer (gui/)
|
||||
@$(MAKE) -C $(GUI) build-debug
|
||||
|
||||
build-web: ## WebAssembly build -> build/web (needs emscripten)
|
||||
@scripts/build_web.sh
|
||||
build-web: ## WebAssembly build -> build/web (gui/, needs emscripten)
|
||||
@$(MAKE) -C $(GUI) build-web
|
||||
|
||||
test: ## Run tests (Odin src/ + Go infra/ + Rust api/)
|
||||
@mkdir -p lib/local
|
||||
$(ODIN) test src $(ODIN_FLAGS)
|
||||
@cd infra && go test ./...
|
||||
@cd api && $(CARGO) test
|
||||
## ---- Aggregates ----------------------------------------------------------
|
||||
|
||||
clean: ## Remove build artifacts
|
||||
rm -rf $(BIN) build
|
||||
@cd api && $(CARGO) clean
|
||||
test: ## Test all projects (odin + cargo + go)
|
||||
@$(MAKE) -C $(GUI) test
|
||||
@$(MAKE) -C $(API) test
|
||||
@$(MAKE) -C $(INFRA) test
|
||||
|
||||
fmt: ## Format Odin sources with odinfmt
|
||||
odinfmt src
|
||||
clean: ## Remove build artifacts from all projects
|
||||
@$(MAKE) -C $(GUI) clean
|
||||
@$(MAKE) -C $(API) clean
|
||||
@$(MAKE) -C $(INFRA) clean
|
||||
|
||||
## ---- API (Rust + axum) ---------------------------------------------------
|
||||
fmt: ## Format all projects (odin + rust)
|
||||
@$(MAKE) -C $(GUI) fmt
|
||||
@$(MAKE) -C $(API) fmt
|
||||
|
||||
api-run: ## Run the API server (dev)
|
||||
@cd api && $(CARGO) run
|
||||
## ---- Passthrough to sub-project Makefiles --------------------------------
|
||||
|
||||
api-build: ## Release build the API -> api/target/release/
|
||||
@cd api && $(CARGO) build --release
|
||||
api-%: ## Forward a target to the api/ Makefile
|
||||
@$(MAKE) -C $(API) $*
|
||||
|
||||
api-test: ## Run API unit/integration tests
|
||||
@cd api && $(CARGO) test
|
||||
|
||||
api-check: ## Typecheck + format-check + lint the API
|
||||
@cd api && $(CARGO) fmt --all --check && $(CARGO) clippy --all-targets -- -D warnings
|
||||
|
||||
api-fmt: ## Format Rust sources with rustfmt
|
||||
@cd api && $(CARGO) fmt
|
||||
|
||||
## ---- Infrastructure (Go + Pulumi) ----------------------------------------
|
||||
|
||||
infra-preview: ## Preview infra changes against the cluster
|
||||
@pulumi preview --cwd infra
|
||||
|
||||
infra-up: ## Deploy/update infra
|
||||
@pulumi up --cwd infra
|
||||
|
||||
infra-down: ## Tear down the stack's resources
|
||||
@pulumi destroy --cwd infra
|
||||
|
||||
infra-refresh: ## Refresh Pulumi state against the live cluster
|
||||
@pulumi refresh --cwd infra
|
||||
|
||||
infra-static: ## Typecheck + vet the Go infra without Pulumi
|
||||
@cd infra && go build -o /dev/null . && go vet ./...
|
||||
infra-%: ## Forward a target to the infra/ Makefile
|
||||
@$(MAKE) -C $(INFRA) $*
|
||||
|
||||
## ---- Tooling -------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -42,17 +42,20 @@ Early scaffolding. The application currently:
|
||||
## Repository Layout
|
||||
|
||||
```
|
||||
src/ Odin source — the interactive 3D experience (entrypoint: src/main.odin)
|
||||
lib/ Third-party Odin dependencies (submodules / vendored libs)
|
||||
gui/ Odin renderer — the interactive 3D experience (entrypoint: gui/src/main.odin)
|
||||
gui/lib/ Third-party Odin dependencies (submodules / vendored libs)
|
||||
gui/www/ Web GUI — WASM shell / static web assets
|
||||
gui/scripts/ Build scripts (WASM build helper)
|
||||
api/ Rust backend API (axum) for serving DESI catalog data
|
||||
infra/ Go + Pulumi infrastructure-as-code (deploys the experience to k8s)
|
||||
scripts/ Build helpers (Odin install, WASM build)
|
||||
scripts/ Repo-level build helpers (Odin install)
|
||||
.gitea/ Gitea Actions CI/CD workflows
|
||||
```
|
||||
|
||||
The renderer (`src/`), the API (`api/`), and the infrastructure (`infra/`) are
|
||||
kept in separate directories so their logic stays cleanly separated; all are
|
||||
orchestrated by the root `Makefile`.
|
||||
The renderer (`gui/`), the API (`api/`), and the infrastructure (`infra/`) are
|
||||
kept in separate directories so their logic stays cleanly separated. Each
|
||||
project carries its own `Makefile`; the root `Makefile` delegates the base
|
||||
commands (`run`, `build`, `test`, ...) into them.
|
||||
|
||||
## Building & Running
|
||||
|
||||
@@ -62,21 +65,33 @@ vendor bindings. The web build additionally requires [Emscripten](https://emscri
|
||||
pinned via `api/rust-toolchain.toml`). The infrastructure requires
|
||||
[Go](https://go.dev) and [Pulumi](https://www.pulumi.com).
|
||||
|
||||
All project commands live in the root `Makefile` (`make help` lists them):
|
||||
The root `Makefile` delegates everything to the per-project Makefiles
|
||||
(`make help` lists the base targets):
|
||||
|
||||
```sh
|
||||
make setup # pull submodules + tidy Go deps
|
||||
make run # run the native app
|
||||
make build # -> bin/desi_explorer
|
||||
make build-debug # debug native build
|
||||
make build-web # -> build/web (wasm + html)
|
||||
make run # run the native app (gui/)
|
||||
make build # -> bin/desi_explorer (gui/)
|
||||
make build-debug # debug native build (gui/)
|
||||
make build-web # -> build/web (wasm + html, gui/)
|
||||
make test # odin test + go test + cargo test
|
||||
make clean # remove build artifacts
|
||||
make api-run # run the Rust API server
|
||||
make api-test # cargo test
|
||||
make api-check # rustfmt check + clippy
|
||||
make clean # remove build artifacts from all projects
|
||||
make fmt # format all projects
|
||||
```
|
||||
|
||||
Project-specific targets live in their own `Makefile` and are reached with
|
||||
`make -C <dir> <target>`:
|
||||
|
||||
```sh
|
||||
make -C gui help # Odin renderer (run, build, build-debug, build-web, test, fmt)
|
||||
make -C api help # Rust API (run, build, test, check, fmt)
|
||||
make -C infra help # Infra (preview, up, down, refresh, static, test)
|
||||
```
|
||||
|
||||
The root also provides thin passthroughs: `make api-<target>` and
|
||||
`make infra-<target>` forward to the corresponding sub-project (e.g.
|
||||
`make api-check` -> `make -C api check`).
|
||||
|
||||
## Dependency Updates (Renovate)
|
||||
|
||||
[Renovate](https://github.com/renovatebot/renovate) keeps dependencies up to
|
||||
@@ -91,5 +106,5 @@ It manages four categories:
|
||||
|
||||
- **Infra dependencies** — `infra/go.mod` (`gomod` manager); minor/patch updates grouped into a single PR.
|
||||
- **API dependencies** — `api/Cargo.toml` (`cargo` manager); minor/patch updates grouped into a single PR.
|
||||
- **Submodules** — `lib/` submodules via `.gitmodules` (`git-submodules` manager).
|
||||
- **Submodules** — `gui/lib/` submodules via `.gitmodules` (`git-submodules` manager).
|
||||
- **Workflow actions** — action versions in `.gitea/workflows/*.yml` (`github-actions` manager, which understands Gitea's `.gitea` layout).
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# api/Makefile — the Rust + axum backend API.
|
||||
#
|
||||
# Driven directly with `make -C api <target>` (or via the root Makefile's
|
||||
# `api-*` convenience targets).
|
||||
|
||||
CARGO ?= cargo
|
||||
|
||||
.PHONY: help run build test check fmt clean
|
||||
|
||||
help: ## List available targets
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
run: ## Run the API server (dev)
|
||||
$(CARGO) run
|
||||
|
||||
build: ## Release build -> target/release/
|
||||
$(CARGO) build --release
|
||||
|
||||
test: ## Run unit/integration tests
|
||||
$(CARGO) test
|
||||
|
||||
check: ## Format-check + lint (clippy -D warnings)
|
||||
$(CARGO) fmt --all --check && $(CARGO) clippy --all-targets -- -D warnings
|
||||
|
||||
fmt: ## Format Rust sources with rustfmt
|
||||
$(CARGO) fmt
|
||||
|
||||
clean: ## Remove Cargo build artifacts
|
||||
$(CARGO) clean
|
||||
@@ -0,0 +1,46 @@
|
||||
# gui/Makefile — the Odin + raylib renderer (the interactive 3D universe map).
|
||||
#
|
||||
# This is the Odin sub-project. It is normally invoked from the repo root via
|
||||
# `make run`, `make build`, etc. (which delegate here through the root
|
||||
# Makefile), but it can also be driven directly with `make -C gui <target>`.
|
||||
#
|
||||
# `lib/` (third-party Odin deps) lives under `gui/lib`; the `bin/` / `build/`
|
||||
# output dirs live at the repo root and are referenced through `$(ROOT)`.
|
||||
|
||||
ODIN ?= odin
|
||||
ROOT := ..
|
||||
BIN := $(ROOT)/bin
|
||||
BINARY := $(BIN)/desi_explorer
|
||||
ODIN_FLAGS := -collection:lib=lib/local
|
||||
WASM_DEFINE := RAYLIB_WASM_LIB=env.o
|
||||
|
||||
.PHONY: help run build build-debug build-web test clean fmt
|
||||
|
||||
help: ## List available targets
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
run: ## Run the native app
|
||||
@mkdir -p lib/local
|
||||
$(ODIN) run src $(ODIN_FLAGS)
|
||||
|
||||
build: ## Release build -> bin/desi_explorer
|
||||
@mkdir -p lib/local $(BIN)
|
||||
$(ODIN) build src $(ODIN_FLAGS) -o:speed -out:$(BINARY)
|
||||
|
||||
build-debug: ## Debug build -> bin/desi_explorer
|
||||
@mkdir -p lib/local $(BIN)
|
||||
$(ODIN) build src $(ODIN_FLAGS) -o:none -debug -out:$(BINARY)
|
||||
|
||||
build-web: ## WebAssembly build -> build/web (needs emscripten)
|
||||
@scripts/build_web.sh
|
||||
|
||||
test: ## Run Odin unit tests
|
||||
@mkdir -p lib/local
|
||||
$(ODIN) test src $(ODIN_FLAGS)
|
||||
|
||||
clean: ## Remove build artifacts
|
||||
rm -rf $(BIN) build
|
||||
|
||||
fmt: ## Format Odin sources with odinfmt
|
||||
odinfmt src
|
||||
@@ -1,7 +1,8 @@
|
||||
# Libraries
|
||||
|
||||
Third-party libraries for the DESI Explorer renderer live here, either as git
|
||||
submodules or vendored directly and wired in via `-collection:lib=lib/local`.
|
||||
submodules or vendored directly and wired in via `-collection:lib=lib/local`
|
||||
(as resolved from the `gui/` directory).
|
||||
|
||||
- `raylib` is bundled with Odin and imported as `vendor:raylib` — it does **not**
|
||||
live in this directory.
|
||||
@@ -1,30 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
# Builds the WebAssembly ("web") build of DESI Explorer with Odin
|
||||
# (js_wasm32) + emscripten. Output: build/web/index.html (+ index.wasm, odin.js).
|
||||
# (js_wasm32) + emscripten. Output: build/web/index.html (+ index.wasm,
|
||||
# odin.js) at the repo root. Run via `make -C gui build-web`.
|
||||
#
|
||||
# Requires:
|
||||
# - `odin` on PATH with the js_wasm32 target
|
||||
# - emcc / emscripten active in PATH
|
||||
# Optional:
|
||||
# - ODIN_ROOT (defaults to `odin root`)
|
||||
# - OUT_DIR (defaults to build/web)
|
||||
# - OUT_DIR (defaults to <repo>/build/web)
|
||||
set -euo pipefail
|
||||
|
||||
OUT_DIR="${OUT_DIR:-build/web}"
|
||||
# Resolve the gui/ project root so this script works regardless of CWD.
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
GUI_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
ROOT_DIR="$(cd "${GUI_DIR}/.." && pwd)"
|
||||
|
||||
OUT_DIR="${OUT_DIR:-${ROOT_DIR}/build/web}"
|
||||
ODIN_ROOT="${ODIN_ROOT:-$(odin root)}"
|
||||
|
||||
mkdir -p lib/local
|
||||
mkdir -p "${GUI_DIR}/lib/local"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
# The Odin compiler emits a wasm object; raylib's C code is linked later by
|
||||
# emcc. `-define:RAYLIB_WASM_LIB=env.o` stops the compiler from trying to
|
||||
# link the raylib lib itself (emcc does that; it ends up in the final module).
|
||||
odin build src \
|
||||
odin build "${GUI_DIR}/src" \
|
||||
-target:js_wasm32 \
|
||||
-build-mode:obj \
|
||||
-define:RAYLIB_WASM_LIB=env.o \
|
||||
-o:speed \
|
||||
-collection:lib=lib/local \
|
||||
-collection:lib="${GUI_DIR}/lib/local" \
|
||||
-out:"${OUT_DIR}/game"
|
||||
|
||||
# Odin's JS runtime glue; the generated module imports functions from it.
|
||||
@@ -36,7 +42,7 @@ emcc \
|
||||
-o "${OUT_DIR}/index.html" \
|
||||
"${OUT_DIR}/game.obj" \
|
||||
"${ODIN_ROOT}/vendor/raylib/wasm/libraylib.web.a" \
|
||||
--shell-file scripts/web/index_template.html \
|
||||
--shell-file "${GUI_DIR}/www/index_template.html" \
|
||||
-sEXPORTED_RUNTIME_METHODS="['HEAPF32']" \
|
||||
-sUSE_GLFW=3 \
|
||||
-sWASM_BIGINT \
|
||||
@@ -0,0 +1,35 @@
|
||||
# infra/Makefile — Go + Pulumi infrastructure-as-code.
|
||||
#
|
||||
# Driven directly with `make -C infra <target>` (or via the root Makefile's
|
||||
# `infra-*` convenience targets). Targets that interact with the live cluster
|
||||
# run Pulumi against the stack defined in Pulumi.yaml.
|
||||
|
||||
.PHONY: help preview up down refresh static test clean tidy
|
||||
|
||||
help: ## List available targets
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
preview: ## Preview infra changes against the cluster
|
||||
pulumi preview
|
||||
|
||||
up: ## Deploy/update infra
|
||||
pulumi up
|
||||
|
||||
down: ## Tear down the stack's resources
|
||||
pulumi destroy
|
||||
|
||||
refresh: ## Refresh Pulumi state against the live cluster
|
||||
pulumi refresh
|
||||
|
||||
static: ## Typecheck + vet without Pulumi
|
||||
go build -o /dev/null . && go vet ./...
|
||||
|
||||
test: ## Run Go unit tests
|
||||
go test ./...
|
||||
|
||||
clean: ## Remove local Go build artifact
|
||||
rm -f desi-explorer-infra
|
||||
|
||||
tidy: ## Tidy Go modules
|
||||
go mod tidy
|
||||
Reference in New Issue
Block a user