# waka-readme-stats is a cron job that rewrites your README from two HTML comments

> anmol098/waka-readme-stats is a Python GitHub Action that takes your WakaTime coding data and commits a metrics block back into your profile README. The integration is two comment markers and a scheduled run, and the sample workflow it documents pins the action to the master branch rather than to any of its three releases, so a nightly job executes whatever is on the branch that morning.

**anmol098/waka-readme-stats** — This GitHub action helps to add cool dev metrics to your github profile Readme

- Repository: https://github.com/anmol098/waka-readme-stats
- Stars: 3,998 · Forks: 648
- Language: Python
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/anmol098-waka-readme-stats

## The sample workflow pins the action to master, not to a release

The workflow the page asks you to copy references the action by branch:

```yml
name: Waka Readme

on:
  schedule:
    # Runs at 12am IST
    - cron: '30 18 * * *'
  workflow_dispatch:
jobs:
  update-readme:
    name: Update Readme with Metrics
    runs-on: ubuntu-latest
    steps:
      - uses: anmol098/waka-readme-stats@master
        with:
          WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
```

That reference is the line to look at twice. The repository has three tagged releases, a fifth major version from 2026-01-04, a fourth from 2021 and a third from 2020, and the documented usage takes none of them, so every scheduled run executes whatever is on the branch at that moment. The rest of the workflow is conventional: a nightly schedule whose comment puts it at midnight in India, a manual dispatch trigger so you can force a run, an Ubuntu runner, and two repository secrets passed in as inputs. The page also points at two cron expression generators rather than explaining the schedule format, on the assumption you can read a five field expression.

## Commit metrics require a token scope the page itself calls dangerous

There are two secrets, and the second one is the interesting decision. The WakaTime key comes from the account settings page, and the GitHub token is only needed if you want commit metrics, which the page describes as requiring the `repo` and `user` scopes. It then adds a note that enabling `repo` seems dangerous, and immediately narrows what the action does with it: it only accesses commit timestamps and the number of lines added or deleted in repositories you contributed to. That is a claim about the code rather than about the permission, and the permission itself is the broad one, since `repo` covers private repositories. The action writes back to your repository with a bot identity by default, and those defaults are spelled out as flags: the commit username defaults to `readme-bot`, the commit email to the GitHub Actions bot address, and the commit message to Updated with Dev Metrics, with a flag available to commit under your own name and email instead.

## The Dockerfile hardcodes the same bot identity it documents as a default

The container image bakes the commit identity in, which means the defaults are not only documented but enforced. Two lines in the Dockerfile run git config globally before the source is copied:

```bash
RUN git config --global user.name "readme-bot"
RUN git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
```

The rest of the image explains the rest of the dependency picture. It starts from python:3.13-alpine with unbuffered output and bytecode writing disabled, creates an assets directory up front, installs a compiler and the image libraries with apk, and then installs the requirements file with pip. Git is installed in the image too, since committing is the last step of every run. The entrypoint is a shell form that changes into the working directory and runs main.py. So there are two places where the bot identity exists, the flag defaults on the page and the global git configuration in the image, and both name the same account.

## Two HTML comments are the whole integration

The contract with your README is a pair of markers and nothing else:

```md
<!--START_SECTION:waka-->
<!--END_SECTION:waka-->
```

Everything the action generates goes between them, and the word `waka` is just a default. The `SECTION_NAME` flag can be any string, which is what lets several blocks coexist in one file, and the same mechanism is used elsewhere in the project: the language switcher at the top of the page is itself wrapped in a navbar start and end pair, so the translation list is regenerated by the same kind of write. The two lines are described as the entry points for the metrics. There is no other integration surface to speak of, no configuration file in your repository and no plugin, so removing the action later means deleting the markers and the scheduled workflow.

## The example environment file lists inputs the page never explains

A file called `.env.example` at the repository root is the closest thing to a full option list, and it disagrees with the documentation in one place. The page says that by default all flags are enabled except the lines of code flag, because that operation is heavy, while the example file sets `INPUT_SHOW_LINES_OF_CODE=True` and is included by the Makefile as the default environment, so a local run and a fresh action run do not start from the same state. The example also carries inputs whose meaning the visible part of the page does not give: a commit-single switch, a symbol version, a force add flag, debug logging plus a separate debug run flag, and a group of presentation values including a badge style of flat, a bar style, a bar radius of zero and four hex colours that are GitHub's own dark theme values. There is a separate documented flag for the updated date format, which defaults to a day, month, year, hour, minute and second pattern.

## The AI coding block stays empty unless WakaTime is already recording it

