Update release intake manifest automation - #3
Conversation
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughRelease intake workflow is automated to synchronize manifest.json with pushed release tags. A new manifest version helper function updates the manifest file, and the intake workflow detects mismatches, auto-updates the manifest on dev, force-pushes the corrected tag, and skips duplicate PRs via marker extraction. ChangesRelease Workflow Manifest Synchronization
Sequence DiagramsequenceDiagram
participant Git as Git / GitHub
participant Intake as release-intake.yml
participant Helper as set_manifest_version
participant Dev as dev branch
participant Main as main branch
Git->>Intake: Tag pushed (vX.Y.Z)
Intake->>Git: Fetch existing open PR
alt PR has matching markers
Intake-->>Git: Exit (duplicate)
else No matching markers
Intake->>Intake: Extract RELEASE_VERSION from tag
Intake->>Git: Read manifest @ TAG_SHA
Intake->>Intake: Compare CURRENT_VERSION
alt Versions differ
Intake->>Dev: Checkout dev branch
Intake->>Helper: set_manifest_version(RELEASE_VERSION)
Helper->>Dev: Update manifest.json
Intake->>Dev: Commit & push manifest change
Intake->>Git: Force-update tag to new TAG_SHA
else Versions match
Intake->>Intake: Assert manifest alignment
end
Intake->>Git: Create PR (dev → main)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
#3: the watchdog rebuild (_start + _subscribe_appliances) sat outside try/except in 'while True', so a transient error (load_aws_token 5xx, subscribe timeout) ended the task and left realtime dead until a reload. Wrap the loop body: re-raise asyncio.CancelledError FIRST (stop() cancels+awaits the task, so swallowing it would deadlock shutdown), and on any other error log a WARNING (exc_info) and keep looping with an additive backoff (capped at 60s, reset on recovery) so a persistent 5xx is not hammered every tick. #13: _subscribe used a blocking awscrt future .result(_SUBSCRIBE_TIMEOUT), freezing the hon_loop up to 10s per topic. Make _subscribe/_subscribe_appliances async and await asyncio.wait_for(asyncio.wrap_future(future), _SUBSCRIBE_TIMEOUT) instead, yielding the loop while keeping the order and the timeout bound. Also use the null-tolerant _subscribed_topics() helper. Tests: watchdog survives a raising _start, propagates CancelledError, backoff grows/resets/caps; subscribe preserves order, yields the loop, honours the timeout.
#3: the watchdog rebuild (_start + _subscribe_appliances) sat outside try/except in 'while True', so a transient error (load_aws_token 5xx, subscribe timeout) ended the task and left realtime dead until a reload. Wrap the loop body: re-raise asyncio.CancelledError FIRST (stop() cancels+awaits the task, so swallowing it would deadlock shutdown), and on any other error log a WARNING (exc_info) and keep looping with an additive backoff (capped at 60s, reset on recovery) so a persistent 5xx is not hammered every tick. #13: _subscribe used a blocking awscrt future .result(_SUBSCRIBE_TIMEOUT), freezing the hon_loop up to 10s per topic. Make _subscribe/_subscribe_appliances async and await asyncio.wait_for(asyncio.wrap_future(future), _SUBSCRIBE_TIMEOUT) instead, yielding the loop while keeping the order and the timeout bound. Also use the null-tolerant _subscribed_topics() helper. Tests: watchdog survives a raising _start, propagates CancelledError, backoff grows/resets/caps; subscribe preserves order, yields the loop, honours the timeout.
#3: the watchdog rebuild (_start + _subscribe_appliances) sat outside try/except in 'while True', so a transient error (load_aws_token 5xx, subscribe timeout) ended the task and left realtime dead until a reload. Wrap the loop body: re-raise asyncio.CancelledError FIRST (stop() cancels+awaits the task, so swallowing it would deadlock shutdown), and on any other error log a WARNING (exc_info) and keep looping with an additive backoff (capped at 60s, reset on recovery) so a persistent 5xx is not hammered every tick. #13: _subscribe used a blocking awscrt future .result(_SUBSCRIBE_TIMEOUT), freezing the hon_loop up to 10s per topic. Make _subscribe/_subscribe_appliances async and await asyncio.wait_for(asyncio.wrap_future(future), _SUBSCRIBE_TIMEOUT) instead, yielding the loop while keeping the order and the timeout bound. Also use the null-tolerant _subscribed_topics() helper. Tests: watchdog survives a raising _start, propagates CancelledError, backoff grows/resets/caps; subscribe preserves order, yields the loop, honours the timeout.
, #4) #3 - one seam, oauth.absolutize(), resolves every scraped login href against the auth host whether it comes back relative or absolute. It is byte-identical to the old `AUTH_API + href` on the live path, and fixes the contradictory _get_token branch: one fetch assumed the href was absolute (a relative href crashed the base_url-less ClientSession with InvalidUrlClientError), the other assumed it was relative (string concat corrupted an absolute href). Applied to every login fetch (_get_token first GET / ProgressiveLogin GET / token GET, _manual_redirect, _open_login_page). Host-pin: an off-host result whose scheme aiohttp would actually connect (http/https/ws/wss/tcp) is re-pinned to the auth host, demoting the foreign host to a path segment via urlunsplit. The check is on the RESOLVED host (yarl-verified across ~250k fuzz cases, 0 escapes), so it cannot be slipped by a protocol-relative '//host', a whitespace/control-char bypass, a scheme-mismatch empty authority ('http:///'), or a non-http but fetchable scheme. The login flow never legitimately leaves account2.hon-smarthome.com (_api_auth/refresh/api.py do not pass through it). #4 - MFAChallengeRequired now DECLARES the `client` field (was a dynamic attribute set in the config flow), so the 2FA handoff carry is part of the exception contract and _mfa_begin reads err.client directly instead of a silent getattr fallback. tests: StrictUrlFakeSession (rejects non-absolute URLs like aiohttp without base_url), absolutize byte-identity + host-pin/bypass cases, MFA declared-field carry. All mutation-proven; full suite green in the CI pytest-only environment.
Maintenance PR for release automation. This is not a release PR and intentionally has no release markers. It updates release-intake so future release tags automatically update manifest.json from the tag version.
Summary by CodeRabbit
Documentation
Chores