Skip to content

One-Simon/GitStats

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitStats

Composite Action Auto README Updates GitHub REST API MIT License

GitStats is set of fully configurable language breakdown Cards for your Github Profile.

I didn´t like the functionality, nor the flexibility of existing projects. Hope you enjoy :)

What it is

  • README-driven config | gitstats:config blocks allow easy configurability.

  • Managed display | Paired gitstats:display markers auto generate Cards.

  • Flexible timeframe | Use all-time language bytes or recent weeks.

  • Two styles | normal extended bar & list. compact labeled bar.

  • Language cleanup | Hide languages, group entries into Other, and fully configure visibility.


GitStats normal language example

Recent compact language stats example



Quick Setup

1. Add the Workflow

Add this workflow to the repository where the Cards should be displayed.
For a GitHub profile README, that is usually YOUR_USERNAME/YOUR_USERNAME.

GitStats is published as a reusable GitHub Action.
the workflow decides when the action runs and grants write permission to the current repository.
GitStats reads README config blocks, generates Cards & updates managed display sections automatically.

name: GitStats

on:
  workflow_dispatch:
  schedule:
    - cron: "17 3 * * 1"
  push:
    branches:
      - main
    paths-ignore:
      - "profile/*.svg"

concurrency:
  group: gitstats-${{ github.ref }}
  cancel-in-progress: true

jobs:
  languages:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v6

      - name: Generate language stats
        uses: One-Simon/GitStats@main
        with:
          token: ${{ secrets.GITSTATS_TOKEN }}
          username: YOUR_USERNAME

2. Add Config Blocks in README

Add a Config Block inside the README for each Card.
Each Card can have a set of settings that let you customize them extensively.

Almost all of them are optional. Only set the values you want to change.
This is the minimal necessary setup:

<!-- gitstats:config
style: normal
timeframe: all-time
gitstats:config -->

<!-- gitstats:config
style: compact
timeframe: 8
gitstats:config -->

3. Add a Display Section

GitStats displays the Cards between the markers with generated image tags.
You do not need to add SVG paths or <img> tags yourself.
The surrounding <div> is yours, you can center the cards, place them in a table, or use any other README layout GitHub supports.

<div align="center">
<!-- gitstats:display -->
<!-- gitstats:display -->
</div>

Tip

You can also display the Cards seperate from one another and show them wherever you like.

For this, name the Configuration blocks however you like:

<!-- gitstats:config allTime
style: normal
timeframe: all-time
gitstats:config -->

<!-- gitstats:config recent
style: compact
timeframe: 8
gitstats:config -->

The block names become the Card names.
These examples generate profile/allTime.svg and profile/recent.svg.

Then display them seperately:

<div align="center">
<!-- gitstats:display allTime-->
<!-- gitstats:display allTime-->
</div>

-----------------

<div align="center">
<!-- gitstats:display recent-->
<!-- gitstats:display recent-->
</div>

4. Token Setup

GitStats needs a Personal Access Token because the default GITHUB_TOKEN only has access to the repository running the workflow.

Recommended secret name:

GITSTATS_TOKEN

For classic Personal Access Tokens:

repo
read:user

For fine-grained Personal Access Tokens:

  • Set Repository access to the repositories you want included, or All repositories.
  • Set Repository permissions -> Metadata to Read-only.
  • For recent renders such as timeframe: 8, also set Repository permissions -> Contents to Read-only.
  • If the token is scoped to an organization with SSO, authorize the token for that organization.

Important

All-time cards use GitHub language byte metadata. Recent cards also ask GitHub for commit file paths and change counts, which is why fine-grained tokens need Contents: read. GitStats does not write repository contents or include private repository/source names in the generated SVG.


5. Run Once

Run the Workflow / Action once from the Actions tab.
After the first successful run, the generated Cards will be committed and displayed in your README. The workflow example above also refreshes the Cards automatically once per week.

Tip

To change a card immediately, edit the matching gitstats:config block and rerun the workflow.

Warning

DO NOT eidt the generated content between display markers.


Settings

Basic Settings

These are the settings you will most likely change first.

