feat(plugin-catalog): rank entries by GitHub stars, probed at most once a day

Catalog entries sort official → stars desc → name, both in browse shelves and
filtered grids, with a ★ pill on each card linking to the repo's stargazers.

Rate-limit discipline is the design constraint: the docs site deploys many
times a day and shares one GitHub App API budget with every other workflow
(tonight's merge train got rate-limited on unrelated uploads). So
website/scripts/fetch-plugin-stars.py first fetches the live site's own
plugin-stars.json (a CDN GET, not the API); if that cache is under 24h old it
is reused verbatim and GitHub is never called. Only a stale cache triggers one
GET /repos/{owner}/{repo} per unique catalog repo, and a 403/429 mid-run keeps
the previous counts instead of zeroing them. extract-plugins.py merges the
cache into plugins.json (`stars`) and plugins-meta.json (`starsFetchedAt`), and
the page footnote says when the ranking was last refreshed.
This commit is contained in:
teknium1
2026-09-14 21:24:33 -07:00
parent 437116f949
commit 3e2e2c50eb
9 changed files with 361 additions and 11 deletions

View File

@@ -164,6 +164,14 @@ jobs:
- name: Extract skill metadata for dashboard
run: python3 website/scripts/extract-skills.py
# Star counts drive the catalog ranking. The script reuses the live site's cache when it
# is < 24h old (one CDN GET, zero API calls); only a stale cache triggers ~1 API call per
# catalog repo. Never touches the API on the many same-day deploys.
- name: Refresh plugin GitHub stars (daily cache)
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: python3 website/scripts/fetch-plugin-stars.py
- name: Extract plugin catalog for the Plugins page
run: python3 website/scripts/extract-plugins.py