Skip to content

Repo enhancement pass: entry-point fix, modularization, test org, release automation - #27

Merged
webdevsamran merged 7 commits into
mainfrom
chore/repo-enhancements
Sep 7, 2026
Merged

Repo enhancement pass: entry-point fix, modularization, test org, release automation#27
webdevsamran merged 7 commits into
mainfrom
chore/repo-enhancements

Conversation

@webdevsamran

Copy link
Copy Markdown
Owner

Repo enhancement pass: fixes, modularization, release automation

Implements the full improvement plan from the repo analysis. Six commits, each independently revertable.

Fixed

  • Console-script entry point ([project.scripts]) referenced apiverity.cli.main:cli — a symbol that does not exist. Any installed copy of the package crashed on the apiverity command. Now main.
  • ARCHITECTURE.md described the CLI as "Click-based"; it is argparse-based.
  • pre-commit ruff hook pinned to v0.16.4 to match CI formatting (was v0.5.5).
  • mypy python_version kept at 3.12 deliberately, documented why (httpx stub chain uses PEP 695 syntax unparsable at 3.11).

Frontend restructure

Single-file 710-line App.tsxcomponents/ui.tsx + hooks/useData.ts + domain-grouped pages/ (overview, contract, testing, runtime, team) with a central page registry. Zero behavior change.

CLI restructure

679-line main.pycli/commands/ grouped by product lane (common, governance, testing, runtime, artifacts, platform). main.py remains parser + stable entry point and re-exports all cmd_*. 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 from apiverity.server.api).

Tests

Suite organized into tests/unit/ and tests/integration/ (files that exercise real servers); tests/README.md added; 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.
  • Hardened non-root Dockerfile (healthcheck on /healthz, volume-backed SQLite, VERITY_DB/VERITY_PORT config) + .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.
  • Docs updated: self-hosting Docker section, CHANGELOG entries, ARCHITECTURE module map.

Verification performed locally

Check Result
pytest (full suite) 181 passed
Coverage 76% (> new 72% floor)
mypy --strict clean, 83 files
ruff 0.16.4 check + format --check all green
scripts/e2e.py PASSED
web lint / vitest / vite build clean · 3/3 · built in ~0.7s
Workflow YAML validity all 4 workflows parse, jobs present

- 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
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@github-actions

Copy link
Copy Markdown

API Verity — contract review

One 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
webdevsamran merged commit d35fc80 into main Sep 7, 2026
8 checks passed
@webdevsamran
webdevsamran deleted the chore/repo-enhancements branch September 7, 2026 04:21
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant