Repo enhancement pass: entry-point fix, modularization, test org, release automation - #27
Merged
Merged
Conversation
- pyproject [project.scripts] referenced apiverity.cli.main:cli which does not exist (main is the entry function); installed packages crashed on the apiverity command - correct CLI doc drift in ARCHITECTURE.md (argparse-based, not Click) - pin pre-commit ruff hook to v0.16.4 to match CI formatting - keep mypy python_version at 3.12 deliberately: the httpx stub chain uses PEP 695 syntax that cannot be parsed when targeting 3.11
App.tsx was a 710-line monolith rendering all 31 pages. Now: - components/ui.tsx — shared presentational building blocks - hooks/useData.ts — demo-data loading hook - pages/ grouped by domain (overview, contract, testing, runtime, team) with pages/index.tsx as the page registry + navigation structure No behavior change; existing vitest suite passes unchanged.
apiverity/cli/commands/ now owns implementations grouped by product lane: common.py (exit codes, spec loading, artifact-emission state via explicit setters), governance.py (validate/diff/breaking/changelog), testing.py (test/workflow/mock/coverage), runtime.py (drift/replay/baseline/regression), artifacts.py (report/export/serve), platform.py (server-db/plugins/rules/ self-test). main.py keeps parser wiring + main() and re-exports every cmd_* function so all external consumers stay source-compatible. Removed dead _start_mock helper.
- server/schema.py holds the explicit SQLite DDL plus timestamp/token helpers so the schema is inspectable without a connection - server/decision.py holds authenticate_safe, compute_can_i_deploy and run row mapping so deploy decisions are testable without Flask - Store and create_app keep their public signatures; apiverity.server.api re-exports the moved helpers for source compatibility
…r to 72% - tests/unit/ — pure-logic suites (models, rules, generators, plugins) - tests/integration/ — suites exercising the mock server and the self-hosted Flask API over live HTTP - tests/README.md documents the layout; conftest.py unchanged at root - CI coverage gate raised from 60% to 72% (measured coverage: 76%)
…erfile - .github/workflows/release.yml: tag-triggered pipeline that builds and twine-checks sdist/wheel, publishes to PyPI via OIDC trusted publishing (id-token only, no stored secrets), creates a GitHub Release with the artifacts, and builds/pushes a versioned server image to GHCR with GHA layer caching - Dockerfile: non-root python:3.12-slim image for the self-hosted server, volume-backed SQLite at /data (VERITY_DB/VERITY_PORT env config), HEALTHCHECK against /healthz; verified the CMD boot path locally (30 routes incl. /healthz) - .dockerignore keeps build context minimal - docs/self-hosting.md gains a Docker section; CHANGELOG + ARCHITECTURE module map updated
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
API Verity — contract reviewOne comment per PR — updated on each push. |
The `contract-gate` job discovered "changed contracts" with a denylist (exclude package/lock/.github and a few directory prefixes). `.pre-commit- config.yaml` at the repo root matched none of those exclusions, so it was handed to `apiverity validate`, which correctly reported that no spec plugin could handle it -- and the gate turned that into "breaking changes or validation errors detected", blocking its own pull request (#27). Two changes, because the workflow was only half the problem: 1. Discovery is now an allowlist (`fixtures/apis|openapi|specs|contracts`). A denylist leaks by construction: `.pre-commit-config.yaml` was the second file to slip through it, and `fixtures/workflows/*.yaml` -- workflow manifests, not specs -- would have been the third. 2. `detect_and_load` now raises `UnrecognizedSpecError` instead of a bare ValueError. "This file is not a contract" and "this contract is broken" are different conditions with different correct responses, and callers scanning a mixed directory need to tell them apart. The CLI reports the former with an actionable hint naming the accepted formats; malformed specs keep failing exactly as before. `UnrecognizedSpecError` subclasses ValueError, so existing handlers are unaffected. Verified: `apiverity validate .pre-commit-config.yaml` now reports "not an API contract" (exit 2) rather than a spec-load failure; a deliberately malformed OpenAPI document still fails as a load error; the crud fixture still validates clean. Full suite 184 passed, coverage 75.5% (gate 72%), ruff and mypy clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
webdevsamran
added a commit
that referenced
this pull request
Sep 7, 2026
…ease automation (#27) * fix: console-script entry point pointed at nonexistent symbol - pyproject [project.scripts] referenced apiverity.cli.main:cli which does not exist (main is the entry function); installed packages crashed on the apiverity command - correct CLI doc drift in ARCHITECTURE.md (argparse-based, not Click) - pin pre-commit ruff hook to v0.16.4 to match CI formatting - keep mypy python_version at 3.12 deliberately: the httpx stub chain uses PEP 695 syntax that cannot be parsed when targeting 3.11 * refactor(web): split single-file app into components/hooks/pages modules App.tsx was a 710-line monolith rendering all 31 pages. Now: - components/ui.tsx — shared presentational building blocks - hooks/useData.ts — demo-data loading hook - pages/ grouped by domain (overview, contract, testing, runtime, team) with pages/index.tsx as the page registry + navigation structure No behavior change; existing vitest suite passes unchanged. * refactor(cli): split main.py into lane-grouped commands package apiverity/cli/commands/ now owns implementations grouped by product lane: common.py (exit codes, spec loading, artifact-emission state via explicit setters), governance.py (validate/diff/breaking/changelog), testing.py (test/workflow/mock/coverage), runtime.py (drift/replay/baseline/regression), artifacts.py (report/export/serve), platform.py (server-db/plugins/rules/ self-test). main.py keeps parser wiring + main() and re-exports every cmd_* function so all external consumers stay source-compatible. Removed dead _start_mock helper. * refactor(server): extract schema and decision helpers from store/api - server/schema.py holds the explicit SQLite DDL plus timestamp/token helpers so the schema is inspectable without a connection - server/decision.py holds authenticate_safe, compute_can_i_deploy and run row mapping so deploy decisions are testable without Flask - Store and create_app keep their public signatures; apiverity.server.api re-exports the moved helpers for source compatibility * test: organize suite into unit/ and integration/; raise coverage floor to 72% - tests/unit/ — pure-logic suites (models, rules, generators, plugins) - tests/integration/ — suites exercising the mock server and the self-hosted Flask API over live HTTP - tests/README.md documents the layout; conftest.py unchanged at root - CI coverage gate raised from 60% to 72% (measured coverage: 76%) * build: release automation (PyPI trusted publishing, GHCR image), Dockerfile - .github/workflows/release.yml: tag-triggered pipeline that builds and twine-checks sdist/wheel, publishes to PyPI via OIDC trusted publishing (id-token only, no stored secrets), creates a GitHub Release with the artifacts, and builds/pushes a versioned server image to GHCR with GHA layer caching - Dockerfile: non-root python:3.12-slim image for the self-hosted server, volume-backed SQLite at /data (VERITY_DB/VERITY_PORT env config), HEALTHCHECK against /healthz; verified the CMD boot path locally (30 routes incl. /healthz) - .dockerignore keeps build context minimal - docs/self-hosting.md gains a Docker section; CHANGELOG + ARCHITECTURE module map updated * fix(gate): stop the contract gate failing on non-spec YAML The `contract-gate` job discovered "changed contracts" with a denylist (exclude package/lock/.github and a few directory prefixes). `.pre-commit- config.yaml` at the repo root matched none of those exclusions, so it was handed to `apiverity validate`, which correctly reported that no spec plugin could handle it -- and the gate turned that into "breaking changes or validation errors detected", blocking its own pull request (#27). Two changes, because the workflow was only half the problem: 1. Discovery is now an allowlist (`fixtures/apis|openapi|specs|contracts`). A denylist leaks by construction: `.pre-commit-config.yaml` was the second file to slip through it, and `fixtures/workflows/*.yaml` -- workflow manifests, not specs -- would have been the third. 2. `detect_and_load` now raises `UnrecognizedSpecError` instead of a bare ValueError. "This file is not a contract" and "this contract is broken" are different conditions with different correct responses, and callers scanning a mixed directory need to tell them apart. The CLI reports the former with an actionable hint naming the accepted formats; malformed specs keep failing exactly as before. `UnrecognizedSpecError` subclasses ValueError, so existing handlers are unaffected. Verified: `apiverity validate .pre-commit-config.yaml` now reports "not an API contract" (exit 2) rather than a spec-load failure; a deliberately malformed OpenAPI document still fails as a load error; the crud fixture still validates clean. Full suite 184 passed, coverage 75.5% (gate 72%), ruff and mypy clean. --------- Co-authored-by: webdevsamran <webdevsamran@users.noreply.github.com>
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.
Repo enhancement pass: fixes, modularization, release automation
Implements the full improvement plan from the repo analysis. Six commits, each independently revertable.
Fixed
[project.scripts]) referencedapiverity.cli.main:cli— a symbol that does not exist. Any installed copy of the package crashed on theapiveritycommand. Nowmain.python_versionkept at 3.12 deliberately, documented why (httpx stub chain uses PEP 695 syntax unparsable at 3.11).Frontend restructure
Single-file 710-line
App.tsx→components/ui.tsx+hooks/useData.ts+ domain-groupedpages/(overview,contract,testing,runtime,team) with a central page registry. Zero behavior change.CLI restructure
679-line
main.py→cli/commands/grouped by product lane (common,governance,testing,runtime,artifacts,platform).main.pyremains parser + stable entry point and re-exports allcmd_*. Removed dead_start_mock. Also fixed the console-script bug above here.Server restructure
Schema DDL + helpers →
server/schema.py; can-i-deploy/auth-fallback logic →server/decision.py. Public API unchanged (Store,create_app, helpers still importable fromapiverity.server.api).Tests
Suite organized into
tests/unit/andtests/integration/(files that exercise real servers);tests/README.mdadded; CI coverage floor raised 60% → 72% (measured: 76%).Release engineering
.github/workflows/release.yml: tag-triggered build + twine check → PyPI trusted publishing (OIDC, no stored tokens) → GitHub Release with artifacts → versioned GHCR container image for the server.Dockerfile(healthcheck on/healthz, volume-backed SQLite,VERITY_DB/VERITY_PORTconfig) +.dockerignore. CMD boot path verified locally (30 routes incl./healthz). Note: Docker daemon was not running locally, so the image build itself will be exercised by the workflow's first tagged run.Verification performed locally