Setting Default Description
title Automatic Optional card title override. Defaults to Most Used Languages for all-time, or Recent Languages for numbered timeframes.
timeframe all-time all-time uses GitHub language bytes. A positive integer, such as 8, uses recent commit changes from that many weeks.
style normal normal renders the full card with a list. compact renders a thicker labeled bar.

Styling Settings

These settings change how each generated card is rendered or displayed in your README.

Setting Default Description
show-values true Shows byte or change totals in the normal renderer. Compact cards always show percentages only.
display-width 100% Width attribute for this card's generated <img> tag inside the managed display section.
display-alt Automatic Alt text for this card's generated <img> tag inside the managed display section.

Language Settings

These settings control which languages appear and how smaller entries are handled.

Setting Default Description
hide-languages HTML,CSS,JSON Comma-separated languages to exclude after loading all detected languages.
grouping true Groups the smallest languages into Other until the bucket is near 5%.
max-languages 10 Positive integer maximum for displayed entries, including Other. Overflow languages are grouped into Other.

Repository Settings

These settings control which repositories GitStats reads from GitHub.

Setting Default Description
include-forks false Includes forked repositories.
include-archived false Includes archived repositories.
include-profile-repo false Includes the username/username profile repository.
affiliation owner Repository affiliation passed to GitHub. Use owner,collaborator,organization_member for broader access.
visibility all Repository visibility passed to GitHub.


Grouping

You are able to choose to group small language sets and dynamically decide how much.
When grouping: true - GitStats groups the smallest languages into Other until that bucket is close to 5%, preferring a smaller bucket over larger ones.

Using max-languages you can set how many languages should be displayed (bar & list) - all remaining get grouped into Other.
If grouping is enabled, but the amount is larger than max-languages - the lowest remaining entries are also merged into Other.


Examples

Mix style, timeframe, and the other settings however you want. These four examples are the same configurable viewer with different settings.

All-Time, Normal

<!-- gitstats:config all-time-normal
style: normal
timeframe: all-time
gitstats:config -->

All-time normal language stats example


All-Time, Compact

<!-- gitstats:config all-time-compact
style: compact
timeframe: all-time
gitstats:config -->

All-time compact language stats example


Recent, Normal

<!-- gitstats:config recent-normal
style: normal
timeframe: 8
gitstats:config -->

Recent normal language stats example


Recent, Compact

<!-- gitstats:config recent-compact
style: compact
timeframe: 8
gitstats:config -->

Recent compact language stats example



Action Inputs

README config blocks drive Card generation.
Workflow inputs provide global defaults and automation behavior.

Input Default Description
token Required GitHub token used to read repositories, language data, and recent commit data.
username Repository owner GitHub username to generate stats for.
readme-config README.md README path containing GitStats config blocks.
commit true Commit and push changed generated SVGs and README display updates using the workflow checkout credentials.
max-languages 10 Positive integer maximum for displayed entries, including Other.
grouping true Group the smallest languages into Other until the bucket is near 5%.
hide-languages HTML,CSS,JSON Languages to exclude after loading all detected languages.
include-forks false Include forked repositories.
include-archived false Include archived repositories.
include-profile-repo false Include the username/username profile repository.
affiliation owner Repository affiliation passed to GitHub.
visibility all Repository visibility passed to GitHub.
title Automatic Global card title fallback. README config blocks can override it per card.
timeframe all-time all-time for language bytes, or a positive integer number of weeks for recent changes.
style normal Rendering style.
show-values true Show byte or change totals in the normal renderer.
user-agent GitStats-language-card User-Agent used for GitHub API requests.
api-request-timeout-ms 15000 Maximum time to wait for each GitHub API request before failing or retrying.
api-max-retry-seconds 60 Maximum total time to spend retrying safe transient GitHub API failures.
api-rate-limit-buffer 50 Minimum GitHub API requests to leave unused when estimating recent card commit-detail work.

How It Works

GitStats reads every gitstats:config block in your README and generates one Card for each block.

<!-- gitstats:config example-name
style: normal
timeframe: all-time
gitstats:config -->

Generated Paths

Save Paths get auto generated based on naming & Card type. Named blocks get saved on their name path. Named block names may contain only letters, numbers, dots, underscores, and hyphens, and cannot start with a dot.

