Automated monthly metrics for Fueled's open source projects.
A self-contained OSS metrics tracker for Fueled's public GitHub repos, their WordPress.org plugins, and npm packages. Runs monthly via GitHub Actions, stores data as JSON, and serves a static dashboard via GitHub Pages.
Dashboard: https://fueled.github.io/oss-metrics/
- On the 1st of each month at 6AM UTC, a GitHub Action runs
scripts/collect_stats.py - The script fetches stars, forks, watchers, dependents, and release counts from the GitHub API, plus active installs, downloads, and ratings from the WordPress.org Plugins API, plus monthly downloads and dependents counts from the npm public APIs
- Results are written to
data/stats/YYYY-MM.jsonand committed back to the repo - GitHub Pages is triggered to rebuild the static dashboard
- A Slack notification is sent to
#oss-practiceonce the dashboard is live (requiresSLACK_WEBHOOK_URLrepo secret) - The static dashboard at
index.htmlloads those JSON files viafetch()and renders charts and tables
The collection script requires a GitHub Personal Access Token to raise the API rate limit from 60 to 5,000 requests/hour.
This repo uses the org-level secret BOT_PUBLIC_GITHUB_TOKEN (a PAT with public_repo read-only scope). No additional secret setup is needed — the org secret is inherited automatically.
- Go to Settings → Pages
- Source: Deploy from a branch
- Branch:
main, folder:/(root) - Save — GitHub will publish the dashboard at
https://fueled.github.io/oss-metrics/
To receive a Slack notification in #oss-practice after each monthly run:
- Create an incoming webhook for the Fueled Slack workspace pointing at
#oss-practice - Add the webhook URL as a repo secret named
SLACK_WEBHOOK_URL
The workflow step is skipped gracefully if the secret is not set.
Go to Actions → Monthly Stats Collection → Run workflow to collect the first month of data immediately.
# Install dependencies
pip install -r scripts/requirements.txt
# Run for the previous calendar month (default)
GH_TOKEN=your_token python scripts/collect_stats.py
# Run for a specific month (backfill)
GH_TOKEN=your_token python scripts/collect_stats.py --period 2025-03Output is written to data/stats/YYYY-MM.json and data/stats/index.json is updated.
Edit data/config.yml. Each entry supports GitHub, WordPress.org, and npm tracking:
repos:
- github: "owner/repo" # GitHub repo slug (exact casing)
label: "Human-readable name"
wordpress_slug: "plugin-slug" # WordPress.org plugin slug, or null
npm_slug: "@scope/package-name" # npm package name, or nullSet any slug to null if the project is not published on that platform.
oss-metrics/
├── .github/
│ └── workflows/
│ └── monthly-stats.yml # Cron + manual trigger
├── data/
│ ├── config.yml # Which repos to track
│ └── stats/
│ ├── index.json # Manifest of available monthly files
│ └── YYYY-MM.json # One file per month (auto-committed)
├── scripts/
│ ├── collect_stats.py # Data collection script
│ ├── backfill.py # One-time backfill from XLSX spreadsheet
│ └── requirements.txt
├── index.html # Self-contained dashboard (GitHub Pages root)
└── README.md
Each monthly file (data/stats/YYYY-MM.json) looks like:
{
"collected_at": "2025-05-01T06:05:00Z",
"period": "2025-04",
"repos": [
{
"github": "10up/ads-txt",
"label": "Ads.txt Manager",
"github_stats": {
"stars": 1234,
"watchers": 56,
"forks": 78,
"releases_this_month": 2,
"used_by_repositories": 890,
"used_by_packages": 12,
"used_by_total": 902
},
"wordpress_stats": {
"active_installs": 50000,
"total_downloads": 250000,
"rating": 92,
"num_ratings": 340
},
"npm_stats": {
"monthly_downloads": 18500,
"dependents": 42
}
}
]
}wordpress_statsisnullfor repos not published on WordPress.orgnpm_statsisnullfor repos not published on npm- Any metric that fails to fetch is stored as
nullrather than aborting the run - WordPress ratings are stored on a 0–100 scale (matching the WordPress.org API) and converted to 0–5 for display on the dashboard
Beta: This project is quite new and we're not sure what our ongoing support level for this will be. Bug reports, feature requests, questions, and pull requests are welcome. If you like this project please let us know, but be cautious using this in a Production environment!
