Release 0.2.1a1 - #70
Open
github-actions[bot] wants to merge 38 commits into
Open
Conversation
chore: Configure Renovate
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
The release used TigreGotico/gh-automations/publish-alpha.yml@master with inline 'python setup.py sdist bdist_wheel' on Python 3.14, failing with ModuleNotFoundError: setuptools — so every alpha release failed and merged dep fixes (ovos-bus-client<3.0.0) never reached PyPI. Switched to the standard OpenVoiceOS/gh-automations/publish-alpha.yml@dev (reads version from version.py, builds with python -m build), matching ovos-audio. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor: migrate packaging to pyproject.toml Replace setup.py + requirements.txt + MANIFEST.in with a single pyproject.toml (PEP 621), dynamic version from ovos_messagebus/version.py. Verified the wheel builds with correct console scripts and bundled resources. (Release workflow already modernized on dev in a prior PR.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: use shared reusable build/publish workflows (pyproject) Replace bespoke build_tests + install_tests + publish_stable (which ran 'python setup.py ...', now removed) with the shared OpenVoiceOS reusable workflows (build-tests/publish-stable @dev), matching ovos-core. build-tests builds via 'python -m build' and installs the wheel. Also removes the NeonGecko build-tests reusable (neongeckocom/.github) per the no-Neon policy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cit get_event_loop (#62) tornado's IOLoop relies on there being a current asyncio event loop. On the main thread, application.listen() implicitly created one via the deprecated asyncio.get_event_loop() alias, and the daemon thread started ioloop.IOLoop.instance().start() (also a deprecated alias) without ever setting a loop on that thread. This logged "DeprecationWarning: There is no current event loop" under python -W always, and will break outright once get_event_loop() stops creating implicit loops. Move application.listen() and ioloop.IOLoop.current().start() into a single function that runs entirely on the daemon thread, first creating and setting an explicit asyncio event loop with asyncio.new_event_loop() / asyncio.set_event_loop(). Behavior and public API are unchanged.
* fix: read ssl from the websocket config section load_message_bus_config() read host/port/route from the `websocket` config section but read `ssl` from the top-level config instead, so the documented `websocket.ssl` key was never honoured. ovos-bus-client does read `websocket.ssl` and builds a `wss://` URL from it, so a user who sets the documented key ends up with clients dialing wss:// against a server that still speaks plain ws:// - breaking the install instead of encrypting it. This does not add TLS termination (needs cert/key config that doesn't exist yet); it fixes the key read and logs a warning at startup if ssl resolves truthy, pointing at a reverse proxy as the supported way to terminate TLS in front of this server. * fix: remove misleading TLS-termination warning websocket.ssl is a client-side setting consumed by ovos-bus-client to build a wss:// URL. It is entirely valid to run ovos-messagebus behind a TLS-terminating reverse proxy and set websocket.ssl: true so clients dial wss://. The warning added in the previous commit assumed the server itself must terminate TLS, which is false, and would fire on every startup of a correctly configured reverse-proxy deployment, telling the operator their working setup is broken. Remove it; the underlying config-section fix (ssl read from `websocket`, not top-level) stays.
* feat: serve wss:// when websocket.ssl is set _run_bus() now passes ssl_options to Tornado's application.listen() when websocket.ssl is truthy, so the server actually terminates TLS itself instead of silently continuing to speak plain ws:// while clients (per ovos-bus-client build_url()) dial wss://. Certificate resolution, in order: - websocket.ssl_cert / websocket.ssl_key if both are configured - otherwise a self-signed pair is generated (or reused if already present) via ovos_utils.security.create_self_signed_cert() under $XDG_DATA_HOME/OpenVoiceOS/ovos-messagebus/certs pyopenssl is not a hard dependency of ovos-messagebus or ovos-utils (create_self_signed_cert requires it internally). It is imported lazily only inside the ssl branch; if missing, a clear RuntimeError is raised instead of silently falling back to plain ws://, since a baffling TLS handshake failure at the client is worse than a loud startup error at the server. * refactor: bundle self-signed cert generator instead of ovos-utils ovos_utils.security.create_self_signed_cert generates a 1024-bit RSA/SHA-1 pair that OpenSSL 3 refuses to load (EE_KEY_TOO_SMALL), and the helper is being removed from ovos-utils upstream. Add ovos_messagebus/ssl_utils.py with an equivalent generator using the cryptography library (RSA-2048/SHA-256, subjectAltName covering the hostname/localhost/127.0.0.1, reuse-if-present), and point _get_ssl_options() at it. Declare pyopenssl as an optional 'ssl' extra, matching the [project.optional-dependencies] style introduced on PR #51. * fix: declare cryptography (not pyopenssl) as the ssl extra ssl_utils.py imports cryptography directly, not pyOpenSSL. Fix the optional-dependency declaration and the RuntimeError/docstring text in _get_ssl_options() to name the package actually imported and the 'ovos-messagebus[ssl]' extra that installs it. Collapse the two byte-identical RuntimeError blocks into a shared _missing_cryptography_error() helper. cryptography>=3.4 was verified (not guessed) to support the x509.CertificateBuilder API surface used, including timezone-aware not_valid_before/not_valid_after.
* benchmark: add live measurements for all three backends (Tornado, webrockets, Rust) - Ran benchmark/run_benchmark.py at 4 load levels (5/20/50/100 clients) against Tornado, webrockets, and ovos-rust-messagebus v1.1.2 - Updated docs/backends.md: full 3-backend comparison tables with min/median/p95/p99/max latency columns; updated observations - Updated FAQ.md: added Rust column to benchmark table, added "Rust connection saturation at 100 clients" Q&A - Updated MAINTENANCE_REPORT.md with two transparency entries Key results (vs Tornado baseline): 5c×200m: Rust +18%, webrockets +11% 20c×1000m: Rust +20%, webrockets +9% 50c×2000m: webrockets +24%, Rust +20% 100c×500m: webrockets +4%, Rust ⚠ 28 conn errors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: modernize workflows to latest gh-automations standards New workflows added: - unit_tests.yml — test.yml@dev, triggers on push+PR to dev - coverage.yml — coverage.yml@dev with pr_comment - pip_audit.yml — pip-audit.yml@dev with pr_comment - lint.yml — lint.yml@dev (ruff) with pr_comment Updated workflows: - build_tests.yml: add python_versions matrix [3.10–3.13], pr_comment, trigger on dev push as well as master - license_tests.yml: add secrets: inherit, fix empty `with:`, trigger on dev push as well as master Removed: - install_tests.yml (replaced by build_tests.yml matrix) All workflows use @dev ref per workspace conventions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: address all CodeRabbit review comments Bug fixes: - load_config.py: ssl=False override was silently ignored due to falsy `or` logic; replaced with `overrides['ssl'] if 'ssl' in overrides` - event_handler.py: filter=True mode returned before broadcast on deserialization failure, dropping malformed frames; now logs at DEBUG and broadcasts raw payload unchanged (matches webrockets behavior) Improvements: - webrockets_backend.py: replace fixed 0.3s sleep with socket-based readiness probe (_wait_for_server_ready); add DEBUG log on deserialization failure instead of silent except - requirements.txt: sync minimums to match pyproject.toml (ovos_bus_client >=1.3.0, ovos-utils >=0.8.0) Tests (47 total, +20): - test_event_handler.py: add TestOnMessage — filter=False/True with valid, malformed JSON, and non-OVOS dict payloads (4 new tests) - test_load_config.py: add ssl override precedence regression tests (ssl=False wins, ssl=True wins, fallback to config) (3 new tests) - test_webrockets_backend.py: add TestWaitForServerReady (port open, timeout graceful); update TestMain to patch _wait_for_server_ready instead of time; use sys.modules.setdefault for stub isolation (3 new tests, 2 updated) Docs: - docs/configuration.md: move ssl to top-level JSON example, add note that it is NOT nested under websocket - docs/events.md: clarify filter mode delivery guarantee (malformed frames are still forwarded after fix) - docs/server.md: fix "class-level set" → "module-level list" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: cross-reference defaults from ovos-config; fix ssl config key; add test extra Bug fixes: - load_config.py: ssl was read from config top-level (config.get('ssl')) but mycroft.conf defines it under websocket; now reads from websocket_configs.get('ssl') matching the actual default config Docs corrected against ovos_config/mycroft.conf source of truth: - docs/configuration.md: move ssl back under websocket in JSON example; correct host default 0.0.0.0 → 127.0.0.1; correct max_msg_size default 10 → 25 (per ovos_config/mycroft.conf); add citation to source - docs/server.md: update ssl source citation pyproject.toml: - add [test] optional-dependency group with pytest>=7.0 and pytest-cov>=4.0 so local test runs don't need external tooling Tests: - test_load_config.py: update VALID_WS_CONFIG to nest ssl under websocket (matching actual ovos-config defaults); update ssl regression tests to use websocket-nested ssl key; fix host assertion 0.0.0.0 → 127.0.0.1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: drop maintenance report scratch file * docs: reconcile SSL/TLS claims now that Tornado terminates wss:// itself The Tornado backend now serves wss:// directly (websocket.ssl / ssl_cert / ssl_key). Update the webrockets backend docstring, runtime warning, and docs/backends.md, docs/configuration.md, docs/index.md, docs/server.md and FAQ.md so none of them still claim or imply that no backend supports TLS, and so operators are pointed at the Tornado backend as the real option for server-terminated TLS instead of only a reverse proxy. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
webrockets cannot terminate TLS (no cert/key option in its Python API), so _build_server() previously only logged a warning and started a plaintext server while ovos-bus-client clients dial wss://. Raise a RuntimeError instead, routed through main()'s existing error_hook/re-raise path, so the server never starts and the failure is actionable: use the Tornado backend (serves wss:// directly) or terminate TLS with a reverse proxy and leave websocket.ssl unset for this process. Also bound the unpinned webrockets dependency to >=0.2.1,<0.3.0 — verified against upstream's 0.2.1 API docs that WebsocketServer, create_route, route.connect/receive/disconnect and conn.broadcast are unchanged from what this backend calls.
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.
Human review requested!