Skip to content

Commit 6498575

Browse files
authored
Merge pull request #33 from codellm-devkit/feature/neo4j
feature/neo4j: property-graph output with Py/PY_-namespaced schema; rename CLI to `canpy`
2 parents 3b3e10e + 4af7d04 commit 6498575

23 files changed

Lines changed: 2620 additions & 206 deletions

.github/workflows/release.yml

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,26 @@ jobs:
3232
run: uv sync --all-groups
3333

3434
- name: Install dependencies
35-
run: uv pip install -e .
35+
run: uv pip install -e ".[neo4j]"
36+
37+
# Keep generated docs in lockstep with the code being released: regenerate the
38+
# README `canpy --help` block and the Neo4j schema.json from source, and commit
39+
# them back to main. Releases are cut from main HEAD, so this fast-forwards;
40+
# best-effort if main moved.
41+
- name: Sync generated docs (README --help + Neo4j schema)
42+
if: startsWith(github.ref, 'refs/tags/')
43+
run: |
44+
uv run python scripts/update_readme.py
45+
uv run canpy --emit schema > schema.neo4j.json
46+
if git diff --quiet README.md schema.neo4j.json; then
47+
echo "Generated docs already current."
48+
else
49+
git config user.name "github-actions[bot]"
50+
git config user.email "github-actions[bot]@users.noreply.github.com"
51+
git add README.md schema.neo4j.json
52+
git commit -m "docs: sync README --help and Neo4j schema for ${GITHUB_REF#refs/tags/}"
53+
git push origin HEAD:main || echo "::warning::could not push doc sync to main (diverged?)"
54+
fi
3655
3756
- name: Run tests
3857
id: test
@@ -51,6 +70,17 @@ jobs:
5170
- name: Build package
5271
run: uv build
5372

73+
# Platform-independent, version-locked release assets published alongside the
74+
# wheels/sdist: the Neo4j schema contract (so a consumer can validate
75+
# producer/consumer compatibility without installing the package) and the
76+
# cargo-dist-style install script.
77+
- name: Stage release assets (Neo4j schema + installer script)
78+
run: |
79+
mkdir -p release-assets
80+
uv run canpy --emit schema > release-assets/schema.json
81+
cp packaging/install/canpy-installer.sh release-assets/canpy-installer.sh
82+
ls -lh release-assets
83+
5484
- name: Get version from tag
5585
id: tag_name
5686
run: |
@@ -77,7 +107,9 @@ jobs:
77107
- name: Publish release on GitHub
78108
uses: softprops/action-gh-release@v1
79109
with:
80-
files: dist/*
110+
files: |
111+
dist/*
112+
release-assets/*
81113
body: |
82114
## Release Notes (from CHANGELOG.md)
83115

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.2.0] - 2026-06-20
9+
10+
### Added
11+
- **Neo4j property-graph output** (`--emit neo4j`). The same in-memory analysis (`PyApplication`) is projected to a labeled property graph, mirroring the `codeanalyzer-typescript` backend. Node labels are `Py`-prefixed and relationship types are `PY_`-prefixed (e.g. `:PyClass`, `PY_CALLS`) so multiple language analyzers can coexist in one database without label or relationship-type collisions. Two writers:
12+
- **`graph.cypher` snapshot** (default) — a self-contained Cypher script (constraints + indexes, a scoped wipe of the project's prior subgraph, then batched `UNWIND … MERGE`). Load it with `cypher-shell < graph.cypher`. Needs no extra dependencies.
13+
- **Live Bolt push** (`--neo4j-uri`) — an **incremental** writer: only modules whose `content_hash` changed are rewritten, and on a full run modules whose source file vanished are pruned. Requires the optional `neo4j` driver (`pip install 'codeanalyzer-python[neo4j]'`).
14+
- **`--emit schema`** — emit the machine-readable, version-stamped Neo4j schema contract (`schema.json`: node labels, relationships, properties, constraints, indexes). Needs no project; bundled in every release as a GitHub Release asset and checked in as `schema.neo4j.json`. A `schema_version` (`1.0.0`) is stamped onto every graph's `:PyApplication` node.
15+
- **New CLI options** mirroring the TypeScript analyzer's entrypoints: `--emit {json,neo4j,schema}`, `--app-name`, `--neo4j-uri`, `--neo4j-user`, `--neo4j-password`, `--neo4j-database`. `-i/--input` is now optional (not required for `--emit schema`). The four Neo4j connection options also read from the standard `NEO4J_URI` / `NEO4J_USERNAME` / `NEO4J_PASSWORD` / `NEO4J_DATABASE` environment variables when the flag is omitted (an explicit flag wins), so the password need not appear in shell history or the process list.
16+
- **`codeanalyzer.neo4j`** package: `catalog` (the single source-of-truth schema catalog), `project` (pure IR → graph rows), `cypher` (snapshot writer), `bolt` (incremental writer), and `rows` (the output-agnostic intermediate).
17+
- **Schema conformance test** (`test/test_neo4j_schema.py`, always runs) — asserts the emitter never produces a label/relationship/property the catalog doesn't declare, and that the checked-in `schema.neo4j.json` is regenerated.
18+
- **Neo4j Testcontainers integration test** (`test/test_neo4j_bolt.py`, opt-in via `RUN_CONTAINER_TESTS=1`) — spins up a real Neo4j and asserts the pushed graph, idempotent re-push, vanished-declaration cleanup, and full-run orphan pruning.
19+
- **Install script** (`packaging/install/canpy-installer.sh`) — a `curl … | sh` installer that provisions the CLI via uv / pipx / pip, published as a release asset.
20+
- **`schema-uml.drawio`** — a clean UML of the `analysis.json` schema (the `PyApplication` containment tree).
21+
22+
### Changed
23+
- **The CLI command is now `canpy`** (was `codeanalyzer`), matching the `cants` (TypeScript) sibling. The PyPI package name is unchanged (`codeanalyzer-python`), as is the importable `codeanalyzer` module. The old `codeanalyzer` command is retained as a **deprecated alias** that prints a notice (to stderr) and then runs unchanged; it will be removed in a future release.
24+
- The README `canpy --help` block is now generated from the live CLI (`scripts/update_readme.py`, between `<!-- BEGIN/END canpy-help -->` markers) so it can't drift from the code.
25+
- The release workflow now installs the `[neo4j]` extra, syncs both the README `--help` block and `schema.neo4j.json` from source before publishing, and uploads the schema contract (`schema.json`) and installer script as GitHub Release assets.
26+
827
## [0.1.15] - 2026-05-15
928

1029
### Fixed

0 commit comments

Comments
 (0)