A minimalist tool to synchronize your GitHub Profile stats. Built with Deno and TypeScript, it uses the GitHub GraphQL API for fast data fetching and headless templating.
This project follows a Headless Templating approach:
- Source:
README.template.md(Markdown with placeholders). - Logic: Deno + TS scripts fetch data from GitHub GraphQL.
- Renderer: Injects stats into placeholders like
{{languages}}and{{commit}}. - Deploy: GitHub Actions automates the sync every 12 hours to your public profile repository.
- Runtime: Deno
- Language: TypeScript
- API: GitHub GraphQL API v4
- Automation: GitHub Actions (Cron)
- Formatting: deno fmt
-
Clone this repository.
-
Install dependencies:
deno install
-
Initialize the environment file and enable the pre-commit hook (runs
deno check+deno lint+deno fmt --check, blocks red commits):deno task setup
-
Set up your
GH_TOKENin the.envfile (see the Authentication section below). -
Run the generator:
deno run -A scripts/index.ts <path-to-target-readme>
SSoT for what get fetch, render, and ship. It stays plain JSON on purpose: the script imports it
native (with { type: 'json' })
| Key | Meaning |
|---|---|
allowedOwner |
Only repos from these owners count. Everything else (other orgs, strangers) is ignored |
excludedLanguages |
Languages dropped from the language chart: noise entries (Procfile, Rich Text Format) or languages you don't want to signal |
topLanguagesCount |
How many bars the chart keeps after sorting by byte size |
output.readme |
Write the README target at all |
output.stats |
Write stats.json (CI ships it to the profile repo) |
output.readmeSections |
Which ASCII sections render (profile, codebase, languages, commit). They only show up if the template carries the matching placeholder |
This project requires a GitHub Personal Access Token (PAT). You can use either:
- Fine-grained PAT: (Recommended) Requires
Contents (Read/Write),Workflows (Read/Write), andProfile (Read-only)permissions. - Classic PAT: (Easier for multiple organizations) Requires
repo,workflow, andread:userscopes.
For local development, copy .env.example to .env and add your GH_TOKEN:
cp .env.example .env
# Edit .env and add your GH_TOKENThe CI workflow requires the following repository secret:
| Secret | Description |
|---|---|
GH_TOKEN |
GitHub PAT with repo, workflow, read:user scopes (or fine-grained equivalent) |
# Read token from stdin, never appear in shell history
gh secret set GH_TOKEN < /path/to/token.txt
# Or pipe directly, not recommended:
echo "ghp_xxxxxxxxxxxx" | gh secret set GH_TOKEN
# with explicit repo (useful in CI/script):
gh secret set GH_TOKEN --repo your-username/your-repo- Go to your repository → Settings → Secrets and variables → Actions
- Click New repository secret
- Name:
GH_TOKEN, Value: your PAT
See the GitHub CLI quickstart for installation and auth:
gh auth loginUpdates happen twice a day at 05:00 & 17:00 UTC. Check .github/workflows/stats.yml for the
CI/CD pipeline details.
The workflow uses repository variables for configurable values. Set them in Settings → Variables (not Secrets) of your repository:
# Public profile repository (format: owner/repo)
gh variable set PUBLIC_PROFILE_REPO --body "your-username/your-profile-repo"
# Git author email for commits
gh variable set GIT_AUTHOR_EMAIL --body "your-email@example.com"
# Git author name for commits
gh variable set GIT_AUTHOR_NAME --body "Your Name"- Go to your repository → Settings → Variables (under "Secrets and variables")
- Click New repository variable
- Add each variable:
PUBLIC_PROFILE_REPO,your-username/your-profile-repoGIT_AUTHOR_EMAIL,your-email@example.comGIT_AUTHOR_NAME,Your Name
Zero-bloat. Performance-first. Scalable.