{
    "type": "project",
    "title": "GitHub Auditor",
    "canonical": "https://www.dealmobile.co.uk/projects/github-auditor",
    "path": "/projects/github-auditor",
    "url": "https://www.dealmobile.co.uk/projects/github-auditor",
    "markdown": "https://www.dealmobile.co.uk/projects/github-auditor.md",
    "json": "https://www.dealmobile.co.uk/projects/github-auditor.json",
    "summary": "A Python CLI that keeps a local clone of every repository in your GitHub and Bitbucket accounts and writes Markdown reports from them. It can also archive, license, tag and reconfigure repositories in bulk.",
    "published": "2026-10-20T16:43:59+01:00",
    "modified": "2026-10-25T18:32:07+00:00",
    "image": {
        "url": "https://www.dealmobile.co.uk/sites/default/files/content/images/products/github-auditor-light.png",
        "alt": "Part of a GitHub Auditor activity report, rendered from its Markdown: a developer leaderboard of commits, lines, pull requests and reviews, a separate table for a dependency bot, and the lines left out of each person’s count. The organisation, repositories and people are made-up sample data."
    },
    "fields": {
        "featured": false,
        "kind": "tool",
        "licence": "MIT",
        "links": [
            {
                "title": "Source on GitHub",
                "url": "https://github.com/tomgould/github-auditor"
            }
        ],
        "stack": [
            "Python",
            "Click",
            "httpx",
            "Rich",
            "Git",
            "REST APIs",
            "pytest"
        ],
        "started": 2026,
        "status": "maintained",
        "tagline": "A command-line tool for looking after a lot of GitHub repositories at once, with reports on their health, on who has access and on what each developer did."
    },
    "body": {
        "html": "<p>GitHub Auditor is for anyone looking after more repositories than they can keep in their head: a personal account with years of projects, or an organisation with dozens of repositories and people. It keeps a local clone of every repository. From those clones and the GitHub API it writes Markdown reports: which repositories are missing a README or a licence, who has access to what, and what each developer did in a given week or month. The installed command is <code>auditer</code>.</p>\n<h2 id=\"what-it-does\">What it does</h2>\n<p>It has 13 commands. These four do most of the work:</p>\n<ul>\n<li><code>checkout</code> clones every repository in an account, or pulls the latest changes, into separate folders for public and private repositories. It reports new branches and tags, spots force pushes, leaves alone any clone with uncommitted changes, and warns about local copies of repositories that have been deleted from GitHub.</li>\n<li><code>audit</code> scans the clones, adds stars, forks, languages and topics from the API, and gives each repository a health score out of 100. The points come from having a README, a licence and a description, recent activity, not being archived and having few open issues. It also lists stale repositories and suggests which to pin.</li>\n<li><code>activity</code> reports what each developer did over a date range: commits, lines added and removed, pull requests opened and merged, merges, reviews, approvals, comments, issues and tags. The report has a leaderboard, daily and weekly breakdowns, a table for each repository and a section for each developer, with a link to every commit. It can cover one repository, one developer or several accounts at once.</li>\n<li><code>access</code> writes a matrix of every collaborator against every repository, showing the highest permission each one holds.</li>\n</ul>\n<p>The others make changes in bulk: add or remove collaborators, remove organisation members, archive stale repositories, add a licence file (MIT, Apache 2.0, GPL 3.0, or the 2- or 3-clause BSD licence), set topics, and change settings such as the description, the wiki or the visibility. The risky ones, such as removing people, archiving or changing visibility, ask for confirmation first. It can also write a README for a repository from its contents, or a profile README for an account.</p>\n<p>It works with any number of personal and organisation accounts, with other people’s public repositories, and with named projects that group repositories from several accounts. Bitbucket Cloud workspaces work for checkout, audit, activity, access, settings, READMEs, licences and listing collaborators and members.</p>\n<h2 id=\"how-its-built\">How it’s built</h2>\n<p>It’s a Python 3.10 command-line tool built with Click. It uses httpx for the GitHub and Bitbucket APIs, Rich for the terminal output and PyYAML for the configuration.</p>\n<p>Git does most of the work. The activity report reads commits, line counts and tags from the local clones, which is fast, costs no API requests and still works after access to an account has ended. Only pull requests, issues and reviews come from the API. If the API isn’t available, the report says so at the top and shows those columns as “n/a” rather than zero.</p>\n<p>The activity report is the largest part of the code, and most of it is about counting fairly. Date ranges are whole days in one timezone, for git and the API alike. Lock files, vendored code, test fixtures, data exports and binary files are left out of the line counts, and the report lists what was left out for each developer. Someone who commits under several names or email addresses gets one row, and bots get a table of their own. <a href=\"/writing/counting-developer-activity-from-git\">Counting developer activity from git</a> goes into the detail.</p>\n<p>Tokens live in a config file that git ignores. Git authenticates through a short-lived <code>GIT_ASKPASS</code> script, so a token never appears in a clone URL, and anything that looks like a GitHub token is masked in the logs. The GitHub client retries server errors, and when the hourly rate limit runs out it waits for the reset instead of failing. There are 910 tests, written with pytest, with respx standing in for the APIs.</p>\n<h2 id=\"how-to-use-it\">How to use it</h2>\n<p>It isn’t on PyPI, so install it from a clone:</p>\n<pre><code class=\"language-bash\">git clone https://github.com/tomgould/github-auditor.git\ncd github-auditor\npython3 -m venv .venv &amp;&amp; source .venv/bin/activate\npip install -e \".[dev]\"\ncp config.example.yaml config.yaml\n</code></pre>\n<p>Add your accounts and a personal access token to <code>config.yaml</code>, then clone everything and report on it:</p>\n<pre><code class=\"language-bash\">auditer checkout --all --full\nauditer audit --all\nauditer activity --account my-org --since 2026-10-01 --until 2026-10-14\n</code></pre>\n<p>The reports go into <code>reports/</code>, with a folder for each account. A script in <code>scripts/</code> runs the checkout for every account, ready to be called from cron each night.</p>"
    },
    "markdown_text": "---\ntitle: 'GitHub Auditor'\ncanonical: 'https://www.dealmobile.co.uk/projects/github-auditor'\nurl: 'https://www.dealmobile.co.uk/projects/github-auditor'\ntype: Project\nsummary: 'A Python CLI that keeps a local clone of every repository in your GitHub and Bitbucket accounts and writes Markdown reports from them. It can also archive, license, tag and reconfigure repositories in bulk.'\n---\n\n# GitHub Auditor\n\nA command-line tool for looking after a lot of GitHub repositories at once, with reports on their health, on who has access and on what each developer did.\n\n![Part of a GitHub Auditor activity report, rendered from its Markdown: a developer leaderboard of commits, lines, pull requests and reviews, a separate table for a dependency bot, and the lines left out of each person’s count. The organisation, repositories and people are made-up sample data.](https://www.dealmobile.co.uk/sites/default/files/styles/almanac_shot_md/public/content/images/products/github-auditor-light.png.webp?itok=KMDFxdi4)\n\n- **Kind:** Tool\n- **Status:** Maintained\n- **Started:** 2026\n- **Licence:** MIT\n- **Stack:** Python, Click, httpx, Rich, Git, REST APIs, pytest\n- **Links:** [Source on GitHub](https://github.com/tomgould/github-auditor)\n\nGitHub Auditor is for anyone looking after more repositories than they can keep in their head: a personal account with years of projects, or an organisation with dozens of repositories and people. It keeps a local clone of every repository. From those clones and the GitHub API it writes Markdown reports: which repositories are missing a README or a licence, who has access to what, and what each developer did in a given week or month. The installed command is `auditer`.\n\n## What it does\n\nIt has 13 commands. These four do most of the work:\n\n- `checkout` clones every repository in an account, or pulls the latest changes, into separate folders for public and private repositories. It reports new branches and tags, spots force pushes, leaves alone any clone with uncommitted changes, and warns about local copies of repositories that have been deleted from GitHub.\n- `audit` scans the clones, adds stars, forks, languages and topics from the API, and gives each repository a health score out of 100. The points come from having a README, a licence and a description, recent activity, not being archived and having few open issues. It also lists stale repositories and suggests which to pin.\n- `activity` reports what each developer did over a date range: commits, lines added and removed, pull requests opened and merged, merges, reviews, approvals, comments, issues and tags. The report has a leaderboard, daily and weekly breakdowns, a table for each repository and a section for each developer, with a link to every commit. It can cover one repository, one developer or several accounts at once.\n- `access` writes a matrix of every collaborator against every repository, showing the highest permission each one holds.\n\nThe others make changes in bulk: add or remove collaborators, remove organisation members, archive stale repositories, add a licence file (MIT, Apache 2.0, GPL 3.0, or the 2- or 3-clause BSD licence), set topics, and change settings such as the description, the wiki or the visibility. The risky ones, such as removing people, archiving or changing visibility, ask for confirmation first. It can also write a README for a repository from its contents, or a profile README for an account.\n\nIt works with any number of personal and organisation accounts, with other people’s public repositories, and with named projects that group repositories from several accounts. Bitbucket Cloud workspaces work for checkout, audit, activity, access, settings, READMEs, licences and listing collaborators and members.\n\n## How it’s built\n\nIt’s a Python 3.10 command-line tool built with Click. It uses httpx for the GitHub and Bitbucket APIs, Rich for the terminal output and PyYAML for the configuration.\n\nGit does most of the work. The activity report reads commits, line counts and tags from the local clones, which is fast, costs no API requests and still works after access to an account has ended. Only pull requests, issues and reviews come from the API. If the API isn’t available, the report says so at the top and shows those columns as “n/a” rather than zero.\n\nThe activity report is the largest part of the code, and most of it is about counting fairly. Date ranges are whole days in one timezone, for git and the API alike. Lock files, vendored code, test fixtures, data exports and binary files are left out of the line counts, and the report lists what was left out for each developer. Someone who commits under several names or email addresses gets one row, and bots get a table of their own. [Counting developer activity from git](https://www.dealmobile.co.uk/writing/counting-developer-activity-from-git.md) goes into the detail.\n\nTokens live in a config file that git ignores. Git authenticates through a short-lived `GIT_ASKPASS` script, so a token never appears in a clone URL, and anything that looks like a GitHub token is masked in the logs. The GitHub client retries server errors, and when the hourly rate limit runs out it waits for the reset instead of failing. There are 910 tests, written with pytest, with respx standing in for the APIs.\n\n## How to use it\n\nIt isn’t on PyPI, so install it from a clone:\n\n```bash\ngit clone https://github.com/tomgould/github-auditor.git\ncd github-auditor\npython3 -m venv .venv && source .venv/bin/activate\npip install -e \".[dev]\"\ncp config.example.yaml config.yaml\n\n```\n\nAdd your accounts and a personal access token to `config.yaml`, then clone everything and report on it:\n\n```bash\nauditer checkout --all --full\nauditer audit --all\nauditer activity --account my-org --since 2026-10-01 --until 2026-10-14\n\n```\n\nThe reports go into `reports/`, with a folder for each account. A script in `scripts/` runs the checkout for every account, ready to be called from cron each night.\n\n---\n\nIndex of this site: [llms.txt](https://www.dealmobile.co.uk/llms.txt)\n"
}