Skip to content

Test/update icon 2 - #2776

Closed
Snailedlt wants to merge 15 commits into
devicons:masterfrom
Snailedlt:test/update-icon-2
Closed

Snailedlt wants to merge 15 commits into
devicons:masterfrom
Snailedlt:test/update-icon-2

Conversation

@Snailedlt

Copy link
Copy Markdown
Collaborator

No description provided.

Snailedlt and others added 15 commits October 24, 2026 19:16
Moves devicon from the `develop` → `master` release flow to trunk-based
development: PRs go straight to `master`, and fonts are built and
released weekly.

## What changes

**Merging**
- Contributors open PRs against `master`; maintainers approve and
squash-merge using GitHub's native rules (ruleset on `master`: 1
approval, squash only, squash title = PR title).
- Removed the `in_develop_labeler` workflows/script and all other
`develop` references (PR template, README, CONTRIBUTING, CodeQL
triggers, Gitpod link).

**Building and releasing: `build_weekly.yml`** (runs every Monday 02:00
UTC, or manually)
- `build`: if `icons/` or `devicon.json` changed since the last `build:`
commit, rebuilds the glyphs of new and updated icons (font versions out
of sync with `icomoon.json`, or font SVGs changed) plus the CSS, and
commits the result to `master`. Opens a `build-failed` issue on failure.
Detection uses file diffs, not PR titles.
- `release`: runs when anything shipped (SVGs, `devicon.json`, CSS,
fonts) changed since the last `v*` tag. Waits for approval on the
`production` environment, derives the semver bump from `release: major`
/ `release: minor` labels on PRs merged since the last `v*` tag, then
bumps, tags and creates the GitHub release.
- `publish`: calls `npm_publish.yml` as a reusable workflow (releases
created with `GITHUB_TOKEN` don't trigger `release` events). Forks only
do `npm publish --dry-run`.
- Manual runs do the same as the weekly run, with an optional `bump`
override.
- Replaces `build_icons.yml`, `version_and_release.yml` and the
auto-merge workflow.

**Check and peek bots**
- Both find the icon from the PR's changed files instead of its title,
so icon PRs titled e.g. `feat: add foo icon` no longer skip SVG
validation and peek.
- The check bot validates every touched icon and, for PRs that change
SVGs, requires one icon per PR and a matching title: `new icon: <name>
(<versions>)` or `update icon: <name> (<versions>)`. On a mismatch it
comments the expected title, and editing the title re-runs the check.
`devicon.json`-only PRs have no title requirement.
- Peek screenshots are stored on a `screenshots` branch instead of
Imgur, and only cover the new icons. PRs without SVG changes get no peek
comment.

## Repo setup required
- Ruleset on the default branch: require PR + 1 approval, squash only,
block force-push/deletion.
- A GitHub App with **Contents: Read and write**, installed on the repo
and added to the ruleset's bypass list (always). Store `vars.BOT_APP_ID`
and `secrets.BOT_APP_PRIVATE_KEY`. The weekly workflow uses it to push
the `build:` and version commits to the protected `master`.
- Environments: `production` (required reviewers) and `release` (with
`NPM_AUTOMATION_TOKEN`).
- Labels: `release: major`, `release: minor`.
- Repo merge settings: squash merge with "Pull request title" as the
default commit title.

## Test plan
- [ ] Manual run with no icon changes since the last build → build
skipped; release skipped if nothing changed since the last tag
- [ ] New icon PR → check + peek comments posted → approve →
squash-merge
- [ ] Manual run → bot pushes `build:` commit with the new glyphs →
release waits for approval → tag, release, npm dry run
- [ ] Manual run again right after → nothing to build, nothing to
release, no approval requested
- [ ] Update icon PR (change an existing font SVG) → manual run rebuilds
only that icon's glyphs
- [ ] SVG-only / `devicon.json`-only change (e.g. alias) → CSS rebuilt,
release happens without a glyph build
- [ ] Icon PR with a wrong title (e.g. `feat: add foo icon`) → check-bot
comments the expected title → fixing the title re-runs the check and
passes
- [ ] PR changing two icons → check-bot asks to split it
- [ ] `devicon.json`-only PR → no title complaint, no peek comment
- [ ] Icon PR from a fork (different account) → checks, peek, merge all
work

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Fixes the failing Check Icon PR and Peek Icons runs on #69.

- `ubuntu-latest` is now Ubuntu 26.04, which has no Python 3.8 build, so
`setup-python` failed. The Python jobs (check, peek, weekly build) now
run on `ubuntu-24.04`, as upstream `develop` did in devicons#2769.
- `requests==2.34.2` needs Python ≥ 3.10, so check/peek move from 3.8 to
3.10 (the weekly build already uses 3.10).
- `selenium==4.51.0` (from the requirements upgrade in devicons#2766) removed
the `find_element_by_*` API our Selenium runners use. Back to `4.1.0`,
which the earlier test builds used.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
The check job succeeded even when it found issues (e.g. a wrong PR title
on #69), so the PR showed a green check and only the comment reported
the problem.

- `check_icon_pr.yml`: uploads the PR number first and the error file
even if the script crashed, then fails the job when there are errors.
- `post_check_icon_pr_comment.yml`: posts the issues comment when the
check failed too (it used to bail out on any non-success run). The
"something went wrong" comment remains for runs that produced no
artifacts. The comment now mentions that editing the PR title re-runs
the check.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
**Scope rule for icon PRs** (any change in `icons/`)
- Only one `icons/<name>/` folder and that icon's `devicon.json` entry
may change. Any other added, modified or deleted file, or another icon's
`devicon.json` entry, fails the check and the check-bot comments the
list.
- `devicon.json`-only PRs (aliases, tags…) aren't icon PRs and have no
scope or title requirement.

**Auto-rename**
- If an icon PR's scope is clean and only its title is wrong, the check
fails and the check-bot renames the PR to the expected title, commenting
`from:` / `to:`. The rename is done with the bot app's token, so it
re-runs the check, which then passes if nothing else is wrong.
- PRs with scope problems are not renamed; the title issue is listed in
the error comment as before.
- Without the bot app configured, the bot comments the expected title
instead.

**Hardening** of `post_check_icon_pr_comment.yml` (rewritten with
`actions/github-script`)
- For PRs from forks, the check runs the fork's own workflow code, so
its artifacts can't be trusted. The bot now only comments on or renames
a PR whose head SHA is the commit that was checked, and only accepts
titles in the icon-title format.

**Setup:** the bot app needs **Pull requests: Read and write** in
addition to Contents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
…73)

`actions/github-script` has no `github.getOctokit`, so creating a second
client with the bot token crashed the rename on #69 ("TypeError:
github.getOctokit is not a function"). The rename now runs in its own
step with `github-token` set to the bot token, and the comment is posted
from a separate step with the default token.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Each workflow now asks the bot app only for the permission it needs:
`contents: write` in `build_weekly.yml`, `pull-requests: write` in
`post_check_icon_pr_comment.yml`. If the installation lacks one (e.g. a
permission update that wasn't accepted, as happened on #69), token
creation fails with a clear error instead of a 403 later on.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Double check these details before you open a PR

<!-- Tick the checkboxes to ensure you've done everything correctly -->
- [ ] PR does not match another non-stale PR currently opened
- [ ] PR name matches the format *new icon: <i>Icon name</i>
(<i>versions separated by comma</i>)*. More details
[here](https://github.com/devicons/devicon/wiki/Overview-on-Submitting-Icons)
- [ ] PR's base is the `master` branch.
- [ ] Your icons are inside a folder as seen
[here](https://github.com/devicons/devicon/wiki/Organizing-SVGs)
- [ ] SVG matches the standards laid out
[here](https://github.com/devicons/devicon/wiki/SVG-Standards)
- [ ] A new object is added in the `devicon.json` file at the correct
alphabetic position as seen
[here](https://github.com/devicons/devicon/wiki/Updating-%60devicon.json%60)

<!-- Refer to the
[contributing](https://github.com/devicons/devicon/blob/master/CONTRIBUTING.md#contributing-to-devicon)
guidelines for more details. -->

**This PR closes NONE**
<!-- List issues that this PR would close above. Ex: This PR closes #1,
#2, #3. -->

## Link to prove your SVG is correct and up-to-date.
<!-- Link to an official page/wiki goes here. Anything that proves your
SVGs are the correct ones. -->
The build's `new_icons.png` screenshot always showed "Glyphs: 0".

The build deselects all icons, uploads the new SVGs, then screenshots
the Generate Font page, which only shows selected icons. The code
assumed icomoon.io selects uploaded icons automatically; it doesn't (the
earlier `new_svgs.png` already showed "Selection (0)"). The build now
selects the new icons, which are the first ones in the top set, right
after uploading. Both screenshots then show only the new icons.

The font itself was never affected: the download step still selects all
icons before generating it.

Also adds a note to CLAUDE.md: a classic branch protection rule on
`master` blocks the bot's pushes even when the ruleset allows them, so
it must be removed (or the bot added to its bypass list) before
switching upstream.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
<!--

Adding a New Icon?

- Add `?quick_pull=1&template=new_icon.md&labels=feature:icon` to the
end of your current URL and press `Enter`.

Adding a New Feature or fixing a bug?

- Add `?quick_pull=1&template=new_feature.md&labels=enhancement` to the
end of your current URL and press `Enter`.

-->
The step 8 build (updating `testicon`) reassigned the codepoints of 940
existing glyphs. `testicon-plain` got `\e900`, the first codepoint, and
everything after it shifted.

**Cause:** icomoon.io assigns codepoints to the icons that are selected
when the Generate Font page opens. Since #75 the build opened that page
with only the new icons selected (for a screenshot), so they took the
first codepoints. Before #75 nothing was selected at that point, so
nothing was reassigned (the step 6 build changed 0 existing codepoints).

**Fix**
- The Generate Font page is only opened after "Select All". Its
screenshot, `font_glyphs.png`, now shows the full glyph count.
`new_svgs.png` still shows the new icons highlighted on the selection
page, which doesn't assign codes.
- New `verify_glyph_codes` guard: after icomoon's download, the build
fails and commits nothing if any glyph that wasn't rebuilt changed its
codepoint or disappeared, or if two glyphs share a codepoint. Rebuilt
glyphs get their codepoint from icomoon.io, and the build log shows them
as `old -> new`.

**Tested** (WSL, against the real `icomoon.json` from today's fork
builds):
- step 6 build → passes: "all 1201 existing glyphs that weren't rebuilt
kept theirs"
- step 8 build → fails with all 940 shifted glyphs listed
- synthetic duplicate-codepoint and missing-glyph cases → fail

The Selenium flow change itself can only be tested by a real build.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: snailedlt <snailedlt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
@Snailedlt Snailedlt closed this Oct 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

env.MESSAGE

@Snailedlt
Snailedlt deleted the test/update-icon-2 branch October 25, 2026 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant