chore: re-track CI workflows + test infra (follow-up to #784)#786
chore: re-track CI workflows + test infra (follow-up to #784)#786
Conversation
The April 2026 commit 6d056b3 ("remove non-HACS files from tracking") untracked .github/workflows/ along with conftest.py and pytest.ini. Effects accumulated invisibly: - Test CI hasn't run on any PR since April 15 (test.yml never reached GitHub Actions). - HACS validate.yml never ran — risk of shipping a broken manifest goes uncaught until someone notices. - version-bump.yml silently froze _VERSION at 3.2.0-rc29 for 2+ months before #784 surfaced it (fixed in #785 by reading manifest.json). This commit re-tracks what CI needs and deletes what's now obsolete: Re-track: - .github/workflows/test.yml — lint + pytest CI gate - .github/workflows/validate.yml — HACS + hassfest validation - conftest.py (root) — stubs homeassistant modules so tests can import beatify without a real HA install (without this, CI hits a metaclass conflict at collection time) - pytest.ini — asyncio_mode = auto, testpaths = tests, pythonpath = . Delete (obsolete): - .github/workflows/version-bump.yml — replaced by #785's manifest.json read at setup_entry; this workflow can never run again on GitHub anyway since the file has been untracked for 2+ months - .github/workflows/pages.yml — was deploying docs/, but docs/ is also untracked; nothing to deploy The .gitignore now explicitly whitelists test.yml + validate.yml under .github/workflows/ so additional contributor-only experiments under .github/ stay out of git unless deliberately whitelisted. Heads up: re-tracking test.yml will surface 6 pre-existing test failures in test_lights.py / test_state.py / test_websocket.py that have been broken since before April. The first PR after this lands will show red CI. That is the correct signal — these tests were broken silently for two months. Worth a follow-up to fix or quarantine them, but out of scope here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request restores CI functionality by whitelisting specific GitHub workflows and test infrastructure in .gitignore, and introduces a root conftest.py to stub Home Assistant modules for isolated testing. A review comment suggests automating the wiring of the stubbed module hierarchy in conftest.py to ensure consistent access to nested modules and prevent potential attribute errors.
| # Wire child attributes onto parent packages so `from homeassistant.X import Y` works | ||
| _ha = sys.modules["homeassistant"] | ||
| _ha.components = sys.modules["homeassistant.components"] # type: ignore[attr-defined] | ||
| _ha.helpers = sys.modules["homeassistant.helpers"] # type: ignore[attr-defined] | ||
| _ha.util = sys.modules["homeassistant.util"] # type: ignore[attr-defined] |
There was a problem hiding this comment.
The manual wiring of stubbed modules is incomplete and only covers one level of depth. This will cause AttributeError when accessing nested modules (e.g., homeassistant.components.media_player) via their parent modules if the parent is a ModuleType (as defined in _PACKAGES).
Additionally, for nested mocks (like media_player.const), this manual approach can lead to identity mismatches where the mock attribute on the parent is a different object than the one registered in sys.modules. Automating this wiring ensures the entire hierarchy is correctly linked and consistent across the test environment.
| # Wire child attributes onto parent packages so `from homeassistant.X import Y` works | |
| _ha = sys.modules["homeassistant"] | |
| _ha.components = sys.modules["homeassistant.components"] # type: ignore[attr-defined] | |
| _ha.helpers = sys.modules["homeassistant.helpers"] # type: ignore[attr-defined] | |
| _ha.util = sys.modules["homeassistant.util"] # type: ignore[attr-defined] | |
| # Wire child attributes onto parent packages so hierarchy is traversable | |
| for _name in sorted(sys.modules.keys()): | |
| if _name.startswith("homeassistant."): | |
| _parent_name, _, _child_name = _name.rpartition(".") | |
| if _parent_name in sys.modules: | |
| setattr(sys.modules[_parent_name], _child_name, sys.modules[_name]) |
chore: ruff fix + format cleanup (CI debt from #786)
Follow-up to #784. The April commit `6d056b35` untracked `.github/workflows/` plus root `conftest.py` + `pytest.ini`. Effects accumulated invisibly:
Changes
Re-tracked (CI dependencies):
Deleted (now obsolete):
`.gitignore` now whitelists the two CI workflows under `.github/workflows/` and explicitly un-ignores `conftest.py` + `pytest.ini`.
Heads up: red CI incoming
Re-tracking `test.yml` will surface 6 pre-existing failures in `test_lights.py` / `test_state.py` / `test_websocket.py` that have been broken since before April:
```
FAILED tests/unit/test_lights.py::TestStartStop::test_stop_handles_service_call_error
FAILED tests/unit/test_lights.py::TestApplyCapability::test_apply_handles_service_error
FAILED tests/unit/test_lights.py::TestApplyCapability::test_apply_continues_after_one_light_fails
FAILED tests/unit/test_state.py::TestAddPlayer::test_add_duplicate_name_rejected
FAILED tests/unit/test_state.py::TestAddPlayer::test_duplicate_name_case_insensitive
FAILED tests/unit/test_websocket.py::TestPlayerOnboarded::test_players_state_includes_onboarded
```
385 pass + 6 fail + 1 xfail. The 6 failures are pre-existing; this PR does not introduce them. The first merge to main after this lands will show red CI — that's the correct signal. Worth a follow-up to fix or quarantine, but deliberately out of scope here so this PR stays a clean infra change.
Why no version bump
This is repo-level infra, not anything that ships to HACS users. The integration is unchanged — `manifest.json` and `sw.js` stay at `3.3.1-rc7`.
🤖 Generated with Claude Code