A GitHub Action that tracks star counts across all your repositories on a schedule, generates visual reports with charts and badges, and sends notifications when changes are detected.
Documentation · Getting Started · Configuration · Examples · Troubleshooting
- What You Get
- Features
- Quick Start
- Configuration
- How It Works
- Embedding in Your README
- Documentation
- Support & Contributing
- Use of AI
Every run, Star Tracker commits these artifacts to a dedicated data branch:
-
Animated SVG charts: star history, per-repo trends, top repos comparison, and growth forecasts - with automatic dark/light mode support:
-
Shields.io-style badge: embeddable star count that updates automatically:
-
Markdown & HTML reports: summary tables, delta indicators, new/removed repos, stargazer details, and forecast tables.
-
CSV & JSON data: machine-readable exports for dashboards, spreadsheets, or downstream pipelines.
- 📈 Animated SVG charts: Star history, per-repo trends, comparisons, and growth forecasts
- 🌙 Dark/light mode: SVG charts auto-adapt to the viewer's color scheme via
prefers-color-scheme - 📷 Historical snapshots: Configurable retention (default: 52 runs) with JSON persistence
- 🔍 Smart filtering: By visibility, ownership, min stars, regex exclusions, archived, forks
- 👥 Stargazer tracking: See who starred your repos with avatars and dates
- 📬 Email notifications: Built-in SMTP with fixed or adaptive thresholds
- 🏢 GitHub Enterprise: GHES support, auto-detected or explicit API URL
- 🌐 Multi-language: English, Spanish, Catalan, Italian
- 📊 CSV export: Machine-readable output for data pipelines
- 🧩 Action outputs:
total-stars,new-stars,new-stars,lost-stars,new-stargazers(and much more) for workflow chaining - 🛡️ Zero runtime deps: Bundled TypeScript action, 98%+ test coverage, 500+ tests
- Go to GitHub Settings > Tokens
- Generate a classic token with
repoorpublic_reposcope - Add it as a repository secret named
STAR_TRACKER_TOKEN
Note
The default GITHUB_TOKEN is not sufficient. See the PAT guide for details.
Create .github/workflows/star-tracker.yml:
name: Track Stars
on:
schedule:
- cron: '0 0 * * *' # Daily at midnight
workflow_dispatch:
permissions:
contents: write
jobs:
track:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: fbuireu/github-star-tracker@v1
with:
github-token: ${{ secrets.STAR_TRACKER_TOKEN }}- Manual run: Actions > Track Stars > Run workflow
- View report: Check the
star-tracker-databranch in your repository
Set options directly in the workflow or via a YAML config file. See the Configuration guide for full details.
- uses: fbuireu/github-star-tracker@v1
with:
github-token: ${{ secrets.STAR_TRACKER_TOKEN }}
visibility: 'public' # public | private | all | owned
locale: 'es' # en | es | ca | it
include-charts: true
track-stargazers: true
min-stars: '5'
exclude-repos: 'test-repo,/^demo-.*/'
notification-threshold: '0' # 0 | N | autoAll Inputs
| Input | Default | Description |
|---|---|---|
github-token |
- | Required. PAT with repo or public_repo scope |
github-api-url |
- | GitHub API base URL (for GHES). Auto-detected on GHES runners |
config-path |
star-tracker.yml |
Path to YAML config file |
visibility |
all |
public, private, all, or owned |
locale |
en |
en, es, ca, or it |
include-charts |
true |
Generate star trend charts |
data-branch |
star-tracker-data |
Branch for tracking data |
max-history |
52 |
Max snapshots to keep |
top-repos |
10 |
Top repos in charts/forecasts |
chart-line-color |
#dfb317 |
Hex color of primary chart line/fill/points (not comparison) |
chart-line-width |
2.5 |
Stroke width (px, >0) of data lines in all charts |
chart-max-points |
30 |
Curve granularity: points across the full span (capped at 365); 0 reconstructs at weekly resolution. Not a time window (see chart-range) |
chart-y-axis-side |
left |
Y-axis labels side: left or right |
chart-smoothing |
true |
Smooth curve (true) or straight segments to show spikes; applies to email charts too |
chart-curve |
monotone |
Curve when smoothing: monotone (no overshoot, best for stars), catmull-rom, cubic-bezier, rounded-step. Email approximates non-monotone curves |
chart-show-points |
true |
Draw a marker on each data point (true) or hide them for a cleaner dense line (false) |
chart-animation |
true |
Animate SVG charts (true) or render them static (false) for email/static contexts |
chart-milestones |
true |
Show milestone reference lines on the main star-history chart (true) or hide them (false) |
chart-begin-at-zero |
false |
Start the Y-axis at zero (true) or zoom into the data range (false) |
chart-theme |
auto |
Color theme: auto (follows prefers-color-scheme), light or dark |
chart-custom-milestones |
(empty) | Comma-separated star counts for the milestone reference lines, replacing the built-in defaults (e.g. 250, 750, 2500). Requires chart-milestones |
chart-range |
all |
Time window plotted: 30d, 90d, 1y or all |
chart-trend-line |
false |
Overlay a dashed moving-average trend line on the main chart |
velocity-metrics |
false |
Add a growth-velocity section (stars/day, % growth, days to next milestone) to the report |
track-stargazers |
false |
Track individual stargazers |
smart-sampling |
false |
Sample stargazer pages for high-star repos (avoids rate limits) |
smart-sampling-threshold |
1500 |
Star count above which a repo is sampled |
smart-sampling-pages |
30 |
Max evenly-spaced stargazer pages per sampled repo |
include-archived |
false |
Include archived repos |
include-forks |
false |
Include forked repos |
exclude-repos |
- | Names or regex to exclude |
only-repos |
- | Only track these repos |
only-orgs |
- | Only track repos under these orgs/owners (name or regex) |
exclude-orgs |
- | Orgs/owners to exclude (name or regex) |
min-stars |
0 |
Min stars to track |
smtp-host |
- | SMTP hostname (enables email) |
smtp-port |
587 |
SMTP port |
smtp-username |
- | SMTP username |
smtp-password |
- | SMTP password |
email-to |
- | Recipient address |
email-from |
GitHub Star Tracker |
Sender name |
send-on-no-changes |
false |
Email even with no changes |
notification-threshold |
0 |
0 (every run), N (threshold), or auto (adaptive) |
In the YAML config file, option keys may be written with either dashes or underscores - include-charts and include_charts are both accepted - so you can copy option names straight from this table without rewriting the separators.
[!TIP]
chart-line-coloraccepts hex with or without a leading#. Because a bare#starts a comment in YAML, either quote the value (chart-line-color: '#6b63ff') or drop the#(chart-line-color: 6b63ff).
Outputs
| Output | Description |
|---|---|
total-stars |
Total star count |
stars-changed |
true / false |
new-stars |
Stars gained |
lost-stars |
Stars lost |
should-notify |
Threshold reached: true / false |
new-stargazers |
New stargazers count |
report |
Full Markdown report |
report-html |
HTML report (for email) |
report-html-path |
File path to the HTML report (for large reports / custom mailers) |
report-csv |
CSV report (for data pipelines) |
API Reference: Complete inputs, outputs, and data formats
---
config:
look: handDrawn
theme: neutral
---
flowchart TD
trigger(["Workflow Trigger"])
config["Parse configuration"]
fetch["Query GitHub REST API(repositories endpoint)"]
filter["Apply filter criteria"]
init["Initialize orphan branch"]
read["Deserialize previous state snapshot"]
compare["Compute delta metrics"]
stargazers["Fetch stargazers (starred_at)"]
history["Build real star history"]
forecast["Compute growth forecast"]
md["Markdown report"]
json["JSON dataset"]
csv["CSV report"]
svg["SVG badge"]
html["HTML digest"]
charts["SVG charts"]
commit["Git commit & push (data branch)"]
setout["Export action outputs"]
email{"SMTP configured?"}
send["Dispatch notification"]
trigger --> config --> fetch --> filter
filter --> init --> read --> compare
compare --> stargazers --> history --> forecast
forecast --> md & json & csv & svg & html & charts
md & json & csv & svg & html & charts --> commit --> setout --> email
email -->|Yes| send
style trigger fill:#e1f5ff,stroke:#01579b,stroke-width:2px
style config fill:#fff3e0,stroke:#e65100,stroke-width:2px
style fetch fill:#fff3e0,stroke:#e65100,stroke-width:2px
style filter fill:#fff3e0,stroke:#e65100,stroke-width:2px
style init fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style read fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style compare fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style stargazers fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style history fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style forecast fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
style md fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
style json fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
style csv fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
style svg fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
style html fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
style charts fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
style commit fill:#fce4ec,stroke:#880e4f,stroke-width:2px
style setout fill:#fce4ec,stroke:#880e4f,stroke-width:2px
style email fill:#fce4ec,stroke:#880e4f,stroke-width:2px
style send fill:#fce4ec,stroke:#880e4f,stroke-width:2px
How It Works: Full architecture and execution pipeline
The charts plot the real historical curve: every star is placed on the date it was actually given. Each stargazer carries a starred_at timestamp (GitHub's application/vnd.github.star+json media type), and the action reconstructs the cumulative star count over real time from those dates, so the timeline runs from a repo's very first star up to now, regardless of when you started running the action.
The per-run snapshots on the data branch are still kept for the report's delta tables and notifications ("how many stars changed since the last run"), but the charts themselves no longer depend on them.
One caveat: GitHub caps the stargazers listing at roughly 40,000 per repo (oldest first), so for very large repos the most recent stars are unreachable. The reachable history is drawn accurately and the recent tail is bridged with a straight ramp up to the true current total, so the early curve stays accurate and the chart never goes flat at the end. Pair this with smart-sampling to keep the request cost bounded on big repos.
The line style is configurable via chart-curve (monotone by default, plus catmull-rom, cubic-bezier and rounded-step), along with theme, colors, milestones, point markers, the time window and more. See the examples gallery for a rendered comparison of every option.
Tip
SVG charts automatically adapt to dark and light mode. No extra configuration needed - they use prefers-color-scheme to match the viewer's theme.
Viewing Reports: All access methods (data branch, badges, outputs, email)
| Guide | Description |
|---|---|
| Getting Started | Setup from token to first run |
| How It Works | Execution flow and architecture |
| Configuration | All options and settings |
| API Reference | Inputs, outputs, and data formats |
| Examples | Real-world workflow configurations |
| Star Trend Charts | Chart types, embedding, and customization |
| Email Notifications | Built-in SMTP and external action setup |
| Viewing Reports | Data branch, badges, outputs, raw data |
| Data Management | Storage, rotation, and manual management |
| Internationalization | Multi-language support |
| Personal Access Token | Classic and fine-grained token setup |
| Technical Stack | Technologies and design decisions |
| Known Limitations | Constraints and workarounds |
| Troubleshooting | Common issues and solutions |
If you find this project useful, consider supporting its development:
This project uses AI assistance primarily for documentation purposes. AI tools (GitHub Copilot, Claude) were used to:
- Write and improve documentation (README, wiki pages)
- Generate boilerplate code and configuration files
- Assist with code reviews and suggestions
The core logic, architecture decisions, and implementation were developed by the maintainer. All AI-generated content has been reviewed and validated.
AGPL-3.0 © Made with 🤘🏼 by Ferran Buireu