feat(config)!: migrate entries to v3 — one address, no androidtv key (t41)

ENTRY_VERSION = 3, declared once in const.py and reused as the flow's VERSION so
the stored shape and the migration cannot drift.

v2 → v3 mirrors the two shape changes:
* the duplicated address fields collapse into CONF_HOST — the protocol host
  wins, else the ADB host (both name the same Shield), reading options first and
  data second so a hand-written seed is covered too;
* the androidtv-entity key is dropped from data AND options with a logged note
  naming the dropped entity (the old value would only mislead now that nothing
  reads it).

A v1 entry still travels the whole way in one call (the v1→v2 protocol defaults
are applied, then the v3 collapse). Downgrades (version > 3) are rejected so HA
can offer a rollback, and the current version is a no-op.

Existing entries carrying the entity key keep working until the migration runs:
nothing reads it anymore (the c1 commit), which is exactly why the migration can
be a plain removal.

Test note: my first version of the version-parity pin called a bare
entity_stublib.install() and leaked the shallow stub set into the entity-module
loader of later tests (STATE_PAUSED/entity_available import failures). It now
uses the file's scoped harness, like every other test there.

Verified: 316 passed / 2 skipped, 317 / 1 with androidtvremote2, ruff clean,
drift engine exit 0 on HEAD (36 call arguments — one more awaited/checked call).
This commit is contained in:
James Mackay committed 2026-10-11 06:19:36 +01:00
1 parent 75ebeb40b0
commit 81f70585cd
5 files changed
+187 -46

No files matched your search

@@ -33,6 +33,7 @@ from .const import (
DEFAULT_ADB_PORT,
DEFAULT_NAME,
DOMAIN,
ENTRY_VERSION,
)
from .helpers import entry_host, protocol_cert_paths, seed_adb_enabled, seed_host
@@ -190,7 +191,7 @@ def _build_selectors():
class NvidiaShieldConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Nvidia Shield."""
VERSION = 2
VERSION = ENTRY_VERSION
def __init__(self):
self._user_data = {}