Skip to content

feat(render): chart GitHub stars added per day (7-day rolling avg) - #4

Merged
ErikBjare merged 6 commits into
masterfrom
feat/star-growth-chart
Oct 14, 2026
Merged

ErikBjare merged 6 commits into
masterfrom
feat/star-growth-chart

Conversation

@ErikBjare

@ErikBjare ErikBjare commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

The cumulative star chart hides whether one week grew 2x or 1/3 of the previous one. This adds a growth chart next to it, using the same method as ActivityWatch/stats' download growth (day-over-day diff, 7-day rolling mean). It also makes star collection work with the built-in GITHUB_TOKEN only.

stars growth

Growth chart (render_star_growth)

  • Covers the full history on a symlog y-axis. Daily counts range from 0 to 303 (the October 2024 launch), and a log scale keeps a 1/day week readable next to that spike. Equal ratios also get equal heights, so "twice last week" looks the same at any level. The busiest week is labelled (1,393 stars, to 2024-10-10).
  • Daily values are drawn as one step fill rather than ~1,000 bar patches, which keeps the SVG and the daily diffs small.

Series (star_totals)

  • From the first daily.csv snapshot (2026-09-14) on, it uses the snapshot stargazers_count, net of unstars, whether or not stars.csv is current.
  • Before that it uses stars.csv by starred_at, shifted to meet the first snapshot.
  • Missing snapshot days are linearly interpolated, so a collection gap doesn't show up as a spike.

Summary fix

"Stars gained, last 30 days" showed 1 because it counted rows in the stale stars.csv. It now uses the same series (36), and the table gains "last 7 days" / "previous 7 days" rows (3 vs 8).

No STATS_GH_TOKEN

  • The workflow now uses only the built-in GITHUB_TOKEN, and the optional STATS_GH_TOKEN is removed.
  • Listing stargazers genuinely requires a user token. I checked with a temporary probe workflow on this PR (since removed):
    • GITHUB_TOKEN gets 403 "Resource not accessible by integration" from REST /stargazers (with and without star+json) and from GraphQL repository.stargazers.
    • Unauthenticated requests get 401 "Requires authentication".
    • Repo metadata (stargazers_count etc.) works fine with GITHUB_TOKEN.
  • So in CI, stars.csv stays as is, at a cost of one failed request per run. Every chart and summary number continues from the daily snapshots, so nothing goes stale.
  • stars.csv can still be filled in by running locally with GITHUB_TOKEN=$(gh auth token) uv run collect.py. The existing incremental tail-page fetch applies. Unstars since the last sync force a full resync (45 requests at 4.4k stars), which is trivial with a user token.

stars.svg, pypi.svg and downloads.svg render byte-identical.

…verage

Cumulative stars hide whether one week grew 2x or 1/3 of the previous one.
Add charts/stars_growth.svg: daily net additions (last 365 days) with a
7-day rolling average, mirroring the diff + 7D rolling mean that
ActivityWatch/stats uses for download growth.

The per-day series combines stars.csv (by starred_at) with the daily
stargazers_count snapshots once stars.csv stops, interpolating missing
snapshot days so collection gaps don't show up as spikes.

Also fix 'Stars gained, last 30 days': it counted stars.csv rows only,
which have not updated since 2026-09-14 (no STATS_GH_TOKEN), so it showed
1 instead of 36. It now uses the same combined series, and the table gains
last-7 / previous-7 day rows.
@ErikBjare

Copy link
Copy Markdown
Member Author

@TimeToBuildBob review

@TimeToBuildBob

TimeToBuildBob commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

🤖 AI code review

This shard changes the star-collection workflow to use only the built-in GITHUB_TOKEN (removing STATS_GH_TOKEN), updates collect.py's token handling and docs, and adds a new growth chart in render.py. render.py gains star_totals() to build a daily star-count series from stars.csv and daily.csv snapshots, render_star_growth() to plot the 7-day rolling average of day-over-day changes, and build_summary() now computes stars_last_7d, stars_prev_7d, and stars_last_30d from that series. README.md adds the growth chart link and new summary rows plus caveats.

This shard adds a new SVG chart file, charts/stars_growth.svg, which plots GitHub stars added per day with a 7-day rolling average. The chart includes a symlog y-axis, a fill between the daily values and the rolling average, a legend, and annotations for the busiest week and recent 7-day totals. The file is a generated matplotlib SVG output with embedded font definitions and path data.

This shard adds the generated SVG chart charts/stars_growth.svg (a daily star-growth plot with a 7-day rolling average, log-scale y-axis, and annotations) and updates data/summary.json to add stars_last_7d and stars_prev_7d fields while changing stars_last_30d from 1 to 36. The SVG is a large generated artifact; the JSON change reflects the new summary fields.

Safe to merge — no P0/P1 findings

Confidence 5/5

ℹ️ Large PR — reviewed in 3 shards (≤180KB of diff each, grouped by directory) with the same prompts, filters and consensus settings as any review; findings were merged and deduplicated. Each shard saw the PR's full file list, but issues that only show when reading files from different shards together are less likely to be caught.

✅ No thread-worthy findings. Advisory notes follow; they are retained without opening review threads.

1 advisory finding (summary-only, not scored)

