Supply-chain graph — Phase 6: graph-service + dashboard views - #185
Merged
Merged
Conversation
… deploy producers (#175) Ship the FastAPI graph-service, its Helm subchart, a dashboard graph view, and the deploy-stage producer. - services/graph-service: FastAPI over the shared cssc_graph query layer. Owns a single LadybugDB writer, rebuilds the graph from the committed data root on startup, and gates /readyz on a successful index. Endpoints: resolve, path, bases, derived, show, tag history, search, and a bounded /graph/neighborhood (json|cytoscape|mermaid); POST /index/rebuild. Depth is capped by MAX_DEPTH. - graph-service Helm subchart: single replica (Recreate), optional git-sync init container for the supply-chain-graph-data branch, ephemeral emptyDir DB or an optional PVC, numeric UID 10001, startup/readiness/liveness probes. Wired into the umbrella chart; dashboard-web gets GRAPH_SERVICE_URL. - dashboard-web: new 'Supply chain graph' stage (index summary) + a /graph/neighborhood route that renders a bounded neighborhood (nodes + edges) for any reference via htmx. - build-graph-event: add ArtifactDeployed kind (image occurrence + environment cluster/namespace + optional chart). New deploy-cssc-dashboard.yml producer resolves each service digest and stages ArtifactDeployed; record-graph-events now also collects it. graph-service added to the build matrix and Makefile. Verified locally: 40 (cssc_graph) + 16 (graph-service) + 21 (dashboard-web) tests pass; helm lint/template clean (incl. git-sync + PVC variants); ArtifactDeployed records validate and index (RUNS edges); actionlint + shellcheck clean. Part of #177; implements #175.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds Phase 6 of the supply-chain graph by introducing a new FastAPI graph-service (backed by the shared cssc_graph.queries layer), wiring it into Helm + build/deploy workflows, and surfacing a new dashboard “Supply chain graph” stage that renders a bounded neighborhood via htmx.
Changes:
- Implement
graph-service(index ownership + readiness gating + query endpoints) with Docker packaging and Helm subchart. - Add
dashboard-web“observability” stage + neighborhood route/templates + GraphService client integration. - Extend graph event production to include deploy-stage
ArtifactDeployedrecords and add a deploy workflow to stage those events.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/python-app/services/graph-service/tests/test_app.py | End-to-end app tests that build a temporary data root and exercise API journeys + readiness gating. |
| apps/python-app/services/graph-service/src/graph_service/indexing.py | Implements the single-writer index owner and rebuild logic around LadybugDB. |
| apps/python-app/services/graph-service/src/graph_service/config.py | Adds environment-driven settings for data root, DB path, rebuild behavior, and depth cap. |
| apps/python-app/services/graph-service/src/graph_service/app.py | FastAPI routes for resolve/path/bases/derived/show/search + neighborhood and rebuild endpoint. |
| apps/python-app/services/graph-service/src/graph_service/init.py | Introduces package version exported to FastAPI app metadata. |
| apps/python-app/services/graph-service/requirements.txt | Runtime deps for running the service with uvicorn. |
| apps/python-app/services/graph-service/pyproject.toml | Package metadata and test dependencies for graph-service. |
| apps/python-app/services/graph-service/Dockerfile | Container build for graph-service, including shared cssc_graph install. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/values.yaml | Chart values including git-sync and optional PVC support. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/templates/service.yaml | Kubernetes Service for graph-service. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/templates/pvc.yaml | Optional PVC template for persisting the graph DB. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/templates/deployment.yaml | Deployment with single-replica writer semantics + probes + init git-sync option. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/templates/configmap.yaml | ConfigMap for non-secret runtime settings. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/templates/_helpers.tpl | Standard Helm naming/labels helpers for the subchart. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/Chart.yaml | Helm chart metadata for graph-service. |
| apps/python-app/services/graph-service/deploy/helm/graph-service/.helmignore | Helm ignore rules for packaging. |
| apps/python-app/services/dashboard-web/tests/test_graph.py | Tests for the new dashboard stage + neighborhood route and GraphService client. |
| apps/python-app/services/dashboard-web/src/dashboard_web/web/routes.py | Adds optional graph neighborhood HTML route when a graph client is provided. |
| apps/python-app/services/dashboard-web/src/dashboard_web/templates/stages/observability.html | New stage template that shows readiness summary and graph explore form. |
| apps/python-app/services/dashboard-web/src/dashboard_web/templates/stages/_graph_neighborhood.html | Fragment template rendering nodes/edges (or empty/error prompts). |
| apps/python-app/services/dashboard-web/src/dashboard_web/stages/observability.py | Adds GraphProvider stage that sources readiness data from graph-service. |
| apps/python-app/services/dashboard-web/src/dashboard_web/config.py | Adds GRAPH_SERVICE_URL to dashboard settings. |
| apps/python-app/services/dashboard-web/src/dashboard_web/clients.py | Adds GraphService HTTP client for readiness + neighborhood calls. |
| apps/python-app/services/dashboard-web/src/dashboard_web/app.py | Wires GraphProvider + GraphServiceClient into app construction and routes. |
| apps/python-app/Makefile | Adds graph-service to build/test targets and includes cssc_graph tests. |
| apps/python-app/deploy/helm/cssc-dashboard/values.yaml | Adds graph-service subchart values + passes GRAPH_SERVICE_URL to dashboard-web. |
| apps/python-app/deploy/helm/cssc-dashboard/Chart.yaml | Adds graph-service as an umbrella chart dependency and updates description. |
| .github/workflows/record-graph-events.yml | Extends collection triggers to include deploy workflow completions. |
| .github/workflows/deploy-cssc-dashboard.yml | New workflow_dispatch producer that resolves image digests and stages ArtifactDeployed events. |
| .github/workflows/build-cssc-dashboard.yml | Adds graph-service to the build matrix. |
| .github/actions/build-graph-event/action.yml | Extends event builder to support ArtifactDeployed record staging. |
Suppressed comments (1)
apps/python-app/services/dashboard-web/src/dashboard_web/app.py:52
- Similarly,
create_apptypesgraphas GraphServiceClient, but the parameter is used as an injectable dependency and only needs to satisfy the GraphClient protocol. Keeping the signature protocol-typed makes tests and alternate implementations type-safe.
def create_app(
registry: StageRegistry | None = None,
settings: DashboardSettings | None = None,
graph: GraphServiceClient | None = None,
) -> FastAPI:
settings = settings or dashboard_settings()
graph = graph or GraphServiceClient(settings.graph_service_url)
registry = registry or build_registry(settings, graph)
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ias, chart guard, shared protocol - graph-service: run every query inside GraphIndex.reading() (holds the writer lock) so /index/rebuild can't close the store mid-request. - graph-service /search: keep the public 'type' query param via alias, use a non-shadowing local name. - build-graph-event: ArtifactDeployed now errors when chart-name is given without chart-version (no more chart.version:""). - dashboard-web: define GraphClient Protocol once in clients.py and reuse it from observability + routes; type build_registry/create_app against the protocol.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements Phase 6 of the supply-chain graph (epic #177): the FastAPI
graph-service, its Helm subchart, a dashboard graph view, and the deploy-stageproducer.
graph-service
apps/python-app/services/graph-service— FastAPI over the sharedcssc_graph.querieslayer (the same code thecssc-graphCLI uses). It owns asingle LadybugDB writer, rebuilds the graph from the committed data root on
startup, and gates
/readyzon a successful index (the pod stays not-ready, notcrash-looping, if the data is invalid).
Endpoints:
resolve,path,bases,derived,show, tag history,search,and a bounded
GET /graph/neighborhood(json|cytoscape|mermaid) for thedashboard, plus
POST /index/rebuild. Every traversal depth is clamped byMAX_DEPTH.Helm
New subchart under the umbrella, consistent with the other services: single
replica (
Recreatestrategy — one writer), numeric UID 10001, startup /readiness / liveness probes, ephemeral
emptyDirdatabase (rebuilt on start) oran optional PVC, and an optional git-sync init container that clones the
supply-chain-graph-databranch into the indexed volume. git-sync is disabled bydefault so a first deploy is green before the data branch exists; enable it once
events have been recorded. dashboard-web gains
GRAPH_SERVICE_URL.dashboard-web
A new Supply chain graph stage shows the index summary, and a
/graph/neighborhoodhtmx route renders a bounded neighborhood (nodes + edges)for any reference — no new frontend dependency.
Deploy producer
build-graph-eventgains anArtifactDeployedkind (image occurrence +environment cluster/namespace + optional chart). New
deploy-cssc-dashboard.yml(dispatch) resolves each service's published digest and stages
ArtifactDeployedper service;
record-graph-eventsnow also collectsdeploy / cssc-dashboard.graph-serviceis added to the build matrix and the Makefile.Validation (local)
cssc_graph) + 16 (graph-service) + 21(
dashboard-web) pass, including transitivebases/derived, theneighborhood renders, depth capping, and the not-ready gate.
helm lint/templateclean for the subchart (default, git-sync, and PVCvariants) and the umbrella.
ArtifactDeployedrecords validate against the schema, keepfilename == id == cssc-graph id, and index intoRUNSedges.actionlint+shellcheck -S warningclean on the new workflow and action.ladybugpublishes cp314 manylinux wheels, so thegolden/python:3.14-slimbase builds the native engine cleanly.
Closes #175. Part of #177.