The evidence this fixes: v2026.10.09 was published while master's manifest still read 2026.10.08, so HACS compared every install against a version that never moved and offered nobody that update. A second release in the same UTC day was also a silent no-op: the date tag already existed, the run resolved to the same version again, and it stopped at "already tagged". * scripts/determine-release-version.sh owns the decision, so it is tested rather than hoped for: the manifest version while it is untagged (bump it to force a release); else today's UTC date; else YYYY.MM.DD.N with the LOWEST untagged N >= 2 (a gap is reused, not burned). An already-released commit, and any version whose tag exists, are an explicit RELEASE=no instead of a failure. The script only ever reads the clock with `date -u`, and it emits VERSION/TAG/SOURCE/BUMP/RELEASE on stdout and into $GITHUB_OUTPUT. * the workflow writes the resolved version into the manifest whenever it differs, commits it as "chore(release): v<VERSION> [skip ci]" with the existing bot identity, pushes HEAD:master, and only then tags THAT commit — so the artifact, its tag and the default branch agree. A branch-protection rejection fails the job with an instruction to bump the manifest manually; nothing is tagged first. * post-push verification reads the manifest out of origin/master (the copy HACS fetches) and refuses to publish when it does not equal the released version. * no self-trigger loop: the conventional [skip ci] marker on the bot commit plus a job-level `if:` that re-checks github.event.head_commit.message. The guard is the load-bearing part — it holds even where a Gitea version ignores the marker. * preserved: manifest-wins precedence, the concurrency group without cancel-in-progress, notes from the commit range, zip asset upload and the 409-tolerant publish path. RELEASE=no replaces the old `exists` output, so an already-tagged version still ends as a clean no-op. Also fixes the data: master's manifest moves 2026.10.08 -> 2026.10.09, the latest released tag, so the repo stops contradicting its own releases immediately rather than only after the next successful run (which resolves to v2026.10.11 either way). tests/test_release_versioning.py drives all of it: the four scenarios, the lowest-free-suffix rule, UTC determinism under three timezones, the error paths, the $GITHUB_OUTPUT handoff, and the workflow's own contract — textual, because the fast suite has no YAML parser; the verify command parses the file with pyyaml. Verified: 356 passed / 2 skipped, 357 / 1 with androidtvremote2, ruff clean, release.yml valid, `bash -n` clean, and the script resolves the real repo to v2026.10.11 (date, bump=yes). The workflow itself cannot run here (no Gitea runner): its run: steps were extracted from the YAML and executed against scratch repos with a bare origin, covering the bump+verify+tag path (commit subject, tag target and tag manifest all agree), the inconsistent-manifest failure and the rejected-push failure.
26 lines
610 B
JSON
26 lines
610 B
JSON
{
|
|
"domain": "nvidia_shield",
|
|
"name": "NVIDIA Shield",
|
|
"codeowners": [
|
|
"@notexpectedyet"
|
|
],
|
|
"config_flow": true,
|
|
"dependencies": [],
|
|
"documentation": "https://git.notexpectedyet.com/notexpectedyet/ha-nvidia-shield",
|
|
"iot_class": "local_push",
|
|
"issue_tracker": "https://git.notexpectedyet.com/notexpectedyet/ha-nvidia-shield/issues",
|
|
"requirements": [
|
|
"adb-shell>=0.4.0",
|
|
"androidtvremote2>=0.2.0"
|
|
],
|
|
"version": "2026.10.09",
|
|
"zeroconf": [
|
|
"_androidtvremote2._tcp.local."
|
|
],
|
|
"integration_type": "device",
|
|
"loggers": [
|
|
"adb_shell",
|
|
"androidtvremote2"
|
|
]
|
|
}
|