Fix Read the Docs build, add Docker dev environment and standards sync - #24
Open
jtdub wants to merge 6 commits into
Open
Fix Read the Docs build, add Docker dev environment and standards sync#24jtdub wants to merge 6 commits into
jtdub wants to merge 6 commits into
Conversation
Switch the hier-config dependency from the git checkout / 3.x range to the 4.0.0b1 beta from PyPI, using a specifier that explicitly includes the prerelease so pip and poetry resolve it. v4 removes the module-level constructor functions, so replace all get_hconfig(platform, text) calls in the service layer with the v4 classmethod HConfig.from_text(platform, text) per the official v3-to-v4 migration guide. No other v3-only APIs (config_to_get_to, dump_simple, tags_add/tags_remove, v2 compatibility helpers, negation rule models) were in use, and WorkflowRemediation is unchanged in v4, so no further code changes are required. poetry.lock is regenerated against the new pin; all 21 tests plus ruff, ruff format, and mypy strict pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adopt the development standards from the hier_config repository so both projects share one toolchain: ruff (ALL rules, preview, line length 88), mypy strict with the pydantic plugin, pyright strict, pylint with extension plugins and pylint_pydantic, yamllint, and flynt, all driven by the parallel runner in scripts/build.py. Coverage is enforced at 95% via 'build.py pytest --coverage' (--cov=hier_config_api). Dev dependencies gain pyright, pylint-pydantic, pytest-xdist, yamllint, flynt, and typer; pytest-asyncio is dropped because the test suite has no async tests. The mypy ignore_missing_imports overrides for hier_config are removed since hier_config 4.x ships py.typed. CI now mirrors hier_config: a Python 3.10-3.14 matrix running 'build.py lint' and 'build.py pytest --coverage' on push/PR to develop and next, and the docs job builds with 'mkdocs build --strict' and deploys to GitHub Pages on push to develop (the default branch; it previously only triggered on the nonexistent main branch). This repo has no CHANGELOG.md, so the change is recorded here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fix all violations surfaced by the hier_config lint stack (64 ruff errors, 22 pyright errors, and 12 pylint messages beyond ruff's fixes): - Routers: drop redundant response_model arguments (FAST001), move to Annotated[..., Query()] dependencies (FAST002/B008), rename the export 'format' parameter to export_format with a query alias to avoid shadowing the builtin (A002), and restructure try blocks so each guards a single statement (pylint too-many-try-statements), extracting small orchestration helpers where several calls must be error-wrapped together. - Services: replace typing.Any parameters with HConfig | HConfigChild (ANN401), pass MatchRule/GenerateRemediationRequest models instead of long argument lists (PLR0913/PLR0917), split boolean-heavy matching into a helper (PLR0916), mark PLATFORMS as ClassVar (RUF012), restructure batch processing so the per-device try/except lives outside the loop body (PERF203), and assign exception messages to a variable before raising (EM102/TRY003). - Models: use keyword 'default=' in Field() calls so pyright's strict dataclass_transform handling recognizes optional fields, and use a named module-level default factory for the ordering field. - Annotate empty-list literals so pyright strict can infer element types. Justified suppressions, each with an explanatory comment: - BLE001/broad-exception-caught in validate_config and batch device processing, where any failure must be reported as data, not raised. - S104 on the dev/container uvicorn entry point binding 0.0.0.0. - T201/S404/S603 in scripts/build.py (a console tool that prints and spawns the lint/test processes), replacing the upstream file's invalid 'ruff:ignore' comments with real noqa directives. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Coverage sat at 89.4% once the hier_config coverage gate was enforced. Add function-based, fully annotated tests for the previously uncovered paths: the root and health endpoints, 404 responses for unknown remediations, reports, and batch jobs, 400 responses when parsing fails (via monkeypatched HConfig.from_text) or a search regex is invalid, the invalid export format guard, YAML export and tag-filtered change queries, per-device failure recording in batch jobs, storage updates for unknown IDs, remediation tag include/exclude filtering, and merge/search service edge cases. Total coverage is now 95.9% with no '# pragma: no cover' exclusions. Update CLAUDE.md and the README development section to document the scripts/build.py commands, the lint/typing stack, the coverage floor, and the new CI matrix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Releases were previously manual with no defined process. Add two GitHub Actions workflows: Prepare Release (admin-gated workflow_dispatch that bumps the version with poetry, opens a release/vX.Y.Z PR against the dispatched branch, and creates a draft GitHub release) and Release (publishes to PyPI via poetry publish when a release is published — the published event, not created, so publishing a draft triggers it). Document the three-step process in the README. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Read the Docs produced no usable build. The config ran `poetry install` without pointing VIRTUAL_ENV at the environment Read the Docs runs mkdocs from, so Poetry created its own virtualenv and mkdocs was never installed where the build could find it. It also declared a second, conflicting install path via docs/requirements.txt. Point the install at $READTHEDOCS_VIRTUALENV_PATH and drop the requirements file, leaving pyproject.toml as the single source of docs dependencies. The package itself must be installed because the mkdocstrings reference pages import it, so the simpler requirements-only approach used by hier_config does not work here. Add a Docker development environment driven by invoke tasks, and adopt the shared standards published by netdevops/hier_config: build.py, sync_standards.py, .yamllint.yml, and .dockerignore now come from there via the .standards.yml manifest, with hier_config rewritten to hier_config_api as they are fetched. A scheduled workflow applies the sync weekly and opens a PR so CI validates the update before it merges. Relax the ruff pin from <0.15 to ^0.16 to match the canonical repository. The old pin was the reason scripts/build.py had diverged: ruff 0.14 does not understand the `# ruff: ignore[...]` directive the canonical file uses. On 0.16 that directive is not merely accepted but required, so the existing `# noqa` comments were converted. Add pytest-profiling for the --profile option the canonical build.py exposes. With those aligned, `invoke sync-standards` reports zero drift. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.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.
Read the Docs
The build produced nothing usable.
.readthedocs.yamlranpoetry installwithout pointingVIRTUAL_ENVat the environment Read the Docs runs mkdocs from, so Poetry created its own virtualenv and mkdocs was never installed where the build could find it. It also declared a second, conflicting install path viadocs/requirements.txt.Fixed by installing into
$READTHEDOCS_VIRTUALENV_PATHand deletingdocs/requirements.txt, leavingpyproject.tomlas the single source of docs dependencies. Note this deliberately does not copyhier_config's simpler requirements-only approach: the mkdocstrings reference pages importhier_config_api, so the package itself has to be installed in the docs environment.Docker development environment
Dockerfileis multi-stage —developmentcarries the full toolchain,productiononly runtime dependencies.docker-compose.ymlbind-mounts the repo for hot reload, with an opt-indocsprofile for live-reload mkdocs on :8001.Driven by invoke tasks (
tasks.py), matching the task names used across the hier-config projects:serveis this repo's addition to the shared set, since a library has no process to serve.Shared standards
Adopts the model added in netdevops/hier_config#298.
scripts/build.py,scripts/sync_standards.py,.yamllint.yml, and.dockerignoreare now pulled from that repository via the.standards.ymlmanifest, withhier_configrewritten tohier_config_apias files are fetched..github/workflows/sync-standards.ymlapplies the sync weekly and opens a PR, so CI validates canonical changes before they land.master, sosync-standardsreports the new files as unpublished until that merges. Everything else here stands alone.The ruff pin
Worth a careful look, as it is the largest behavioral change. This repo pinned
ruff >=0.14.14,<0.15; the canonical repo tracks 0.16. That pin was the cause of thebuild.pydivergence — ruff 0.14 does not understand the# ruff: ignore[...]directive the canonical file uses, so this repo's copy had been rewritten to# noqaand the two could never converge.Relaxing to
^0.16flips the relationship: under 0.16's preview rules that directive is not merely accepted but required, so the pre-existing# noqacomments inmain.pyandplatform_service.pywere converted. Also addspytest-profilingfor the--profileoption the canonicalbuild.pyexposes.With those aligned,
invoke sync-standardsreports zero drift onscripts/build.py.Verification
poetry run python scripts/build.py lint— clean on ruff 0.16poetry run mkdocs build --strict— clean/api/openapi.jsonpoetry run python scripts/sync_standards.py check— zero drift on the already-published files🤖 Generated with Claude Code