feat: deployment-scoped requires + UI editors, gateway nav, services filter
Model:
- Drop `requires` from ProgramSpec; requires is now deployment-only.
Collapse Requirement to {ref, bind} with kind defaulting to "deployment"
(drop the unused `version`). System-package preconditions stay on the
program as `system_dependencies`, synthesized into {kind: system} for the
functional check. relations.py/deploy.py read only the deployment's requires.
- create.py seeds a stack's substrate dependency onto the deployment, not the
program. Docs + tests updated.
UI:
- Add a `requires` editor (useRequires) on service, job, and static detail
pages — edit service→service deps (ref + optional bind env var).
- Restore the gateway route table "Open" column: a kind-aware in-app link to
each route's deployment.
- Reformat the reach control: name baked into each option
(localhost:PORT (local) / <name>.<domain> (internal) / <name>.<pubdomain> (public)).
- Services page: sort statics in with systemd services by name, add a
search + kind-filter bar mirroring the programs page.
This commit is contained in:
@@ -105,12 +105,13 @@ class TestCreateCommand:
|
||||
comp = config.programs["guestbook"]
|
||||
assert comp.stack == "supabase"
|
||||
assert comp.build is not None and comp.build.outputs == ["public"]
|
||||
# The supabase stack seeds a `requires` on the substrate so the graph shows
|
||||
# the dependency (stack stays uncoupled — it just declares the edge once).
|
||||
assert [(r.kind, r.ref) for r in comp.requires] == [("deployment", "supabase")]
|
||||
dep = config.statics["guestbook"]
|
||||
assert dep.manager == "caddy"
|
||||
assert dep.root == "public"
|
||||
# The supabase stack seeds a `requires` on the substrate (on the deployment)
|
||||
# so the graph shows the dependency (stack stays uncoupled — it just declares
|
||||
# the edge once).
|
||||
assert [(r.kind, r.ref) for r in dep.requires] == [("deployment", "supabase")]
|
||||
assert config.deployments_of("guestbook") == [("guestbook", "static")]
|
||||
|
||||
def test_create_duplicate_fails(self, castle_root: Path, capsys: object) -> None:
|
||||
|
||||
Reference in New Issue
Block a user