Add repository brand icon endpoint#5388
Open
Niek wants to merge 3 commits into
Open
Conversation
Serve brand icons for integrations from HACS itself, now that custom integrations ship brand images in the repository and home-assistant/brands no longer accepts them: - Downloaded integrations are served from the local brand folder. - Other integrations are fetched from the repository content on GitHub and cached on disk, keyed by the version they were fetched for. - Repositories without a brand icon are redirected to the brands CDN.
2 tasks
4 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a new unauthenticated HTTP view in the HACS integration that serves repository brand icons (icon.png / dark_icon.png) to address missing icons for custom integrations since the HA 2026.3 brands changes. It serves icons from the local custom_components/<domain>/brand/ folder for downloaded integrations, otherwise fetches from raw.githubusercontent.com and caches results (including negative caching), with CDN/placeholder fallback behavior.
Changes:
- Introduces
HacsRepositoryIconViewwith local/remote icon serving, on-disk caching, and redirect fallbacks. - Registers the new view during HACS startup.
- Adds a new test suite for the view plus API-usage snapshots.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
custom_components/hacs/brands.py |
New icon-serving endpoint with local/remote fetch logic and caching. |
custom_components/hacs/__init__.py |
Registers the new icon view at startup. |
tests/test_brands.py |
Adds tests covering local serve, remote fetch/cache, redirects, and validation cases. |
tests/snapshots/api-usage/tests/test_brandstest-*.json |
Adds API usage snapshots for the new tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ling Address review feedback: - Local and cached icons go through the same PNG magic-byte and size validation as downloaded ones. - The cache filename now percent-encodes the ref so distinct refs can not collide. - async_download_file already returns None on failure, so the try/except around it was dead code.
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.
Proposed change
Adds an authenticated endpoint that serves brand icons for repositories HACS knows about:
Since Home Assistant 2026.3, custom integrations ship brand images in
custom_components/<domain>/brand/, andhome-assistant/brandsno longer accepts images for custom integrations (announcement). The HACS dashboard still builds icon URLs against the brands CDN, so custom integrations that are not grandfathered into the CDN show a placeholder (#5171, #5223, #5179).The core brands proxy only covers installed integrations, which was the main concern raised against switching the frontend to it in hacs/frontend#937. This implements the HACS repository endpoint design discussed there:
brands/access_token.raw.githubusercontent.com. Both standard repository layouts andcontent_in_rootare supported.last_commitas their cache identity, so a new commit refreshes the icon.dark_icon.pngfalls back toicon.pngwhile preserving the access token.Repositories without a usable icon ultimately redirect to the brands CDN, preserving grandfathered images and its placeholder behavior. The update entity picture is intentionally unchanged; #5228 / #5339 cover that separately.
Frontend companion PR: hacs/frontend#945.
Release follow-up
The integration currently pins frontend release
20250128065759inscripts/install/frontend. To ship this end to end:hacs/frontendrelease containing Use the HACS repository icon endpoint for dashboard icons frontend#945.FRONTEND_VERSIONinhacs/integrationto that release.The pin cannot be updated in this PR until that frontend release exists.
Related issues and PRs: fixes #5171, #5179, and #5223 together with the frontend PR; alternative to hacs/frontend#937 and hacs/frontend#929, which only cover installed integrations.
Checklist
content_in_root, branch cache refresh, transient failures, streamed size limits, dark fallback, and config-entry reloads.