Repository navigation
Check and apply plugin icon requests with workflows - #1305
Merged
Merged
Conversation
Adding the `icon-approved` label to an icon request (or to a verification request that attached an icon) downloads the icon, resizes it to a 100x100 PNG, adds it to icons/ and plugin-icons.json (replacing the existing icon if the plugin has one), regenerates assets/ via sort-json-files, commits `icon: <plugin>` to latest, and reports back on the issue. Icon requests are closed once applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Icons no longer require verification. sort-json-files.js keeps icon entries for any plugin whose icon file exists and adds those plugins to assets/plugins*.json, so the UI (which shows any plugin with an `i` entry) picks them up. The icon workflow drops its verified check and instead confirms the package exists on npm. The README and icon request template no longer say an icon needs a verified plugin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The icon workflow now runs only when `icon-approved` is added to an issue labelled `request-icon`, and closes the request once the icon is in. Icons attached to verification requests need their own icon request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes the CodeQL incomplete-escaping alert: replace('/', '%2F') only
replaced the first slash.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Decode the untrusted image in a `prepare` job with read-only access and no stored git credentials; the `apply` job that pushes only gets the finished PNG and checks its header without decoding it. - Check the requester develops the plugin (repo owner, npm maintainer, or public member of the owning org); maintainers may request any. - Cap image size at 4096x4096 px, time out downloads after 30 s, stop reading past 5 MB, and give each job a timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new Icon Request Check workflow runs the read-only prepare step when an icon request is opened, edited or reopened, on a `/check` comment, or by hand. It keeps one comment on the issue saying whether the request is ready (with the icon as it will appear) or what to fix, and sets awaiting-final-review or awaiting-changes. Requests opened without the form get the request-icon label. `icon-approved` now only applies an icon when the latest check passed, the issue has not been edited since, and the image downloaded matches the SHA-256 the check recorded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each job in both workflows now writes a summary for the Actions run
page: who approved and why it went ahead or was refused, the prepared
image (source, size, SHA-256), the commit, and what was done on the
issue. The approval workflow is renamed icon-approved.yml ("Icon
Approved").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 26, 2026
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.
Adds two workflows that check icon requests and apply them once a maintainer approves, so icons no longer need adding by hand.
1. Checking requests:
icon-request-check.ymlWhen it runs: an icon request is opened, edited or reopened; someone comments
/checkon its own line; or a maintainer runs it by hand with an issue number, which is useful for the current backlog. It applies to issues labelledrequest-iconor titled "Plugin Icon Request:".What it does: runs the read-only
preparestep ofscripts/apply-icon-request.js:Nothing is committed.
Reports back: it keeps one comment on the issue, updated in place.
It also sets
awaiting-final-revieworawaiting-changes(and removespending). Requests opened without the form get therequest-iconlabel.Plugins that aren't verified: the check reports them as needing changes and asks the author to request verification first. The hidden marker still records the request and image as valid, and the approval workflow doesn't look at verification, so a maintainer can still approve one as a one-off.
2. Approving:
icon-approved.ymlA maintainer adds the new
icon-approvedlabel. Four jobs then run:authorize: the approver must have write access. The icon is only applied if the latest check passed and the issue hasn't been edited since. Otherwise it says why on the issue.prepare(read-only token, no stored git credentials): runs the same step again. It refuses unless the downloaded image matches the SHA-256 the check recorded, so the icon committed is the one the check showed.apply(can push):icons/<name>.pngand theplugin-icons.jsonentry, replacing an existing icon if there is onesort-json-files.jsto regenerateassets/icon: <plugin>straight tolatestreport: comments with the icon as committed and closes the request. If anything fails, it comments with the reason instead.The untrusted image is only ever decoded in read-only jobs. The label is removed after every run, so adding it again retries. Approvals run one at a time.
Run summaries: every job in both workflows writes a summary to the Actions run page. It covers who approved and why it went ahead or was refused, the prepared image (source, original size, SHA-256, converted size), the commit, and what was done on the issue.
icon-approveddoes nothing on issues withoutrequest-icon. Stage 2, noted in the files, will also apply an icon attached to a verification request whenverifiedis added.sort-json-files.jsnow keeps every icon entry whose file exists, and includes those plugins inassets/plugins*.json.Testing
I ran the script against real open issues, and the workflows' GitHub API calls against mocked responses:
homebridge-eufy's developer) and a made-up requester.awaiting-final-revieworawaiting-changes, removespending, and addsrequest-iconto requests opened without the formcommitrefuses tampered input: random bytes, a 480×480 PNG, and a plugin name containing../.sort-json-files.jsproduces the same output as before. The only difference is one line of existing drift inassets/(from author: homebridge-simplisafe3 → shamoon #1304).Neither workflow has run on GitHub yet.
Before merging
icon-approvedlabel./checkon them.🤖 Generated with Claude Code