[DevOps]
CI matrices, containers, Nuitka LSP binaries, metadata crypto, Cloud Run, and operational invariants for PYNE.
DevOps
Abstract
PYNE is not a single binary. It is a multi-surface product: a pure-Python library, a Click CLI, a pygls Language Server, a Flask Pro API, a VS Code extension, an AXIS PWA AXIS, and colocated edge workers. DevOps here means keeping those surfaces buildable, testable, and deployable without drifting from the same evaluate contract.
This tab documents the operational graph: local loops, GitHub Actions, release tags, Docker images, Nuitka compilation, Fernet-encrypted LSP metadata, GCP Cloud Build/Run, observability hooks, and security controls.
Conceptual model
Invariant: CI green on main is necessary but not sufficient for a release. Tag-triggered release workflows build platform LSP binaries and VSIX; Cloud Build deploys the API image on its own pipeline.
Interface surface
| Concern | Entry | Doc |
|---|---|---|
| Local install & loops | Makefile, hatch envs | Local development |
| PR / push CI | .github/workflows/ci.yml | CI |
| Versioned LSP + VSIX | .github/workflows/release.yml | Release |
| Pro API containers | Dockerfile (targets api/api-dev/lsp), docker-bake.hcl, docker-compose.yml | Docker |
| Compiled LSP | scripts/build/compile.py, ci_build.py | Nuitka build |
| Builtin metadata crypto | Fernet key + .enc | Metadata crypto |
| Cloud Run | cloudbuild.yaml | GCP |
| Logs / health | Flask /, gunicorn, Cloud Logging | Observability |
| Auth, CORS, secrets | backend/middleware/auth.py | Security |
Internals (repo map)
| Path | Role |
|---|---|
Makefile | Human-facing orthography: install, test, lint, build, docker, worker |
pyproject.toml | Hatch envs (test, lint, docs), optional extras (lsp, data) |
.github/workflows/ | ci.yml, release.yml, axis-nightly.yml |
scripts/build/ | Nuitka compile + CI build + Fernet metadata stage |
scripts/generate_builtin_metadata.py | Regenerates LSP builtin_metadata.json from live builtins |
Dockerfile / docker-bake.hcl | Multi-target Buildx images (api, api-dev, lsp) |
docker-compose.yml | Local API (+ optional Redis / LSP profiles) |
cloudbuild.yaml | Build → GCR push → Cloud Run deploy; optional LSP compile |
vscode-extension/ | Node 22 extension package / vsce |
Invariants & edge cases
- Two console scripts, two entrypoints.
pynescript(Click) ≠pynescript-lsp(pygls). Ops scripts must not conflate them. - Generated artifacts are not hand-edited. ANTLR/ASDL under
generated/andbuiltin_metadata.jsonare code-derived. - Fernet key is gitignored. Without a stable
CRYPTO_KEY/METADATA_KEYsecret, every CI encrypt produces a different.encblob (harmless functionally, bad for reproducibility). - Python matrix vs local default. CI tests 3.10–3.13; Nuitka release currently pins 3.12.
- AXIS nightly is not PR-blocking. Full Playwright + security gates run on schedule (
axis-nightly.yml).
Worked examples
# Fast local confidence loop
make install
make lint
make test-lsp
make build-check # import check only, ~30s, no Nuitka compile
# API in Docker — local *dev* stack (api-dev + source mounts)
make docker-up
make docker-smoke
# Production image bake (load local) + optional prod compose overlay
make docker-build
# export ADMIN_TOKEN=… && make docker-prod
Failure modes
| Symptom | Likely cause | Fix |
|---|---|---|
| CI lint red, local green | Different ruff/mypy versions | Match CI install pins in workflow |
| Metadata decrypt fails in binary | Missing key at runtime | Set PYNESCRIPT_METADATA_KEY or embed key at build |
| Cloud Run 502 after deploy | Image missing deps / gunicorn bind | Confirm Dockerfile target api ENTRYPOINT + PORT / GUNICORN_BIND |
| VSIX empty / missing | npm ci / vsce not run | Use make build-vscode or release job artifacts |
| Nuitka Anaconda link error | Static libpython missing | conda install libpython-static or keep --static-libpython=no |