These P2 guard, heuristic, trade-off, or documentation claims are retained for judgment without opening review threads.

⚠️ P2 medium — data/summary.json:6

The summary JSON adds stars_last_7d and stars_prev_7d fields, but the PR description says the summary table gains these rows. However, the JSON file itself does not contain a table; it is a data file. The change is consistent with the PR description. No issue found here.

How this was verified: Checked the JSON file and the PR description. The fields are added as described.

Files changed (6) — the diff as I read it
  • .github/workflows/collect.yml — Removes the STATS_GH_TOKEN secret and adds a comment explaining the built-in token cannot list stargazers.
  • README.md — Adds the stars_growth.svg chart link, new 'stars gained' table rows, and caveats about token requirements and the growth series.
  • collect.py — Drops STATS_GH_TOKEN from token resolution, updates TokenNotAccepted docstring, and adjusts the warning comment in collect_stars.
  • render.py — Adds star_totals() and render_star_growth(), changes build_summary() to use the totals series, and adds the growth chart to main().
  • charts/stars_growth.svg — Adds a new SVG chart showing daily star growth with a 7-day rolling average, including axis labels, legend, and annotations.
  • data/summary.json — Adds stars_last_7d and stars_prev_7d fields and updates stars_last_30d from 1 to 36.
Previous review passes
commit score findings engine when
b4cb18424900 4/5 2 llm 2026-10-13 22:59 UTC
c8db4e7e26bf 3/5 1 llm 2026-10-13 23:12 UTC

Reviewed d8f87cf7fa4b · openrouter/deepseek/deepseek-v4-flash-0731 · llm engine · 172s · about this reviewer

Maintainer commands

@TimeToBuildBob review (own line) — fresh review · @TimeToBuildBob fix — a worker acts on the findings. Once per comment; 👀 = received.

Comment thread render.py Outdated
Comment thread render.py Outdated
…rent

Use daily.csv snapshots from the first snapshot on and stars.csv only
before it (offset to meet the first snapshot), so the growth series stays
net of unstars after the stargazer token is restored. Skip the growth chart
when there is less than two days of history.
@ErikBjare

Copy link
Copy Markdown
Member Author

@TimeToBuildBob review

Comment thread render.py Outdated
…HUB_TOKEN only

- stars_growth.svg now covers the full history on a symlog y-axis, so the
  October 2024 launch week (1,393 stars) and today's ~1/day both stay
  readable, and the busiest week is labelled.
- Drop the optional STATS_GH_TOKEN secret. The workflow uses the built-in
  GITHUB_TOKEN only. GitHub refuses stargazer listings to it (403, REST and
  GraphQL alike) and to anonymous requests (401), so stars.csv only grows on
  local runs with a user token; every chart and summary number continues
  from the daily stargazers_count snapshots, so nothing goes stale.
- Remove the temporary token probe workflow.
@ErikBjare

Copy link
Copy Markdown
Member Author

@TimeToBuildBob review

ErikBjare added a commit to gptme/gptme that referenced this pull request Oct 13, 2026
Adds a /stats/ page to the site/next landing site: GitHub stars, PyPI and
release downloads, and repository numbers from gptme/stats summary.json,
with the charts gptme/stats publishes under charts/.

Numbers are fetched at build time (with the existing committed fallback),
charts are embedded from raw.githubusercontent.com, and charts gptme/stats
doesn't publish yet (stars_growth.svg, gptme/stats#4) are left out until
they exist. docs.yml now also rebuilds gptme.org daily after the stats
collection run, so the page stays current without committing data here.

The Stats nav link now points at the page, and it is added to the footer.

@TimeToBuildBob TimeToBuildBob left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Reviewed the actual logic:

  • star_totals(): offset stitching at the first snapshot is correct — cumulative pre-snapshot stars shifted so the two series meet. Linear interpolation for collection gaps is the right call over showing one-day spikes.
  • build_summary(): parameterized stars_gained(days, offset) is a clean refactor. One note: it returns None when the date isn't in totals — caller handles that fine (I checked the surrounding code).
  • render_star_growth(): symlog with linthresh=1 correctly places zero and negative days; fill_between step plot keeps SVG diffs small (good call). FixedLocator ticks cover the range well.
  • collect.py: STATS_GH_TOKEN removal is correct — it was unused in CI and the chart path never needed per-star timestamps.

Safe to merge.

@ErikBjare
ErikBjare merged commit e1cc5b1 into master Oct 14, 2026
ErikBjare added a commit to gptme/gptme that referenced this pull request Oct 14, 2026
* feat(site): add gptme.org/stats/ page from gptme/stats

Adds a /stats/ page to the site/next landing site: GitHub stars, PyPI and
release downloads, and repository numbers from gptme/stats summary.json,
with the charts gptme/stats publishes under charts/.

Numbers are fetched at build time (with the existing committed fallback),
charts are embedded from raw.githubusercontent.com, and charts gptme/stats
doesn't publish yet (stars_growth.svg, gptme/stats#4) are left out until
they exist. docs.yml now also rebuilds gptme.org daily after the stats
collection run, so the page stays current without committing data here.

The Stats nav link now points at the page, and it is added to the footer.

* fix(site): order scheduled docs deploys with master pushes; don't require charts on /stats/
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.

2 participants