Two flags control the newest output. One hides the all time AI Code Time badge, and the other hides the weekly breakdown, which the page itemises as AI coding time, AI lines against human written lines, token usage, an estimated AI cost, a count of sessions and prompts, a per model breakdown and what it calls deduced insights. Both depend on data that has to exist before the action runs, and the note attached to them is specific about the two failure shapes. If the account has no AI data at all time, the badge is hidden entirely, so the block is absent rather than zero. If the account has AI data overall but none for the current week, the weekly block still renders and shows a message saying no AI coding activity was tracked this week, instead of numbers. That distinction is the difference between a reader thinking the feature is broken and a reader understanding that a quiet week looks like that.

## The local Makefile tells you to run a target that does not exist

Local testing goes through a Makefile whose help text and target list disagree. The help target prints that the action can be tested locally with `make run`, and it is right about the intent and wrong about the name, because the target in the file is `run-locally`:

```make
run-locally: venv
	@ # Run action locally
	mkdir ./assets/ 2>/dev/null || true
	python3 ./sources/main.py
```

The file sets `.ONESHELL`, exports every variable and includes `.env.example` directly, with the virtual environment directory prepended to the path. The other targets build a venv and install the requirements, build and run the container with the example env file and the assets directory mounted, run flake8 and black at a line length of 160, and clean up, including a `repo` directory and any `package*.json` files that no other target creates. The help text also states Python 3.8 or newer for local runs and Docker 20 or newer for the image, while the Dockerfile is built on python:3.13-alpine.

## One dependency is pinned exactly and the rest are not

The requirements file is grouped by role, and the pinning style is not consistent across those groups. The GitHub integration entries are `PyGithub==2.8.1`, pinned to a single exact release, and GitPython with a compatible release constraint. The markdown and formatting helpers are pytz and humanize, both loose. The drawing stack is numpy and matplotlib, the request layer is httpx and PyYAML, and the two code style checkers, black and flake8, are listed alongside them as install requirements rather than as development only extras:

```text
PyGithub==2.8.1
GitPython~=3.1
numpy~=2.3
matplotlib~=3.10
httpx~=0.27
PyYAML~=6.0
black~=25.12
flake8~=7.3
```

So the image installs a formatter and a linter on every run, while the library that talks to GitHub is the one component that cannot float. The repository root carries the action definition, the sources directory, the locales directory for the ten translations, the Dockerfile, the Makefile and this requirements file, with no lock file anywhere in the tree.

## Conclusion

This action is worth using if your profile README is where you keep your dev metrics anyway and you are comfortable letting a scheduled job commit to that repository, because the whole integration is two comment markers, a WakaTime key and a cron entry. It is a poor fit if you would rather not hand a token with repository scope to a third party action, or if you want the version you run pinned to something reviewed. Before you wire it up, check four things. Whether you pin the action reference to a release tag or to the branch, since the page's own sample uses the branch. Whether you need the commit metrics at all, since that is what requires the token scope the page itself calls dangerous, and what turns off the default exemption of the lines of code flag. Which secrets names you use, because the action reads its inputs from repository secrets in a fixed set of names. And whether the AI coding block will show anything, since it stays empty unless WakaTime is already recording AI activity on your account.

## FAQ

### What does waka-readme-stats write into my README?

Metrics derived from your WakaTime data: whether you are an early or a night person and when you are most productive, the languages you code in, your editors, projects and operating system, total code time, and, depending on flags, lines of code written, profile views, a per repository language breakdown, an updated date, and the AI coding blocks.

### Which secrets does waka-readme-stats need?

A WakaTime API key saved as WAKATIME_API_KEY and a GitHub token saved as GH_TOKEN. The GitHub token needs the repo and user scopes for the commit metrics, and the page notes that the repo scope seems dangerous while stating the action only reads commit timestamps and lines added or deleted in repositories you contributed to.

### Which languages is waka-readme-stats translated into?

Ten, listed in a switcher at the top of the page: English, German, Spanish, French, Hindi, Japanese, Korean, Portuguese, Russian and Chinese, with a LOCALE flag to choose one. The repository carries an open issue asking for translators.

### How do I schedule waka-readme-stats?

With a cron schedule in a workflow, the sample using 30 18 * * * so it runs at midnight in India, plus a workflow_dispatch trigger so you can run it by hand from the Actions tab. The page links two cron expression generators rather than explaining the format.

### Can I run waka-readme-stats outside GitHub Actions?

Yes. The Makefile creates a virtual environment and installs the requirements, a run target executes sources/main.py directly, and another target builds the container image and runs it with the example environment file. The help text asks for Python 3.8 or newer locally and Docker 20 or newer for the image.

## Sources

- [anmol098/waka-readme-stats on GitHub](https://github.com/anmol098/waka-readme-stats)
- [Issues](https://github.com/anmol098/waka-readme-stats/issues)
- [License: MIT](https://github.com/anmol098/waka-readme-stats/blob/master/LICENSE)
- [README](https://github.com/anmol098/waka-readme-stats/blob/master/README.md)
- [Releases](https://github.com/anmol098/waka-readme-stats/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/anmol098-waka-readme-stats
