{"id":17125333,"url":"https://github.com/astrochun/github-stats-pages","last_synced_at":"2025-10-27T10:08:30.232Z","repository":{"id":37032228,"uuid":"330507480","full_name":"astrochun/github-stats-pages","owner":"astrochun","description":"Retrieve statistics for a user's repositories and populate the information onto a GitHub static page","archived":false,"fork":false,"pushed_at":"2023-11-24T03:38:04.000Z","size":492,"stargazers_count":2,"open_issues_count":11,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-13T06:14:39.197Z","etag":null,"topics":["github","github-pages","github-stats-pages","python3","stats"],"latest_commit_sha":null,"homepage":"","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/astrochun.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"astrochun"}},"created_at":"2021-01-17T23:27:27.000Z","updated_at":"2023-05-02T14:15:36.000Z","dependencies_parsed_at":"2023-11-24T04:35:38.915Z","dependency_job_id":null,"html_url":"https://github.com/astrochun/github-stats-pages","commit_stats":{"total_commits":299,"total_committers":1,"mean_commits":299.0,"dds":0.0,"last_synced_commit":"0a548bbb4cd72a41d9c8ba31465fa3129a6738f0"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrochun%2Fgithub-stats-pages","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrochun%2Fgithub-stats-pages/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrochun%2Fgithub-stats-pages/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astrochun%2Fgithub-stats-pages/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/astrochun","download_url":"https://codeload.github.com/astrochun/github-stats-pages/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248670435,"owners_count":21142904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github","github-pages","github-stats-pages","python3","stats"],"created_at":"2024-10-14T18:44:42.080Z","updated_at":"2025-10-27T10:08:30.135Z","avatar_url":"https://github.com/astrochun.png","language":"CSS","readme":"# github-stats-pages\nRetrieve statistics for a user's repositories and populate the information onto a GitHub static page\n\n| Categories | Status                                                                                                                                                                                                                                                                                                                                                                                                                                             |\n|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| General    | ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/github-stats-pages) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)                                                                                                                                                                                                                                               |\n| CI/CD      | [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/astrochun/github-stats-pages/Python%20package/main?color=blue\u0026label=build\u0026logo=github)](https://github.com/astrochun/github-stats-pages/actions?query=workflow%3A%22Python+package%22+branch%3Amain) ![Coverage badge](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/wiki/astrochun/github-stats-pages/python-coverage-comment-action-badge.json) |\n| PyPI       | [![PyPI](https://img.shields.io/pypi/v/github-stats-pages?color=blue)](https://pypi.org/project/github-stats-pages) ![PyPI - Downloads](https://img.shields.io/pypi/dm/github-stats-pages?color=light%20green\u0026label=PyPI-download)                                                                                                                                                                                                                 |\n\n- [Overview](#overview)\n- [Requirements](#requirements)\n- [Deployment](#deployment)\n   - [GitHub Actions Deployment](#github-actions-deployment)\n   - [Docker Deployment](#docker-deployment)\n   - [From Source](#from-source)\n- [Installation](#installation)\n- [Execution](#execution)\n- [FAQ](#faq)\n- [Versioning](#versioning)\n- [Continuous Integration](#continuous-integration)\n- [Authors](#authors)\n- [License](#license)\n- [Used by](#used-by)\n\n## Overview\n\nThis software is both a GitHub Docker container action and a Python\npackaged software. The former allows for this to run to generate GitHub\npages while the latter gives flexibility to deploy on a variety of\ncompute resources (e.g., cloud, dev).\n\nSome key features of this software:\n\n1. Flexible - Designed to be deployed in a number of ways\n2. Python - Most of the code is Python (excluding static assets) with static types\n3. Copy-left license: This is supported by open source and thus is open source\n   with an MIT License!\n4. Continuous Integration - We currently have 100% code coverage of the Python\n   codebase and the Docker action\n5. Environmentally friendly - [Websitecarbon.com](https://www.websitecarbon.com/)\n   reported that a GitHub Pages deployment of this code has a lower carbon\n   footprint than 90% of web pages tested\n\n## Requirements\n\n[Traffic data](https://docs.github.com/en/github/visualizing-repository-data-with-graphs/viewing-traffic-to-a-repository)\nfor repositories are limited to those who have write or ownership access.\nThus, regardless of how you choose to deploy, you will need a token.\nThis codebase uses\n[GitHub's Personal Access Token (PAT)](https://github.blog/2013-05-16-personal-api-tokens/).\n\nTo create one, follow these\n[instructions](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token)\nor go [here](https://github.com/settings/tokens).\nFor scopes, select: `repo`. Save your PAT in a safe place as you will need it later.\n\n## Deployment\n\nThis code is intended to deploy in a number of ways to allow for the greatest flexibility.\nFirst, this repository is also as a\n[GitHub Docker container action](https://docs.github.com/en/actions/creating-actions/about-actions#docker-container-actions) (see [below](#github-actions-deployment)).\nSecond, this code is package on [PyPI](https://pypi.org/project/github-stats-pages/).\nThird, the source code can be [forked](https://github.com/astrochun/github-stats-pages/fork)\nor cloned.\nFinally, a [Dockerfile](Dockerfile) is included for containerization.\n\n### GitHub Actions Deployment\n\n#### TL;DR\n\nFor easy deployment, try this\n[GitHub template](https://github.com/astrochun/github-stats). Simply:\n\n1. [Use it!](https://github.com/astrochun/github-stats/generate)\n2. Add a Personal access token, as a repository secret, `GH_TOKEN`.\n   See [above](#requirements) (Settings \u003e Secrets)\n3. If not already enabled, enable GitHub Actions (Settings \u003e Actions)\n4. Sit back and enjoy that ☕️ !\n\nNote: After the first Action run, you may need to enable GitHub pages through\nthe  settings page and select `gh-pages` (Settings \u003e Pages)\n\n#### The Nitty Gritty\n\nGitHub Pages deployment is simple with the following GitHub Actions `cronjob` workflow:\n\n```yaml\nname: Deploy GitHub pages with traffic stats\n\non:\n  schedule:\n    - cron: \"0 3 * * *\"\n\njobs:\n  build-n-publish:\n    runs-on: ubuntu-latest\n    env:\n      BOT_NAME: 'github-actions[bot]'\n      BOT_EMAIL: '41898282+github-actions[bot]@users.noreply.github.com'\n\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v2\n    - name: Get current date\n      id: date\n      run: echo \"::set-output name=date::$(date +'%Y-%m-%d')\"\n    - name: Build GitHub stats pages\n      uses: astrochun/github-stats-pages@latest\n      with:\n        username: ${{ github.repository_owner }}\n        token: ${{ secrets.GH_TOKEN }}\n    - name: Upload data to main branch\n      uses: EndBug/add-and-commit@v7.0.0\n      with:\n        add: 'data'\n        branch: main\n        message: \"Update data: ${{ steps.date.outputs.date }}\"\n        author_name: env.BOT_NAME\n        author_email: env.BOT_EMAIL\n    - name: Upload static files to gh-pages\n      uses: peaceiris/actions-gh-pages@v3\n      with:\n        personal_token: ${{ secrets.GH_TOKEN }}\n        publish_dir: ./public\n        keep_files: false\n        user_name: env.BOT_NAME\n        user_email: env.BOT_EMAIL\n        publish_branch: gh-pages\n        commit_message: \"Update static pages: ${{ steps.date.outputs.date }}\"\n```\n\nThis workflow will run for all public repositories.\n\n##### Inputs\n\n| Variable        | Description                                                                                | Required? | Type  | Defaults | Examples                                   |\n|-----------------|--------------------------------------------------------------------------------------------|-----------|-------|----------|--------------------------------------------|\n| `username`      | GitHub username or organization                                                            | **Yes**   | `str` | N/A      | `astrochun`                                |\n| `token`         | GitHub Personal Access Token (PAT)                                                         | **Yes**   | `str` | N/A      | `abcdef12345678`                           |\n| `include-repos` | Comma-separated lists of repositories. This overrides the full list of public repositories | No        | `str` | `''`     | `'github-stats-pages,astrochun.github.io'` |\n| `exclude-repos` | Comma-separated lists of repositories to exclude from default public repository list       | No        | `str` | `''`     | `'repo1'`                                  |\n\n##### Other GitHub Action deployment examples:\n\nTo override all public repositories and limit to a subset of public repositories,\nspecify a comma-separated list (_no spaces between commas_) for `include-repos` argument.\n\n```yaml\n    - name: Build GitHub stats pages\n      uses: astrochun/github-stats-pages@latest\n      with:\n        username: ${{ github.repository_owner }}\n        token: ${{ secrets.GH_TOKEN }}\n        include-repos: \"github-stats-pages\"\n```\n\nAlternatively to exclude specific repositories from the list of public repositories,\nuse the `exclude-repos` argument with a comma-separated list (_no spaces between commas_).\n\n```yaml\n    - name: Build GitHub stats pages\n      uses: astrochun/github-stats-pages@latest\n      with:\n        username: ${{ github.repository_owner }}\n        token: ${{ secrets.GH_TOKEN }}\n        exclude-repos: \"repo1,repo2\"\n```\n\nNote that you can only specify `include-repos` _or_ `exclude-repos`.\n**Specifying both will fail**!\n\n### Docker Deployment\n\nThis repository includes a [Dockerfile](Dockerfile).\nMore details/instructions provided later.\n\n### From source\n\nTo run this code from original source, you will need to install it.\n\n#### Installation\n\nUse our [PyPI package](https://pypi.org/project/github-traffic-stats/) to\nget the most stable release:\n```\n(venv) $ pip install github-stats-pages\n```\n\nOr if you want the latest version then:\n```\n(venv) $ git clone https://github.com/astrochun/github-stats-pages\n(venv) $ cd github-stats_pages\n(venv) $ python setup.py install\n```\n\n#### Execution from source\n\nTL;DR: If you decide to run this code from source, there are a few things you should know.\n\nFirst, this repository includes an [`entrypoint.sh`](entrypoint.sh).\nYou can simply execute it with the following:\n```\n(venv) laptop:github_data $ username=\"\u003cusername\u003e\"\n(venv) laptop:github_data $ token=\"\u003cpersonal_access_token\u003e\"\n(venv) laptop:github_data $ /path/to/github-stats-pages/entrypoint.sh $username $token\n```\n\nSecond, it is recommended to create a folder (e.g., `github_data`) as the contents\nwill ultimately contain multiple files.\n\n#### More details\n\nHere's an overview providing more details how this codebase works.\nThere are four primary scripts accompanying `github-stats-pages`\n1. `get_repo_list`\n2. `gts_run_all_repos`\n3. `make_stats_plots`\n4. `merge_csv`\n\n`get_repo_list` generates a CSV file containing a list of public repositories\nfor a GitHub user/organization. This database allows the code to aggregate\nstatistics  for all repositories. To run, simply use the following command:\n\n```\n(venv) laptop:github_data $ get_repo_list -u \u003cusername/organization\u003e\n```\n\nThis will generate a CSV file called \"\u003cusername/organization\u003e.csv\".\nIt is recommended to create a folder (e.g., `github_data`) as the contents\nwill ultimately contain multiple files.\n\nNext, let's gather the statistics for all public repositories that are not\nforks. We use another Python library that does this called\n[github-traffic-stats](https://github.com/nchah/github-traffic-stats). It\nis accompanied by a `python` script called `gts`.\n\nTo access traffic data, this requires a PAT. See [above](#requirements)\nfor instructions. Then you can execute the next script:\n\n```\n(venv) laptop:github_data $ token='abcdef12345678'\n(venv) laptop:github_data $ gts_run_all_repos -u \u003cusername/organization\u003e -t $token -c \u003cusername/organization\u003e.csv\n```\n\nThis will generate CSV files with date and time stamps prefixes for clones,\ntraffic, and referrals. With routine running of this code, you will\ngenerate additional CSV files that allow for you to extend beyond a two-week\nwindow of data aggregation. The data can be merged with the `merge-csv.sh`\nscript:\n\n```\n(venv) laptop:github_data $ merge_csv\n```\n\nThis generates four files: merged_clone.csv, merged_paths.csv, merged_referrers.csv,\nand merge_traffic.csv. These files are used in the final step to generate the\nplots.\n\nFinally to generate static pages containing the visualization, we\nuse the `make_stats_plots` script:\n\n```\n(venv) laptop:github_data $ make_stats_plots -u \u003cusername\u003e -c \u003cusername\u003e.csv -t $token\n```\n\nThis will generate all contents in the local path. Note that you can specify\nan output directory with the `-o`/`--out-dir` option. Default is the current\npath.\n\nThe resulting folder structure, for example, will be the following:\n\n```\ngithub_data/\n├── data\n│   ├── 2021-01-17-00h-46m-clone-stats.csv\n│   ├── 2021-01-17-00h-46m-referrer-stats.csv\n│   ├── 2021-01-17-00h-46m-traffic-stats.csv\n│   ├── ...\n│   ├── merged_clone.csv\n│   ├── merged_paths.csv\n│   ├── merged_referrer.csv\n│   └── merged_traffic.csv\n├── repos\n│   ├── github-stats-pages.html\n│   └── ...\n├── styles\n|   ├── css\n|   │   └── style.css\n|   └── js\n|       ├── bootstrap.min.js\n|       ├── jquery.min.js\n|       ├── main.js\n|       └── popper.js\n├── about.html\n├── index.html\n├── repositories.html\n└── \u003cusername\u003e.csv\n```\n\n## FAQ\n\n### 1. How do I add old data?\n\nIf you ran this code outside your production deployment (e.g., GitHub pages),\nit is in fact straightforward to include those data.\n\nFor GitHub Pages deployment, simply:\n   1. `git clone` your copy of the [`github-stats`](https://github.com/astrochun/github-stats) repo\n   2. Move/copy previous CSV files to the `data` folder in the `main` branch.\n      These files follow a YYYY-MM-DD prefix\n   3. Then add, commit, and push:\n      `git add data/????-??-??*stats.csv`, `git commit -m \"Add old data\"`, `git push`\n\nOn the next GitHub Action scheduled run, the live pages will automatically incorporate these data.\n\nFor any other deployments (e.g., cloud), simply:\n   1. Move/copy/`rsync`/`scp` the previous CSV files to the `data` folder in the deployed instance\n\nUpon the next `cronjob` or script run, the old data will automatically be incorporated.\n\n### 2. How do I add content to the home page (`index.html`)?\n\nThe deployed `index.html` can be customized to provide a biography, cool\ngraphics, and/or additional statistics. This is possible through a\n[GitHub profile README](https://docs.github.com/en/github/setting-up-and-managing-your-github-profile/managing-your-profile-readme)\nthat you can create. The link above provides instruction for setting up one. This software\nwill convert the markdown content to HTML and include it in the `index.html`.\nAn example of the outcome can be found [here](https://astrochun.github.io/github-stats/).\n\nMany GitHub users have developed fancy GitHub profile READMEs:\n[https://github.com/abhisheknaiidu/awesome-github-profile-readme](https://github.com/abhisheknaiidu/awesome-github-profile-readme).\nBy including those in your profile README, they should be included in your deployed version.\nIf it doesn't work, feel free to reach out.\n\nNote: While a GitHub profile README does not work for an organization in the same manner as\nindividual GitHub accounts, this software will still use its content if it is publicly available.\nHere's an [example](https://ual-odis.github.io/github-stats/)\n\n### 3. What happens when I renamed a repository?\n\nThis software will retrieve the latest list of public repositories. When the\nstatistics pages are then generated, it searches the `data/` folder for the\ninformation for each repo. As such, there is an issue with renaming of\nrepositories. This will be apparent in the logs with the following warnings:\n```\nWARNING: Possible issue with repository name, ...\nIf you renamed it, you will need to update data/ contents\n```\n\nTo rectify this issue, you can `git clone` your GitHub repository, and rename\neach occurrence of the old repositories with the new ones using your preferred\nIDE or command-line options (e.g., `sed`). Then `git add`, `git commit`, and\n`git push` these changes. The next scheduled run will then work as intended.\n\n## Versioning\n\n## Continuous Integration\n\n## Authors\n\n* Chun Ly, Ph.D. ([@astrochun](http://www.github.com/astrochun))\n\nSee also the list of\n[contributors](https://github.com/astrochun/github-stats-pages/contributors) who participated in this project.\n\n\n## License\n\nThis project is licensed under the [MIT License](https://opensource.org/licenses/MIT) - see the [LICENSE](LICENSE) file for details.\n\n\n## Used by\n\nA list of repos using `github-stats-pages` can be found [here](https://github.com/topics/github-stats-pages).\n\n\u003c!-- start: readme-repos-list --\u003e\n\u003c!-- This list is auto-generated using koj-co/readme-repos-list --\u003e\n\u003c!-- Do not edit this list manually, your changes will be overwritten --\u003e\n[![astrochun/test-stats](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F20305734%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://github.com/astrochun/test-stats)\n[![schorschinho/github-stats-osprey](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F16669943%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://github.com/schorschinho/github-stats-osprey)\n[![hessevans/test1](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F85516139%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://github.com/hessevans/test1)\n[![awang-karisma/github-stats](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F4899660%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://github.com/awang-karisma/github-stats)\n[![UAL-RE/github-stats](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F61063507%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://UAL-RE.github.io/github-stats)\n[![thenomaniqbal/thenomaniqbal](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F45229497%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://github.com/thenomaniqbal/thenomaniqbal)\n[![Mo-Shakib/Mo-Shakib](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F50780268%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://github.com/Mo-Shakib/Mo-Shakib)\n[![hyochan/github-stats](https://images.weserv.nl/?url=avatars.githubusercontent.com%2Fu%2F27461460%3Fv%3D4\u0026h=50\u0026w=50\u0026fit=cover\u0026mask=circle\u0026maxage=7d)](https://stats.hyochan.dev)\n\u003c!-- end: readme-repos-list --\u003e\n","funding_links":["https://github.com/sponsors/astrochun"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastrochun%2Fgithub-stats-pages","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fastrochun%2Fgithub-stats-pages","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastrochun%2Fgithub-stats-pages/lists"}