Config type Output path
Named block, such as most-used profile/most-used.svg
Unnamed all-time normal block profile/GitStats-MostUsed-normal.svg
Duplicate generated path GitStats appends -2, -3, and so on.

Display Markers

Named display markers display the card of the corresponding block.
For example, <!-- gitstats:display most-used --> displays the card generated by <!-- gitstats:config most-used.

Marker Behavior
<!-- gitstats:display --> Displays all generated cards in config order.
<!-- gitstats:display most-used --> Displays only the matching named config block.

Note

Display markers should be paired, not used alone. GitStats rewrites only the content between the markers.

Warning

Only image tags & image width get injected. To adjust the width, use the display-width: setting
Layout HTML has to be OUTSIDE the markers - use the injected Cards however you like.

<div align="center">
<!-- gitstats:display -->
<!-- gitstats:display -->
</div>

Generation Flow

  1. Reads repository metadata visible to the token.
  2. Filters repositories by owner, forks, archived status, and profile repository settings.
  3. For a numbered timeframe, reads recent commit file paths and change counts.
  4. For timeframe: all-time - reads GitHub language byte totals.
  5. Applies hide-languages, dynamic grouping, and max-languages.
  6. Renders every SVG in memory before writing any file.
  7. Rewrites the marked README display section with matching image tags and spacing only after all cards succeed.
  8. Auto commits changed generated SVGs and README display updates with [skip ci], and refuses to push if the remote branch moved while the workflow was running.


Troubleshooting

Important

GitHub may cache README images for a short while after the workflow updates the SVG files. If the raw SVG file is correct but the README still shows the old card, wait a bit and refresh later.


The Workflow Succeeded, but the README Still Shows the Old Card

GitHub caches images rendered inside READMEs. Check the SVG file directly in the repository, for example profile/most-used.svg. If that raw file is updated, the workflow worked and the README image cache should catch up after a little while.


The Workflow Fails With Bad credentials

The stats token could be missing, blank, expired, revoked, or copied with the wrong value. GitStats trims the token and checks authentication before generating cards, so this error should happen before any SVG or README file is written. Rotate the secret, confirm the workflow uses the same secret name, and rerun the workflow.


The Workflow Fails With a Permission Error

Fine-grained tokens need Metadata: read for all-time cards and Contents: read for recent cards. If organization repositories are included, make sure SSO is authorized for the token. GitStats includes the endpoint type, card name, repository, request id, accepted permissions, and rate-limit state in the failure message when GitHub provides those headers.


The Workflow Fails With API Rate Limit Exceeded

GitStats reads repository, language, and commit data through the GitHub API. Wait until the rate limit reset time shown in the error, then rerun the workflow from the Actions tab. Recent cards can use more requests than all-time cards because they inspect commits and changed files inside the selected timeframe.

GitStats caches repeated work across matching cards and estimates the commit-detail budget before writing files. If the remaining quota is too low, it fails early instead of publishing partial stats. Lower the recent timeframe, exclude noisy repositories, or rerun after reset.


The Workflow Fails Because the Remote Branch Moved

GitStats fetches the checked-out branch before committing. If another push lands while the workflow is generating cards, GitStats fails clearly instead of pushing stale generated README content. Rerun the workflow after the branch is up to date.


The Card Does Not Use My README Config

Make sure the workflow uses readme-config: README.md or leaves that input at its default. Config blocks inside fenced code examples are ignored, so active blocks should live directly in the README body.


The Workflow Cannot Find a Display Block

Add paired <!-- gitstats:display --> markers to your README. GitStats needs those markers to know where it may write the generated image HTML. If you use a named display block, make sure the name matches a named gitstats:config block.



Notes

  • All-time numbers are GitHub language byte counts, not lines of code.
  • Recent numbers are commit file change counts, usually additions plus deletions. They show activity, not how much code exists in that language.
  • SVGs are vector graphics. Use display-width to control the generated image width, and use layout HTML outside the display markers for positioning.
  • Recent language detection is based on changed file paths and extensions.
  • Private repository names and source code are not written to the SVG.
  • Generated SVGs are public if committed to a public repository.
  • Automatic commits use the workflow GITHUB_TOKEN from actions/checkout, not the stats token.

License

MIT

About

Generate GitHub profile language stats as an SVG, including private repositories via a token

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors