Skip to content

fix(validation): bundle schemas before wheel builds#898

Merged
bokelley merged 1 commit into
mainfrom
issue-897
May 28, 2026
Merged

fix(validation): bundle schemas before wheel builds#898
bokelley merged 1 commit into
mainfrom
issue-897

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Summary

  • run schema bundling before release-package builds so published wheels/sdists include adcp/_schemas
  • run schema bundling in the CI wheel smoke build so tested wheels match release packaging
  • surface missing SDK-pinned schema bundles at warning level while keeping explicit unsupported version= misses quiet

Fixes #897

Validation

  • expert review: DX/release packaging pass found the direct CI wheel-build gap; addressed in this PR
  • expert review: code review pass found explicit-version warning noise; addressed with regression tests
  • uv run --extra dev --group dev pytest tests/test_schema_loader_per_version.py tests/test_legacy_schema_bundle_v2_5.py tests/test_schema_validation.py tests/test_validation_version.py
  • uv run --extra dev --group dev pytest tests/ -v --cov=src/adcp --cov-report=term-missing
  • uv run --extra dev --group dev ruff check src/ tests/test_schema_loader_per_version.py
  • uv run --extra dev --group dev mypy src/adcp/
  • uv run --extra dev --group dev mypy --strict tests/type_checks/
  • uv run --extra dev --group dev python scripts/check_type_ignore_contract.py
  • uv run --extra dev --group dev python scripts/bundle_schemas.py && uv run --extra dev --group dev --with build python -m build --wheel --outdir dist/
  • verified built wheel contains 3468 adcp/_schemas/*.json entries

Copy link
Copy Markdown
Contributor

@aao-ipr-bot aao-ipr-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Fix is the right shape — bundle before build at both CI smoke and release plumbing, and warn (not debug) when the SDK pin can't find its own bundle.

Things I checked

  • _ensure_state discrimination at src/adcp/validation/schema_loader.py:189-197: log_missing = logger.warning if version is None else logger.debug is correct. SDK-pinned miss = packaging bug worth surfacing; explicit version= miss = caller asked for a bundle we don't ship, stays quiet. Fail-closed beats fail-open here.
  • One-shot warning behavior. _state_misses.add(bundle_key) at L196 plus the early returns at L179 and L187 mean the warning fires exactly once per bundle_key per process. No log spam in long-lived workers.
  • Both new tests at tests/test_schema_loader_per_version.py:194-223 wrap in _reset_for_tests() before and after, so _state_misses is clean across the assertion window. The monkeypatch on _resolve_schema_root exercises the branch as intended.
  • Workflow gating in .github/workflows/release-please.yml:98-100: same release_created || workflow_dispatch+publish condition as the existing build step. Symmetric.
  • CI smoke build at .github/workflows/ci.yml:171-175 now bundles before python -m build --wheel, so the smoke wheel matches the release wheel shape. The validation gap that hid #897 is closed.
  • No public-API drift. schema_loader is reachable from adcp.validation, but the change is logger-level only.

Follow-ups (non-blocking — file as issues)

  • Wheel-content assertion in CI. Three lines (python -m zipfile -l dist/*.whl | grep -q 'adcp/_schemas/.*\.json') on the smoke job would have caught #897 the first time, and is cheap insurance against any future regression in bundle_schemas.py, package-data globs, or workflow ordering. Notable that a PR landing schema-bundling into CI doesn't also assert the schemas ended up in the wheel.
  • Move bundling into the build backend. Anyone running python -m build outside this workflow — local release, downstream rebuild, uv build, vendor repackaging — reproduces #897. A setuptools build_py subclass or an in-tree PEP 517 backend wrapper would make the wheel correct by construction. The current CI-step approach is a workaround at the wrong layer.
  • warnings.warn vs logging.warning for the implicit-bundle miss. logger.warning is invisible to adopters who haven't configured the adcp.validation logger — the common case on a first-touch broken install. A once-per-process warnings.warn would surface in pytest and most app harnesses without logger config. Not blocking — warning is a strict improvement over debug either way.

Minor nits (non-blocking)

  1. Negative test could be tighter. tests/test_schema_loader_per_version.py:215-223 asserts the specific string isn't in caplog.records. Asserting not any(r.levelno >= logging.WARNING for r in caplog.records) would also catch a regression that emits a different message at warning level on the explicit-version path.

Approving on the strength of the gating-condition symmetry plus the one-shot-warning behavior.

@bokelley bokelley merged commit 0cdcf29 into main May 28, 2026
26 checks passed
@bokelley bokelley deleted the issue-897 branch May 28, 2026 12:34
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.

Package beta.5 without _schemas causes schema validation to skip

1 participant