CI integration overview
graphlens is built to run in a pipeline. Adapters are pure data producers, node IDs are deterministic, and the graph round-trips through JSON — so a CI job can index your repository, publish the graph as an artifact, and fail the build when analysis degrades.
This page covers the building blocks. The next two pages give concrete GitHub Actions and Docker recipes.
The two things you produce
- A serialized graph —
graphlens analyze . --output graph.json. This is the artifact downstream steps (agents, the MCP server, dashboards) consume. - A pass/fail signal —
graphlens analyze . --strictexits non-zero if the resolver did not complete, so the job fails loudly instead of shipping a half-resolved graph.
You usually want both at once:
graphlens analyze . --strict --output graph.json
Strict mode
Type-aware analysis can degrade — a toolchain may be missing, or a file may not
type-check. graphlens records the outcome on graph.metadata[RESOLVER_STATUS_KEY]:
| Status | Meaning | --strict result |
|---|---|---|
ok | the type-aware layer ran to completion | exit 0 |
degraded | the resolver started but some queries failed | exit non-zero |
unavailable | the resolver never started | exit non-zero |
Without --strict, a degraded graph is still produced (and still useful for
structure-only views) — the status just lives in the metadata. With --strict,
anything other than ok fails the command. Gate your pipeline on it so agents
never receive an incomplete graph.
# The same check in code
from graphlens import RESOLVER_STATUS_KEY
assert graph.metadata[RESOLVER_STATUS_KEY] == "ok"
Two ways to get the toolchains
Each resolver drives an external engine (ty, Node, gopls, rust-analyzer).
You have two options in CI:
- The Docker image —
ghcr.io/neko1313/graphlensbundles the CLI with every adapter and every toolchain pre-installed. Nothing to set up, and the only supported way to get the Go and Rust adapters. Recommended for CI. See the Docker guide. - pip/uv install — install
graphlens-cliwith the extras you need. Good for Python/TypeScript-only repos where you already have Node available.
Running it locally
Everything CI does, you can do on your machine before pushing.
With the project's task runner
If you are working in the graphlens repository, the Taskfile wraps the common workflows:
task install # uv sync --all-groups
task lint # ruff + ty + bandit across all packages
task tests # all tests with coverage
As a pre-commit-style check
Run analysis as a local guard before committing. For example, a simple Git
pre-push hook (.git/hooks/pre-push):
#!/usr/bin/env bash
set -euo pipefail
graphlens analyze . --strict --output /tmp/graphlens.json
Or with the Docker image so you do not need the toolchains installed:
#!/usr/bin/env bash
set -euo pipefail
docker run --rm -v "$PWD:/workspace" ghcr.io/neko1313/graphlens \
analyze /workspace --strict
Caching the graph
Because node IDs are deterministic, a graph is cacheable and diffable. A common
pattern is to store the previous run's graph.json and diff against it to report
what changed:
from graphlens import GraphLens
old = GraphLens.from_json(open("graph.prev.json").read())
new = GraphLens.from_json(open("graph.json").read())
diff = old.diff(new)
if not diff.is_empty:
print(f"+{len(diff.added_nodes)} -{len(diff.removed_nodes)} nodes")
Next
- GitHub Actions — ready-to-copy workflows.
- Docker — the pre-built image in depth.